forked from mirrors/linux
		
	mm: shrinkers: make count and scan in shrinker debugfs lockless
Like global and memcg slab shrink, also use SRCU to make count and scan operations in memory shrinker debugfs lockless. Link: https://lkml.kernel.org/r/20230313112819.38938-6-zhengqi.arch@bytedance.com Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Acked-by: Kirill Tkhai <tkhai@ya.ru> Acked-by: Roman Gushchin <roman.gushchin@linux.dev> Cc: Christian König <christian.koenig@amd.com> Cc: David Hildenbrand <david@redhat.com> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@kernel.org> Cc: Muchun Song <muchun.song@linux.dev> Cc: Paul E. McKenney <paulmck@kernel.org> Cc: Shakeel Butt <shakeelb@google.com> Cc: Sultan Alsawaf <sultan@kerneltoast.com> Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> Cc: Yang Shi <shy828301@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									475733dda5
								
							
						
					
					
						commit
						20cd1892fc
					
				
					 1 changed files with 8 additions and 17 deletions
				
			
		|  | @ -5,10 +5,12 @@ | |||
| #include <linux/seq_file.h> | ||||
| #include <linux/shrinker.h> | ||||
| #include <linux/memcontrol.h> | ||||
| #include <linux/srcu.h> | ||||
| 
 | ||||
| /* defined in vmscan.c */ | ||||
| extern struct rw_semaphore shrinker_rwsem; | ||||
| extern struct list_head shrinker_list; | ||||
| extern struct srcu_struct shrinker_srcu; | ||||
| 
 | ||||
| static DEFINE_IDA(shrinker_debugfs_ida); | ||||
| static struct dentry *shrinker_debugfs_root; | ||||
|  | @ -49,18 +51,13 @@ static int shrinker_debugfs_count_show(struct seq_file *m, void *v) | |||
| 	struct mem_cgroup *memcg; | ||||
| 	unsigned long total; | ||||
| 	bool memcg_aware; | ||||
| 	int ret, nid; | ||||
| 	int ret = 0, nid, srcu_idx; | ||||
| 
 | ||||
| 	count_per_node = kcalloc(nr_node_ids, sizeof(unsigned long), GFP_KERNEL); | ||||
| 	if (!count_per_node) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	ret = down_read_killable(&shrinker_rwsem); | ||||
| 	if (ret) { | ||||
| 		kfree(count_per_node); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	rcu_read_lock(); | ||||
| 	srcu_idx = srcu_read_lock(&shrinker_srcu); | ||||
| 
 | ||||
| 	memcg_aware = shrinker->flags & SHRINKER_MEMCG_AWARE; | ||||
| 
 | ||||
|  | @ -91,8 +88,7 @@ static int shrinker_debugfs_count_show(struct seq_file *m, void *v) | |||
| 		} | ||||
| 	} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL); | ||||
| 
 | ||||
| 	rcu_read_unlock(); | ||||
| 	up_read(&shrinker_rwsem); | ||||
| 	srcu_read_unlock(&shrinker_srcu, srcu_idx); | ||||
| 
 | ||||
| 	kfree(count_per_node); | ||||
| 	return ret; | ||||
|  | @ -115,9 +111,8 @@ static ssize_t shrinker_debugfs_scan_write(struct file *file, | |||
| 		.gfp_mask = GFP_KERNEL, | ||||
| 	}; | ||||
| 	struct mem_cgroup *memcg = NULL; | ||||
| 	int nid; | ||||
| 	int nid, srcu_idx; | ||||
| 	char kbuf[72]; | ||||
| 	ssize_t ret; | ||||
| 
 | ||||
| 	read_len = size < (sizeof(kbuf) - 1) ? size : (sizeof(kbuf) - 1); | ||||
| 	if (copy_from_user(kbuf, buf, read_len)) | ||||
|  | @ -146,11 +141,7 @@ static ssize_t shrinker_debugfs_scan_write(struct file *file, | |||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = down_read_killable(&shrinker_rwsem); | ||||
| 	if (ret) { | ||||
| 		mem_cgroup_put(memcg); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	srcu_idx = srcu_read_lock(&shrinker_srcu); | ||||
| 
 | ||||
| 	sc.nid = nid; | ||||
| 	sc.memcg = memcg; | ||||
|  | @ -159,7 +150,7 @@ static ssize_t shrinker_debugfs_scan_write(struct file *file, | |||
| 
 | ||||
| 	shrinker->scan_objects(shrinker, &sc); | ||||
| 
 | ||||
| 	up_read(&shrinker_rwsem); | ||||
| 	srcu_read_unlock(&shrinker_srcu, srcu_idx); | ||||
| 	mem_cgroup_put(memcg); | ||||
| 
 | ||||
| 	return size; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Qi Zheng
						Qi Zheng