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

RE: Kernel oops using DMA on MCM



Great, good work!

>What has happened was probably not the cache-bug though, because according
>to its doco it was only supposed to happen for DMA receive channels, not
>transmit. Any thoughts?

No, not really. I have to check your code in detail. After a quick peak
it seams dangerous to have IN_BUFFER_SIZE = OUT_BUFFER_SIZE = 240
because 240 = 7.5 cacheline. Does your sync_port look like this:

char out_buffer[OUT_BUFFER_SIZE];
volatile char* outreadp;  /* Next byte to be read by dma (updated at interrupt time) */
volatile char* outwritep; /* Next byte to be written by tasklet */
char in_buffer[IN_BUFFER_SIZE] __attribute__ ((aligned (32)));
volatile char* inreadp;  /* Next byte to be read by tasklet */
volatile char* inwritep; /* Next byte to be written by dma (updated at interript handler) */

you have to make sure that inreadp etc does not share cache line 
with in_buffer. This can be done by making sure that either:

1. IN_BUFFER_SIZE is a multiple of 32
2. A pad is added after in_buffer that is never used
3. inreadp is also cache line aligned 

e.g.

char in_buffer[IN_BUFFER_SIZE] __attribute__ ((aligned (32)));
char pad[32 - (IN_BUFFER_SIZE % 32)];

or 

char in_buffer[IN_BUFFER_SIZE] __attribute__ ((aligned (32)));
int dummy __attribute__ ((aligned (32))); 

PS. The CRIS compiler never pads struct. DS

/Mikael