[PATCHv2 2/3] ARM: mvebu: disable I/O coherency on non-SMP situations on Armada 370/XP

Jason Cooper jason at lakedaemon.net
Thu Nov 6 18:53:03 PST 2014


On Mon, Oct 27, 2014 at 04:32:34PM +0100, Thomas Petazzoni wrote:
> Enabling the hardware I/O coherency on Armada 370 and Armada XP
> requires a certain number of conditions:
> 
>  - On Armada 370, the cache policy must be set to write-allocate.
>  - On Armada XP, the cache policy must be set to write-allocate, the
>    pages must be mapped with the shareable attribute, and the SMP bit
>    must be set
> 
> Currently, on Armada XP, when CONFIG_SMP is enabled, those conditions
> are met. However, when Armada XP is used in a !CONFIG_SMP kernel, none
> of these conditions are met. With Armada 370, the situation is worse:
> since the processor is single core, regardless of whether CONFIG_SMP
> or !CONFIG_SMP is used, the cache policy will be set to write-back by
> the kernel and not write-allocate.
> 
> Since solving this problem turns out to be quite complicated, and we
> don't want to let users with a mainline kernel known to have
> infrequent but existing data corruptions, this commit proposes to
> simply disable hardware I/O coherency in situations where it is known
> not to work.
> 
> And basically, the is_smp() function of the kernel tells us whether it
> is OK to enable hardware I/O coherency or not, so this commit slightly
> refactors the coherency_type() function to return
> COHERENCY_FABRIC_TYPE_NONE when is_smp() is false, or the appropriate
> type of the coherency fabric in the other case.
> 
> Thanks to this, the I/O coherency fabric will no longer be used at all
> in !CONFIG_SMP configurations. It will continue to be used in
> CONFIG_SMP configurations on Armada XP, Armada 375 and Armada 38x
> (which are multiple cores processors), but will no longer be used on
> Armada 370 (which is a single core processor).
> 
> In the process, it simplifies the implementation of the
> coherency_type() function, and adds a missing call to of_node_put().
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
> Fixes: e60304f8cb7bb545e79fe62d9b9762460c254ec2 ("arm: mvebu: Add hardware I/O Coherency support")
> Cc: <stable at vger.kernel.org> # v3.8+
> ---
>  arch/arm/mach-mvebu/coherency.c | 37 +++++++++++++++++++++++--------------
>  1 file changed, 23 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
> index 2bdc323..abf4535 100644
> --- a/arch/arm/mach-mvebu/coherency.c
> +++ b/arch/arm/mach-mvebu/coherency.c
> @@ -361,25 +361,34 @@ static int coherency_type(void)
>  {
>  	struct device_node *np;
>  	const struct of_device_id *match;
> +	int type;
>  
> -	np = of_find_matching_node_and_match(NULL, of_coherency_table, &match);
> -	if (np) {
> -		int type = (int) match->data;
> +	/*
> +	 * The coherency fabric is needed:
> +	 * - For coherency between processors on Armada XP, so only
> +	 *   when SMP is enabled.
> +	 * - For coherency between the processor and I/O devices, but
> +	 *   this coherency requires many pre-requisites (write
> +	 *   allocate cache policy, shareable pages, SMP bit set) that
> +	 *   are only meant in SMP situations.
> +	 *
> +	 * Note that this means that on Armada 370, there is currently
> +	 * no way to use hardware I/O coherency, because even when
> +	 * CONFIG_SMP is enabled, is_smp() returns false due to the
> +	 * Armada 370 being a single-core processor.

Could we extend this a bit to let future readers know what needs to
change to re-enable support on the 370?

thx,

Jason.

> +	 */
> +	if (!is_smp())
> +		return COHERENCY_FABRIC_TYPE_NONE;
>  
> -		/* Armada 370/XP coherency works in both UP and SMP */
> -		if (type == COHERENCY_FABRIC_TYPE_ARMADA_370_XP)
> -			return type;
> +	np = of_find_matching_node_and_match(NULL, of_coherency_table, &match);
> +	if (!np)
> +		return COHERENCY_FABRIC_TYPE_NONE;
>  
> -		/* Armada 375 coherency works only on SMP */
> -		else if (type == COHERENCY_FABRIC_TYPE_ARMADA_375 && is_smp())
> -			return type;
> +	type = (int) match->data;
>  
> -		/* Armada 380 coherency works only on SMP */
> -		else if (type == COHERENCY_FABRIC_TYPE_ARMADA_380 && is_smp())
> -			return type;
> -	}
> +	of_node_put(np);
>  
> -	return COHERENCY_FABRIC_TYPE_NONE;
> +	return type;
>  }
>  
>  int coherency_available(void)
> -- 
> 2.0.0
> 



More information about the linux-arm-kernel mailing list