Date: Tue, 26 Mar 2013 22:09:51 +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: r248769 - head/sys/dev/nvme Message-ID: <201303262209.r2QM9pN6031479@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303262209.r2QM9pN6031479>