Commit 451ea25da71590361c71bf3044c55b870a887d53
Committed by
Linus Torvalds
1 parent
bf88c8c83e
Exists in
master
and in
39 other branches
mm: perform non-atomic test-clear of PG_mlocked on free
By the time PG_mlocked is cleared in the page freeing path, nobody else is looking at our page->flags anymore. It is thus safe to make the test-and-clear non-atomic and thereby removing an unnecessary and expensive operation from a hotpath. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Christoph Lameter <cl@linux-foundation.org> Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 11 additions and 5 deletions Side-by-side Diff
include/linux/page-flags.h
... | ... | @@ -158,6 +158,9 @@ |
158 | 158 | static inline int TestClearPage##uname(struct page *page) \ |
159 | 159 | { return test_and_clear_bit(PG_##lname, &page->flags); } |
160 | 160 | |
161 | +#define __TESTCLEARFLAG(uname, lname) \ | |
162 | +static inline int __TestClearPage##uname(struct page *page) \ | |
163 | + { return __test_and_clear_bit(PG_##lname, &page->flags); } | |
161 | 164 | |
162 | 165 | #define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \ |
163 | 166 | SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname) |
... | ... | @@ -184,6 +187,9 @@ |
184 | 187 | #define TESTCLEARFLAG_FALSE(uname) \ |
185 | 188 | static inline int TestClearPage##uname(struct page *page) { return 0; } |
186 | 189 | |
190 | +#define __TESTCLEARFLAG_FALSE(uname) \ | |
191 | +static inline int __TestClearPage##uname(struct page *page) { return 0; } | |
192 | + | |
187 | 193 | struct page; /* forward declaration */ |
188 | 194 | |
189 | 195 | TESTPAGEFLAG(Locked, locked) TESTSETFLAG(Locked, locked) |
190 | 196 | |
... | ... | @@ -250,11 +256,11 @@ |
250 | 256 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT |
251 | 257 | #define MLOCK_PAGES 1 |
252 | 258 | PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked) |
253 | - TESTSCFLAG(Mlocked, mlocked) | |
259 | + TESTSCFLAG(Mlocked, mlocked) __TESTCLEARFLAG(Mlocked, mlocked) | |
254 | 260 | #else |
255 | 261 | #define MLOCK_PAGES 0 |
256 | -PAGEFLAG_FALSE(Mlocked) | |
257 | - SETPAGEFLAG_NOOP(Mlocked) TESTCLEARFLAG_FALSE(Mlocked) | |
262 | +PAGEFLAG_FALSE(Mlocked) SETPAGEFLAG_NOOP(Mlocked) | |
263 | + TESTCLEARFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked) | |
258 | 264 | #endif |
259 | 265 | |
260 | 266 | #ifdef CONFIG_ARCH_USES_PG_UNCACHED |
mm/page_alloc.c
... | ... | @@ -557,7 +557,7 @@ |
557 | 557 | unsigned long flags; |
558 | 558 | int i; |
559 | 559 | int bad = 0; |
560 | - int wasMlocked = TestClearPageMlocked(page); | |
560 | + int wasMlocked = __TestClearPageMlocked(page); | |
561 | 561 | |
562 | 562 | kmemcheck_free_shadow(page, order); |
563 | 563 | |
... | ... | @@ -1026,7 +1026,7 @@ |
1026 | 1026 | struct zone *zone = page_zone(page); |
1027 | 1027 | struct per_cpu_pages *pcp; |
1028 | 1028 | unsigned long flags; |
1029 | - int wasMlocked = TestClearPageMlocked(page); | |
1029 | + int wasMlocked = __TestClearPageMlocked(page); | |
1030 | 1030 | |
1031 | 1031 | kmemcheck_free_shadow(page, 0); |
1032 | 1032 |