[U-Boot] [PATCH 2/3] net/designware: invalidate entire descriptor in dw_eth_send

Alexey Brodkin Alexey.Brodkin at synopsys.com
Thu Apr 24 19:41:18 CEST 2014


Dear Ian,

On Sat, 2014-04-19 at 14:52 +0100, Ian Campbell wrote:
> -	/* Invalidate only "status" field for the following check */
> -	invalidate_dcache_range((unsigned long)&desc_p->txrx_status,
> -				(unsigned long)&desc_p->txrx_status +
> -				sizeof(desc_p->txrx_status));
> +	/* Strictly we only need to invalidate the "status" field for
> +	 * the following check, but on some platforms we cannot
> +	 * invalidate only 4 bytes, so invalidate the the whole thing
> +	 * which is known to be DMA aligned. */
> +	invalidate_dcache_range((unsigned long)desc_p,
> +				(unsigned long)desc_p +
> +				sizeof(struct dmamacdescr));
>  
>  	/* Check if the descriptor is owned by CPU */
>  	if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {

Unfortunately I cannot recall exactly why I wanted to invalidate only
"status" field.

Now looking at this code I may assume that I wanted to save some CPU
cycles. Because:

1. We don't care about all other fields except "status". GMAC only
changes "status" field when it resets "OWNED_BY_DMA" flag and all other
fields CPU writes but not reads while sending packets.

2. We may save quite a few CPU cycles if only invalidating minimum
amount of bytes (remember each read from external memory may cost 100s
of cycles).

So I would advise:

1. Don't invalidate "sizeof(struct dmamacdescr)" but only
"roundup(sizeof(desc_p->txrx_status), ARCH_DMA_MINALIGN))".

2. In the following lines implements rounding as well:
============
	/* Flush data to be sent */
	flush_dcache_range((unsigned long)desc_p->dmamac_addr,
			   (unsigned long)desc_p->dmamac_addr + length);
============

We may be sure "desc_p->dmamac_addr" is properly aligned, but length
could be not-aligned. So I'd replace "length" with "roundup(length,
ARCH_DMA_MINALIGN)" as you did in 3rd patch.

3. Check carefully if there're other instances of probably unaligned
cache operations. I erroneously didn't care about alignment on cache
invalidation/flushing because my implementation of those cache
operations deals with non-aligned start/end internally within
invalidate/flush functions - which might be not that good even if it's
convenient for me.

4. Why don't you squeeze all 3 patches in 1 and name it like "fix
alignment issues with caches on some platforms"? Basically with all 3
patches you fix one and only issue and application of any one of those 3
patches doesn't solve your problem, right?

Regards,
Alexey




More information about the U-Boot mailing list