Commit 1b096e5a authored by Vitaly Wool's avatar Vitaly Wool Committed by Linus Torvalds

z3fold: extend compaction function

z3fold_compact_page() currently only handles the situation when there's
a single middle chunk within the z3fold page.  However it may be worth
it to move middle chunk closer to either first or last chunk, whichever
is there, if the gap between them is big enough.

This patch adds the relevant code, using BIG_CHUNK_GAP define as a
threshold for middle chunk to be worth moving.

Link: http://lkml.kernel.org/r/20170131214334.c4f3eac9a477af0fa9a22c46@gmail.comSigned-off-by: default avatarVitaly Wool <vitalywool@gmail.com>
Reviewed-by: default avatarDan Streetman <ddstreet@ieee.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ede93213
...@@ -268,6 +268,7 @@ static inline void *mchunk_memmove(struct z3fold_header *zhdr, ...@@ -268,6 +268,7 @@ static inline void *mchunk_memmove(struct z3fold_header *zhdr,
zhdr->middle_chunks << CHUNK_SHIFT); zhdr->middle_chunks << CHUNK_SHIFT);
} }
#define BIG_CHUNK_GAP 3
/* Has to be called with lock held */ /* Has to be called with lock held */
static int z3fold_compact_page(struct z3fold_header *zhdr) static int z3fold_compact_page(struct z3fold_header *zhdr)
{ {
...@@ -286,8 +287,31 @@ static int z3fold_compact_page(struct z3fold_header *zhdr) ...@@ -286,8 +287,31 @@ static int z3fold_compact_page(struct z3fold_header *zhdr)
zhdr->middle_chunks = 0; zhdr->middle_chunks = 0;
zhdr->start_middle = 0; zhdr->start_middle = 0;
zhdr->first_num++; zhdr->first_num++;
return 1;
} }
return 1;
/*
* moving data is expensive, so let's only do that if
* there's substantial gain (at least BIG_CHUNK_GAP chunks)
*/
if (zhdr->first_chunks != 0 && zhdr->last_chunks == 0 &&
zhdr->start_middle - (zhdr->first_chunks + ZHDR_CHUNKS) >=
BIG_CHUNK_GAP) {
mchunk_memmove(zhdr, zhdr->first_chunks + ZHDR_CHUNKS);
zhdr->start_middle = zhdr->first_chunks + ZHDR_CHUNKS;
return 1;
} else if (zhdr->last_chunks != 0 && zhdr->first_chunks == 0 &&
TOTAL_CHUNKS - (zhdr->last_chunks + zhdr->start_middle
+ zhdr->middle_chunks) >=
BIG_CHUNK_GAP) {
unsigned short new_start = TOTAL_CHUNKS - zhdr->last_chunks -
zhdr->middle_chunks;
mchunk_memmove(zhdr, new_start);
zhdr->start_middle = new_start;
return 1;
}
return 0;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment