Skip to content
Permalink
Browse files

kernel: pipes: fix k_pipe_block_put() when not enough space

If k_pipe_block_put() is called and the pipe does not have enough
space to accomodate all the data in the memory pool, the subsequent
get operation will cause a CPU fault. The CPU fault is caused by
the timeout struct in the dummy thread not being initialized and
thus the scheduler will read bad memory. After fixing this,
another issue came up where the get operation would stall with
k_pipe_block_put() in same situation. This is due to the async
descriptor not being setup correctly. So fix this too.

This was discovered when debugging #9273.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
  • Loading branch information...
dcpleung authored and nashif committed Aug 19, 2018
1 parent 5919851 commit 1c6d202ee841d3f28756e790bff45910f83c614a
Showing with 8 additions and 0 deletions.
  1. +8 −0 kernel/pipes.c
@@ -107,6 +107,9 @@ static int init_pipes_module(struct device *dev)
for (int i = 0; i < CONFIG_NUM_PIPE_ASYNC_MSGS; i++) {
async_msg[i].thread.thread_state = _THREAD_DUMMY;
async_msg[i].thread.swap_data = &async_msg[i].desc;

_init_thread_timeout(&async_msg[i].thread);

k_stack_push(&pipe_async_msgs, (u32_t)&async_msg[i]);
}
#endif /* CONFIG_NUM_PIPE_ASYNC_MSGS > 0 */
@@ -537,6 +540,11 @@ int _k_pipe_put_internal(struct k_pipe *pipe, struct k_pipe_async *async_desc,
*/
key = irq_lock();
_sched_unlock_no_reschedule();

async_desc->desc.buffer = data + num_bytes_written;
async_desc->desc.bytes_to_xfer =
bytes_to_write - num_bytes_written;

_pend_thread((struct k_thread *) &async_desc->thread,
&pipe->wait_q.writers, K_FOREVER);
_reschedule(key);

0 comments on commit 1c6d202

Please sign in to comment.
You can’t perform that action at this time.