2021-03-18 07:41:39

by Ahmad Fatoum

[permalink] [raw]
Subject: [PATCH 1/2] driver core: clear deferred probe reason on probe retry

When retrying a deferred probe, any old defer reason string should be
discarded. Otherwise, if probe is deferred again at a different spot,
but without setting a message, a now incorrect probe reason will remain.

This was observed with the i.MX I2C driver, which ultimately failed
to probe due to lack of the GPIO driver. The probe defer for GPIO
doesn't record a message, but a previous probe defer to clock_get did.
This had the effect that /sys/kernel/debug/devices_deferred listed
a misleading probe deferral reason.

Cc: [email protected]
Fixes: d090b70ede02 ("driver core: add deferring probe reason to devices_deferred property")
Signed-off-by: Ahmad Fatoum <[email protected]>
---
drivers/base/dd.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 9179825ff646..e2cf3b29123e 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -97,6 +97,9 @@ static void deferred_probe_work_func(struct work_struct *work)

get_device(dev);

+ kfree(dev->p->deferred_probe_reason);
+ dev->p->deferred_probe_reason = NULL;
+
/*
* Drop the mutex while probing each device; the probe path may
* manipulate the deferred list
--
2.29.2


2021-03-18 07:42:15

by Ahmad Fatoum

[permalink] [raw]
Subject: [PATCH 2/2] driver core: add helper for deferred probe reason setting

We now have three places within the same file doing the same operation
of freeing this pointer and setting it anew. A helper make this
arguably easier to read, so add one.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
drivers/base/dd.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index e2cf3b29123e..4201baa1cc13 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -69,6 +69,12 @@ static char async_probe_drv_names[ASYNC_DRV_NAMES_MAX_LEN];
*/
static bool defer_all_probes;

+static void __device_set_deferred_probe_reason(const struct device *dev, char *reason)
+{
+ kfree(dev->p->deferred_probe_reason);
+ dev->p->deferred_probe_reason = reason;
+}
+
/*
* deferred_probe_work_func() - Retry probing devices in the active list.
*/
@@ -97,8 +103,7 @@ static void deferred_probe_work_func(struct work_struct *work)

get_device(dev);

- kfree(dev->p->deferred_probe_reason);
- dev->p->deferred_probe_reason = NULL;
+ __device_set_deferred_probe_reason(dev, NULL);

/*
* Drop the mutex while probing each device; the probe path may
@@ -140,8 +145,7 @@ void driver_deferred_probe_del(struct device *dev)
if (!list_empty(&dev->p->deferred_probe)) {
dev_dbg(dev, "Removed from deferred list\n");
list_del_init(&dev->p->deferred_probe);
- kfree(dev->p->deferred_probe_reason);
- dev->p->deferred_probe_reason = NULL;
+ __device_set_deferred_probe_reason(dev, NULL);
}
mutex_unlock(&deferred_probe_mutex);
}
@@ -220,11 +224,12 @@ void device_unblock_probing(void)
void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf)
{
const char *drv = dev_driver_string(dev);
+ char *reason;

mutex_lock(&deferred_probe_mutex);

- kfree(dev->p->deferred_probe_reason);
- dev->p->deferred_probe_reason = kasprintf(GFP_KERNEL, "%s: %pV", drv, vaf);
+ reason = kasprintf(GFP_KERNEL, "%s: %pV", drv, vaf);
+ __device_set_deferred_probe_reason(dev, reason);

mutex_unlock(&deferred_probe_mutex);
}
--
2.29.2

2021-03-18 12:50:10

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 1/2] driver core: clear deferred probe reason on probe retry

On Thu, Mar 18, 2021 at 9:39 AM Ahmad Fatoum <[email protected]> wrote:
>
> When retrying a deferred probe, any old defer reason string should be
> discarded. Otherwise, if probe is deferred again at a different spot,

probe -> the probe

> but without setting a message, a now incorrect probe reason will remain.

a now incorrect -> now the incorrect

> This was observed with the i.MX I2C driver, which ultimately failed
> to probe due to lack of the GPIO driver. The probe defer for GPIO
> doesn't record a message, but a previous probe defer to clock_get did.
> This had the effect that /sys/kernel/debug/devices_deferred listed
> a misleading probe deferral reason.

Reviewed-by: Andy Shevchenko <[email protected]>

> Cc: [email protected]
> Fixes: d090b70ede02 ("driver core: add deferring probe reason to devices_deferred property")
> Signed-off-by: Ahmad Fatoum <[email protected]>
> ---
> drivers/base/dd.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 9179825ff646..e2cf3b29123e 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -97,6 +97,9 @@ static void deferred_probe_work_func(struct work_struct *work)
>
> get_device(dev);
>
> + kfree(dev->p->deferred_probe_reason);
> + dev->p->deferred_probe_reason = NULL;
> +
> /*
> * Drop the mutex while probing each device; the probe path may
> * manipulate the deferred list
> --
> 2.29.2
>


--
With Best Regards,
Andy Shevchenko

2021-03-22 08:24:45

by Andrzej Hajda

[permalink] [raw]
Subject: Re: [PATCH 2/2] driver core: add helper for deferred probe reason setting


W dniu 18.03.2021 o 08:39, Ahmad Fatoum pisze:
> We now have three places within the same file doing the same operation
> of freeing this pointer and setting it anew. A helper make this
> arguably easier to read, so add one.
>
> Signed-off-by: Ahmad Fatoum <[email protected]>

Reviewed-by: Andrzej Hajda <[email protected]>

Regards

Andrzej

> ---
> drivers/base/dd.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index e2cf3b29123e..4201baa1cc13 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -69,6 +69,12 @@ static char async_probe_drv_names[ASYNC_DRV_NAMES_MAX_LEN];
> */
> static bool defer_all_probes;
>
> +static void __device_set_deferred_probe_reason(const struct device *dev, char *reason)
> +{
> + kfree(dev->p->deferred_probe_reason);
> + dev->p->deferred_probe_reason = reason;
> +}
> +
> /*
> * deferred_probe_work_func() - Retry probing devices in the active list.
> */
> @@ -97,8 +103,7 @@ static void deferred_probe_work_func(struct work_struct *work)
>
> get_device(dev);
>
> - kfree(dev->p->deferred_probe_reason);
> - dev->p->deferred_probe_reason = NULL;
> + __device_set_deferred_probe_reason(dev, NULL);
>
> /*
> * Drop the mutex while probing each device; the probe path may
> @@ -140,8 +145,7 @@ void driver_deferred_probe_del(struct device *dev)
> if (!list_empty(&dev->p->deferred_probe)) {
> dev_dbg(dev, "Removed from deferred list\n");
> list_del_init(&dev->p->deferred_probe);
> - kfree(dev->p->deferred_probe_reason);
> - dev->p->deferred_probe_reason = NULL;
> + __device_set_deferred_probe_reason(dev, NULL);
> }
> mutex_unlock(&deferred_probe_mutex);
> }
> @@ -220,11 +224,12 @@ void device_unblock_probing(void)
> void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf)
> {
> const char *drv = dev_driver_string(dev);
> + char *reason;
>
> mutex_lock(&deferred_probe_mutex);
>
> - kfree(dev->p->deferred_probe_reason);
> - dev->p->deferred_probe_reason = kasprintf(GFP_KERNEL, "%s: %pV", drv, vaf);
> + reason = kasprintf(GFP_KERNEL, "%s: %pV", drv, vaf);
> + __device_set_deferred_probe_reason(dev, reason);
>
> mutex_unlock(&deferred_probe_mutex);
> }