Skip to content

Commit

Permalink
driver core: add test of driver remove calls during probe
Browse files Browse the repository at this point in the history
In recent discussions on ksummit-discuss[1], it was suggested to do a
sequence of probe, remove, probe for testing driver remove paths. This
adds a kconfig option for said test.

[1] https://lists.linuxfoundation.org/pipermail/ksummit-discuss/2016-August/003459.html

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Rob Herring authored and Greg Kroah-Hartman committed Aug 31, 2016
1 parent cebf8fd commit bea5b15
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
10 changes: 10 additions & 0 deletions drivers/base/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ config DEBUG_DEVRES

If you are unsure about this, Say N here.

config DEBUG_TEST_DRIVER_REMOVE
bool "Test driver remove calls during probe"
depends on DEBUG_KERNEL
help
Say Y here if you want the Driver core to test driver remove functions
by calling probe, remove, probe. This tests the remove path without
having to unbind the driver or unload the driver module.

If you are unsure about this, say N here.

config SYS_HYPERVISOR
bool
default n
Expand Down
21 changes: 21 additions & 0 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
{
int ret = -EPROBE_DEFER;
int local_trigger_count = atomic_read(&deferred_trigger_count);
bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE);

if (defer_all_probes) {
/*
Expand All @@ -346,6 +347,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
drv->bus->name, __func__, drv->name, dev_name(dev));
WARN_ON(!list_empty(&dev->devres_head));

re_probe:
dev->driver = drv;

/* If using pinctrl, bind pins now before probing */
Expand Down Expand Up @@ -383,6 +385,25 @@ static int really_probe(struct device *dev, struct device_driver *drv)
goto probe_failed;
}

if (test_remove) {
test_remove = false;

if (dev->bus && dev->bus->remove)
dev->bus->remove(dev);
else if (drv->remove)
drv->remove(dev);

devres_release_all(dev);
driver_sysfs_remove(dev);
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
if (dev->pm_domain && dev->pm_domain->dismiss)
dev->pm_domain->dismiss(dev);
pm_runtime_reinit(dev);

goto re_probe;
}

pinctrl_init_done(dev);

if (dev->pm_domain && dev->pm_domain->sync)
Expand Down

0 comments on commit bea5b15

Please sign in to comment.