Author: jimharris
Date: Tue Mar 26 22:09:51 2013
New Revision: 248769
URL: http://svnweb.freebsd.org/changeset/base/248769

Log:
  Replace usages of mtx_pool_find used for admin commands with a polling
  mechanism.
  
  Now that all requests are timed, we are guaranteed to get a completion
  notification, even if it is an abort status due to a timed out admin
  command.
  
  This has the effect of simplifying the controller and namespace setup
  code, so that it reads straight through rather than broken up into
  a bunch of different callback functions.
  
  Sponsored by: Intel
  Reviewed by:  carl

Modified:
  head/sys/dev/nvme/nvme.c
  head/sys/dev/nvme/nvme_ctrlr.c
  head/sys/dev/nvme/nvme_ns.c
  head/sys/dev/nvme/nvme_private.h

Modified: head/sys/dev/nvme/nvme.c
==============================================================================
--- head/sys/dev/nvme/nvme.c    Tue Mar 26 22:06:05 2013        (r248768)
+++ head/sys/dev/nvme/nvme.c    Tue Mar 26 22:09:51 2013        (r248769)
@@ -397,3 +397,18 @@ nvme_unregister_consumer(struct nvme_con
        consumer->id = INVALID_CONSUMER_ID;
 }
 
+void
+nvme_completion_poll_cb(void *arg, const struct nvme_completion *cpl)
+{
+       struct nvme_completion_poll_status      *status = arg;
+
+       /*
+        * Copy status into the argument passed by the caller, so that
+        *  the caller can check the status to determine if the
+        *  the request passed or failed.
+        */
+       memcpy(&status->cpl, cpl, sizeof(*cpl));
+       wmb();
+       status->done = TRUE;
+}
+

Modified: head/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- head/sys/dev/nvme/nvme_ctrlr.c      Tue Mar 26 22:06:05 2013        
(r248768)
+++ head/sys/dev/nvme/nvme_ctrlr.c      Tue Mar 26 22:09:51 2013        
(r248769)
@@ -41,24 +41,6 @@ __FBSDID("$FreeBSD$");
 static void nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
                                                struct nvme_async_event_request 
*aer);
 
