diff options
author | Mel Gorman <mgorman@techsingularity.net> | 2016-07-28 18:47:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-28 19:07:41 -0400 |
commit | 785b99febb33db0e7779b6293ca34945a1269e21 (patch) | |
tree | fb617777dc1ab0e07063d2a0b0b6d61a6c64d845 /mm/vmscan.c | |
parent | 22fecdf5e1702a7724d7cd8697212307e25f571c (diff) |
mm, vmscan: release/reacquire lru_lock on pgdat change
With node-lru, the locking is based on the pgdat. As Minchan pointed
out, there is an opportunity to reduce LRU lock release/acquire in
check_move_unevictable_pages by only changing lock on a pgdat change.
[mgorman@techsingularity.net: remove double initialisation]
Link: http://lkml.kernel.org/r/20160719074835.GC10438@techsingularity.net
Link: http://lkml.kernel.org/r/1468853426-12858-3-git-send-email-mgorman@techsingularity.net
Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index 4978ee9b5892..22aec2bcfeec 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -3774,24 +3774,23 @@ int page_evictable(struct page *page) | |||
3774 | void check_move_unevictable_pages(struct page **pages, int nr_pages) | 3774 | void check_move_unevictable_pages(struct page **pages, int nr_pages) |
3775 | { | 3775 | { |
3776 | struct lruvec *lruvec; | 3776 | struct lruvec *lruvec; |
3777 | struct zone *zone = NULL; | 3777 | struct pglist_data *pgdat = NULL; |
3778 | int pgscanned = 0; | 3778 | int pgscanned = 0; |
3779 | int pgrescued = 0; | 3779 | int pgrescued = 0; |
3780 | int i; | 3780 | int i; |
3781 | 3781 | ||
3782 | for (i = 0; i < nr_pages; i++) { | 3782 | for (i = 0; i < nr_pages; i++) { |
3783 | struct page *page = pages[i]; | 3783 | struct page *page = pages[i]; |
3784 | struct zone *pagezone; | 3784 | struct pglist_data *pagepgdat = page_pgdat(page); |
3785 | 3785 | ||
3786 | pgscanned++; | 3786 | pgscanned++; |
3787 | pagezone = page_zone(page); | 3787 | if (pagepgdat != pgdat) { |
3788 | if (pagezone != zone) { | 3788 | if (pgdat) |
3789 | if (zone) | 3789 | spin_unlock_irq(&pgdat->lru_lock); |
3790 | spin_unlock_irq(zone_lru_lock(zone)); | 3790 | pgdat = pagepgdat; |
3791 | zone = pagezone; | 3791 | spin_lock_irq(&pgdat->lru_lock); |
3792 | spin_lock_irq(zone_lru_lock(zone)); | ||
3793 | } | 3792 | } |
3794 | lruvec = mem_cgroup_page_lruvec(page, zone->zone_pgdat); | 3793 | lruvec = mem_cgroup_page_lruvec(page, pgdat); |
3795 | 3794 | ||
3796 | if (!PageLRU(page) || !PageUnevictable(page)) | 3795 | if (!PageLRU(page) || !PageUnevictable(page)) |
3797 | continue; | 3796 | continue; |
@@ -3807,10 +3806,10 @@ void check_move_unevictable_pages(struct page **pages, int nr_pages) | |||
3807 | } | 3806 | } |
3808 | } | 3807 | } |
3809 | 3808 | ||
3810 | if (zone) { | 3809 | if (pgdat) { |
3811 | __count_vm_events(UNEVICTABLE_PGRESCUED, pgrescued); | 3810 | __count_vm_events(UNEVICTABLE_PGRESCUED, pgrescued); |
3812 | __count_vm_events(UNEVICTABLE_PGSCANNED, pgscanned); | 3811 | __count_vm_events(UNEVICTABLE_PGSCANNED, pgscanned); |
3813 | spin_unlock_irq(zone_lru_lock(zone)); | 3812 | spin_unlock_irq(&pgdat->lru_lock); |
3814 | } | 3813 | } |
3815 | } | 3814 | } |
3816 | #endif /* CONFIG_SHMEM */ | 3815 | #endif /* CONFIG_SHMEM */ |