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