Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Apr 2013 17:34:49 +0000 (UTC)
From:      Jim Harris <jimharris@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r249416 - head/sys/dev/nvme
Message-ID:  <201304121734.r3CHYnNo089616@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jimharris
Date: Fri Apr 12 17:34:49 2013
New Revision: 249416
URL: http://svnweb.freebsd.org/changeset/base/249416

Log:
  Do not panic when a busdma mapping operation fails.
  
  Instead, print an error message and fail the associated command with
  DATA_TRANSFER_ERROR NVMe completion status.
  
  Sponsored by:	Intel

Modified:
  head/sys/dev/nvme/nvme.c
  head/sys/dev/nvme/nvme_qpair.c

Modified: head/sys/dev/nvme/nvme.c
==============================================================================
--- head/sys/dev/nvme/nvme.c	Fri Apr 12 17:22:12 2013	(r249415)
+++ head/sys/dev/nvme/nvme.c	Fri Apr 12 17:34:49 2013	(r249416)
@@ -235,7 +235,13 @@ nvme_payload_map(void *arg, bus_dma_segm
 	struct nvme_tracker 	*tr = arg;
 	uint32_t		cur_nseg;
 
-	KASSERT(error == 0, ("nvme_payload_map error != 0\n"));
+	/*
+	 * If the mapping operation failed, return immediately.  The caller
+	 *  is responsible for detecting the error status and failing the
+	 *  tracker manually.
+	 */
+	if (error != 0)
+		return;
 
 	/*
 	 * Note that we specified PAGE_SIZE for alignment and max

Modified: head/sys/dev/nvme/nvme_qpair.c
==============================================================================
--- head/sys/dev/nvme/nvme_qpair.c	Fri Apr 12 17:22:12 2013	(r249415)
+++ head/sys/dev/nvme/nvme_qpair.c	Fri Apr 12 17:34:49 2013	(r249416)
@@ -702,7 +702,7 @@ static void
 _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
 {
 	struct nvme_tracker	*tr;
-	int			err;
+	int			err = 0;
 
 	mtx_assert(&qpair->lock, MA_OWNED);
 
@@ -745,7 +745,8 @@ _nvme_qpair_submit_request(struct nvme_q
 		err = bus_dmamap_load(tr->qpair->dma_tag, tr->payload_dma_map,
 		    req->u.payload, req->payload_size, nvme_payload_map, tr, 0);
 		if (err != 0)
-			panic("bus_dmamap_load returned non-zero!\n");
+			nvme_printf(qpair->ctrlr,
+			    "bus_dmamap_load returned 0x%x!\n", err);
 		break;
 	case NVME_REQUEST_NULL:
 		nvme_qpair_submit_tracker(tr->qpair, tr);
@@ -755,20 +756,36 @@ _nvme_qpair_submit_request(struct nvme_q
 		    tr->payload_dma_map, req->u.uio, nvme_payload_map_uio,
 		    tr, 0);
 		if (err != 0)
-			panic("bus_dmamap_load_uio returned non-zero!\n");
+			nvme_printf(qpair->ctrlr,
+			    "bus_dmamap_load_uio returned 0x%x!\n", err);
 		break;
 #ifdef NVME_UNMAPPED_BIO_SUPPORT
 	case NVME_REQUEST_BIO:
 		err = bus_dmamap_load_bio(tr->qpair->dma_tag,
 		    tr->payload_dma_map, req->u.bio, nvme_payload_map, tr, 0);
 		if (err != 0)
-			panic("bus_dmamap_load_bio returned non-zero!\n");
+			nvme_printf(qpair->ctrlr,
+			    "bus_dmamap_load_bio returned 0x%x!\n", err);
 		break;
 #endif
 	default:
 		panic("unknown nvme request type 0x%x\n", req->type);
 		break;
 	}
+
+	if (err != 0) {
+		/*
+		 * The dmamap operation failed, so we manually fail the
+		 *  tracker here with DATA_TRANSFER_ERROR status.
+		 *
+		 * nvme_qpair_manual_complete_tracker must not be called
+		 *  with the qpair lock held.
+		 */
+		mtx_unlock(&qpair->lock);
+		nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
+		    NVME_SC_DATA_TRANSFER_ERROR, 1 /* do not retry */, TRUE);
+		mtx_lock(&qpair->lock);
+	}
 }
 
 void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201304121734.r3CHYnNo089616>