From owner-svn-src-all@FreeBSD.ORG Tue Mar 26 19:58:18 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 98FCDE87; Tue, 26 Mar 2013 19:58:18 +0000 (UTC) (envelope-from jimharris@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 8B84BA7F; Tue, 26 Mar 2013 19:58:18 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r2QJwIY9089079; Tue, 26 Mar 2013 19:58:18 GMT (envelope-from jimharris@svn.freebsd.org) Received: (from jimharris@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r2QJwIJW089076; Tue, 26 Mar 2013 19:58:18 GMT (envelope-from jimharris@svn.freebsd.org) Message-Id: <201303261958.r2QJwIJW089076@svn.freebsd.org> From: Jim Harris Date: Tue, 26 Mar 2013 19:58:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r248748 - head/sys/dev/nvme X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Mar 2013 19:58:18 -0000 Author: jimharris Date: Tue Mar 26 19:58:17 2013 New Revision: 248748 URL: http://svnweb.freebsd.org/changeset/base/248748 Log: Add handling for controller fatal status (csts.cfs). On any I/O timeout, check for csts.cfs==1. If set, the controller is reporting fatal status and we reset the controller immediately, rather than trying to abort the timed out command. This changeset also includes deferring the controller start portion of the reset to a separate task. This ensures we are always performing a controller start operation from a consistent context. 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 Modified: head/sys/dev/nvme/nvme_ctrlr.c ============================================================================== --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 19:52:57 2013 (r248747) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 26 19:58:17 2013 (r248748) @@ -427,7 +427,7 @@ nvme_ctrlr_reset(struct nvme_controller status = nvme_ctrlr_hw_reset(ctrlr); DELAY(100*1000); if (status == 0) - nvme_ctrlr_start(ctrlr); + taskqueue_enqueue(ctrlr->taskqueue, &ctrlr->restart_task); } static int @@ -686,6 +686,14 @@ err: } static void +nvme_ctrlr_restart_task(void *arg, int pending) +{ + struct nvme_controller *ctrlr = arg; + + nvme_ctrlr_start(ctrlr); +} + +static void nvme_ctrlr_intx_handler(void *arg) { struct nvme_controller *ctrlr = arg; @@ -864,6 +872,11 @@ intx: ctrlr->cdev->si_drv1 = (void *)ctrlr; + TASK_INIT(&ctrlr->restart_task, 0, nvme_ctrlr_restart_task, ctrlr); + ctrlr->taskqueue = taskqueue_create("nvme_taskq", M_WAITOK, + taskqueue_thread_enqueue, &ctrlr->taskqueue); + taskqueue_start_threads(&ctrlr->taskqueue, 1, PI_DISK, "nvme taskq"); + return (0); } @@ -872,6 +885,8 @@ nvme_ctrlr_destruct(struct nvme_controll { int i; + taskqueue_free(ctrlr->taskqueue); + for (i = 0; i < NVME_MAX_NAMESPACES; i++) nvme_ns_destruct(&ctrlr->ns[i]); Modified: head/sys/dev/nvme/nvme_private.h ============================================================================== --- head/sys/dev/nvme/nvme_private.h Tue Mar 26 19:52:57 2013 (r248747) +++ head/sys/dev/nvme/nvme_private.h Tue Mar 26 19:58:17 2013 (r248748) @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -236,6 +237,8 @@ struct nvme_controller { uint32_t ns_identified; uint32_t queues_created; uint32_t num_start_attempts; + struct task restart_task; + struct taskqueue *taskqueue; /* For shared legacy interrupt. */ int rid; Modified: head/sys/dev/nvme/nvme_qpair.c ============================================================================== --- head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 19:52:57 2013 (r248747) +++ head/sys/dev/nvme/nvme_qpair.c Tue Mar 26 19:58:17 2013 (r248748) @@ -98,7 +98,7 @@ nvme_qpair_construct_tracker(struct nvme bus_dmamap_load(qpair->dma_tag, tr->prp_dma_map, tr->prp, sizeof(tr->prp), nvme_single_map, &tr->prp_bus_addr, 0); - callout_init_mtx(&tr->timer, &qpair->lock, 0); + callout_init(&tr->timer, 1); tr->cid = cid; tr->qpair = qpair; } @@ -456,8 +456,24 @@ static void nvme_timeout(void *arg) { struct nvme_tracker *tr = arg; + struct nvme_qpair *qpair = tr->qpair; + struct nvme_controller *ctrlr = qpair->ctrlr; + union csts_register csts; - nvme_ctrlr_cmd_abort(tr->qpair->ctrlr, tr->cid, tr->qpair->id, + csts.raw = nvme_mmio_read_4(ctrlr, csts); + if (csts.bits.cfs == 1) { + /* + * The controller is reporting fatal status. Don't bother + * trying to abort the timed out command - proceed + * immediately to a controller-level reset. + */ + device_printf(ctrlr->dev, + "controller reports fatal status, resetting...\n"); + nvme_ctrlr_reset(ctrlr); + return; + } + + nvme_ctrlr_cmd_abort(ctrlr, tr->cid, qpair->id, nvme_abort_complete, tr); }