Tue Oct 4 18:20:49 2016 UTC ()
vioscsi_req_get()/virtio_enqueue_prep() failing is actually perfectly
normal - observed failures included 10, 27, 61 in-flight commands,
so probably depends on particular command mix; return with
XS_RESOURCE_SHORTAGE rather then panic

do vioscsi_req_put() when initial bus_dmamap_load() fails, as suggested
by the XXX; the vq_done hook is called by virtio, but in that case we never
get to commit the request to it


(jdolecek)
diff -r1.6 -r1.7 src/sys/dev/pci/vioscsi.c

cvs diff -r1.6 -r1.7 src/sys/dev/pci/vioscsi.c (expand / switch to unified diff)

--- src/sys/dev/pci/vioscsi.c 2015/11/01 08:55:05 1.6
+++ src/sys/dev/pci/vioscsi.c 2016/10/04 18:20:49 1.7
@@ -1,33 +1,34 @@ @@ -1,33 +1,34 @@
 1/* $NetBSD: vioscsi.c,v 1.7 2016/10/04 18:20:49 jdolecek Exp $ */
1/* $OpenBSD: vioscsi.c,v 1.3 2015/03/14 03:38:49 jsg Exp $ */ 2/* $OpenBSD: vioscsi.c,v 1.3 2015/03/14 03:38:49 jsg Exp $ */
2 3
3/* 4/*
4 * Copyright (c) 2013 Google Inc. 5 * Copyright (c) 2013 Google Inc.
5 * 6 *
6 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
9 * 10 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 18 */
18 19
19#include <sys/cdefs.h> 20#include <sys/cdefs.h>
20__KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.6 2015/11/01 08:55:05 pooka Exp $"); 21__KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.7 2016/10/04 18:20:49 jdolecek Exp $");
21 22
22#include <sys/param.h> 23#include <sys/param.h>
23#include <sys/systm.h> 24#include <sys/systm.h>
24#include <sys/device.h> 25#include <sys/device.h>
25#include <sys/bus.h> 26#include <sys/bus.h>
26#include <sys/buf.h> 27#include <sys/buf.h>
27 28
28#include <dev/pci/pcidevs.h> 29#include <dev/pci/pcidevs.h>
29#include <dev/pci/pcireg.h> 30#include <dev/pci/pcireg.h>
30#include <dev/pci/pcivar.h> 31#include <dev/pci/pcivar.h>
31 32
32#include <dev/pci/vioscsireg.h> 33#include <dev/pci/vioscsireg.h>
33#include <dev/pci/virtiovar.h> 34#include <dev/pci/virtiovar.h>
@@ -217,36 +218,35 @@ vioscsi_scsipi_request(struct scsipi_cha @@ -217,36 +218,35 @@ vioscsi_scsipi_request(struct scsipi_cha
217 int slot, error; 218 int slot, error;
218 219
219 DPRINTF(("%s: enter\n", __func__)); 220 DPRINTF(("%s: enter\n", __func__));
220 221
221 if (request != ADAPTER_REQ_RUN_XFER) { 222 if (request != ADAPTER_REQ_RUN_XFER) {
222 DPRINTF(("%s: unhandled %d\n", __func__, request)); 223 DPRINTF(("%s: unhandled %d\n", __func__, request));
223 return; 224 return;
224 } 225 }
225  226
226 xs = arg; 227 xs = arg;
227 periph = xs->xs_periph; 228 periph = xs->xs_periph;
228 229
229 vr = vioscsi_req_get(sc); 230 vr = vioscsi_req_get(sc);
230#ifdef DIAGNOSTIC 
231 /* 231 /*
232 * This should never happen as we track the resources 232 * This can happen when we run out of queue slots.
233 * in the mid-layer. 
234 */ 233 */
235 if (vr == NULL) { 234 if (vr == NULL) {
236 scsipi_printaddr(xs->xs_periph); 235 xs->error = XS_RESOURCE_SHORTAGE;
237 panic("%s: unable to allocate request\n", __func__); 236 scsipi_done(xs);
 237 return;
238 } 238 }
239#endif 239
240 req = &vr->vr_req; 240 req = &vr->vr_req;
241 slot = vr - sc->sc_reqs; 241 slot = vr - sc->sc_reqs;
242 242
243 vr->vr_xs = xs; 243 vr->vr_xs = xs;
244 244
245 /* 245 /*
246 * "The only supported format for the LUN field is: first byte set to 246 * "The only supported format for the LUN field is: first byte set to
247 * 1, second byte set to target, third and fourth byte representing a 247 * 1, second byte set to target, third and fourth byte representing a
248 * single level LUN structure, followed by four zero bytes." 248 * single level LUN structure, followed by four zero bytes."
249 */ 249 */
250 if (periph->periph_target >= 256 || periph->periph_lun >= 16384) { 250 if (periph->periph_target >= 256 || periph->periph_lun >= 16384) {
251 DPRINTF(("%s: bad target %u or lun %u\n", __func__, 251 DPRINTF(("%s: bad target %u or lun %u\n", __func__,
252 periph->periph_target, periph->periph_lun)); 252 periph->periph_target, periph->periph_lun));
@@ -274,27 +274,27 @@ vioscsi_scsipi_request(struct scsipi_cha @@ -274,27 +274,27 @@ vioscsi_scsipi_request(struct scsipi_cha
274 switch (error) { 274 switch (error) {
275 case 0: 275 case 0:
276 break; 276 break;
277 case ENOMEM: 277 case ENOMEM:
278 case EAGAIN: 278 case EAGAIN:
279 xs->error = XS_RESOURCE_SHORTAGE; 279 xs->error = XS_RESOURCE_SHORTAGE;
280 goto nomore; 280 goto nomore;
281 default: 281 default:
282 aprint_error_dev(sc->sc_dev, "error %d loading DMA map\n", 282 aprint_error_dev(sc->sc_dev, "error %d loading DMA map\n",
283 error); 283 error);
284 stuffup: 284 stuffup:
285 xs->error = XS_DRIVER_STUFFUP; 285 xs->error = XS_DRIVER_STUFFUP;
286nomore: 286nomore:
287 // XXX: free req? 287 vioscsi_req_put(sc, vr);
288 scsipi_done(xs); 288 scsipi_done(xs);
289 return; 289 return;
290 } 290 }
291 291
292 int nsegs = VIRTIO_SCSI_MIN_SEGMENTS; 292 int nsegs = VIRTIO_SCSI_MIN_SEGMENTS;
293 if ((xs->xs_control & (XS_CTL_DATA_IN|XS_CTL_DATA_OUT)) != 0) 293 if ((xs->xs_control & (XS_CTL_DATA_IN|XS_CTL_DATA_OUT)) != 0)
294 nsegs += vr->vr_data->dm_nsegs; 294 nsegs += vr->vr_data->dm_nsegs;
295 295
296 error = virtio_enqueue_reserve(vsc, vq, slot, nsegs); 296 error = virtio_enqueue_reserve(vsc, vq, slot, nsegs);
297 if (error) { 297 if (error) {
298 DPRINTF(("%s: error reserving %d\n", __func__, error)); 298 DPRINTF(("%s: error reserving %d\n", __func__, error));
299 goto stuffup; 299 goto stuffup;
300 } 300 }