Sat Jan 7 21:11:14 2017 UTC ()
kill alloca in favor of ssp


(christos)
diff -r1.13 -r1.14 src/sys/dev/dmover/swdmover.c

cvs diff -r1.13 -r1.14 src/sys/dev/dmover/swdmover.c (expand / switch to unified diff)

--- src/sys/dev/dmover/swdmover.c 2015/08/20 14:40:17 1.13
+++ src/sys/dev/dmover/swdmover.c 2017/01/07 21:11:14 1.14
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: swdmover.c,v 1.13 2015/08/20 14:40:17 christos Exp $ */ 1/* $NetBSD: swdmover.c,v 1.14 2017/01/07 21:11:14 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2002, 2003 Wasabi Systems, Inc. 4 * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -39,27 +39,27 @@ @@ -39,27 +39,27 @@
39 * swdmover.c: Software back-end providing the dmover functions 39 * swdmover.c: Software back-end providing the dmover functions
40 * mentioned in dmover(9). 40 * mentioned in dmover(9).
41 * 41 *
42 * This module provides a fallback for cases where no hardware 42 * This module provides a fallback for cases where no hardware
43 * data movers are present in a system, and also serves an an 43 * data movers are present in a system, and also serves an an
44 * example of how to write a dmover back-end. 44 * example of how to write a dmover back-end.
45 * 45 *
46 * Note that even through the software dmover doesn't require 46 * Note that even through the software dmover doesn't require
47 * interrupts to be blocked, we block them anyway to demonstrate 47 * interrupts to be blocked, we block them anyway to demonstrate
48 * the locking protocol. 48 * the locking protocol.
49 */ 49 */
50 50
51#include <sys/cdefs.h> 51#include <sys/cdefs.h>
52__KERNEL_RCSID(0, "$NetBSD: swdmover.c,v 1.13 2015/08/20 14:40:17 christos Exp $"); 52__KERNEL_RCSID(0, "$NetBSD: swdmover.c,v 1.14 2017/01/07 21:11:14 christos Exp $");
53 53
54#include <sys/param.h> 54#include <sys/param.h>
55#include <sys/kthread.h> 55#include <sys/kthread.h>
56#include <sys/systm.h> 56#include <sys/systm.h>
57#include <sys/uio.h> 57#include <sys/uio.h>
58 58
59#include <dev/dmover/dmovervar.h> 59#include <dev/dmover/dmovervar.h>
60 60
61#include "ioconf.h" 61#include "ioconf.h"
62 62
63struct swdmover_function { 63struct swdmover_function {
64 void (*sdf_process)(struct dmover_request *); 64 void (*sdf_process)(struct dmover_request *);
65}; 65};
@@ -137,42 +137,41 @@ swdmover_thread(void *arg) @@ -137,42 +137,41 @@ swdmover_thread(void *arg)
137static void 137static void
138swdmover_func_zero_process(struct dmover_request *dreq) 138swdmover_func_zero_process(struct dmover_request *dreq)
139{ 139{
140 140
141 switch (dreq->dreq_outbuf_type) { 141 switch (dreq->dreq_outbuf_type) {
142 case DMOVER_BUF_LINEAR: 142 case DMOVER_BUF_LINEAR:
143 memset(dreq->dreq_outbuf.dmbuf_linear.l_addr, 0, 143 memset(dreq->dreq_outbuf.dmbuf_linear.l_addr, 0,
144 dreq->dreq_outbuf.dmbuf_linear.l_len); 144 dreq->dreq_outbuf.dmbuf_linear.l_len);
145 break; 145 break;
146 146
147 case DMOVER_BUF_UIO: 147 case DMOVER_BUF_UIO:
148 { 148 {
149 struct uio *uio = dreq->dreq_outbuf.dmbuf_uio; 149 struct uio *uio = dreq->dreq_outbuf.dmbuf_uio;
150 char *cp; 150 char cp[1024];
151 size_t count, buflen; 151 size_t count, buflen;
152 int error; 152 int error;
153 153
154 if (uio->uio_rw != UIO_READ) { 154 if (uio->uio_rw != UIO_READ) {
155 /* XXXLOCK */ 155 /* XXXLOCK */
156 dreq->dreq_error = EINVAL; 156 dreq->dreq_error = EINVAL;
157 dreq->dreq_flags |= DMOVER_REQ_ERROR; 157 dreq->dreq_flags |= DMOVER_REQ_ERROR;
158 /* XXXUNLOCK */ 158 /* XXXUNLOCK */
159 break; 159 break;
160 } 160 }
161 161
162 buflen = uio->uio_resid; 162 buflen = uio->uio_resid;
163 if (buflen > 1024) 163 if (buflen > sizeof(cp))
164 buflen = 1024; 164 buflen = sizeof(cp);
165 cp = alloca(buflen); 
166 memset(cp, 0, buflen); 165 memset(cp, 0, buflen);
167 166
168 while ((count = uio->uio_resid) != 0) { 167 while ((count = uio->uio_resid) != 0) {
169 if (count > buflen) 168 if (count > buflen)
170 count = buflen; 169 count = buflen;
171 error = uiomove(cp, count, uio); 170 error = uiomove(cp, count, uio);
172 if (error) { 171 if (error) {
173 /* XXXLOCK */ 172 /* XXXLOCK */
174 dreq->dreq_error = error; 173 dreq->dreq_error = error;
175 dreq->dreq_flags |= DMOVER_REQ_ERROR; 174 dreq->dreq_flags |= DMOVER_REQ_ERROR;
176 /* XXXUNLOCK */ 175 /* XXXUNLOCK */
177 break; 176 break;
178 } 177 }
@@ -199,42 +198,41 @@ static void @@ -199,42 +198,41 @@ static void
199swdmover_func_fill8_process(struct dmover_request *dreq) 198swdmover_func_fill8_process(struct dmover_request *dreq)
200{ 199{
201 200
202 switch (dreq->dreq_outbuf_type) { 201 switch (dreq->dreq_outbuf_type) {
203 case DMOVER_BUF_LINEAR: 202 case DMOVER_BUF_LINEAR:
204 memset(dreq->dreq_outbuf.dmbuf_linear.l_addr, 203 memset(dreq->dreq_outbuf.dmbuf_linear.l_addr,
205 dreq->dreq_immediate[0], 204 dreq->dreq_immediate[0],
206 dreq->dreq_outbuf.dmbuf_linear.l_len); 205 dreq->dreq_outbuf.dmbuf_linear.l_len);
207 break; 206 break;
208 207
209 case DMOVER_BUF_UIO: 208 case DMOVER_BUF_UIO:
210 { 209 {
211 struct uio *uio = dreq->dreq_outbuf.dmbuf_uio; 210 struct uio *uio = dreq->dreq_outbuf.dmbuf_uio;
212 char *cp; 211 char cp[1024];
213 size_t count, buflen; 212 size_t count, buflen;
214 int error; 213 int error;
215 214
216 if (uio->uio_rw != UIO_READ) { 215 if (uio->uio_rw != UIO_READ) {
217 /* XXXLOCK */ 216 /* XXXLOCK */
218 dreq->dreq_error = EINVAL; 217 dreq->dreq_error = EINVAL;
219 dreq->dreq_flags |= DMOVER_REQ_ERROR; 218 dreq->dreq_flags |= DMOVER_REQ_ERROR;
220 /* XXXUNLOCK */ 219 /* XXXUNLOCK */
221 break; 220 break;
222 } 221 }
223 222
224 buflen = uio->uio_resid; 223 buflen = uio->uio_resid;
225 if (buflen > 1024) 224 if (buflen > sizeof(cp))
226 buflen = 1024; 225 buflen = sizeof(cp);
227 cp = alloca(buflen); 
228 memset(cp, dreq->dreq_immediate[0], buflen); 226 memset(cp, dreq->dreq_immediate[0], buflen);
229 227
230 while ((count = uio->uio_resid) != 0) { 228 while ((count = uio->uio_resid) != 0) {
231 if (count > buflen) 229 if (count > buflen)
232 count = buflen; 230 count = buflen;
233 error = uiomove(cp, count, uio); 231 error = uiomove(cp, count, uio);
234 if (error) { 232 if (error) {
235 /* XXXLOCK */ 233 /* XXXLOCK */
236 dreq->dreq_error = error; 234 dreq->dreq_error = error;
237 dreq->dreq_flags |= DMOVER_REQ_ERROR; 235 dreq->dreq_flags |= DMOVER_REQ_ERROR;
238 /* XXXUNLOCK */ 236 /* XXXUNLOCK */
239 break; 237 break;
240 } 238 }
@@ -324,45 +322,43 @@ swdmover_func_xor_process(struct dmover_ @@ -324,45 +322,43 @@ swdmover_func_xor_process(struct dmover_
324 *dst8 ^= *src8; 322 *dst8 ^= *src8;
325 } 323 }
326 dst8++; 324 dst8++;
327 } 325 }
328 } 326 }
329 327
330 break; 328 break;
331 329
332 case DMOVER_BUF_UIO: 330 case DMOVER_BUF_UIO:
333 { 331 {
334 struct uio *uio_out = dreq->dreq_outbuf.dmbuf_uio; 332 struct uio *uio_out = dreq->dreq_outbuf.dmbuf_uio;
335 struct uio *uio_in = dreq->dreq_inbuf[0].dmbuf_uio; 333 struct uio *uio_in = dreq->dreq_inbuf[0].dmbuf_uio;
336 struct uio *uio; 334 struct uio *uio;
337 char *cp, *dst; 335 char cp[1024], dst[1024];
338 size_t count, buflen; 336 size_t count, buflen;
339 int error; 337 int error;
340 338
341 if (uio_in->uio_rw != UIO_WRITE || 339 if (uio_in->uio_rw != UIO_WRITE ||
342 uio_out->uio_rw != UIO_READ || 340 uio_out->uio_rw != UIO_READ ||
343 uio_in->uio_resid != uio_out->uio_resid) { 341 uio_in->uio_resid != uio_out->uio_resid) {
344 /* XXXLOCK */ 342 /* XXXLOCK */
345 dreq->dreq_error = EINVAL; 343 dreq->dreq_error = EINVAL;
346 dreq->dreq_flags |= DMOVER_REQ_ERROR; 344 dreq->dreq_flags |= DMOVER_REQ_ERROR;
347 /* XXXUNLOCK */ 345 /* XXXUNLOCK */
348 break; 346 break;
349 } 347 }
350 348
351 buflen = uio_in->uio_resid; 349 buflen = uio_in->uio_resid;
352 if (buflen > 1024) 350 if (buflen > sizeof(cp))
353 buflen = 1024; 351 buflen = sizeof(cp);
354 cp = alloca(buflen); 
355 dst = alloca(buflen); 
356 352
357 /* 353 /*
358 * For each block, copy first input buffer into the destination 354 * For each block, copy first input buffer into the destination
359 * buffer and then read the rest, one by one, into a temporary 355 * buffer and then read the rest, one by one, into a temporary
360 * buffer and xor into the destination buffer. After all of 356 * buffer and xor into the destination buffer. After all of
361 * the inputs have been xor'd in, move the destination buffer 357 * the inputs have been xor'd in, move the destination buffer
362 * out and loop. 358 * out and loop.
363 */ 359 */
364 while ((count = uio_in->uio_resid) != 0) { 360 while ((count = uio_in->uio_resid) != 0) {
365 if (count > buflen) 361 if (count > buflen)
366 count = buflen; 362 count = buflen;
367 error = uiomove(dst, count, uio_in); 363 error = uiomove(dst, count, uio_in);
368 if (error) { 364 if (error) {
@@ -430,44 +426,43 @@ swdmover_func_copy_process(struct dmover @@ -430,44 +426,43 @@ swdmover_func_copy_process(struct dmover
430 dreq->dreq_flags |= DMOVER_REQ_ERROR; 426 dreq->dreq_flags |= DMOVER_REQ_ERROR;
431 /* XXXUNLOCK */ 427 /* XXXUNLOCK */
432 break; 428 break;
433 } 429 }
434 memcpy(dreq->dreq_outbuf.dmbuf_linear.l_addr, 430 memcpy(dreq->dreq_outbuf.dmbuf_linear.l_addr,
435 dreq->dreq_inbuf[0].dmbuf_linear.l_addr, 431 dreq->dreq_inbuf[0].dmbuf_linear.l_addr,
436 dreq->dreq_outbuf.dmbuf_linear.l_len); 432 dreq->dreq_outbuf.dmbuf_linear.l_len);
437 break; 433 break;
438 434
439 case DMOVER_BUF_UIO: 435 case DMOVER_BUF_UIO:
440 { 436 {
441 struct uio *uio_out = dreq->dreq_outbuf.dmbuf_uio; 437 struct uio *uio_out = dreq->dreq_outbuf.dmbuf_uio;
442 struct uio *uio_in = dreq->dreq_inbuf[0].dmbuf_uio; 438 struct uio *uio_in = dreq->dreq_inbuf[0].dmbuf_uio;
443 char *cp; 439 char cp[1024];
444 size_t count, buflen; 440 size_t count, buflen;
445 int error; 441 int error;
446 442
447 if (uio_in->uio_rw != UIO_WRITE || 443 if (uio_in->uio_rw != UIO_WRITE ||
448 uio_out->uio_rw != UIO_READ || 444 uio_out->uio_rw != UIO_READ ||
449 uio_in->uio_resid != uio_out->uio_resid) { 445 uio_in->uio_resid != uio_out->uio_resid) {
450 /* XXXLOCK */ 446 /* XXXLOCK */
451 dreq->dreq_error = EINVAL; 447 dreq->dreq_error = EINVAL;
452 dreq->dreq_flags |= DMOVER_REQ_ERROR; 448 dreq->dreq_flags |= DMOVER_REQ_ERROR;
453 /* XXXUNLOCK */ 449 /* XXXUNLOCK */
454 break; 450 break;
455 } 451 }
456 452
457 buflen = uio_in->uio_resid; 453 buflen = uio_in->uio_resid;
458 if (buflen > 1024) 454 if (buflen > sizeof(cp))
459 buflen = 1024; 455 buflen = sizeof(cp);
460 cp = alloca(buflen); 
461 456
462 while ((count = uio_in->uio_resid) != 0) { 457 while ((count = uio_in->uio_resid) != 0) {
463 if (count > buflen) 458 if (count > buflen)
464 count = buflen; 459 count = buflen;
465 error = uiomove(cp, count, uio_in); 460 error = uiomove(cp, count, uio_in);
466 if (error == 0) 461 if (error == 0)
467 error = uiomove(cp, count, uio_out); 462 error = uiomove(cp, count, uio_out);
468 if (error) { 463 if (error) {
469 /* XXXLOCK */ 464 /* XXXLOCK */
470 dreq->dreq_error = error; 465 dreq->dreq_error = error;
471 dreq->dreq_flags |= DMOVER_REQ_ERROR; 466 dreq->dreq_flags |= DMOVER_REQ_ERROR;
472 /* XXXUNLOCK */ 467 /* XXXUNLOCK */
473 break; 468 break;
@@ -585,42 +580,41 @@ swdmover_func_iscsi_crc32c_process(struc @@ -585,42 +580,41 @@ swdmover_func_iscsi_crc32c_process(struc
585 } 580 }
586 581
587 memcpy(&result, dreq->dreq_immediate, sizeof(result)); 582 memcpy(&result, dreq->dreq_immediate, sizeof(result));
588 583
589 switch (dreq->dreq_inbuf_type) { 584 switch (dreq->dreq_inbuf_type) {
590 case DMOVER_BUF_LINEAR: 585 case DMOVER_BUF_LINEAR:
591 result = iscsi_crc32c(dreq->dreq_inbuf[0].dmbuf_linear.l_addr, 586 result = iscsi_crc32c(dreq->dreq_inbuf[0].dmbuf_linear.l_addr,
592 dreq->dreq_inbuf[0].dmbuf_linear.l_len, result); 587 dreq->dreq_inbuf[0].dmbuf_linear.l_len, result);
593 break; 588 break;
594 589
595 case DMOVER_BUF_UIO: 590 case DMOVER_BUF_UIO:
596 { 591 {
597 struct uio *uio_in = dreq->dreq_inbuf[0].dmbuf_uio; 592 struct uio *uio_in = dreq->dreq_inbuf[0].dmbuf_uio;
598 uint8_t *cp; 593 uint8_t cp[1024];
599 size_t count, buflen; 594 size_t count, buflen;
600 int error; 595 int error;
601 596
602 if (uio_in->uio_rw != UIO_WRITE) { 597 if (uio_in->uio_rw != UIO_WRITE) {
603 /* XXXLOCK */ 598 /* XXXLOCK */
604 dreq->dreq_error = EINVAL; 599 dreq->dreq_error = EINVAL;
605 dreq->dreq_flags |= DMOVER_REQ_ERROR; 600 dreq->dreq_flags |= DMOVER_REQ_ERROR;
606 /* XXXUNLOCK */ 601 /* XXXUNLOCK */
607 goto done; 602 goto done;
608 } 603 }
609 604
610 buflen = uio_in->uio_resid; 605 buflen = uio_in->uio_resid;
611 if (buflen > 1024) 606 if (buflen > sizeof(cp))
612 buflen = 1024; 607 buflen = sizeof(cp);
613 cp = alloca(buflen); 
614 608
615 while ((count = uio_in->uio_resid) != 0) { 609 while ((count = uio_in->uio_resid) != 0) {
616 if (count > buflen) 610 if (count > buflen)
617 count = buflen; 611 count = buflen;
618 error = uiomove(cp, count, uio_in); 612 error = uiomove(cp, count, uio_in);
619 if (error) { 613 if (error) {
620 /* XXXLOCK */ 614 /* XXXLOCK */
621 dreq->dreq_error = error; 615 dreq->dreq_error = error;
622 dreq->dreq_flags |= DMOVER_REQ_ERROR; 616 dreq->dreq_flags |= DMOVER_REQ_ERROR;
623 /* XXXUNLOCK */ 617 /* XXXUNLOCK */
624 goto done; 618 goto done;
625 } else 619 } else
626 result = iscsi_crc32c(cp, count, result); 620 result = iscsi_crc32c(cp, count, result);