[Sound-open-firmware] cache invalidation evicting wrong lines
Liam Girdwood
liam.r.girdwood at linux.intel.com
Mon Mar 18 14:37:45 CET 2019
On Fri, 2019-03-15 at 17:56 +0100, Guennadi Liakhovetski wrote:
> > Could the list be corrupt ? I cant see where cacscade_list is invalidated ?
>
> list_for_item_smp does that:
>
> #define list_for_item_smp(item, list) \
> dcache_invalidate_region(list, sizeof(*(list))); \
> for (item = (list)->next, dcache_invalidate_region(item, \
> sizeof(*(item))); \
> item != list; \
> item = (item)->next, dcache_invalidate_region(item, \
> sizeof(*(item))))
>
> > > struct irq_cascade_desc *c = container_of(list,
> > > struct irq_cascade_desc,
> > > list);
> > >
> > > // One of these kills "cascade"
Another issue could possible be the compiler re-ordering some of these
statements above ? Try removing -O2.
Btw, are you writing back prior to releasing the lock on the data ?
> >
> > Is cascade killed on the first list iteration or a subsequent iteration. Is
> > this
> > iteration random or always consistent. Does this bug location change with
> > debug
> > code added ?
>
> It seemed to be consistent. First 4 "level2" - "level5" cascading controllers
> are
> added, all is good then. Then 2 INTC controllers are added - for the low and
> the
> high 32 bits respectively. When the first one of those is added and when the
> list
> of already installed controllers is checked, on a specific one of them the
> .irq
> gets invalidated.
Also see (cacheasm.h), called by dcache_invalidate(), this is taking care of
cache line alignment for address and size.
/*
* Macro to apply a 'hit' cache instruction to a memory region,
* ie. to any cache entries that cache a specified portion (region) of memory.
* Takes care of the unaligned cases, ie. may apply to one
* more cache line than $asize / lineSize if $aaddr is not aligned.
*
*
* Parameters are:
* cainst instruction/macro that takes an address register parameter
* and an offset parameter (currently always zero)
* and generates a cache instruction (eg. "dhi", "dhwb", "ihi", etc.)
* linesize_log2 log2(size of cache line in bytes)
* addr register containing start address of region (clobbered)
* asize register containing size of the region in bytes (clobbered)
* askew unique register used as temporary
* awb unique register used as temporary for erratum 497.
*
* Note: A possible optimization to this macro is to apply the operation
* to the entire cache if the region exceeds the size of the cache
* by some empirically determined amount or factor. Some experimentation
* is required to determine the appropriate factors, which also need
* to be tunable if required.
*/
.macro cache_hit_region cainst, linesize_log2, addr, asize, askew, awb=a0
// Make \asize the number of iterations:
extui \askew, \addr, 0, \linesize_log2 // get unalignment amount of \addr
add \asize, \asize, \askew // ... and add it to \asize
addi \asize, \asize, (1 << \linesize_log2) - 1 // round up!
srli \asize, \asize, \linesize_log2
// Iterate over region:
.ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // don't use awb if set to a0
movi \awb, 0
.endif
floopnez \asize, cacheh\@
\cainst \addr, 0
.ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // do memw after 8 cainst wb instructions
addi \awb, \awb, 1
blti \awb, 8, .Lstart_memw\@
memw
movi \awb, 0
.Lstart_memw\@:
.endif
addi \addr, \addr, (1 << \linesize_log2) // move to next line
floopend \asize, cacheh\@
.endm
Liam
More information about the Sound-open-firmware
mailing list