Skip to content

Commit

Permalink
percpu: fix iteration to prevent skipping over block
Browse files Browse the repository at this point in the history
The iterator functions pcpu_next_md_free_region and
pcpu_next_fit_region use the block offset to determine if they have
checked the area in the prior iteration. However, this causes an issue
when the block offset is greater than subsequent block contig hints. If
within the iterator it moves to check subsequent blocks, it may fail in
the second predicate due to the block offset not being cleared. Thus,
this causes the allocator to skip over blocks leading to false failures
when allocating from the reserved chunk. While this happens in the
general case as well, it will only fail if it cannot allocate a new
chunk.

This patch resets the block offset to 0 to pass the second predicate
when checking subseqent blocks within the iterator function.

Signed-off-by: Dennis Zhou <[email protected]>
Reported-and-tested-by: Luis Henriques <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
  • Loading branch information
dennisszhou authored and htejun committed Sep 28, 2017
1 parent 2e08d20 commit 1fa4df3
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions mm/percpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ static void pcpu_next_md_free_region(struct pcpu_chunk *chunk, int *bit_off,
block->contig_hint_start);
return;
}
/* reset to satisfy the second predicate above */
block_off = 0;

*bits = block->right_free;
*bit_off = (i + 1) * PCPU_BITMAP_BLOCK_BITS - block->right_free;
Expand Down Expand Up @@ -407,6 +409,8 @@ static void pcpu_next_fit_region(struct pcpu_chunk *chunk, int alloc_bits,
*bit_off = pcpu_block_off_to_off(i, block->first_free);
return;
}
/* reset to satisfy the second predicate above */
block_off = 0;

*bit_off = ALIGN(PCPU_BITMAP_BLOCK_BITS - block->right_free,
align);
Expand Down

0 comments on commit 1fa4df3

Please sign in to comment.