All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
To: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Frank Rowand
	<frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
Cc: Pantelis Antoniou
	<pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH 3/4] of: Custom printk format specifier for device node
Date: Wed, 14 Jun 2017 13:56:48 -0700	[thread overview]
Message-ID: <1497473808.18751.70.camel@perches.com> (raw)
In-Reply-To: <20170614203025.7581-4-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

On Wed, 2017-06-14 at 15:30 -0500, Rob Herring wrote:
> From: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

I think the commit subject is wrong.
It adds an "of" specific bit to vsprintf.c.
The subject should be
'vsprintf:  Add %p extension "%pO" for device tree'

> 90% of the usage of device node's full_name is printing it out
> in a kernel message. Preparing for the eventual delayed allocation
> introduce a custom printk format specifier that is both more
> compact and more pleasant to the eye.
> 
> For instance typical use is:
> 	pr_info("Frobbing node %s\n", node->full_name);
> 
> Which can be written now as:
> 	pr_info("Frobbing node %pOF\n", node);

Somehow I think this example is poor as node->full_name
is a pretty obvious to read use.  %pOF requires you to
look up or know what the output is going to be.

> More fine-grained control of formatting includes printing the name,
> flag, path-spec name, reference count and others, explained in the
> documentation entry.
> 
> Originally written by Pantelis, but pretty much rewrote the core
> function using existing string/number functions. The 2 passes were
> unnecessary and have been removed. Also, updated the checkpatch.pl
> check.

Some comments about the code.

> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> []
> @@ -1470,6 +1471,123 @@ char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt)
>  	return format_flags(buf, end, flags, names);
>  }
>  
> +static noinline_for_stack
> +char *device_node_gen_full_name(const struct device_node *np, char *buf, char *end)
> +{
> +	int len, ret;
> +
> +	if (!np || !np->parent)
> +		return buf;
> +
> +	buf = device_node_gen_full_name(np->parent, buf, end);

This is recursive.  How many levels of parents could there be?
Perhaps there should be a recursion limit.

> +
> +	if (buf < end)
> +		len = end - buf;
> +	else
> +		len = 0;
> +	ret = snprintf(buf, len, "/%s", kbasename(np->full_name));
> +	if (ret <= 0)
> +		return buf;
> +	else if (len == 0 || ret < len)
> +		return buf + ret;
> +	return buf + len;
> +}

Does this work with %p<len>OF for a right justified or padded
length string?  Perhaps widen_string should be added.

> +static noinline_for_stack
> +char *device_node_string(char *buf, char *end, struct device_node *dn,
> +			 struct printf_spec spec, const char *fmt)
> +{
> +	char tbuf[sizeof("xxxxxxxxxx") + 1];
> +	const char *fmtp, *p;
> +	int ret;
> +	char *buf_start = buf;
> +	struct property *prop;
> +	bool has_mult, pass;
> +	const struct printf_spec num_spec = {
> +		.flags = SMALL,
> +		.field_width = -1,
> +		.precision = -1,
> +		.base = 10,
> +	};
> +
> +	struct printf_spec str_spec = spec;
> +	str_spec.field_width = -1;
> +
> +	if (!IS_ENABLED(CONFIG_OF))
> +		return string(buf, end, "(!OF)", spec);
> +
> +	if ((unsigned long)dn < PAGE_SIZE)
> +		return string(buf, end, "(null)", spec);
> +
> +	/* simple case without anything any more format specifiers */
> +	if (fmt[1] == '\0' || strcspn(fmt + 1,"fnpPFcCr") > 0)
> +		fmt = "Ff";
> +
> +	for (fmtp = fmt + 1, pass = false; strspn(fmtp,"fnpPFcCr"); fmtp++, pass = true) {

why not
	while (isalpha(*++fmt))
like ip6 or isalnum like FORMAT_TYPE_PTR uses?

> +		if (pass && (*fmtp != 'f')) {
> +			if (buf < end)
> +				*buf = '|';
> +			buf++;
> +		}
> +
> +		switch (*fmtp) {
> +		case 'f':	/* full_name */
> +			if (pass) {
> +				if (buf < end)
> +					*buf = ':';
> +				buf++;
> +			}
> +			buf = device_node_gen_full_name(dn, buf, end);
> +			break;
> +		case 'n':	/* name */
> +			buf = string(buf, end, dn->name, str_spec);
> +			break;
> +		case 'p':	/* phandle */
> +			buf = number(buf, end, (unsigned int)dn->phandle, num_spec);
> +			break;
> +		case 'P':	/* path-spec */
> +			buf = string(buf, end, kbasename(of_node_full_name(dn)), str_spec);
> +			break;
> +		case 'F':	/* flags */
> +			snprintf(tbuf, sizeof(tbuf), "%c%c%c%c",
> +				of_node_check_flag(dn, OF_DYNAMIC) ?
> +					'D' : '-',
> +				of_node_check_flag(dn, OF_DETACHED) ?
> +					'd' : '-',
> +				of_node_check_flag(dn, OF_POPULATED) ?
> +					'P' : '-',
> +				of_node_check_flag(dn,
> +					OF_POPULATED_BUS) ?  'B' : '-');

I'd try to avoid all uses of snprintf as it's effectively
another fairly
large stack frame.

It's probably better to avoid more recursion stack depth use
and just use *buf++ as appropriate.

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: Joe Perches <joe@perches.com>
To: Rob Herring <robh@kernel.org>,
	Frank Rowand <frowand.list@gmail.com>,
	Mark Rutland <mark.rutland@arm.com>
Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/4] of: Custom printk format specifier for device node
Date: Wed, 14 Jun 2017 13:56:48 -0700	[thread overview]
Message-ID: <1497473808.18751.70.camel@perches.com> (raw)
In-Reply-To: <20170614203025.7581-4-robh@kernel.org>

On Wed, 2017-06-14 at 15:30 -0500, Rob Herring wrote:
> From: Pantelis Antoniou <pantelis.antoniou@konsulko.com>

I think the commit subject is wrong.
It adds an "of" specific bit to vsprintf.c.
The subject should be
'vsprintf:  Add %p extension "%pO" for device tree'

> 90% of the usage of device node's full_name is printing it out
> in a kernel message. Preparing for the eventual delayed allocation
> introduce a custom printk format specifier that is both more
> compact and more pleasant to the eye.
> 
> For instance typical use is:
> 	pr_info("Frobbing node %s\n", node->full_name);
> 
> Which can be written now as:
> 	pr_info("Frobbing node %pOF\n", node);

Somehow I think this example is poor as node->full_name
is a pretty obvious to read use.  %pOF requires you to
look up or know what the output is going to be.

> More fine-grained control of formatting includes printing the name,
> flag, path-spec name, reference count and others, explained in the
> documentation entry.
> 
> Originally written by Pantelis, but pretty much rewrote the core
> function using existing string/number functions. The 2 passes were
> unnecessary and have been removed. Also, updated the checkpatch.pl
> check.

Some comments about the code.

> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> []
> @@ -1470,6 +1471,123 @@ char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt)
>  	return format_flags(buf, end, flags, names);
>  }
>  
> +static noinline_for_stack
> +char *device_node_gen_full_name(const struct device_node *np, char *buf, char *end)
> +{
> +	int len, ret;
> +
> +	if (!np || !np->parent)
> +		return buf;
> +
> +	buf = device_node_gen_full_name(np->parent, buf, end);

This is recursive.  How many levels of parents could there be?
Perhaps there should be a recursion limit.

> +
> +	if (buf < end)
> +		len = end - buf;
> +	else
> +		len = 0;
> +	ret = snprintf(buf, len, "/%s", kbasename(np->full_name));
> +	if (ret <= 0)
> +		return buf;
> +	else if (len == 0 || ret < len)
> +		return buf + ret;
> +	return buf + len;
> +}

Does this work with %p<len>OF for a right justified or padded
length string?  Perhaps widen_string should be added.

