Actually, I'm a bit worried about this code now. I see that block->state is modified and read in multiple threads without enough memory barriers or synchronisation. I see some scattered calls to smp_rmb() and smp_wmb(), but am rusty as to their correct use.
Writes
assign_buffer() set state to BLOCK_DMA, called from ISR. This has no barrier.
receive_isr_block() sets state to BLOCK_DATA or BLOCK_DATA_END, also called from ISR. This is preceded by smp_wmb().
allocate_blocks() initialises state to BLOCK_FREE. Not too worried about this one.
start_hardware() similarly.
advance_block() sets state to BLOCK_FREE, preceded by smp_wmb(), called from user process.
Reads
advance_isr_block() checks block is BLOCK_FREE. Called from ISR, no barrier.
wait_for_block() waits until block is not BLOCK_DMA. I suspect there are the appropriate memory barriers in the implementation of wait_event_interruptible_timeout() which wraps this test. This is called from the user process.
panda_stream_read() checks for blocks not BLOCK_DMA. No memory barriers, also called from user process.
Originally posted by @Araneidae in #16 (comment)
Actually, I'm a bit worried about this code now. I see that
block->stateis modified and read in multiple threads without enough memory barriers or synchronisation. I see some scattered calls tosmp_rmb()andsmp_wmb(), but am rusty as to their correct use.Writes
assign_buffer()setstatetoBLOCK_DMA, called from ISR. This has no barrier.receive_isr_block()sets state toBLOCK_DATAorBLOCK_DATA_END, also called from ISR. This is preceded bysmp_wmb().allocate_blocks()initialises state toBLOCK_FREE. Not too worried about this one.start_hardware()similarly.advance_block()sets state toBLOCK_FREE, preceded bysmp_wmb(), called from user process.Reads
advance_isr_block()checks block isBLOCK_FREE. Called from ISR, no barrier.wait_for_block()waits until block is notBLOCK_DMA. I suspect there are the appropriate memory barriers in the implementation ofwait_event_interruptible_timeout()which wraps this test. This is called from the user process.panda_stream_read()checks for blocks notBLOCK_DMA. No memory barriers, also called from user process.Originally posted by @Araneidae in #16 (comment)