[v1] ACPI / platform: Unregister stale platform devices
diff mbox series

Message ID 20190830143432.21695-1-andriy.shevchenko@linux.intel.com
State Awaiting Upstream
Delegated to: Rafael Wysocki
Headers show
Series
  • [v1] ACPI / platform: Unregister stale platform devices
Related show

Commit Message

Andy Shevchenko Aug. 30, 2019, 2:34 p.m. UTC
When the commit 68bdb6773289

  ("ACPI: add support for ACPI reconfiguration notifiers")

introduced reconfiguration notifiers it misses the point that the ACPI table,
which may be loaded and then unloaded via ConfigFS, can contain devices that are
not enumerated by their parents.

In such case the stale platform device is dangling in the system while the rest
of the devices from the same table are already gone.

Introduce acpi_platform_device_remove_notify() notifier that, in similar way to
I²C or SPI buses, unregisters the platform devices on table removal event.

Depends-on: 00500147cbd3 ("drivers: Introduce device lookup variants by ACPI_COMPANION device")
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/acpi/acpi_platform.c | 43 ++++++++++++++++++++++++++++++++++++
 drivers/acpi/scan.c          |  1 +
 2 files changed, 44 insertions(+)

Comments

Andy Shevchenko Sept. 2, 2019, 9:52 a.m. UTC | #1
On Mon, Sep 02, 2019 at 02:38:05PM +0800, kbuild test robot wrote:
> Hi Andy,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on linus/master]
> [cannot apply to v5.3-rc6 next-20190830]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Andy-Shevchenko/ACPI-platform-Unregister-stale-platform-devices/20190902-001307
> config: x86_64-lkp (attached as .config)
> compiler: gcc-7 (Debian 7.4.0-11) 7.4.0
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
> 
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>    drivers//acpi/acpi_platform.c: In function 'acpi_platform_device_find_by_adev':
> >> drivers//acpi/acpi_platform.c:38:8: error: implicit declaration of function 'bus_find_device_by_acpi_dev'; did you mean 'bus_find_device_by_name'? [-Werror=implicit-function-declaration]

False positive, it has Depends-on tag for the dependency which is not yet in
upstream.

Btw, have you noticed double slash in the paths in your scripts for LKP?
(Look above)
Andy Shevchenko Sept. 2, 2019, 9:55 a.m. UTC | #2
On Mon, Sep 02, 2019 at 03:19:11PM +0800, kbuild test robot wrote:
>    drivers/acpi/acpi_platform.c: In function 'acpi_platform_device_find_by_adev':
> >> drivers/acpi/acpi_platform.c:38:8: error: implicit declaration of function 'bus_find_device_by_acpi_dev'; did you mean 'bus_find_device_by_name'? [-Werror=implicit-function-declaration]

Same false positive.
kernel test robot Sept. 4, 2019, 8:46 a.m. UTC | #3
On 9/2/19 5:52 PM, Andy Shevchenko wrote:
> On Mon, Sep 02, 2019 at 02:38:05PM +0800, kbuild test robot wrote:
>> Hi Andy,
>>
>> I love your patch! Yet something to improve:
>>
>> [auto build test ERROR on linus/master]
>> [cannot apply to v5.3-rc6 next-20190830]
>> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>
>> url:    https://github.com/0day-ci/linux/commits/Andy-Shevchenko/ACPI-platform-Unregister-stale-platform-devices/20190902-001307
>> config: x86_64-lkp (attached as .config)
>> compiler: gcc-7 (Debian 7.4.0-11) 7.4.0
>> reproduce:
>>          # save the attached .config to linux build tree
>>          make ARCH=x86_64
>>
>> If you fix the issue, kindly add following tag
>> Reported-by: kbuild test robot <lkp@intel.com>
>>
>> All errors (new ones prefixed by >>):
>>
>>     drivers//acpi/acpi_platform.c: In function 'acpi_platform_device_find_by_adev':
>>>> drivers//acpi/acpi_platform.c:38:8: error: implicit declaration of function 'bus_find_device_by_acpi_dev'; did you mean 'bus_find_device_by_name'? [-Werror=implicit-function-declaration]
> False positive, it has Depends-on tag for the dependency which is not yet in
> upstream.
>
> Btw, have you noticed double slash in the paths in your scripts for LKP?
> (Look above)

Hi Andy,

Thanks for the new finding, The double slash not always appears .
I think the double slash is not from our scripts.

