aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/page-flags.h38
-rw-r--r--mm/page-writeback.c4
2 files changed, 12 insertions, 30 deletions
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index a454176c3e30..209d3a47f50f 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -189,37 +189,15 @@ static inline void SetPageUptodate(struct page *page)
189#define __SetPagePrivate(page) __set_bit(PG_private, &(page)->flags) 189#define __SetPagePrivate(page) __set_bit(PG_private, &(page)->flags)
190#define __ClearPagePrivate(page) __clear_bit(PG_private, &(page)->flags) 190#define __ClearPagePrivate(page) __clear_bit(PG_private, &(page)->flags)
191 191
192/*
193 * Only test-and-set exist for PG_writeback. The unconditional operators are
194 * risky: they bypass page accounting.
195 */
192#define PageWriteback(page) test_bit(PG_writeback, &(page)->flags) 196#define PageWriteback(page) test_bit(PG_writeback, &(page)->flags)
193#define SetPageWriteback(page) \ 197#define TestSetPageWriteback(page) test_and_set_bit(PG_writeback, \
194 do { \ 198 &(page)->flags)
195 if (!test_and_set_bit(PG_writeback, \ 199#define TestClearPageWriteback(page) test_and_clear_bit(PG_writeback, \
196 &(page)->flags)) \ 200 &(page)->flags)
197 inc_zone_page_state(page, NR_WRITEBACK); \
198 } while (0)
199#define TestSetPageWriteback(page) \
200 ({ \
201 int ret; \
202 ret = test_and_set_bit(PG_writeback, \
203 &(page)->flags); \
204 if (!ret) \
205 inc_zone_page_state(page, NR_WRITEBACK); \
206 ret; \
207 })
208#define ClearPageWriteback(page) \
209 do { \
210 if (test_and_clear_bit(PG_writeback, \
211 &(page)->flags)) \
212 dec_zone_page_state(page, NR_WRITEBACK); \
213 } while (0)
214#define TestClearPageWriteback(page) \
215 ({ \
216 int ret; \
217 ret = test_and_clear_bit(PG_writeback, \
218 &(page)->flags); \
219 if (ret) \
220 dec_zone_page_state(page, NR_WRITEBACK); \
221 ret; \
222 })
223 201
224#define PageBuddy(page) test_bit(PG_buddy, &(page)->flags) 202#define PageBuddy(page) test_bit(PG_buddy, &(page)->flags)
225#define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags) 203#define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 51b3eb6ab445..63512a9ed57e 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -987,6 +987,8 @@ int test_clear_page_writeback(struct page *page)
987 } else { 987 } else {
988 ret = TestClearPageWriteback(page); 988 ret = TestClearPageWriteback(page);
989 } 989 }
990 if (ret)
991 dec_zone_page_state(page, NR_WRITEBACK);
990 return ret; 992 return ret;
991} 993}
992 994
@@ -1012,6 +1014,8 @@ int test_set_page_writeback(struct page *page)
1012 } else { 1014 } else {
1013 ret = TestSetPageWriteback(page); 1015 ret = TestSetPageWriteback(page);
1014 } 1016 }
1017 if (!ret)
1018 inc_zone_page_state(page, NR_WRITEBACK);
1015 return ret; 1019 return ret;
1016 1020
1017} 1021}