57
57
#include <linux/khugepaged.h>
58
58
#include <linux/rculist_nulls.h>
59
59
#include <linux/random.h>
60
- #include <linux/srcu.h>
61
60
62
61
#include <asm/tlbflush.h>
63
62
#include <asm/div64.h>
@@ -191,7 +190,6 @@ int vm_swappiness = 60;
191
190
192
191
LIST_HEAD (shrinker_list );
193
192
DECLARE_RWSEM (shrinker_rwsem );
194
- DEFINE_SRCU (shrinker_srcu );
195
193
196
194
#ifdef CONFIG_MEMCG
197
195
static int shrinker_nr_max ;
@@ -742,7 +740,7 @@ void free_prealloced_shrinker(struct shrinker *shrinker)
742
740
void register_shrinker_prepared (struct shrinker * shrinker )
743
741
{
744
742
down_write (& shrinker_rwsem );
745
- list_add_tail_rcu (& shrinker -> list , & shrinker_list );
743
+ list_add_tail (& shrinker -> list , & shrinker_list );
746
744
shrinker -> flags |= SHRINKER_REGISTERED ;
747
745
shrinker_debugfs_add (shrinker );
748
746
up_write (& shrinker_rwsem );
@@ -797,15 +795,13 @@ void unregister_shrinker(struct shrinker *shrinker)
797
795
return ;
798
796
799
797
down_write (& shrinker_rwsem );
800
- list_del_rcu (& shrinker -> list );
798
+ list_del (& shrinker -> list );
801
799
shrinker -> flags &= ~SHRINKER_REGISTERED ;
802
800
if (shrinker -> flags & SHRINKER_MEMCG_AWARE )
803
801
unregister_memcg_shrinker (shrinker );
804
802
debugfs_entry = shrinker_debugfs_detach (shrinker , & debugfs_id );
805
803
up_write (& shrinker_rwsem );
806
804
807
- synchronize_srcu (& shrinker_srcu );
808
-
809
805
shrinker_debugfs_remove (debugfs_entry , debugfs_id );
810
806
811
807
kfree (shrinker -> nr_deferred );
@@ -825,7 +821,6 @@ void synchronize_shrinkers(void)
825
821
{
826
822
down_write (& shrinker_rwsem );
827
823
up_write (& shrinker_rwsem );
828
- synchronize_srcu (& shrinker_srcu );
829
824
}
830
825
EXPORT_SYMBOL (synchronize_shrinkers );
831
826
@@ -1036,7 +1031,6 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
1036
1031
{
1037
1032
unsigned long ret , freed = 0 ;
1038
1033
struct shrinker * shrinker ;
1039
- int srcu_idx ;
1040
1034
1041
1035
/*
1042
1036
* The root memcg might be allocated even though memcg is disabled
@@ -1048,10 +1042,10 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
1048
1042
if (!mem_cgroup_disabled () && !mem_cgroup_is_root (memcg ))
1049
1043
return shrink_slab_memcg (gfp_mask , nid , memcg , priority );
1050
1044
1051
- srcu_idx = srcu_read_lock (& shrinker_srcu );
1045
+ if (!down_read_trylock (& shrinker_rwsem ))
1046
+ goto out ;
1052
1047
1053
- list_for_each_entry_srcu (shrinker , & shrinker_list , list ,
1054
- srcu_read_lock_held (& shrinker_srcu )) {
1048
+ list_for_each_entry (shrinker , & shrinker_list , list ) {
1055
1049
struct shrink_control sc = {
1056
1050
.gfp_mask = gfp_mask ,
1057
1051
.nid = nid ,
@@ -1062,9 +1056,19 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
1062
1056
if (ret == SHRINK_EMPTY )
1063
1057
ret = 0 ;
1064
1058
freed += ret ;
1059
+ /*
1060
+ * Bail out if someone want to register a new shrinker to
1061
+ * prevent the registration from being stalled for long periods
1062
+ * by parallel ongoing shrinking.
1063
+ */
1064
+ if (rwsem_is_contended (& shrinker_rwsem )) {
1065
+ freed = freed ? : 1 ;
1066
+ break ;
1067
+ }
1065
1068
}
1066
1069
1067
- srcu_read_unlock (& shrinker_srcu , srcu_idx );
1070
+ up_read (& shrinker_rwsem );
1071
+ out :
1068
1072
cond_resched ();
1069
1073
return freed ;
1070
1074
}
0 commit comments