Date: Tue, 18 Mar 2014 18:09:08 +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: r263310 - head/sys/dev/nvme Message-ID: <201403181809.s2II98oi074405@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jimharris Date: Tue Mar 18 18:09:08 2014 New Revision: 263310 URL: http://svnweb.freebsd.org/changeset/base/263310 Log: nvme: Close hole where nvd(4) would not be notified of all nvme(4) instances if modules loaded during boot. Sponsored by: Intel MFC after: 3 days Modified: head/sys/dev/nvme/nvme.c head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_private.h Modified: head/sys/dev/nvme/nvme.c ============================================================================== --- head/sys/dev/nvme/nvme.c Tue Mar 18 17:17:42 2014 (r263309) +++ head/sys/dev/nvme/nvme.c Tue Mar 18 18:09:08 2014 (r263310) @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -266,39 +266,75 @@ nvme_detach (device_t dev) } static void -nvme_notify_consumer(struct nvme_consumer *cons) +nvme_notify(struct nvme_consumer *cons, + struct nvme_controller *ctrlr) { - device_t *devlist; - struct nvme_controller *ctrlr; struct nvme_namespace *ns; void *ctrlr_cookie; - int dev_idx, ns_idx, devcount; + int cmpset, ns_idx; + + /* + * The consumer may register itself after the nvme devices + * have registered with the kernel, but before the + * driver has completed initialization. In that case, + * return here, and when initialization completes, the + * controller will make sure the consumer gets notified. + */ + if (!ctrlr->is_initialized) + 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->cons_cookie[cons->id] = ctrlr_cookie; + if (ctrlr->is_failed) { + if (cons->fail_fn != NULL) + (*cons->fail_fn)(ctrlr_cookie); + /* + * Do not notify consumers about the namespaces of a + * failed controller. + */ + return; + } + for (ns_idx = 0; ns_idx < ctrlr->cdata.nn; ns_idx++) { + ns = &ctrlr->ns[ns_idx]; + if (cons->ns_fn != NULL) + ns->cons_cookie[cons->id] = + (*cons->ns_fn)(ns, ctrlr_cookie); + } +} + +void +nvme_notify_new_controller(struct nvme_controller *ctrlr) +{ + int i; + + for (i = 0; i < NVME_MAX_CONSUMERS; i++) { + if (nvme_consumer[i].id != INVALID_CONSUMER_ID) { + nvme_notify(&nvme_consumer[i], ctrlr); + } + } +} + +static void +nvme_notify_new_consumer(struct nvme_consumer *cons) +{ + device_t *devlist; + struct nvme_controller *ctrlr; + int dev_idx, devcount; if (devclass_get_devices(nvme_devclass, &devlist, &devcount)) return; for (dev_idx = 0; dev_idx < devcount; dev_idx++) { ctrlr = DEVICE2SOFTC(devlist[dev_idx]); - if (cons->ctrlr_fn != NULL) - ctrlr_cookie = (*cons->ctrlr_fn)(ctrlr); - else - ctrlr_cookie = NULL; - ctrlr->cons_cookie[cons->id] = ctrlr_cookie; - if (ctrlr->is_failed) { - if (cons->fail_fn != NULL) - (*cons->fail_fn)(ctrlr_cookie); - /* - * Do not notify consumers about the namespaces of a - * failed controller. - */ - continue; - } - for (ns_idx = 0; ns_idx < ctrlr->cdata.nn; ns_idx++) { - ns = &ctrlr->ns[ns_idx]; - if (cons->ns_fn != NULL) - ns->cons_cookie[cons->id] = - (*cons->ns_fn)(ns, ctrlr_cookie); - } + nvme_notify(cons, ctrlr); } free(devlist, M_TEMP); @@ -353,7 +389,7 @@ nvme_register_consumer(nvme_cons_ns_fn_t nvme_consumer[i].async_fn = async_fn; nvme_consumer[i].fail_fn = fail_fn; - nvme_notify_consumer(&nvme_consumer[i]); + nvme_notify_new_consumer(&nvme_consumer[i]); return (&nvme_consumer[i]); } Modified: head/sys/dev/nvme/nvme_ctrlr.c ============================================================================== --- head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 18 17:17:42 2014 (r263309) +++ head/sys/dev/nvme/nvme_ctrlr.c Tue Mar 18 18:09:08 2014 (r263310) @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -851,6 +851,9 @@ nvme_ctrlr_start_config_hook(void *arg) nvme_ctrlr_start(ctrlr); config_intrhook_disestablish(&ctrlr->config_hook); + + ctrlr->is_initialized = 1; + nvme_notify_new_controller(ctrlr); } static void @@ -1174,6 +1177,8 @@ intx: taskqueue_start_threads(&ctrlr->taskqueue, 1, PI_DISK, "nvme taskq"); ctrlr->is_resetting = 0; + ctrlr->is_initialized = 0; + ctrlr->notification_sent = 0; TASK_INIT(&ctrlr->reset_task, 0, nvme_ctrlr_reset_task, ctrlr); TASK_INIT(&ctrlr->fail_req_task, 0, nvme_ctrlr_fail_req_task, ctrlr); Modified: head/sys/dev/nvme/nvme_private.h ============================================================================== --- head/sys/dev/nvme/nvme_private.h Tue Mar 18 17:17:42 2014 (r263309) +++ head/sys/dev/nvme/nvme_private.h Tue Mar 18 18:09:08 2014 (r263310) @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2012-2014 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -330,7 +330,9 @@ struct nvme_controller { void *cons_cookie[NVME_MAX_CONSUMERS]; - uint32_t is_resetting; + uint32_t is_resetting; + uint32_t is_initialized; + uint32_t notification_sent; boolean_t is_failed; STAILQ_HEAD(, nvme_request) fail_req; @@ -556,5 +558,6 @@ void nvme_notify_async_consumers(struct uint32_t log_page_id, void *log_page_buffer, uint32_t log_page_size); void nvme_notify_fail_consumers(struct nvme_controller *ctrlr); +void nvme_notify_new_controller(struct nvme_controller *ctrlr); #endif /* __NVME_PRIVATE_H__ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201403181809.s2II98oi074405>