diff options
author | Hans Rosenfeld <hans.rosenfeld@nexenta.com> | 2016-08-04 15:40:22 +0200 |
---|---|---|
committer | Hans Rosenfeld <hans.rosenfeld@nexenta.com> | 2016-08-10 17:04:01 +0200 |
commit | 6afc9eb26c8915821607cde21b0a32addc165a72 (patch) | |
tree | 7a20f7b2fa9d1f24907fc4020645a4fcb622a69d /usr/src | |
parent | 745caa4284ab4cda9ab810405f99417d7cc6e8e6 (diff) | |
download | illumos-gate-6afc9eb26c8915821607cde21b0a32addc165a72.tar.gz |
7275 nvme shouldn't use ddi_intr_enable/disable to block interrupts
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/io/nvme/nvme.c | 73 |
1 files changed, 24 insertions, 49 deletions
diff --git a/usr/src/uts/common/io/nvme/nvme.c b/usr/src/uts/common/io/nvme/nvme.c index c548a1ed92..1cb0389063 100644 --- a/usr/src/uts/common/io/nvme/nvme.c +++ b/usr/src/uts/common/io/nvme/nvme.c @@ -10,7 +10,7 @@ */ /* - * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ /* @@ -194,8 +194,6 @@ static int nvme_attach(dev_info_t *, ddi_attach_cmd_t); static int nvme_detach(dev_info_t *, ddi_detach_cmd_t); static int nvme_quiesce(dev_info_t *); static int nvme_fm_errcb(dev_info_t *, ddi_fm_error_t *, const void *); -static void nvme_disable_interrupts(nvme_t *); -static int nvme_enable_interrupts(nvme_t *); static int nvme_setup_interrupts(nvme_t *, int, int); static void nvme_release_interrupts(nvme_t *); static uint_t nvme_intr(caddr_t, caddr_t); @@ -1936,16 +1934,15 @@ nvme_init(nvme_t *nvme) nvme->n_abort_command_limit = nvme->n_idctl->id_acl + 1; - /* disable NVMe interrupts while reinitializing the semaphore */ - nvme_disable_interrupts(nvme); + /* + * Reinitialize the semaphore with the true abort command limit + * supported by the hardware. It's not necessary to disable interrupts + * as only command aborts use the semaphore, and no commands are + * executed or aborted while we're here. + */ sema_destroy(&nvme->n_abort_sema); sema_init(&nvme->n_abort_sema, nvme->n_abort_command_limit - 1, NULL, SEMA_DRIVER, NULL); - if (nvme_enable_interrupts(nvme) != DDI_SUCCESS) { - dev_err(nvme->n_dip, CE_WARN, - "!failed to re-enable interrupts"); - goto fail; - } nvme->n_progress |= NVME_CTRL_LIMITS; @@ -2198,7 +2195,7 @@ nvme_intr(caddr_t arg1, caddr_t arg2) } static void -nvme_disable_interrupts(nvme_t *nvme) +nvme_release_interrupts(nvme_t *nvme) { int i; @@ -2210,41 +2207,6 @@ nvme_disable_interrupts(nvme_t *nvme) (void) ddi_intr_block_disable(&nvme->n_inth[i], 1); else (void) ddi_intr_disable(nvme->n_inth[i]); - } -} - -static int -nvme_enable_interrupts(nvme_t *nvme) -{ - int i, fail = 0; - - for (i = 0; i < nvme->n_intr_cnt; i++) { - if (nvme->n_inth[i] == NULL) - break; - - if (nvme->n_intr_cap & DDI_INTR_FLAG_BLOCK) { - if (ddi_intr_block_enable(&nvme->n_inth[i], 1) != - DDI_SUCCESS) - fail++; - } else { - if (ddi_intr_enable(nvme->n_inth[i]) != DDI_SUCCESS) - fail++; - } - } - - return (fail ? DDI_FAILURE : DDI_SUCCESS); -} - -static void -nvme_release_interrupts(nvme_t *nvme) -{ - int i; - - nvme_disable_interrupts(nvme); - - for (i = 0; i < nvme->n_intr_cnt; i++) { - if (nvme->n_inth[i] == NULL) - break; (void) ddi_intr_remove_handler(nvme->n_inth[i]); (void) ddi_intr_free(nvme->n_inth[i]); @@ -2260,6 +2222,7 @@ nvme_release_interrupts(nvme_t *nvme) static int nvme_setup_interrupts(nvme_t *nvme, int intr_type, int nqpairs) { + int failed = 0; int nintrs, navail, count; int ret; int i; @@ -2328,11 +2291,23 @@ nvme_setup_interrupts(nvme_t *nvme, int intr_type, int nqpairs) (void) ddi_intr_get_cap(nvme->n_inth[0], &nvme->n_intr_cap); - ret = nvme_enable_interrupts(nvme); + for (i = 0; i < count; i++) { + if (nvme->n_inth[i] == NULL) + break; - if (ret != DDI_SUCCESS) { + if (nvme->n_intr_cap & DDI_INTR_FLAG_BLOCK) { + if (ddi_intr_block_enable(&nvme->n_inth[i], 1) != + DDI_SUCCESS) + failed++; + } else { + if (ddi_intr_enable(nvme->n_inth[i]) != DDI_SUCCESS) + failed++; + } + } + + if (failed != 0) { dev_err(nvme->n_dip, CE_WARN, - "!%s: nvme_enable_interrupts failed", __func__); + "!%s: enabling interrupts failed", __func__); goto fail; } |