Skip to content

Commit b35ea17

Browse files
kosakitorvalds
authored andcommitted
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 fb8d14e (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 <[email protected]> Signed-off-by: KOSAKI Motohiro <[email protected]> Reviewed-by: Rik van Riel <[email protected]> Reviewed-by: Minchan Kim <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 44c241f commit b35ea17

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

mm/vmscan.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,20 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
10761076
nr_taken = sc->isolate_pages(sc->swap_cluster_max,
10771077
&page_list, &nr_scan, sc->order, mode,
10781078
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+
10791093
nr_active = clear_active_flags(&page_list, count);
10801094
__count_vm_events(PGDEACTIVATE, nr_active);
10811095

@@ -1088,8 +1102,6 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
10881102
__mod_zone_page_state(zone, NR_INACTIVE_ANON,
10891103
-count[LRU_INACTIVE_ANON]);
10901104

1091-
if (scanning_global_lru(sc))
1092-
zone->pages_scanned += nr_scan;
10931105

10941106
reclaim_stat->recent_scanned[0] += count[LRU_INACTIVE_ANON];
10951107
reclaim_stat->recent_scanned[0] += count[LRU_ACTIVE_ANON];
@@ -1123,18 +1135,12 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
11231135
}
11241136

11251137
nr_reclaimed += nr_freed;
1138+
11261139
local_irq_disable();
1127-
if (current_is_kswapd()) {
1128-
__count_zone_vm_events(PGSCAN_KSWAPD, zone, nr_scan);
1140+
if (current_is_kswapd())
11291141
__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-
11331142
__count_zone_vm_events(PGSTEAL, zone, nr_freed);
11341143

1135-
if (nr_taken == 0)
1136-
goto done;
1137-
11381144
spin_lock(&zone->lru_lock);
11391145
/*
11401146
* Put back any unfreeable pages.
@@ -1164,9 +1170,9 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
11641170
}
11651171
}
11661172
} while (nr_scanned < max_scan);
1167-
spin_unlock(&zone->lru_lock);
1173+
11681174
done:
1169-
local_irq_enable();
1175+
spin_unlock_irq(&zone->lru_lock);
11701176
pagevec_release(&pvec);
11711177
return nr_reclaimed;
11721178
}

0 commit comments

Comments
 (0)