Skip to content

Commit

Permalink
kernel: pipes: fix k_pipe_block_put() when not enough space
Browse files Browse the repository at this point in the history
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 29, 2018
1 parent 5919851 commit 1c6d202
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions kernel/pipes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 1c6d202

Please sign in to comment.