Re: [PATCH 1/2] libfdt: Improve fdt_get_phandle

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



On Wed, Mar 14, 2018 at 02:41:03PM +0100, Mario Six wrote:
1;5002;0c> Given a node offset, the function fdt_get_phandle finds and returns the
> phandle property defined in this node.
> 
> The current implementation first tries to read the "phandle" property,
> then, should this not succeed, tries to read the "linux,phandle" property
> afterwards (both by using the fdt_getprop function), and returns either
> one if it is found.
> 
> This means that we potentially iterate over the properties of the node
> twice (if the neither the "phandle", nor the "linux,phandle" property is
> found).
> 
> Instead of doing this, iterate once over the nodes' properties, and
> check each one if it is equal to either "phandle" or "linux,phandle",
> and return the value in either case. Hence, we only iterate over the
> properties exactly once.
> 
> Signed-off-by: Mario Six <mario.six@xxxxxxxx>

Unless we have someone hitting performance problems in practice, I'm a
bit dubious as to whether the performance increase is worth the
increase in code complexity.

> ---
>  libfdt/fdt_ro.c | 31 ++++++++++++++++++++++---------
>  1 file changed, 22 insertions(+), 9 deletions(-)
> 
> diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
> index dfb3236..7d049fb 100644
> --- a/libfdt/fdt_ro.c
> +++ b/libfdt/fdt_ro.c
> @@ -424,19 +424,32 @@ const void *fdt_getprop(const void *fdt, int nodeoffset,
>  
>  uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
>  {
> -	const fdt32_t *php;
> +	const fdt32_t *php = NULL;
>  	int len;
> +	int offset;
>  
> -	/* FIXME: This is a bit sub-optimal, since we potentially scan
> -	 * over all the properties twice. */
> -	php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
> -	if (!php || (len != sizeof(*php))) {
> -		php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
> -		if (!php || (len != sizeof(*php)))
> -			return 0;
> +	for (offset = fdt_first_property_offset(fdt, nodeoffset);
> +	     (offset >= 0);
> +	     (offset = fdt_next_property_offset(fdt, offset))) {
> +		const struct fdt_property *prop;
> +
> +		if (!(prop = fdt_get_property_by_offset(fdt, offset, &len))) {
> +			offset = -FDT_ERR_INTERNAL;
> +			break;
> +		}
> +		if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff),
> +				   "phandle", strlen("phandle")))
> +			php = (const fdt32_t *)prop->data;
> +
> +		if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff),
> +				   "linux,phandle", strlen("linux,phandle")))
> +			php = (const fdt32_t *)prop->data;
> +
> +		if (php)
> +			return fdt32_to_cpu(*php);
>  	}
>  
> -	return fdt32_to_cpu(*php);
> +	return 0;
>  }
>  
>  const char *fdt_get_alias_namelen(const void *fdt,

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux