Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incomplete use of memory barriers in driver code #20

Open
Araneidae opened this issue Sep 21, 2021 · 3 comments
Open

Incomplete use of memory barriers in driver code #20

Araneidae opened this issue Sep 21, 2021 · 3 comments
Assignees

Comments

@Araneidae
Copy link
Contributor

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)

@Araneidae
Copy link
Contributor Author

Unfortunately my understanding of how to use memory barriers properly is a bit wobbly. I think it would be good to write out our understanding of the rules here and make sure this code is doing things properly. In particular, any communication between ISR and user-space code must be properly guarded.

Even if this isn't biting us now, I'd expect this to potentially give us trouble with Zynq+ on ARMv8.

@thomascobb
Copy link

@Araneidae to discuss this with @lyodaom

@Araneidae
Copy link
Contributor Author

Relevant documentation:

It looks as if we should be guarding our reads and writes with READ_ONCE() and WRITE_ONCE() as well as the appropriate barriers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants