From cf37d86788b0869717841b4d99f9d133c0bc2cc8 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Fri, 31 Dec 2021 11:39:00 +0800 Subject: [PATCH 1/2] driver core: Move driver_sysfs_remove() after driver_sysfs_add() ANBZ: #27979 commit 885e50253bfd6750327a265405461496d6af1639 upstream. The driver_sysfs_remove() should be called after driver_sysfs_add() in really_probe(). The out-of-order driver_sysfs_remove() tries to remove some nonexistent nodes under the device and driver sysfs nodes. This is allowed, hence this change doesn't fix any problem, just a cleanup. Signed-off-by: Lu Baolu Link: https://lore.kernel.org/r/20211231033901.2168664-2-baolu.lu@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Chu Guangqing --- drivers/base/dd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 87377e4aa157..3dde195c78b3 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -565,14 +565,14 @@ static int really_probe(struct device *dev, struct device_driver *drv) if (dev->bus->dma_configure) { ret = dev->bus->dma_configure(dev); if (ret) - goto probe_failed; + goto sysfs_failed; } ret = driver_sysfs_add(dev); if (ret) { pr_err("%s: driver_sysfs_add(%s) failed\n", __func__, dev_name(dev)); - goto probe_failed; + goto sysfs_failed; } if (dev->pm_domain && dev->pm_domain->activate) { @@ -648,6 +648,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) else if (drv->remove) drv->remove(dev); probe_failed: + driver_sysfs_remove(dev); +sysfs_failed: if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DRIVER_NOT_BOUND, dev); @@ -659,7 +661,6 @@ static int really_probe(struct device *dev, struct device_driver *drv) arch_teardown_dma_ops(dev); kfree(dev->dma_range_map); dev->dma_range_map = NULL; - driver_sysfs_remove(dev); dev->driver = NULL; dev_set_drvdata(dev, NULL); if (dev->pm_domain && dev->pm_domain->dismiss) -- Gitee From add3af4866a203c5f3f6860a126b357649434245 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 23 Feb 2022 16:52:56 -0600 Subject: [PATCH 2/2] driver core: Refactor multiple copies of device cleanup ANBZ: #27979 commit 9ad307213fa4081f4bc2f2daa31d4f2d35d7a213 upstream. There are 3 copies of the same device cleanup code used for probe failure, testing re-probing, and device unbinding. Changes to this code often miss at least one of the copies of the code. See commits d0243bbd5dd3 ("drivers core: Free dma_range_map when driver probe failed") and d8f7a5484f21 ("driver core: Free DMA range map when device is released") for example. Let's refactor the code to its own function. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220223225257.1681968-2-robh@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Chu Guangqing --- drivers/base/dd.c | 47 +++++++++++++++++------------------------------ 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 3dde195c78b3..40c9ea7b87e6 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -494,6 +494,19 @@ static ssize_t state_synced_show(struct device *dev, } static DEVICE_ATTR_RO(state_synced); +static void device_unbind_cleanup(struct device *dev) +{ + devres_release_all(dev); + arch_teardown_dma_ops(dev); + kfree(dev->dma_range_map); + dev->dma_range_map = NULL; + 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); + dev_pm_set_driver_flags(dev, 0); +} static int call_driver_probe(struct device *dev, struct device_driver *drv) { @@ -616,16 +629,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) else if (drv->remove) drv->remove(dev); - devres_release_all(dev); - arch_teardown_dma_ops(dev); - kfree(dev->dma_range_map); - dev->dma_range_map = NULL; 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); + device_unbind_cleanup(dev); goto re_probe; } @@ -657,16 +662,7 @@ static int really_probe(struct device *dev, struct device_driver *drv) dev->bus->dma_cleanup(dev); pinctrl_bind_failed: device_links_no_driver(dev); - devres_release_all(dev); - arch_teardown_dma_ops(dev); - kfree(dev->dma_range_map); - dev->dma_range_map = NULL; - 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); - dev_pm_set_driver_flags(dev, 0); + device_unbind_cleanup(dev); done: return ret; } @@ -1233,21 +1229,12 @@ static void __device_release_driver(struct device *dev, struct device *parent) else if (drv->remove) drv->remove(dev); - devres_release_all(dev); - arch_teardown_dma_ops(dev); - kfree(dev->dma_range_map); - dev->dma_range_map = NULL; - 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); - dev_pm_set_driver_flags(dev, 0); - if (dev->bus && dev->bus->dma_cleanup) dev->bus->dma_cleanup(dev); + device_links_driver_cleanup(dev); + device_unbind_cleanup(dev); klist_remove(&dev->p->knode_driver); device_pm_check_callbacks(dev); -- Gitee