Commit d93d5ab9 authored by Wei Yang's avatar Wei Yang Committed by Linus Torvalds

mm/page_alloc.c: simplify pageblock bitmap access

Due to commit e58469ba ("mm: page_alloc: use word-based accesses for
get/set pageblock bitmaps"), pageblock bitmap is accessed with word-based
access.  This operation could be simplified a little.

Intuitively, if we want to get a bit range [start_idx, end_idx] in a word,
we can do like this:

    mask = (1 << (end_bitidx - start_bitidx + 1)) - 1;
    ret = (word >> start_idx) & mask;

And also if we want to set a bit range [start_idx, end_idx] with flags, we
can do the same by just shift start_bitidx.

By doing so we reduce some instructions for these two helper functions:

                                Before   Patched
    set_pfnblock_flags_mask     209      198(-5%)
    get_pfnblock_flags_mask     101      87(-13%)

Since the syntax is changed a little, we need to check the whole 4-bit
migrate_type instead of part of it.
Signed-off-by: default avatarWei Yang <richard.weiyang@linux.alibaba.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Cc: Mel Gorman <mgorman@suse.de>
Link: http://lkml.kernel.org/r/20200623124201.8199-3-richard.weiyang@linux.alibaba.comSigned-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 399b795b
...@@ -66,25 +66,17 @@ void set_pfnblock_flags_mask(struct page *page, ...@@ -66,25 +66,17 @@ void set_pfnblock_flags_mask(struct page *page,
unsigned long mask); unsigned long mask);
/* Declarations for getting and setting flags. See mm/page_alloc.c */ /* Declarations for getting and setting flags. See mm/page_alloc.c */
#define get_pageblock_flags_group(page, start_bitidx, end_bitidx) \
get_pfnblock_flags_mask(page, page_to_pfn(page), \
end_bitidx, \
(1 << (end_bitidx - start_bitidx + 1)) - 1)
#define set_pageblock_flags_group(page, flags, start_bitidx, end_bitidx) \
set_pfnblock_flags_mask(page, flags, page_to_pfn(page), \
end_bitidx, \
(1 << (end_bitidx - start_bitidx + 1)) - 1)
#ifdef CONFIG_COMPACTION #ifdef CONFIG_COMPACTION
#define get_pageblock_skip(page) \ #define get_pageblock_skip(page) \
get_pageblock_flags_group(page, PB_migrate_skip, \ get_pfnblock_flags_mask(page, page_to_pfn(page), \
PB_migrate_skip) PB_migrate_skip, (1 << (PB_migrate_skip)))
#define clear_pageblock_skip(page) \ #define clear_pageblock_skip(page) \
set_pageblock_flags_group(page, 0, PB_migrate_skip, \ set_pfnblock_flags_mask(page, 0, page_to_pfn(page), \
PB_migrate_skip) PB_migrate_skip, (1 << PB_migrate_skip))
#define set_pageblock_skip(page) \ #define set_pageblock_skip(page) \
set_pageblock_flags_group(page, 1, PB_migrate_skip, \ set_pfnblock_flags_mask(page, (1 << PB_migrate_skip), \
PB_migrate_skip) page_to_pfn(page), \
PB_migrate_skip, (1 << PB_migrate_skip))
#else #else
static inline bool get_pageblock_skip(struct page *page) static inline bool get_pageblock_skip(struct page *page)
{ {
......
...@@ -489,8 +489,7 @@ static __always_inline unsigned long __get_pfnblock_flags_mask(struct page *page ...@@ -489,8 +489,7 @@ static __always_inline unsigned long __get_pfnblock_flags_mask(struct page *page
bitidx &= (BITS_PER_LONG-1); bitidx &= (BITS_PER_LONG-1);
word = bitmap[word_bitidx]; word = bitmap[word_bitidx];
bitidx += end_bitidx; return (word >> bitidx) & mask;
return (word >> (BITS_PER_LONG - bitidx - 1)) & mask;
} }
unsigned long get_pfnblock_flags_mask(struct page *page, unsigned long pfn, unsigned long get_pfnblock_flags_mask(struct page *page, unsigned long pfn,
...@@ -532,9 +531,8 @@ void set_pfnblock_flags_mask(struct page *page, unsigned long flags, ...@@ -532,9 +531,8 @@ void set_pfnblock_flags_mask(struct page *page, unsigned long flags,
VM_BUG_ON_PAGE(!zone_spans_pfn(page_zone(page), pfn), page); VM_BUG_ON_PAGE(!zone_spans_pfn(page_zone(page), pfn), page);
bitidx += end_bitidx; mask <<= bitidx;
mask <<= (BITS_PER_LONG - bitidx - 1); flags <<= bitidx;
flags <<= (BITS_PER_LONG - bitidx - 1);
word = READ_ONCE(bitmap[word_bitidx]); word = READ_ONCE(bitmap[word_bitidx]);
for (;;) { for (;;) {
...@@ -551,8 +549,9 @@ void set_pageblock_migratetype(struct page *page, int migratetype) ...@@ -551,8 +549,9 @@ void set_pageblock_migratetype(struct page *page, int migratetype)
migratetype < MIGRATE_PCPTYPES)) migratetype < MIGRATE_PCPTYPES))
migratetype = MIGRATE_UNMOVABLE; migratetype = MIGRATE_UNMOVABLE;
set_pageblock_flags_group(page, (unsigned long)migratetype, set_pfnblock_flags_mask(page, (unsigned long)migratetype,
PB_migrate, PB_migrate_end); page_to_pfn(page), PB_migrate_end,
MIGRATETYPE_MASK);
} }
#ifdef CONFIG_DEBUG_VM #ifdef CONFIG_DEBUG_VM
......
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