diff options
author | David Rientjes <rientjes@google.com> | 2007-10-17 02:26:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-17 11:42:46 -0400 |
commit | d773ed6b856a96bd6d18b6e04455e3ced0876da4 (patch) | |
tree | f0235be6843ec323aeedcdadbee34a777b6c2690 /include/linux/mmzone.h | |
parent | ae74138da609c576b221c765efa8b81b2365f465 (diff) |
mm: test and set zone reclaim lock before starting reclaim
Introduces new zone flag interface for testing and setting flags:
int zone_test_and_set_flag(struct zone *zone, zone_flags_t flag)
Instead of setting and clearing ZONE_RECLAIM_LOCKED each time shrink_zone() is
called, this flag is test and set before starting zone reclaim. Zone reclaim
starts in __alloc_pages() when a zone's watermark fails and the system is in
zone_reclaim_mode. If it's already in reclaim, there's no need to start again
so it is simply considered full for that allocation attempt.
There is a change of behavior with regard to concurrent zone shrinking. It is
now possible for try_to_free_pages() or kswapd to already be shrinking a
particular zone when __alloc_pages() starts zone reclaim. In this case, it is
possible for two concurrent threads to invoke shrink_zone() for a single zone.
This change forbids a zone to be in zone reclaim twice, which was always the
behavior, but allows for concurrent try_to_free_pages() or kswapd shrinking
when starting zone reclaim.
Cc: Andrea Arcangeli <andrea@suse.de>
Cc: Christoph Lameter <clameter@sgi.com>
Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/mmzone.h')
-rw-r--r-- | include/linux/mmzone.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 9011505e740d..4c4522a51a3b 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -351,6 +351,12 @@ static inline void zone_set_flag(struct zone *zone, zone_flags_t flag) | |||
351 | { | 351 | { |
352 | set_bit(flag, &zone->flags); | 352 | set_bit(flag, &zone->flags); |
353 | } | 353 | } |
354 | |||
355 | static inline int zone_test_and_set_flag(struct zone *zone, zone_flags_t flag) | ||
356 | { | ||
357 | return test_and_set_bit(flag, &zone->flags); | ||
358 | } | ||
359 | |||
354 | static inline void zone_clear_flag(struct zone *zone, zone_flags_t flag) | 360 | static inline void zone_clear_flag(struct zone *zone, zone_flags_t flag) |
355 | { | 361 | { |
356 | clear_bit(flag, &zone->flags); | 362 | clear_bit(flag, &zone->flags); |
@@ -360,10 +366,12 @@ static inline int zone_is_all_unreclaimable(const struct zone *zone) | |||
360 | { | 366 | { |
361 | return test_bit(ZONE_ALL_UNRECLAIMABLE, &zone->flags); | 367 | return test_bit(ZONE_ALL_UNRECLAIMABLE, &zone->flags); |
362 | } | 368 | } |
369 | |||
363 | static inline int zone_is_reclaim_locked(const struct zone *zone) | 370 | static inline int zone_is_reclaim_locked(const struct zone *zone) |
364 | { | 371 | { |
365 | return test_bit(ZONE_RECLAIM_LOCKED, &zone->flags); | 372 | return test_bit(ZONE_RECLAIM_LOCKED, &zone->flags); |
366 | } | 373 | } |
374 | |||
367 | static inline int zone_is_oom_locked(const struct zone *zone) | 375 | static inline int zone_is_oom_locked(const struct zone *zone) |
368 | { | 376 | { |
369 | return test_bit(ZONE_OOM_LOCKED, &zone->flags); | 377 | return test_bit(ZONE_OOM_LOCKED, &zone->flags); |