Best Regards,
Rong Chen
Andy Shevchenko Oct. 17, 2019, 11:38 a.m. UTC | #4
On Fri, Aug 30, 2019 at 05:34:32PM +0300, Andy Shevchenko wrote:
> When the commit 68bdb6773289
> 
>   ("ACPI: add support for ACPI reconfiguration notifiers")
> 
> introduced reconfiguration notifiers it misses the point that the ACPI table,
> which may be loaded and then unloaded via ConfigFS, can contain devices that are
> not enumerated by their parents.
> 
> In such case the stale platform device is dangling in the system while the rest
> of the devices from the same table are already gone.
> 
> Introduce acpi_platform_device_remove_notify() notifier that, in similar way to
> I²C or SPI buses, unregisters the platform devices on table removal event.
> 

Rafael, all dependencies now in v5.4-rc1.
Can this be applied, or I need to do more work?

> Depends-on: 00500147cbd3 ("drivers: Introduce device lookup variants by ACPI_COMPANION device")
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/acpi/acpi_platform.c | 43 ++++++++++++++++++++++++++++++++++++
>  drivers/acpi/scan.c          |  1 +
>  2 files changed, 44 insertions(+)
> 
> diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
> index 00ec4f2bf015..dfcd6210828e 100644
> --- a/drivers/acpi/acpi_platform.c
> +++ b/drivers/acpi/acpi_platform.c
> @@ -31,6 +31,44 @@ static const struct acpi_device_id forbidden_id_list[] = {
>  	{"", 0},
>  };
>  
> +static struct platform_device *acpi_platform_device_find_by_adev(struct acpi_device *adev)
> +{
> +	struct device *dev;
> +
> +	dev = bus_find_device_by_acpi_dev(&platform_bus_type, adev);
> +	return dev ? to_platform_device(dev) : NULL;
> +}
> +
> +static int acpi_platform_device_remove_notify(struct notifier_block *nb,
> +					      unsigned long value, void *arg)
> +{
> +	struct acpi_device *adev = arg;
> +	struct platform_device *pdev;
> +
> +	switch (value) {
> +	case ACPI_RECONFIG_DEVICE_ADD:
> +		/* Nothing to do here */
> +		break;
> +	case ACPI_RECONFIG_DEVICE_REMOVE:
> +		if (!acpi_device_enumerated(adev))
> +			break;
> +
> +		pdev = acpi_platform_device_find_by_adev(adev);
> +		if (!pdev)
> +			break;
> +
> +		platform_device_unregister(pdev);
> +		put_device(&pdev->dev);
> +		break;
> +	}
> +
> +	return NOTIFY_OK;
> +}
> +
> +static struct notifier_block acpi_platform_notifier = {
> +	.notifier_call = acpi_platform_device_remove_notify,
> +};
> +
>  static void acpi_platform_fill_resource(struct acpi_device *adev,
>  	const struct resource *src, struct resource *dest)
>  {
> @@ -130,3 +168,8 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
>  	return pdev;
>  }
>  EXPORT_SYMBOL_GPL(acpi_create_platform_device);
> +
> +void __init acpi_platform_init(void)
> +{
> +	acpi_reconfig_notifier_register(&acpi_platform_notifier);
> +}
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index aad6be5c0af0..915650bf519f 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -2174,6 +2174,7 @@ int __init acpi_scan_init(void)
>  	acpi_pci_root_init();
>  	acpi_pci_link_init();
>  	acpi_processor_init();
> +	acpi_platform_init();
>  	acpi_lpss_init();
>  	acpi_apd_init();
>  	acpi_cmos_rtc_init();
> -- 
> 2.23.0.rc1
>
Rafael J. Wysocki Oct. 17, 2019, 9:57 p.m. UTC | #5
On Fri, Aug 30, 2019 at 4:34 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> When the commit 68bdb6773289
>
>   ("ACPI: add support for ACPI reconfiguration notifiers")
>
> introduced reconfiguration notifiers it misses the point that the ACPI table,
> which may be loaded and then unloaded via ConfigFS, can contain devices that are
> not enumerated by their parents.
>
> In such case the stale platform device is dangling in the system while the rest
> of the devices from the same table are already gone.
>
> Introduce acpi_platform_device_remove_notify() notifier that, in similar way to
> I²C or SPI buses, unregisters the platform devices on table removal event.
>
> Depends-on: 00500147cbd3 ("drivers: Introduce device lookup variants by ACPI_COMPANION device")
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/acpi/acpi_platform.c | 43 ++++++++++++++++++++++++++++++++++++
>  drivers/acpi/scan.c          |  1 +
>  2 files changed, 44 insertions(+)
>
> diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
> index 00ec4f2bf015..dfcd6210828e 100644
> --- a/drivers/acpi/acpi_platform.c
> +++ b/drivers/acpi/acpi_platform.c
> @@ -31,6 +31,44 @@ static const struct acpi_device_id forbidden_id_list[] = {
>         {"", 0},
>  };
>
> +static struct platform_device *acpi_platform_device_find_by_adev(struct acpi_device *adev)
> +{
> +       struct device *dev;
> +
> +       dev = bus_find_device_by_acpi_dev(&platform_bus_type, adev);
> +       return dev ? to_platform_device(dev) : NULL;
> +}
> +
> +static int acpi_platform_device_remove_notify(struct notifier_block *nb,
> +                                             unsigned long value, void *arg)
> +{
> +       struct acpi_device *adev = arg;
> +       struct platform_device *pdev;
> +
> +       switch (value) {
> +       case ACPI_RECONFIG_DEVICE_ADD:
> +               /* Nothing to do here */
> +               break;
> +       case ACPI_RECONFIG_DEVICE_REMOVE:
> +               if (!acpi_device_enumerated(adev))
> +                       break;
> +
> +               pdev = acpi_platform_device_find_by_adev(adev);
> +               if (!pdev)
> +                       break;
> +
> +               platform_device_unregister(pdev);
> +               put_device(&pdev->dev);
> +               break;
> +       }
> +
> +       return NOTIFY_OK;
> +}
> +
> +static struct notifier_block acpi_platform_notifier = {
> +       .notifier_call = acpi_platform_device_remove_notify,
> +};
> +
>  static void acpi_platform_fill_resource(struct acpi_device *adev,
>         const struct resource *src, struct resource *dest)
>  {
> @@ -130,3 +168,8 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
>         return pdev;
>  }
>  EXPORT_SYMBOL_GPL(acpi_create_platform_device);
> +
> +void __init acpi_platform_init(void)
> +{
> +       acpi_reconfig_notifier_register(&acpi_platform_notifier);
> +}
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index aad6be5c0af0..915650bf519f 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -2174,6 +2174,7 @@ int __init acpi_scan_init(void)
>         acpi_pci_root_init();
>         acpi_pci_link_init();
>         acpi_processor_init();
> +       acpi_platform_init();
>         acpi_lpss_init();
>         acpi_apd_init();
>         acpi_cmos_rtc_init();
> --

