Re: [PATCH 1/2] dtc: add ability to make nodes conditional on them being referenced

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



On Sat, Feb 03, 2018 at 10:14:31AM +0100, Maxime Ripard wrote:
> From: Heiko Stuebner <heiko.stuebner@xxxxxx>

Sorry I've taken so long to look at this.

> 
> On i.MX, which carries a lot of pin-groups of which most are unused on
> individual boards, they noticed that this plethora of nodes also results
> in the runtime-lookup-performance also degrading [0].

I do kind of wonder if that indicates that using the tree without
doing some kind of unflattening and indexing on it is the right
option.

> A i.MX-specific solution defining the pingroups in the board files but
> using macros to reference the pingroup-data was not well received.

Ok.  I'm not seeing much sign of poor reception in that thread; did
that happen elsewhere?

> This patch is trying to solve this issue in a more general way, by
> adding the ability to mark nodes as needing to be referenced somewhere
> in the tree.
> 
> To mark a node a needing to be referenced it must be prefixed with
> /delete-if-unreferenced/. This makes dtc check the nodes reference-status
> when creating the flattened tree, dropping it if unreferenced.
> 
> For example, the i.MX6SL pingroup
> 
> 	/delete-if-unreferenced/ pinctrl_ecspi1_1: ecspi1grp-1 {
> 		fsl,pins = <
> 			MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
> 			MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
> 			MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
> 		>;
> 	};
> 
> would only be included in the dtb if it got referenced somewhere
> as pingroup via
> 
> 	node {
> 		pinctrl-0 <&pinctrl_ecscpi1_1>;
> 	};
> 
> [0] http://thread.gmane.org/gmane.linux.ports.arm.kernel/275912/

Ok.  As you might guess from above, I have some misgivings about how
significant this use case is.  That said, though, this is pretty small
and well-contained, so I'm happy enough to merge something like this
even if the use case is a bit marginal.

There are some fairly minor things to fix in the implementation, see
below:

