Commit 451ea25da71590361c71bf3044c55b870a887d53

Authored by Johannes Weiner
Committed by Linus Torvalds
1 parent bf88c8c83e

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
... ... @@ -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