aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDennis Zhou (Facebook) <dennisszhou@gmail.com>2017-07-24 19:02:15 -0400
committerTejun Heo <tj@kernel.org>2017-07-26 17:41:05 -0400
commit268625a6f9df6a7c9b0ae7707a8a1cd5a9993bd2 (patch)
tree4f178b5e62a183be1c23a5d058c6eecedbfd67d5
parent13f966373f9296c0da2fb2764654cce520b3a6b4 (diff)
percpu: keep track of the best offset for contig hints
This patch makes the contig hint starting offset optimization from the previous patch as honest as it can be. For both chunk and block starting offsets, make sure it keeps the starting offset with the best alignment. The block skip optimization is added in a later patch when the pcpu_find_block_fit iterator is swapped in. Signed-off-by: Dennis Zhou <dennisszhou@gmail.com> Reviewed-by: Josef Bacik <jbacik@fb.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--mm/percpu.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/mm/percpu.c b/mm/percpu.c
index 734745a0c9b6..d0d3fa872a8c 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -401,12 +401,18 @@ static inline int pcpu_cnt_pop_pages(struct pcpu_chunk *chunk, int bit_off,
401 * @bits: size of free area 401 * @bits: size of free area
402 * 402 *
403 * This updates the chunk's contig hint and starting offset given a free area. 403 * This updates the chunk's contig hint and starting offset given a free area.
404 * Choose the best starting offset if the contig hint is equal.
404 */ 405 */
405static void pcpu_chunk_update(struct pcpu_chunk *chunk, int bit_off, int bits) 406static void pcpu_chunk_update(struct pcpu_chunk *chunk, int bit_off, int bits)
406{ 407{
407 if (bits > chunk->contig_bits) { 408 if (bits > chunk->contig_bits) {
408 chunk->contig_bits_start = bit_off; 409 chunk->contig_bits_start = bit_off;
409 chunk->contig_bits = bits; 410 chunk->contig_bits = bits;
411 } else if (bits == chunk->contig_bits && chunk->contig_bits_start &&
412 (!bit_off ||
413 __ffs(bit_off) > __ffs(chunk->contig_bits_start))) {
414 /* use the start with the best alignment */
415 chunk->contig_bits_start = bit_off;
410 } 416 }
411} 417}
412 418
@@ -461,7 +467,8 @@ static void pcpu_chunk_refresh_hint(struct pcpu_chunk *chunk)
461 * @end: end offset in block 467 * @end: end offset in block
462 * 468 *
463 * Updates a block given a known free area. The region [start, end) is 469 * Updates a block given a known free area. The region [start, end) is
464 * expected to be the entirety of the free area within a block. 470 * expected to be the entirety of the free area within a block. Chooses
471 * the best starting offset if the contig hints are equal.
465 */ 472 */
466static void pcpu_block_update(struct pcpu_block_md *block, int start, int end) 473static void pcpu_block_update(struct pcpu_block_md *block, int start, int end)
467{ 474{
@@ -477,6 +484,10 @@ static void pcpu_block_update(struct pcpu_block_md *block, int start, int end)
477 if (contig > block->contig_hint) { 484 if (contig > block->contig_hint) {
478 block->contig_hint_start = start; 485 block->contig_hint_start = start;
479 block->contig_hint = contig; 486 block->contig_hint = contig;
487 } else if (block->contig_hint_start && contig == block->contig_hint &&
488 (!start || __ffs(start) > __ffs(block->contig_hint_start))) {
489 /* use the start with the best alignment */
490 block->contig_hint_start = start;
480 } 491 }
481} 492}
482 493