> Signed-off-by: Heiko Stuebner <heiko.stuebner@xxxxxx>
> Signed-off-by: Maxime Ripard <maxime.ripard@xxxxxxxxxxx>
> ---
> Hi,
> 
> This is a respin of the patch previously sent by Heiko here:
> https://patchwork.kernel.org/patch/3840371/
> 
> With hopefully all your comments addressed.
> 
> Let me know what you think,
> Maxime
> 
>  checks.c     |  2 ++
>  dtc-lexer.l  |  7 +++++++
>  dtc-parser.y |  5 +++++
>  dtc.h        |  4 ++++
>  flattree.c   |  3 +++
>  livetree.c   | 14 ++++++++++++++
>  6 files changed, 35 insertions(+)
> 
> diff --git a/checks.c b/checks.c
> index 1cded3658491..a1e0ad91b083 100644
> --- a/checks.c
> +++ b/checks.c
> @@ -571,6 +571,8 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
>  
>  			phandle = get_node_phandle(dt, refnode);
>  			*((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
> +
> +			reference_node(refnode);

You only reference nodes for phandle references, not for path
references.  That's probably what not what you want.  If that really
was your intention, then I don't think you actually need the
referenced flag - you could infer it from whether the node has a
phandle assigned.

>  		}
>  	}
>  }
> diff --git a/dtc-lexer.l b/dtc-lexer.l
> index fd825ebba69c..2afde3acad8a 100644
> --- a/dtc-lexer.l
> +++ b/dtc-lexer.l
> @@ -153,6 +153,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
>  			return DT_DEL_NODE;
>  		}
>  
> +<*>"/delete-if-unreferenced/"	{

Maybe "/omit-if-no-ref/".  It's a bit shorter, and I prefer "omit" to
"delete", because this doesn't work quite the same way that say
/delete-node/ and /delete-property/ do.

> +			DPRINT("Keyword: /delete-if-unreferenced/\n");
> +			DPRINT("<PROPNODENAME>\n");
> +			BEGIN(PROPNODENAME);
> +			return DT_DEL_UNREFERENCED;
> +		}
> +
>  <*>{LABEL}:	{
>  			DPRINT("Label: %s\n", yytext);
>  			yylval.labelref = xstrdup(yytext);
> diff --git a/dtc-parser.y b/dtc-parser.y
> index 44af170abfea..55c951c5327f 100644
> --- a/dtc-parser.y
> +++ b/dtc-parser.y
> @@ -63,6 +63,7 @@ extern bool treesource_error;
>  %token DT_BITS
>  %token DT_DEL_PROP
>  %token DT_DEL_NODE
> +%token DT_DEL_UNREFERENCED
>  %token <propnodename> DT_PROPNODENAME
>  %token <integer> DT_LITERAL
>  %token <integer> DT_CHAR_LITERAL
> @@ -523,6 +524,10 @@ subnode:
>  		{
>  			$$ = name_node(build_node_delete(), $2);
>  		}
> +	| DT_DEL_UNREFERENCED subnode
> +		{
> +			$$ = mark_node_needs_reference($2);
> +		}
>  	| DT_LABEL subnode
>  		{
>  			add_label(&$2->labels, $1);
> diff --git a/dtc.h b/dtc.h
> index 3b18a42b866e..cb7e3752af5a 100644
> --- a/dtc.h
> +++ b/dtc.h
> @@ -168,6 +168,8 @@ struct node {
>  
>  	struct label *labels;
>  	const struct bus_type *bus;
> +
> +	int needs_reference, is_referenced;

I'd prefer to rename "needs_reference" to something closer matching
the actual tag.  It really is an exact correspondance, so matching the
names makes it easier to grep for.

Also, use 'bool' for these.

>  };
>  
>  #define for_each_label_withdel(l0, l) \
> @@ -202,6 +204,8 @@ struct property *reverse_properties(struct property *first);
>  struct node *build_node(struct property *proplist, struct node *children);
>  struct node *build_node_delete(void);
>  struct node *name_node(struct node *node, char *name);
> +struct node *mark_node_needs_reference(struct node *node);
> +struct node *reference_node(struct node *node);
>  struct node *chain_node(struct node *first, struct node *list);
>  struct node *merge_nodes(struct node *old_node, struct node *new_node);
>  struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
> diff --git a/flattree.c b/flattree.c
> index 8d268fb785db..39eb9934457b 100644
> --- a/flattree.c
> +++ b/flattree.c
> @@ -258,6 +258,9 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
>  	if (tree->deleted)
>  		return;
>  
> +	if (tree->needs_reference && !tree->is_referenced)
> +		return;
> +

So this only applies the change when using -Odtb or -Oasm, which might
violate least surprise.  In particular -Idts -Odts will leave the node
in, while stripping the /delete-if-unreferenced/ tag.  That means that
chaining -I dts -O dts then -I dts -O dtb won't result in the same
output as using -I dts -O dtb directly, which isn't really expected.

I think it would probably be preferable to do the stripping of
unreferenced nodes before running the output pass (you can probably
make it another "fixup" pass) would be preferable.

>  	emit->beginnode(etarget, tree->labels);
>  
>  	if (vi->flags & FTF_FULLPATH)
> diff --git a/livetree.c b/livetree.c
> index 57b7db2ed153..4b595c4b5e0a 100644
> --- a/livetree.c
> +++ b/livetree.c
> @@ -134,6 +134,20 @@ struct node *name_node(struct node *node, char *name)
>  	return node;
>  }
>  
> +struct node *mark_node_needs_reference(struct node *node)
> +{
> +	node->needs_reference = 1;
> +
> +	return node;
> +}
> +
> +struct node *reference_node(struct node *node)
> +{
> +	node->is_referenced = 1;
> +
> +	return node;
> +}
> +
>  struct node *merge_nodes(struct node *old_node, struct node *new_node)
>  {
>  	struct property *new_prop, *old_prop;

-- 
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