Subject: Re: [PATCH 08/10] powerpc/xive: take into account '/ibm,plat-res-int-priorities'

From: David Gibson <[email-masked]>
Date: Wed, 9 Aug 2017 14:02:27 +1000

On Tue, Aug 08, 2017 at 10:56:18AM +0200, Cédric Le Goater wrote:
> '/ibm,plat-res-int-priorities' contains a list of priorities that the
> hypervisor has reserved for its own use. Scan these ranges to choose
> the lowest unused priority for the xive spapr backend.
> 
> Signed-off-by: Cédric Le Goater <[email-masked]>
> ---
>  arch/powerpc/sysdev/xive/spapr.c | 62 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 61 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
> index 7fc40047c23d..220331986bd8 100644
> --- a/arch/powerpc/sysdev/xive/spapr.c
> +++ b/arch/powerpc/sysdev/xive/spapr.c
> @@ -532,13 +532,70 @@ static const struct xive_ops xive_spapr_ops = {
>  	.name			= "spapr",
>  };
>  
> +/*
> + * get max priority from "/ibm,plat-res-int-priorities"
> + */
> +static bool xive_get_max_prio(u8 *max_prio)
> +{
> +	struct device_node *rootdn;
> +	const __be32 *reg;
> +	u32 len;
> +	int prio, found;
> +
> +	rootdn = of_find_node_by_path("/");
> +	if (!rootdn) {
> +		pr_err("not root node found !\n");
> +		return false;
> +	}
> +
> +	reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len);
> +	if (!reg) {
> +		pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n");
> +		return false;
> +	}
> +
> +	if (len % (2 * sizeof(u32)) != 0) {
> +		pr_err("invalid 'ibm,plat-res-int-priorities' property\n");
> +		return false;
> +	}
> +
> +	/* HW supports priorities in the range [0-7] and 0xFF is a
> +	 * wildcard priority used to mask. We scan the ranges reserved
> +	 * by the hypervisor to find the lowest priority we can use.
> +	 */
> +	found = 0xFF;
> +	for (prio = 0; prio < 8; prio++) {
> +		int reserved = 0;
> +		int i;
> +
> +		for (i = 0; i < len / (2 * sizeof(u32)); i++) {
> +			int base  = be32_to_cpu(reg[2 * i]);
> +			int range = be32_to_cpu(reg[2 * i + 1]);
> +
> +			if (prio >= base && prio < base + range)
> +				reserved++;
> +		}
> +
> +		if (!reserved)
> +			found = prio;

So you continue the loop here, rather than using break.  Which means
found will be the highest valued priority that's not reserved.  Is
that what you intended?  The commit message says you find the lowest
unused, but do lower numbers mean higher priorities or the other way around?

> +	}
> +
> +	if (found == 0xFF) {
> +		pr_err("no valid priority found in 'ibm,plat-res-int-priorities'\n");
> +		return false;
> +	}
> +
> +	*max_prio = found;
> +	return true;
> +}
> +
>  bool xive_spapr_init(void)
>  {
>  	struct device_node *np;
>  	struct resource r;
>  	void __iomem *tima;
>  	struct property *prop;
> -	u8 max_prio = 7;
> +	u8 max_prio;
>  	u32 val;
>  	u32 len;
>  	const __be32 *reg;
> @@ -566,6 +623,9 @@ bool xive_spapr_init(void)
>  		return false;
>  	}
>  
> +	if (!xive_get_max_prio(&max_prio))
> +		return false;
> +
>  	/* Feed the IRQ number allocator with the ranges given in the DT */
>  	reg = of_get_property(np, "ibm,xive-lisn-ranges", &len);
>  	if (!reg) {

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