> +static noinline_for_stack
> +char *device_node_string(char *buf, char *end, struct device_node *dn,
> +			 struct printf_spec spec, const char *fmt)
> +{
> +	char tbuf[sizeof("xxxxxxxxxx") + 1];
> +	const char *fmtp, *p;
> +	int ret;
> +	char *buf_start = buf;
> +	struct property *prop;
> +	bool has_mult, pass;
> +	const struct printf_spec num_spec = {
> +		.flags = SMALL,
> +		.field_width = -1,
> +		.precision = -1,
> +		.base = 10,
> +	};
> +
> +	struct printf_spec str_spec = spec;
> +	str_spec.field_width = -1;
> +
> +	if (!IS_ENABLED(CONFIG_OF))
> +		return string(buf, end, "(!OF)", spec);
> +
> +	if ((unsigned long)dn < PAGE_SIZE)
> +		return string(buf, end, "(null)", spec);
> +
> +	/* simple case without anything any more format specifiers */
> +	if (fmt[1] == '\0' || strcspn(fmt + 1,"fnpPFcCr") > 0)
> +		fmt = "Ff";
> +
> +	for (fmtp = fmt + 1, pass = false; strspn(fmtp,"fnpPFcCr"); fmtp++, pass = true) {

why not
	while (isalpha(*++fmt))
like ip6 or isalnum like FORMAT_TYPE_PTR uses?

> +		if (pass && (*fmtp != 'f')) {
> +			if (buf < end)
> +				*buf = '|';
> +			buf++;
> +		}
> +
> +		switch (*fmtp) {
> +		case 'f':	/* full_name */
> +			if (pass) {
> +				if (buf < end)
> +					*buf = ':';
> +				buf++;
> +			}
> +			buf = device_node_gen_full_name(dn, buf, end);
> +			break;
> +		case 'n':	/* name */
> +			buf = string(buf, end, dn->name, str_spec);
> +			break;
> +		case 'p':	/* phandle */
> +			buf = number(buf, end, (unsigned int)dn->phandle, num_spec);
> +			break;
> +		case 'P':	/* path-spec */
> +			buf = string(buf, end, kbasename(of_node_full_name(dn)), str_spec);
> +			break;
> +		case 'F':	/* flags */
> +			snprintf(tbuf, sizeof(tbuf), "%c%c%c%c",
> +				of_node_check_flag(dn, OF_DYNAMIC) ?
> +					'D' : '-',
> +				of_node_check_flag(dn, OF_DETACHED) ?
> +					'd' : '-',
> +				of_node_check_flag(dn, OF_POPULATED) ?
> +					'P' : '-',
> +				of_node_check_flag(dn,
> +					OF_POPULATED_BUS) ?  'B' : '-');

I'd try to avoid all uses of snprintf as it's effectively
another fairly
large stack frame.

It's probably better to avoid more recursion stack depth use
and just use *buf++ as appropriate.

  parent reply	other threads:[~2017-06-14 20:56 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-14 20:30 [PATCH 0/4] DT printf format specifiers Rob Herring
2017-06-14 20:30 ` Rob Herring
     [not found] ` <20170614203025.7581-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-06-14 20:30   ` [PATCH 1/4] of: use kbasename instead of open coding Rob Herring
2017-06-14 20:30     ` Rob Herring
     [not found]     ` <20170614203025.7581-2-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-06-17 17:30       ` Andy Shevchenko
2017-06-17 17:30         ` Andy Shevchenko
2017-06-14 20:30 ` [PATCH 2/4] of: find_node_by_full_name rewrite to compare each level Rob Herring
2017-06-14 20:30 ` [PATCH 3/4] of: Custom printk format specifier for device node Rob Herring
     [not found]   ` <20170614203025.7581-4-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-06-14 20:56     ` Joe Perches [this message]
2017-06-14 20:56       ` Joe Perches
     [not found]       ` <1497473808.18751.70.camel-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
2017-06-15 12:30         ` Rob Herring
2017-06-15 12:30           ` Rob Herring
     [not found]           ` <CAL_JsqJ_cc46Hf2XdZoXkgZyOh+0KXVXfeWYe1100E9vuRt12A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-15 16:51             ` Joe Perches
2017-06-15 16:51               ` Joe Perches
2017-06-15 21:26         ` Rob Herring
2017-06-15 21:26           ` Rob Herring
2017-06-15 21:50           ` Joe Perches
2017-06-15 21:50             ` Joe Perches
2017-06-22 20:44     ` [PATCH v2] vsprintf: Add %p extension "%pOF" for device tree Rob Herring
2017-06-22 20:44       ` Rob Herring
2017-06-22 22:44       ` Randy Dunlap
     [not found]         ` <d22444aa-39da-ec74-42a1-63f1fa40c7d3-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2017-06-23 14:08           ` Rob Herring
2017-06-23 14:08             ` Rob Herring
     [not found]       ` <20170622204445.14930-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-06-23  3:01         ` Joe Perches
2017-06-23  3:01           ` Joe Perches
     [not found]           ` <1498186912.24295.9.camel-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
2017-06-23 14:13             ` Rob Herring
2017-06-23 14:13               ` Rob Herring
2017-06-23 17:30       ` [PATCH v3] " Rob Herring
     [not found]         ` <20170623173053.636-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-06-23 17:38           ` Joe Perches
2017-06-23 17:38             ` Joe Perches
2017-06-14 20:30 ` [PATCH 4/4] of: Convert to using %pOF instead of full_name Rob Herring
     [not found]   ` <20170614203025.7581-5-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-06-14 20:58     ` Joe Perches
2017-06-14 20:58       ` Joe Perches

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=1497473808.18751.70.camel@perches.com \
    --to=joe-6d6dil74uinbdgjk7y7tuq@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
    --cc=pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org \
    --cc=robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    /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.