Skip to content

Commit d6ecbcd

Browse files
Qi Zhengakpm00
authored andcommitted
Revert "mm: vmscan: add shrinker_srcu_generation"
This reverts commit 475733d. Kernel test robot reports -88.8% regression in stress-ng.ramfs.ops_per_sec test case [1], which is caused by commit f95bdb7 ("mm: vmscan: make global slab shrink lockless"). The root cause is that SRCU has to be careful to not frequently check for SRCU read-side critical section exits. Therefore, even if no one is currently in the SRCU read-side critical section, synchronize_srcu() cannot return quickly. That's why unregister_shrinker() has become slower. We will try to use the refcount+RCU method [2] proposed by Dave Chinner to continue to re-implement the lockless slab shrink. So revert the shrinker_srcu related changes first. [1]. https://lore.kernel.org/lkml/[email protected]/ [2]. https://lore.kernel.org/lkml/[email protected]/ Link: https://lkml.kernel.org/r/[email protected] Reported-by: kernel test robot <[email protected]> Closes: https://lore.kernel.org/oe-lkp/[email protected] Signed-off-by: Qi Zheng <[email protected]> Cc: Dave Chinner <[email protected]> Cc: Kirill Tkhai <[email protected]> Cc: Muchun Song <[email protected]> Cc: Roman Gushchin <[email protected]> Cc: Vlastimil Babka <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 1a554ec commit d6ecbcd

File tree

1 file changed

+4
-20
lines changed

1 file changed

+4
-20
lines changed

mm/vmscan.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ int vm_swappiness = 60;
192192
LIST_HEAD(shrinker_list);
193193
DECLARE_RWSEM(shrinker_rwsem);
194194
DEFINE_SRCU(shrinker_srcu);
195-
static atomic_t shrinker_srcu_generation = ATOMIC_INIT(0);
196195

197196
#ifdef CONFIG_MEMCG
198197
static int shrinker_nr_max;
@@ -818,7 +817,6 @@ void unregister_shrinker(struct shrinker *shrinker)
818817
debugfs_entry = shrinker_debugfs_detach(shrinker, &debugfs_id);
819818
up_write(&shrinker_rwsem);
820819

821-
atomic_inc(&shrinker_srcu_generation);
822820
synchronize_srcu(&shrinker_srcu);
823821

824822
shrinker_debugfs_remove(debugfs_entry, debugfs_id);
@@ -840,7 +838,6 @@ void synchronize_shrinkers(void)
840838
{
841839
down_write(&shrinker_rwsem);
842840
up_write(&shrinker_rwsem);
843-
atomic_inc(&shrinker_srcu_generation);
844841
synchronize_srcu(&shrinker_srcu);
845842
}
846843
EXPORT_SYMBOL(synchronize_shrinkers);
@@ -950,20 +947,18 @@ static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int nid,
950947
{
951948
struct shrinker_info *info;
952949
unsigned long ret, freed = 0;
953-
int srcu_idx, generation;
954-
int i = 0;
950+
int srcu_idx;
951+
int i;
955952

956953
if (!mem_cgroup_online(memcg))
957954
return 0;
958955

959-
again:
960956
srcu_idx = srcu_read_lock(&shrinker_srcu);
961957
info = shrinker_info_srcu(memcg, nid);
962958
if (unlikely(!info))
963959
goto unlock;
964960

965-
generation = atomic_read(&shrinker_srcu_generation);
966-
for_each_set_bit_from(i, info->map, info->map_nr_max) {
961+
for_each_set_bit(i, info->map, info->map_nr_max) {
967962
struct shrink_control sc = {
968963
.gfp_mask = gfp_mask,
969964
.nid = nid,
@@ -1009,11 +1004,6 @@ static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int nid,
10091004
set_shrinker_bit(memcg, nid, i);
10101005
}
10111006
freed += ret;
1012-
if (atomic_read(&shrinker_srcu_generation) != generation) {
1013-
srcu_read_unlock(&shrinker_srcu, srcu_idx);
1014-
i++;
1015-
goto again;
1016-
}
10171007
}
10181008
unlock:
10191009
srcu_read_unlock(&shrinker_srcu, srcu_idx);
@@ -1053,7 +1043,7 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
10531043
{
10541044
unsigned long ret, freed = 0;
10551045
struct shrinker *shrinker;
1056-
int srcu_idx, generation;
1046+
int srcu_idx;
10571047

10581048
/*
10591049
* The root memcg might be allocated even though memcg is disabled
@@ -1067,7 +1057,6 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
10671057

10681058
srcu_idx = srcu_read_lock(&shrinker_srcu);
10691059

1070-
generation = atomic_read(&shrinker_srcu_generation);
10711060
list_for_each_entry_srcu(shrinker, &shrinker_list, list,
10721061
srcu_read_lock_held(&shrinker_srcu)) {
10731062
struct shrink_control sc = {
@@ -1080,11 +1069,6 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
10801069
if (ret == SHRINK_EMPTY)
10811070
ret = 0;
10821071
freed += ret;
1083-
1084-
if (atomic_read(&shrinker_srcu_generation) != generation) {
1085-
freed = freed ? : 1;
1086-
break;
1087-
}
10881072
}
10891073

10901074
srcu_read_unlock(&shrinker_srcu, srcu_idx);

0 commit comments

Comments
 (0)