svn commit: r351534 - stable/12/sys/dev/nvme
Alexander Motin
mav at FreeBSD.org
Tue Aug 27 04:03:43 UTC 2019
Author: mav
Date: Tue Aug 27 04:03:42 2019
New Revision: 351534
URL: https://svnweb.freebsd.org/changeset/base/351534
Log:
MFC r351320: Formalize NVMe controller consumer life cycle.
This fixes possible double call of fail_fn, for example on hot removal.
It also allows ctrlr_fn to safely return NULL cookie in case of failure
and not get useless ns_fn or fail_fn call with NULL cookie later.
Modified:
stable/12/sys/dev/nvme/nvme.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/dev/nvme/nvme.c
==============================================================================
--- stable/12/sys/dev/nvme/nvme.c Tue Aug 27 04:02:25 2019 (r351533)
+++ stable/12/sys/dev/nvme/nvme.c Tue Aug 27 04:03:42 2019 (r351534)
@@ -330,16 +330,21 @@ nvme_notify(struct nvme_consumer *cons,
return;
cmpset = atomic_cmpset_32(&ctrlr->notification_sent, 0, 1);
-
if (cmpset == 0)
return;
if (cons->ctrlr_fn != NULL)
ctrlr_cookie = (*cons->ctrlr_fn)(ctrlr);
else
- ctrlr_cookie = NULL;
+ ctrlr_cookie = (void *)(uintptr_t)0xdeadc0dedeadc0de;
ctrlr->cons_cookie[cons->id] = ctrlr_cookie;
+
+ /* ctrlr_fn has failed. Nothing to notify here any more. */
+ if (ctrlr_cookie == NULL)
+ return;
+
if (ctrlr->is_failed) {
+ ctrlr->cons_cookie[cons->id] = NULL;
if (cons->fail_fn != NULL)
(*cons->fail_fn)(ctrlr_cookie);
/*
@@ -395,13 +400,16 @@ nvme_notify_async_consumers(struct nvme_controller *ct
uint32_t log_page_size)
{
struct nvme_consumer *cons;
+ void *ctrlr_cookie;
uint32_t i;
for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
cons = &nvme_consumer[i];
- if (cons->id != INVALID_CONSUMER_ID && cons->async_fn != NULL)
- (*cons->async_fn)(ctrlr->cons_cookie[i], async_cpl,
+ if (cons->id != INVALID_CONSUMER_ID && cons->async_fn != NULL &&
+ (ctrlr_cookie = ctrlr->cons_cookie[i]) != NULL) {
+ (*cons->async_fn)(ctrlr_cookie, async_cpl,
log_page_id, log_page_buffer, log_page_size);
+ }
}
}
@@ -409,6 +417,7 @@ void
nvme_notify_fail_consumers(struct nvme_controller *ctrlr)
{
struct nvme_consumer *cons;
+ void *ctrlr_cookie;
uint32_t i;
/*
@@ -422,8 +431,12 @@ nvme_notify_fail_consumers(struct nvme_controller *ctr
for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
cons = &nvme_consumer[i];
- if (cons->id != INVALID_CONSUMER_ID && cons->fail_fn != NULL)
- cons->fail_fn(ctrlr->cons_cookie[i]);
+ if (cons->id != INVALID_CONSUMER_ID &&
+ (ctrlr_cookie = ctrlr->cons_cookie[i]) != NULL) {
+ ctrlr->cons_cookie[i] = NULL;
+ if (cons->fail_fn != NULL)
+ cons->fail_fn(ctrlr_cookie);
+ }
}
}
@@ -432,6 +445,7 @@ nvme_notify_ns(struct nvme_controller *ctrlr, int nsid
{
struct nvme_consumer *cons;
struct nvme_namespace *ns = &ctrlr->ns[nsid - 1];
+ void *ctrlr_cookie;
uint32_t i;
if (!ctrlr->is_initialized)
@@ -439,9 +453,9 @@ nvme_notify_ns(struct nvme_controller *ctrlr, int nsid
for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
cons = &nvme_consumer[i];
- if (cons->id != INVALID_CONSUMER_ID && cons->ns_fn != NULL)
- ns->cons_cookie[cons->id] =
- (*cons->ns_fn)(ns, ctrlr->cons_cookie[cons->id]);
+ if (cons->id != INVALID_CONSUMER_ID && cons->ns_fn != NULL &&
+ (ctrlr_cookie = ctrlr->cons_cookie[i]) != NULL)
+ ns->cons_cookie[i] = (*cons->ns_fn)(ns, ctrlr_cookie);
}
}
More information about the svn-src-stable-12
mailing list