Author: jimharris Date: Tue Mar 26 20:02:35 2013 New Revision: 248749 URL: http://svnweb.freebsd.org/changeset/base/248749
Log: Add a tunable for the I/O timeout interval. Default is still 30 seconds, but can be adjusted between a min/max of 5 and 120 seconds. Sponsored by: Intel Reviewed by: carl Modified: head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h head/sys/dev/nvme/nvme_qpair.c head/sys/dev/nvme/nvme_sysctl.c Modified: head/sys/dev/nvme/nvme_ctrlr.c ============================================================================== --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 19:58:17 2013 (r248748) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 20:02:35 2013 (r248749) @@ -592,10 +592,10 @@ nvme_ctrlr_construct_and_submit_aer(stru aer->req = req; /* - * Override default timeout value here, since asynchronous event - * requests should by nature never be timed out. + * Disable timeout here, since asynchronous event requests should by + * nature never be timed out. */ - req->timeout = 0; + req->timeout = FALSE; req->cmd.opc = NVME_OPC_ASYNC_EVENT_REQUEST; nvme_ctrlr_submit_admin_request(ctrlr, req); } @@ -791,6 +791,7 @@ nvme_ctrlr_construct(struct nvme_control union cap_lo_register cap_lo; union cap_hi_register cap_hi; int num_vectors, per_cpu_io_queues, status = 0; + int timeout_period; ctrlr->dev = dev; ctrlr->is_started = FALSE; @@ -822,6 +823,12 @@ nvme_ctrlr_construct(struct nvme_control cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo); ctrlr->ready_timeout_in_ms = cap_lo.bits.to * 500; + timeout_period = NVME_DEFAULT_TIMEOUT_PERIOD; + TUNABLE_INT_FETCH("hw.nvme.timeout_period", &timeout_period); + timeout_period = min(timeout_period, NVME_MAX_TIMEOUT_PERIOD); + timeout_period = max(timeout_period, NVME_MIN_TIMEOUT_PERIOD); + ctrlr->timeout_period = timeout_period; + per_cpu_io_queues = 1; TUNABLE_INT_FETCH("hw.nvme.per_cpu_io_queues", &per_cpu_io_queues); ctrlr->per_cpu_io_queues = per_cpu_io_queues ? TRUE : FALSE; Modified: head/sys/dev/nvme/nvme_private.h ============================================================================== --- head/sys/dev/nvme/nvme_private.h Tue Mar 26 19:58:17 2013 (r248748) +++ head/sys/dev/nvme/nvme_private.h Tue Mar 26 20:02:35 2013 (r248749) @@ -100,7 +100,9 @@ MALLOC_DECLARE(M_NVME); #define NVME_MAX_CONSUMERS (2) #define NVME_MAX_ASYNC_EVENTS (8) -#define NVME_TIMEOUT_IN_SEC (30) +#define NVME_DEFAULT_TIMEOUT_PERIOD (30) /* in seconds */ +#define NVME_MIN_TIMEOUT_PERIOD (5) +#define NVME_MAX_TIMEOUT_PERIOD (120) #ifndef CACHE_LINE_SIZE #define CACHE_LINE_SIZE (64) @@ -113,7 +115,7 @@ struct nvme_request { struct nvme_command cmd; void *payload; uint32_t payload_size; - uint32_t timeout; + boolean_t timeout; struct uio *uio; nvme_cb_fn_t cb_fn; void *cb_arg; @@ -257,6 +259,9 @@ struct nvme_controller { /** interrupt coalescing threshold */ uint32_t int_coal_threshold; + /** timeout period in seconds */ + uint32_t timeout_period; + struct nvme_qpair adminq; struct nvme_qpair *ioq; @@ -427,7 +432,7 @@ nvme_allocate_request(void *payload, uin req->payload_size = payload_size; req->cb_fn = cb_fn; req->cb_arg = cb_arg; - req->timeout = NVME_TIMEOUT_IN_SEC; + req->timeout = TRUE; return (req); } @@ -444,7 +449,7 @@ nvme_allocate_request_uio(struct uio *ui req->uio = uio; req->cb_fn = cb_fn; req->cb_arg = cb_arg; - req->timeout = NVME_TIMEOUT_IN_SEC; + req->timeout = TRUE; return (req); } Modified: head/sys/dev/nvme/nvme_qpair.c ============================================================================== --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 19:58:17 2013 (r248748) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 20:02:35 2013 (r248749) @@ -480,20 +480,23 @@ nvme_timeout(void *arg) void nvme_qpair_submit_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr) { - struct nvme_request *req; + struct nvme_request *req; + struct nvme_controller *ctrlr; mtx_assert(&qpair->lock, MA_OWNED); req = tr->req; req->cmd.cid = tr->cid; qpair->act_tr[tr->cid] = tr; + ctrlr = qpair->ctrlr; - if (req->timeout > 0) + if (req->timeout) #if __FreeBSD_version >= 800030 - callout_reset_curcpu(&tr->timer, req->timeout * hz, + callout_reset_curcpu(&tr->timer, ctrlr->timeout_period * hz, nvme_timeout, tr); #else - callout_reset(&tr->timer, req->timeout * hz, nvme_timeout, tr); + callout_reset(&tr->timer, ctrlr->timeout_period * hz, + nvme_timeout, tr); #endif /* Copy the command from the tracker to the submission queue. */ Modified: head/sys/dev/nvme/nvme_sysctl.c ============================================================================== --- head/sys/dev/nvme/nvme_sysctl.c Tue Mar 26 19:58:17 2013 (r248748) +++ head/sys/dev/nvme/nvme_sysctl.c Tue Mar 26 20:02:35 2013 (r248749) @@ -123,6 +123,25 @@ nvme_sysctl_int_coal_threshold(SYSCTL_HA return (0); } +static int +nvme_sysctl_timeout_period(SYSCTL_HANDLER_ARGS) +{ + struct nvme_controller *ctrlr = arg1; + uint32_t oldval = ctrlr->timeout_period; + int error = sysctl_handle_int(oidp, &ctrlr->timeout_period, 0, req); + + if (error) + return (error); + + if (ctrlr->timeout_period > NVME_MAX_TIMEOUT_PERIOD || + ctrlr->timeout_period < NVME_MIN_TIMEOUT_PERIOD) { + ctrlr->timeout_period = oldval; + return (EINVAL); + } + + return (0); +} + static void nvme_qpair_reset_stats(struct nvme_qpair *qpair) { @@ -244,6 +263,11 @@ nvme_sysctl_initialize_ctrlr(struct nvme "Interrupt coalescing threshold"); SYSCTL_ADD_PROC(ctrlr_ctx, ctrlr_list, OID_AUTO, + "timeout_period", CTLTYPE_UINT | CTLFLAG_RW, ctrlr, 0, + nvme_sysctl_timeout_period, "IU", + "Timeout period (in seconds)"); + + SYSCTL_ADD_PROC(ctrlr_ctx, ctrlr_list, OID_AUTO, "num_cmds", CTLTYPE_S64 | CTLFLAG_RD, ctrlr, 0, nvme_sysctl_num_cmds, "IU", "Number of commands submitted"); _______________________________________________ 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"