All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sascha Hauer <sha@pengutronix.de>
To: Johannes Zink <j.zink@pengutronix.de>
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH v3] base: driver: print dev_err_probe message on permanent probe deferral
Date: Tue, 12 Jul 2022 09:30:44 +0200	[thread overview]
Message-ID: <20220712073044.GC23482@pengutronix.de> (raw)
In-Reply-To: <20220708094138.112060-1-j.zink@pengutronix.de>

On Fri, Jul 08, 2022 at 11:41:38AM +0200, Johannes Zink wrote:
> This stores the probe deferral reason in the device structure.
> If a probe is permanently deferred, the last reason is displayed.
> 
> Example output on a permanently deferred probe:
>   ERROR: imx-pgc-domain0: probe permanently deferred (Failed to get domain's regulator)
> 
> Other dev_err_probe outputs are displayed as before.
> 
> Signed-off-by: Johannes Zink <j.zink@pengutronix.de>
> ---

Applied, thanks

Sascha

> v1 -> v2:
>   - improved commit message
>   - improved function prototypes
>   - improved debug output, device name is displayed once only per
>     message
>   - reverted removal of MSG_DEBUG output on deferred probe
>   - replaced kfree by free
>   - removed unnecessary null checks before free
>   - fixed several typos
>   - fixed compiler warnings
>   - fixed coding style issues
> v2 -> v3:
>   - dropped const from dev_err_probe
>   - use xasprintf instead of basprintf: guarantee memory allocation
>   - prevent newline within message on permanent deferral
>   - removed unnecessary helper functions
>   - fixed remaining typos and whitespace changes
>   - improved comments
>   - reverted removal of kernel doc comment 
>   - added example in commit message
> ---
>  drivers/base/driver.c  | 44 +++++++++++++++++++++++++++++++++++-------
>  include/driver.h       |  5 +++++
>  include/linux/printk.h |  6 +++---
>  3 files changed, 45 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/base/driver.c b/drivers/base/driver.c
> index 303ca061c..4898e0114 100644
> --- a/drivers/base/driver.c
> +++ b/drivers/base/driver.c
> @@ -283,6 +283,7 @@ void free_device_res(struct device_d *dev)
>  	dev->name = NULL;
>  	free(dev->unique_name);
>  	dev->unique_name = NULL;
> +	free(dev->deferred_probe_reason);
>  }
>  EXPORT_SYMBOL(free_device_res);
>  
> @@ -333,9 +334,13 @@ static int device_probe_deferred(void)
>  		}
>  	} while (success);
>  
> -	list_for_each_entry(dev, &deferred, active)
> -		dev_err(dev, "probe permanently deferred\n");
> -
> +	list_for_each_entry(dev, &deferred, active) {
> +		if (dev->deferred_probe_reason)
> +			dev_err(dev, "probe permanently deferred (%s)\n",
> +				dev->deferred_probe_reason);
> +		else
> +			dev_err(dev, "probe permanently deferred\n");
> +	}
>  	return 0;
>  }
>  late_initcall(device_probe_deferred);
> @@ -573,6 +578,24 @@ const void *device_get_match_data(struct device_d *dev)
>  	return NULL;
>  }
>  
> +static void device_set_deferred_probe_reason(struct device_d *dev, const struct va_format *vaf)
> +{
> +	char *reason;
> +	char *last_char;
> +
> +	free(dev->deferred_probe_reason);
> +
> +	reason = xasprintf("%pV", vaf);
> +
> +	/* drop newline char at end of reason string */
> +	last_char = reason + strlen(reason) - 1;
> +
> +	if (*last_char == '\n')
> +		*last_char = '\0';
> +
> +	dev->deferred_probe_reason = reason;
> +}
> +
>  /**
>   * dev_err_probe - probe error check and log helper
>   * @loglevel: log level configured in source file
> @@ -584,8 +607,12 @@ const void *device_get_match_data(struct device_d *dev)
>   * This helper implements common pattern present in probe functions for error
>   * checking: print debug or error message depending if the error value is
>   * -EPROBE_DEFER and propagate error upwards.
> - * In case of -EPROBE_DEFER it sets also defer probe reason, which can be
> - * checked later by reading devices_deferred debugfs attribute.
> + *
> + * In case of -EPROBE_DEFER it sets the device's deferred_probe_reason attribute,
> + * but does not report an error. The error is recorded and displayed later, if
> + * (and only if) the probe is permanently deferred. For all other error codes,
> + * it just outputs the error along with the formatted message.
> + *
>   * It replaces code sequence::
>   *
>   * 	if (err != -EPROBE_DEFER)
> @@ -601,8 +628,8 @@ const void *device_get_match_data(struct device_d *dev)
>   * Returns @err.
>   *
>   */
> -int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...);
> -int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...)
> +int dev_err_probe(struct device_d *dev, int err, const char *fmt, ...);
> +int dev_err_probe(struct device_d *dev, int err, const char *fmt, ...)
>  {
>  	struct va_format vaf;
>  	va_list args;
> @@ -611,6 +638,9 @@ int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...)
>  	vaf.fmt = fmt;
>  	vaf.va = &args;
>  
> +	if (err == -EPROBE_DEFER)
> +		device_set_deferred_probe_reason(dev, &vaf);
> +
>  	dev_printf(err == -EPROBE_DEFER ? MSG_DEBUG : MSG_ERR,
>  		   dev, "error %pe: %pV", ERR_PTR(err), &vaf);
>  
> diff --git a/include/driver.h b/include/driver.h
> index b35b5f397..a89ce7af9 100644
> --- a/include/driver.h
> +++ b/include/driver.h
> @@ -88,6 +88,11 @@ struct device_d {
>  	 * when the driver should actually detect client devices
>  	 */
>  	int     (*detect) (struct device_d *);
> +
> +	/*
> +	 * if a driver probe is deferred, this stores the last error
> +	 */
> +	char *deferred_probe_reason;
>  };
>  
>  /** @brief Describes a driver present in the system */
> diff --git a/include/linux/printk.h b/include/linux/printk.h
> index 39523b057..e21e859bf 100644
> --- a/include/linux/printk.h
> +++ b/include/linux/printk.h
> @@ -76,12 +76,12 @@ static inline int pr_print(int level, const char *format, ...)
>  	__dev_printf(8, (dev) , format , ## arg)
>  
>  #if LOGLEVEL >= MSG_ERR
> -int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...)
> +int dev_err_probe(struct device_d *dev, int err, const char *fmt, ...)
>  	__attribute__ ((format(__printf__, 3, 4)));
>  #elif !defined(dev_err_probe)
> -static int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...)
> +static int dev_err_probe(struct device_d *dev, int err, const char *fmt, ...)
>  	__attribute__ ((format(__printf__, 3, 4)));
> -static inline int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...)
> +static inline int dev_err_probe(struct device_d *dev, int err, const char *fmt, ...)
>  {
>  	return err;
>  }
> -- 
> 2.30.2
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



      parent reply	other threads:[~2022-07-12  7:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-08  9:41 [PATCH v3] base: driver: print dev_err_probe message on permanent probe deferral Johannes Zink
2022-07-08 10:36 ` Ahmad Fatoum
2022-07-12  7:30 ` Sascha Hauer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220712073044.GC23482@pengutronix.de \
    --to=sha@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=j.zink@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.