diff options
author | KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> | 2009-09-21 20:01:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-22 10:17:28 -0400 |
commit | b35ea17b7bbf5dea35faa0de11030acc620c3197 (patch) | |
tree | fba2dabec71193f769c16c3737e152900682bbfa /mm/vmscan.c | |
parent | 44c241f166b31999482c3c40448f4bbb2157a804 (diff) |
mm: shrink_inactive_list() nr_scan accounting fix fix
If sc->isolate_pages() return 0, we don't need to call shrink_page_list().
In past days, shrink_inactive_list() handled it properly.
But commit fb8d14e1 (three years ago commit!) breaked it. current
shrink_inactive_list() always call shrink_page_list() although
isolate_pages() return 0.
This patch restore proper return value check.
Requirements:
o "nr_taken == 0" condition should stay before calling shrink_page_list().
o "nr_taken == 0" condition should stay after nr_scan related statistics
modification.
Cc: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Reviewed-by: Rik van Riel <riel@redhat.com>
Reviewed-by: Minchan Kim <minchan.kim@gmail.com>
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 | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index 45a150a3a442..d86a91f8c16b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1076,6 +1076,20 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1076 | nr_taken = sc->isolate_pages(sc->swap_cluster_max, | 1076 | nr_taken = sc->isolate_pages(sc->swap_cluster_max, |
1077 | &page_list, &nr_scan, sc->order, mode, | 1077 | &page_list, &nr_scan, sc->order, mode, |
1078 | zone, sc->mem_cgroup, 0, file); | 1078 | zone, sc->mem_cgroup, 0, file); |
1079 | |||
1080 | if (scanning_global_lru(sc)) { | ||
1081 | zone->pages_scanned += nr_scan; | ||
1082 | if (current_is_kswapd()) | ||
1083 | __count_zone_vm_events(PGSCAN_KSWAPD, zone, | ||
1084 | nr_scan); | ||
1085 | else | ||
1086 | __count_zone_vm_events(PGSCAN_DIRECT, zone, | ||
1087 | nr_scan); | ||
1088 | } | ||
1089 | |||
1090 | if (nr_taken == 0) | ||
1091 | goto done; | ||
1092 | |||
1079 | nr_active = clear_active_flags(&page_list, count); | 1093 | nr_active = clear_active_flags(&page_list, count); |
1080 | __count_vm_events(PGDEACTIVATE, nr_active); | 1094 | __count_vm_events(PGDEACTIVATE, nr_active); |
1081 | 1095 | ||
@@ -1088,8 +1102,6 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1088 | __mod_zone_page_state(zone, NR_INACTIVE_ANON, | 1102 | __mod_zone_page_state(zone, NR_INACTIVE_ANON, |
1089 | -count[LRU_INACTIVE_ANON]); | 1103 | -count[LRU_INACTIVE_ANON]); |
1090 | 1104 | ||
1091 | if (scanning_global_lru(sc)) | ||
1092 | zone->pages_scanned += nr_scan; | ||
1093 | 1105 | ||
1094 | reclaim_stat->recent_scanned[0] += count[LRU_INACTIVE_ANON]; | 1106 | reclaim_stat->recent_scanned[0] += count[LRU_INACTIVE_ANON]; |
1095 | reclaim_stat->recent_scanned[0] += count[LRU_ACTIVE_ANON]; | 1107 | reclaim_stat->recent_scanned[0] += count[LRU_ACTIVE_ANON]; |
@@ -1123,18 +1135,12 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1123 | } | 1135 | } |
1124 | 1136 | ||
1125 | nr_reclaimed += nr_freed; | 1137 | nr_reclaimed += nr_freed; |
1138 | |||
1126 | local_irq_disable(); | 1139 | local_irq_disable(); |
1127 | if (current_is_kswapd()) { | 1140 | if (current_is_kswapd()) |
1128 | __count_zone_vm_events(PGSCAN_KSWAPD, zone, nr_scan); | ||
1129 | __count_vm_events(KSWAPD_STEAL, nr_freed); | 1141 | __count_vm_events(KSWAPD_STEAL, nr_freed); |
1130 | } else if (scanning_global_lru(sc)) | ||
1131 | __count_zone_vm_events(PGSCAN_DIRECT, zone, nr_scan); | ||
1132 | |||
1133 | __count_zone_vm_events(PGSTEAL, zone, nr_freed); | 1142 | __count_zone_vm_events(PGSTEAL, zone, nr_freed); |
1134 | 1143 | ||
1135 | if (nr_taken == 0) | ||
1136 | goto done; | ||
1137 | |||
1138 | spin_lock(&zone->lru_lock); | 1144 | spin_lock(&zone->lru_lock); |
1139 | /* | 1145 | /* |
1140 | * Put back any unfreeable pages. | 1146 | * Put back any unfreeable pages. |
@@ -1164,9 +1170,9 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1164 | } | 1170 | } |
1165 | } | 1171 | } |
1166 | } while (nr_scanned < max_scan); | 1172 | } while (nr_scanned < max_scan); |
1167 | spin_unlock(&zone->lru_lock); | 1173 | |
1168 | done: | 1174 | done: |
1169 | local_irq_enable(); | 1175 | spin_unlock_irq(&zone->lru_lock); |
1170 | pagevec_release(&pvec); | 1176 | pagevec_release(&pvec); |
1171 | return nr_reclaimed; | 1177 | return nr_reclaimed; |
1172 | } | 1178 | } |