35
35
#include <linux/cpuset.h>
36
36
#include <linux/compaction.h>
37
37
#include <linux/notifier.h>
38
- #include <linux/mutex .h>
38
+ #include <linux/rwsem .h>
39
39
#include <linux/delay.h>
40
40
#include <linux/kthread.h>
41
41
#include <linux/freezer.h>
@@ -190,7 +190,7 @@ struct scan_control {
190
190
int vm_swappiness = 60 ;
191
191
192
192
LIST_HEAD (shrinker_list );
193
- DEFINE_MUTEX ( shrinker_mutex );
193
+ DECLARE_RWSEM ( shrinker_rwsem );
194
194
DEFINE_SRCU (shrinker_srcu );
195
195
static atomic_t shrinker_srcu_generation = ATOMIC_INIT (0 );
196
196
@@ -213,7 +213,7 @@ static struct shrinker_info *shrinker_info_protected(struct mem_cgroup *memcg,
213
213
{
214
214
return srcu_dereference_check (memcg -> nodeinfo [nid ]-> shrinker_info ,
215
215
& shrinker_srcu ,
216
- lockdep_is_held (& shrinker_mutex ));
216
+ lockdep_is_held (& shrinker_rwsem ));
217
217
}
218
218
219
219
static struct shrinker_info * shrinker_info_srcu (struct mem_cgroup * memcg ,
@@ -292,7 +292,7 @@ int alloc_shrinker_info(struct mem_cgroup *memcg)
292
292
int nid , size , ret = 0 ;
293
293
int map_size , defer_size = 0 ;
294
294
295
- mutex_lock ( & shrinker_mutex );
295
+ down_write ( & shrinker_rwsem );
296
296
map_size = shrinker_map_size (shrinker_nr_max );
297
297
defer_size = shrinker_defer_size (shrinker_nr_max );
298
298
size = map_size + defer_size ;
@@ -308,7 +308,7 @@ int alloc_shrinker_info(struct mem_cgroup *memcg)
308
308
info -> map_nr_max = shrinker_nr_max ;
309
309
rcu_assign_pointer (memcg -> nodeinfo [nid ]-> shrinker_info , info );
310
310
}
311
- mutex_unlock ( & shrinker_mutex );
311
+ up_write ( & shrinker_rwsem );
312
312
313
313
return ret ;
314
314
}
@@ -324,7 +324,7 @@ static int expand_shrinker_info(int new_id)
324
324
if (!root_mem_cgroup )
325
325
goto out ;
326
326
327
- lockdep_assert_held (& shrinker_mutex );
327
+ lockdep_assert_held (& shrinker_rwsem );
328
328
329
329
map_size = shrinker_map_size (new_nr_max );
330
330
defer_size = shrinker_defer_size (new_nr_max );
@@ -374,7 +374,7 @@ static int prealloc_memcg_shrinker(struct shrinker *shrinker)
374
374
if (mem_cgroup_disabled ())
375
375
return - ENOSYS ;
376
376
377
- mutex_lock ( & shrinker_mutex );
377
+ down_write ( & shrinker_rwsem );
378
378
id = idr_alloc (& shrinker_idr , shrinker , 0 , 0 , GFP_KERNEL );
379
379
if (id < 0 )
380
380
goto unlock ;
@@ -388,7 +388,7 @@ static int prealloc_memcg_shrinker(struct shrinker *shrinker)
388
388
shrinker -> id = id ;
389
389
ret = 0 ;
390
390
unlock :
391
- mutex_unlock ( & shrinker_mutex );
391
+ up_write ( & shrinker_rwsem );
392
392
return ret ;
393
393
}
394
394
@@ -398,7 +398,7 @@ static void unregister_memcg_shrinker(struct shrinker *shrinker)
398
398
399
399
BUG_ON (id < 0 );
400
400
401
- lockdep_assert_held (& shrinker_mutex );
401
+ lockdep_assert_held (& shrinker_rwsem );
402
402
403
403
idr_remove (& shrinker_idr , id );
404
404
}
@@ -433,7 +433,7 @@ void reparent_shrinker_deferred(struct mem_cgroup *memcg)
433
433
parent = root_mem_cgroup ;
434
434
435
435
/* Prevent from concurrent shrinker_info expand */
436
- mutex_lock ( & shrinker_mutex );
436
+ down_write ( & shrinker_rwsem );
437
437
for_each_node (nid ) {
438
438
child_info = shrinker_info_protected (memcg , nid );
439
439
parent_info = shrinker_info_protected (parent , nid );
@@ -442,7 +442,7 @@ void reparent_shrinker_deferred(struct mem_cgroup *memcg)
442
442
atomic_long_add (nr , & parent_info -> nr_deferred [i ]);
443
443
}
444
444
}
445
- mutex_unlock ( & shrinker_mutex );
445
+ up_write ( & shrinker_rwsem );
446
446
}
447
447
448
448
static bool cgroup_reclaim (struct scan_control * sc )
@@ -743,9 +743,9 @@ void free_prealloced_shrinker(struct shrinker *shrinker)
743
743
shrinker -> name = NULL ;
744
744
#endif
745
745
if (shrinker -> flags & SHRINKER_MEMCG_AWARE ) {
746
- mutex_lock ( & shrinker_mutex );
746
+ down_write ( & shrinker_rwsem );
747
747
unregister_memcg_shrinker (shrinker );
748
- mutex_unlock ( & shrinker_mutex );
748
+ up_write ( & shrinker_rwsem );
749
749
return ;
750
750
}
751
751
@@ -755,11 +755,11 @@ void free_prealloced_shrinker(struct shrinker *shrinker)
755
755
756
756
void register_shrinker_prepared (struct shrinker * shrinker )
757
757
{
758
- mutex_lock ( & shrinker_mutex );
758
+ down_write ( & shrinker_rwsem );
759
759
list_add_tail_rcu (& shrinker -> list , & shrinker_list );
760
760
shrinker -> flags |= SHRINKER_REGISTERED ;
761
761
shrinker_debugfs_add (shrinker );
762
- mutex_unlock ( & shrinker_mutex );
762
+ up_write ( & shrinker_rwsem );
763
763
}
764
764
765
765
static int __register_shrinker (struct shrinker * shrinker )
@@ -810,13 +810,13 @@ void unregister_shrinker(struct shrinker *shrinker)
810
810
if (!(shrinker -> flags & SHRINKER_REGISTERED ))
811
811
return ;
812
812
813
- mutex_lock ( & shrinker_mutex );
813
+ down_write ( & shrinker_rwsem );
814
814
list_del_rcu (& shrinker -> list );
815
815
shrinker -> flags &= ~SHRINKER_REGISTERED ;
816
816
if (shrinker -> flags & SHRINKER_MEMCG_AWARE )
817
817
unregister_memcg_shrinker (shrinker );
818
818
debugfs_entry = shrinker_debugfs_detach (shrinker , & debugfs_id );
819
- mutex_unlock ( & shrinker_mutex );
819
+ up_write ( & shrinker_rwsem );
820
820
821
821
atomic_inc (& shrinker_srcu_generation );
822
822
synchronize_srcu (& shrinker_srcu );
0 commit comments