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

kernel/mempool: Handle transient failure condition #7934

Merged
merged 1 commit into from May 27, 2018

Conversation

andyross
Copy link
Contributor

@andyross andyross commented May 25, 2018

The sys_mem_pool implementation has a subtle error case where it
detected a simultaneous allocation after having released the lock, in
which case exactly one of the racing allocators will return with
-EAGAIN (the other one suceeds of course).

I documented this condition at the lower level, but forgot to actually
handle it at the k_mem_pool level where we want to retry once before
going to sleep, as it doesn't generally represent an empty heap. It
got caught by code auditing in:

Fixes #6757

(Full disclosure: I tested this by whiteboxing the first failure. I
wasn't able to put together a rig to reliably exercise the actual
race.)

This patch also fixes a noop thinko in the return logic in the same
function, which contained:

(ret == -EAGAIN) || (ret && ret != -ENOMEM)

The first term is needless and implied by the second.

Signed-off-by: Andy Ross andrew.j.ross@intel.com

The sys_mem_pool implementation has a subtle error case where it
detected a simultaneous allocation after having released the lock, in
which case exactly one of the racing allocators will return with
-EAGAIN (the other one suceeds of course).

I documented this condition at the lower level, but forgot to actually
handle it at the k_mem_pool level where we want to retry once before
going to sleep, as it doesn't generally represent an empty heap.  It
got caught by code auditing in:

zephyrproject-rtos#6757

(Full disclosure: I tested this by whiteboxing the first failure.  I
wasn't able to put together a rig to reliably exercise the actual
race.)

This patch also fixes a noop thinko in the return logic in the same
function, which contained:

   (ret == -EAGAIN) || (ret && ret != -ENOMEM)

The first term is needless and implied by the second.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
@andyross andyross requested a review from andrewboie as a code owner May 25, 2018 15:45
@codecov-io
Copy link

Codecov Report

Merging #7934 into master will decrease coverage by <.01%.
The diff coverage is 28.57%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #7934      +/-   ##
==========================================
- Coverage   55.03%   55.02%   -0.01%     
==========================================
  Files         483      483              
  Lines       53966    53971       +5     
  Branches    10490    10493       +3     
==========================================
+ Hits        29698    29699       +1     
- Misses      19992    19993       +1     
- Partials     4276     4279       +3
Impacted Files Coverage Δ
kernel/mempool.c 82.05% <28.57%> (-4.26%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a59f544...453b889. Read the comment docs.

if (ret == -EAGAIN) {
ret = -ENOMEM;
}

block->id.pool = pool_id(p);
block->id.level = level_num;
block->id.block = block_num;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you move these assignments before the previous if statement, a return -ENOMEM can be performed instead of setting ret -- should shave off a few bytes from the if statement below.

@nashif nashif added this to the v1.12.0 milestone May 26, 2018
@nashif nashif merged commit 75398d2 into zephyrproject-rtos:master May 27, 2018
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

Successfully merging this pull request may close these issues.

kernel:the API of k_mem_pool_alloc need try again to -EAGAIN[bug]
5 participants