-static void
-nvme_ctrlr_cb(void *arg, const struct nvme_completion *status)
-{
-       struct nvme_completion  *cpl = arg;
-       struct mtx              *mtx;
-
-       /*
-        * Copy status into the argument passed by the caller, so that
-        *  the caller can check the status to determine if the
-        *  the request passed or failed.
-        */
-       memcpy(cpl, status, sizeof(*cpl));
-       mtx = mtx_pool_find(mtxpool_sleep, cpl);
-       mtx_lock(mtx);
-       wakeup(cpl);
-       mtx_unlock(mtx);
-}
-
 static int
 nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr)
 {
@@ -479,18 +461,14 @@ nvme_ctrlr_reset(struct nvme_controller 
 static int
 nvme_ctrlr_identify(struct nvme_controller *ctrlr)
 {
-       struct mtx              *mtx;
-       struct nvme_completion  cpl;
-       int                     status;
-
-       mtx = mtx_pool_find(mtxpool_sleep, &cpl);
+       struct nvme_completion_poll_status      status;
 
-       mtx_lock(mtx);
+       status.done = FALSE;
        nvme_ctrlr_cmd_identify_controller(ctrlr, &ctrlr->cdata,
-           nvme_ctrlr_cb, &cpl);
-       status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5);
-       mtx_unlock(mtx);
-       if ((status != 0) || nvme_completion_is_error(&cpl)) {
+           nvme_completion_poll_cb, &status);
+       while (status.done == FALSE)
+               DELAY(5);
+       if (nvme_completion_is_error(&status.cpl)) {
                printf("nvme_identify_controller failed!\n");
                return (ENXIO);
        }
@@ -514,18 +492,15 @@ nvme_ctrlr_identify(struct nvme_controll
 static int
 nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr)
 {
-       struct mtx              *mtx;
-       struct nvme_completion  cpl;
-       int                     cq_allocated, sq_allocated, status;
-
-       mtx = mtx_pool_find(mtxpool_sleep, &cpl);
+       struct nvme_completion_poll_status      status;
+       int                                     cq_allocated, sq_allocated;
 
-       mtx_lock(mtx);
+       status.done = FALSE;
        nvme_ctrlr_cmd_set_num_queues(ctrlr, ctrlr->num_io_queues,
-           nvme_ctrlr_cb, &cpl);
-       status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5);
-       mtx_unlock(mtx);
-       if ((status != 0) || nvme_completion_is_error(&cpl)) {
+           nvme_completion_poll_cb, &status);
+       while (status.done == FALSE)
+               DELAY(5);
+       if (nvme_completion_is_error(&status.cpl)) {
                printf("nvme_set_num_queues failed!\n");
                return (ENXIO);
        }
@@ -535,8 +510,8 @@ nvme_ctrlr_set_num_qpairs(struct nvme_co
         * Lower 16-bits indicate number of submission queues allocated.
         * Upper 16-bits indicate number of completion queues allocated.
         */
-       sq_allocated = (cpl.cdw0 & 0xFFFF) + 1;
-       cq_allocated = (cpl.cdw0 >> 16) + 1;
+       sq_allocated = (status.cpl.cdw0 & 0xFFFF) + 1;
+       cq_allocated = (status.cpl.cdw0 >> 16) + 1;
 
        /*
         * Check that the controller was able to allocate the number of
@@ -558,32 +533,29 @@ nvme_ctrlr_set_num_qpairs(struct nvme_co
 static int
 nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr)
 {
-       struct mtx              *mtx;
-       struct nvme_qpair       *qpair;
-       struct nvme_completion  cpl;
-       int                     i, status;
-
-       mtx = mtx_pool_find(mtxpool_sleep, &cpl);
+       struct nvme_completion_poll_status      status;
+       struct nvme_qpair                       *qpair;
+       int                                     i;
 
        for (i = 0; i < ctrlr->num_io_queues; i++) {
                qpair = &ctrlr->ioq[i];
 
-               mtx_lock(mtx);
+               status.done = FALSE;
                nvme_ctrlr_cmd_create_io_cq(ctrlr, qpair, qpair->vector,
-                   nvme_ctrlr_cb, &cpl);
-               status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5);
-               mtx_unlock(mtx);
-               if ((status != 0) || nvme_completion_is_error(&cpl)) {
+                   nvme_completion_poll_cb, &status);
+               while (status.done == FALSE)
+                       DELAY(5);
+               if (nvme_completion_is_error(&status.cpl)) {
                        printf("nvme_create_io_cq failed!\n");
                        return (ENXIO);
                }
 
-               mtx_lock(mtx);
+               status.done = FALSE;
                nvme_ctrlr_cmd_create_io_sq(qpair->ctrlr, qpair,
-                   nvme_ctrlr_cb, &cpl);
-               status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5);
-               mtx_unlock(mtx);
-               if ((status != 0) || nvme_completion_is_error(&cpl)) {
+                   nvme_completion_poll_cb, &status);
+               while (status.done == FALSE)
+                       DELAY(5);
+               if (nvme_completion_is_error(&status.cpl)) {
                        printf("nvme_create_io_sq failed!\n");
                        return (ENXIO);
                }
@@ -906,9 +878,8 @@ static int
 nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag,
     struct thread *td)
 {
-       struct nvme_controller  *ctrlr;
-       struct nvme_completion  cpl;
-       struct mtx              *mtx;
+       struct nvme_completion_poll_status      status;
+       struct nvme_controller                  *ctrlr;
 
        ctrlr = cdev->si_drv1;
 
@@ -925,13 +896,12 @@ nvme_ctrlr_ioctl(struct cdev *cdev, u_lo
                }
 #endif
                /* Refresh data before returning to user. */
-               mtx = mtx_pool_find(mtxpool_sleep, &cpl);
-               mtx_lock(mtx);
+               status.done = FALSE;
                nvme_ctrlr_cmd_identify_controller(ctrlr, &ctrlr->cdata,
-                   nvme_ctrlr_cb, &cpl);
-               msleep(&cpl, mtx, PRIBIO, "nvme_ioctl", 0);
-               mtx_unlock(mtx);
-               if (nvme_completion_is_error(&cpl))
+                   nvme_completion_poll_cb, &status);
+               while (status.done == FALSE)
+                       DELAY(5);
+               if (nvme_completion_is_error(&status.cpl))
                        return (ENXIO);
                memcpy(arg, &ctrlr->cdata, sizeof(ctrlr->cdata));
                break;

Modified: head/sys/dev/nvme/nvme_ns.c
==============================================================================
--- head/sys/dev/nvme/nvme_ns.c Tue Mar 26 22:06:05 2013        (r248768)
+++ head/sys/dev/nvme/nvme_ns.c Tue Mar 26 22:09:51 2013        (r248769)
@@ -41,32 +41,13 @@ __FBSDID("$FreeBSD$");
 
 #include "nvme_private.h"
 
-static void
-nvme_ns_cb(void *arg, const struct nvme_completion *status)
-{
-       struct nvme_completion  *cpl = arg;
-       struct mtx              *mtx;
-
-       /*
-        * Copy status into the argument passed by the caller, so that
-        *  the caller can check the status to determine if the
-        *  the request passed or failed.
-        */
-       memcpy(cpl, status, sizeof(*cpl));
-       mtx = mtx_pool_find(mtxpool_sleep, cpl);
-       mtx_lock(mtx);
-       wakeup(cpl);
-       mtx_unlock(mtx);
-}
-
 static int
 nvme_ns_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag,
     struct thread *td)
 {
-       struct nvme_namespace   *ns;
-       struct nvme_controller  *ctrlr;
-       struct nvme_completion  cpl;
-       struct mtx              *mtx;
+       struct nvme_completion_poll_status      status;
+       struct nvme_namespace                   *ns;
+       struct nvme_controller                  *ctrlr;
 
        ns = cdev->si_drv1;
        ctrlr = ns->ctrlr;
@@ -84,13 +65,12 @@ nvme_ns_ioctl(struct cdev *cdev, u_long 
                }
 #endif
                /* Refresh data before returning to user. */
-               mtx = mtx_pool_find(mtxpool_sleep, &cpl);
-               mtx_lock(mtx);
+               status.done = FALSE;
                nvme_ctrlr_cmd_identify_namespace(ctrlr, ns->id, &ns->data,
-                   nvme_ns_cb, &cpl);
-               msleep(&cpl, mtx, PRIBIO, "nvme_ioctl", 0);
-               mtx_unlock(mtx);
-               if (nvme_completion_is_error(&cpl))
+                   nvme_completion_poll_cb, &status);
+               while (status.done == FALSE)
+                       DELAY(5);
+               if (nvme_completion_is_error(&status.cpl))
                        return (ENXIO);
                memcpy(arg, &ns->data, sizeof(ns->data));
                break;
@@ -319,9 +299,7 @@ int
 nvme_ns_construct(struct nvme_namespace *ns, uint16_t id,
     struct nvme_controller *ctrlr)
 {
-       struct nvme_completion  cpl;
-       struct mtx              *mtx;
-       int                     status;
+       struct nvme_completion_poll_status      status;
 
        ns->ctrlr = ctrlr;
        ns->id = id;
@@ -331,14 +309,12 @@ nvme_ns_construct(struct nvme_namespace 
                nvme_ns_populate_chatham_data(ns);
        else {
 #endif
-               mtx = mtx_pool_find(mtxpool_sleep, &cpl);
-
-               mtx_lock(mtx);
+               status.done = FALSE;
                nvme_ctrlr_cmd_identify_namespace(ctrlr, id, &ns->data,
-                   nvme_ns_cb, &cpl);
-               status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5);
-               mtx_unlock(mtx);
-               if ((status != 0) || nvme_completion_is_error(&cpl)) {
+                   nvme_completion_poll_cb, &status);
+               while (status.done == FALSE)
+                       DELAY(5);
+               if (nvme_completion_is_error(&status.cpl)) {
                        printf("nvme_identify_namespace failed!\n");
                        return (ENXIO);
                }

Modified: head/sys/dev/nvme/nvme_private.h
==============================================================================
--- head/sys/dev/nvme/nvme_private.h    Tue Mar 26 22:06:05 2013        
(r248768)
+++ head/sys/dev/nvme/nvme_private.h    Tue Mar 26 22:09:51 2013        
(r248769)
@@ -116,6 +116,12 @@ MALLOC_DECLARE(M_NVME);
 extern uma_zone_t      nvme_request_zone;
 extern int32_t         nvme_retry_count;
 
+struct nvme_completion_poll_status {
+
+       struct nvme_completion  cpl;
+       boolean_t               done;
+};
+
 struct nvme_request {
 
        struct nvme_command             cmd;
@@ -399,6 +405,7 @@ void        nvme_payload_map(void *arg, bus_dma
                         int error);
 void   nvme_payload_map_uio(void *arg, bus_dma_segment_t *seg, int nseg,
                             bus_size_t mapsize, int error);
+void   nvme_completion_poll_cb(void *arg, const struct nvme_completion *cpl);
 
 int    nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev);
 void   nvme_ctrlr_destruct(struct nvme_controller *ctrlr, device_t dev);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to