nvme: use config_intrhook_drain to avoid removable card races
nvme drives are configured early in boot. However, a number of the configuration steps takes which take a while, so we defer those to a config intrhook that runs before the root filesystem is mounted. At the same time, the PCI hot plug wakes up and tests the status of the card. It may decide that the card has gone away and deletes the child. As part of that process nvme_detach is called. If this call happens after the config_intrhook starts to run, but before it is finished, there's a race where we can tear down the device's soft state while the config_intrhook is still using it. Use the new config_intrhook_drain to disestablish the hook. Either it will be removed w/o running, or the routine will wait for it to finish. This closes the race and allows safe hotplug at any time, even very early in boot. Sponsored by: Netflix, Inc Reviewed by: jhb, mav Differential Revision: https://reviews.freebsd.org/D29006
This commit is contained in:
parent
e52368365d
commit
8423f5d4c1
@ -143,10 +143,7 @@ nvme_detach(device_t dev)
|
||||
{
|
||||
struct nvme_controller *ctrlr = DEVICE2SOFTC(dev);
|
||||
|
||||
if (ctrlr->config_hook.ich_arg != NULL) {
|
||||
config_intrhook_disestablish(&ctrlr->config_hook);
|
||||
ctrlr->config_hook.ich_arg = NULL;
|
||||
}
|
||||
config_intrhook_drain(&ctrlr->config_hook);
|
||||
|
||||
nvme_ctrlr_destruct(ctrlr, dev);
|
||||
return (0);
|
||||
|
@ -1135,7 +1135,6 @@ nvme_ctrlr_start_config_hook(void *arg)
|
||||
fail:
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
config_intrhook_disestablish(&ctrlr->config_hook);
|
||||
ctrlr->config_hook.ich_arg = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1154,7 +1153,6 @@ nvme_ctrlr_start_config_hook(void *arg)
|
||||
|
||||
nvme_sysctl_initialize_ctrlr(ctrlr);
|
||||
config_intrhook_disestablish(&ctrlr->config_hook);
|
||||
ctrlr->config_hook.ich_arg = NULL;
|
||||
|
||||
ctrlr->is_initialized = 1;
|
||||
nvme_notify_new_controller(ctrlr);
|
||||
|
Loading…
Reference in New Issue
Block a user