Applying (with minor modifications) as 5.5 material, thanks!
Andy Shevchenko Oct. 18, 2019, 8:35 a.m. UTC | #6
On Thu, Oct 17, 2019 at 11:57:25PM +0200, Rafael J. Wysocki wrote:

> Applying (with minor modifications) as 5.5 material, thanks!

Thank you!

Patch
diff mbox series

diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 00ec4f2bf015..dfcd6210828e 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -31,6 +31,44 @@  static const struct acpi_device_id forbidden_id_list[] = {
 	{"", 0},
 };
 
+static struct platform_device *acpi_platform_device_find_by_adev(struct acpi_device *adev)
+{
+	struct device *dev;
+
+	dev = bus_find_device_by_acpi_dev(&platform_bus_type, adev);
+	return dev ? to_platform_device(dev) : NULL;
+}
+
+static int acpi_platform_device_remove_notify(struct notifier_block *nb,
+					      unsigned long value, void *arg)
+{
+	struct acpi_device *adev = arg;
+	struct platform_device *pdev;
+
+	switch (value) {
+	case ACPI_RECONFIG_DEVICE_ADD:
+		/* Nothing to do here */
+		break;
+	case ACPI_RECONFIG_DEVICE_REMOVE:
+		if (!acpi_device_enumerated(adev))
+			break;
+
+		pdev = acpi_platform_device_find_by_adev(adev);
+		if (!pdev)
+			break;
+
+		platform_device_unregister(pdev);
+		put_device(&pdev->dev);
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block acpi_platform_notifier = {
+	.notifier_call = acpi_platform_device_remove_notify,
+};
+
 static void acpi_platform_fill_resource(struct acpi_device *adev,
 	const struct resource *src, struct resource *dest)
 {
@@ -130,3 +168,8 @@  struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
 	return pdev;
 }
 EXPORT_SYMBOL_GPL(acpi_create_platform_device);
+
+void __init acpi_platform_init(void)
+{
+	acpi_reconfig_notifier_register(&acpi_platform_notifier);
+}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index aad6be5c0af0..915650bf519f 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2174,6 +2174,7 @@  int __init acpi_scan_init(void)
 	acpi_pci_root_init();
 	acpi_pci_link_init();
 	acpi_processor_init();
+	acpi_platform_init();
 	acpi_lpss_init();
 	acpi_apd_init();
 	acpi_cmos_rtc_init();