From: Tang Yizhou tangyizhou@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4EUVI CVE: NA
-------------------------------------------------
To simplify the design, we can put the pointer of sp_proc_stat in sp_group_master so we don't need call proc_stat = idr_find(id).
Signed-off-by: Tang Yizhou tangyizhou@huawei.com Reviewed-by: Ding Tianhong dingtianhong@huawei.com Signed-off-by: Zhou Guanghui zhouguanghui1@huawei.com Reviewed-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- include/linux/share_pool.h | 44 ++++++++++++------------ mm/oom_kill.c | 2 +- mm/share_pool.c | 70 ++++++++++++++------------------------ 3 files changed, 48 insertions(+), 68 deletions(-)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index c3cf15f5da051..fc9f411f7a33c 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -73,6 +73,25 @@ struct sp_spg_stat { DECLARE_HASHTABLE(hash, SP_SPG_HASH_BITS); };
+/* we estimate a process ususally belongs to at most 16 sp-group */ +#define SP_PROC_HASH_BITS 4 + +/* per process memory usage statistics indexed by tgid */ +struct sp_proc_stat { + atomic_t use_count; + int tgid; + struct mm_struct *mm; + struct mutex lock; /* protect hashtable */ + DECLARE_HASHTABLE(hash, SP_PROC_HASH_BITS); + char comm[TASK_COMM_LEN]; + /* + * alloc amount minus free amount, may be negative when freed by + * another task in the same sp group. + */ + atomic64_t alloc_size; + atomic64_t k2u_size; +}; + /* Processes in the same sp_group can share memory. * Memory layout for share pool: * @@ -123,10 +142,10 @@ struct sp_group_master { * a.k.a the number of sp_node in node_list */ unsigned int count; - int sp_stat_id; /* list head of sp_node */ struct list_head node_list; struct mm_struct *mm; + struct sp_proc_stat *stat; };
/* @@ -154,25 +173,6 @@ struct sp_walk_data { pmd_t *pmd; };
-/* we estimate a process ususally belongs to at most 16 sp-group */ -#define SP_PROC_HASH_BITS 4 - -/* per process memory usage statistics indexed by tgid */ -struct sp_proc_stat { - atomic_t use_count; - int tgid; - struct mm_struct *mm; - struct mutex lock; /* protect hashtable */ - DECLARE_HASHTABLE(hash, SP_PROC_HASH_BITS); - char comm[TASK_COMM_LEN]; - /* - * alloc amount minus free amount, may be negative when freed by - * another task in the same sp group. - */ - atomic64_t alloc_size; - atomic64_t k2u_size; -}; - #define MAP_SHARE_POOL 0x100000
#define MMAP_TOP_4G_SIZE 0x100000000UL @@ -221,7 +221,7 @@ extern int sp_register_notifier(struct notifier_block *nb); extern int sp_unregister_notifier(struct notifier_block *nb); extern bool sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid); extern bool is_sharepool_addr(unsigned long addr); -extern struct sp_proc_stat *sp_get_proc_stat_ref(int tgid); +extern struct sp_proc_stat *sp_get_proc_stat_ref(struct mm_struct *mm); extern void sp_proc_stat_drop(struct sp_proc_stat *stat); extern void spa_overview_show(struct seq_file *seq); extern void spg_overview_show(struct seq_file *seq); @@ -426,7 +426,7 @@ static inline bool is_sharepool_addr(unsigned long addr) return false; }
-static inline struct sp_proc_stat *sp_get_proc_stat_ref(int tgid) +static inline struct sp_proc_stat *sp_get_proc_stat_ref(struct mm_struct *mm) { return NULL; } diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 19b0b266437c4..2799a47105014 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -481,7 +481,7 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask) }
if (ascend_sp_oom_show()) { - stat = sp_get_proc_stat_ref(task->tgid); + stat = sp_get_proc_stat_ref(task->mm);
pr_cont("[%7d] %5d %5d %8lu %8lu ", task->pid, from_kuid(&init_user_ns, task_uid(task)), diff --git a/mm/share_pool.c b/mm/share_pool.c index e6f013e3b84ff..b7af4752879f0 100644 --- a/mm/share_pool.c +++ b/mm/share_pool.c @@ -135,7 +135,7 @@ static struct sp_group_master *sp_init_group_master_locked(
INIT_LIST_HEAD(&master->node_list); master->count = 0; - master->sp_stat_id = 0; + master->stat = NULL; master->mm = mm; mm->sp_group_master = master;
@@ -143,48 +143,37 @@ static struct sp_group_master *sp_init_group_master_locked( return master; }
-/* The caller must hold sp_stat_sem */ -static struct sp_proc_stat *sp_get_proc_stat_locked(int tgid) +static struct sp_proc_stat *sp_get_proc_stat(struct mm_struct *mm) { struct sp_proc_stat *stat;
- stat = idr_find(&sp_proc_stat_idr, tgid); - - /* maybe NULL or not, we always return it */ - return stat; -} - -/* The caller must hold sp_stat_sem */ -static struct sp_proc_stat *sp_get_proc_stat_ref_locked(int tgid) -{ - struct sp_proc_stat *stat; + if (!mm->sp_group_master) + return NULL;
- stat = idr_find(&sp_proc_stat_idr, tgid); - if (!stat || !atomic_inc_not_zero(&stat->use_count)) - stat = NULL; + down_read(&sp_proc_stat_sem); + stat = mm->sp_group_master->stat; + up_read(&sp_proc_stat_sem);
/* maybe NULL or not, we always return it */ return stat; }
-static struct sp_proc_stat *sp_get_proc_stat(int tgid) +/* user must call sp_proc_stat_drop() after use */ +struct sp_proc_stat *sp_get_proc_stat_ref(struct mm_struct *mm) { struct sp_proc_stat *stat;
+ if (!mm->sp_group_master) + return NULL; + down_read(&sp_proc_stat_sem); - stat = sp_get_proc_stat_locked(tgid); + stat = mm->sp_group_master->stat; up_read(&sp_proc_stat_sem); - return stat; -}
-/* user must call sp_proc_stat_drop() after use */ -struct sp_proc_stat *sp_get_proc_stat_ref(int tgid) -{ - struct sp_proc_stat *stat; + if (!stat || !atomic_inc_not_zero(&stat->use_count)) + stat = NULL;
- down_read(&sp_proc_stat_sem); - stat = sp_get_proc_stat_ref_locked(tgid); - up_read(&sp_proc_stat_sem); + /* maybe NULL or not, we always return it */ return stat; }
@@ -215,22 +204,13 @@ static struct sp_proc_stat *sp_init_proc_stat(struct sp_group_master *master, struct mm_struct *mm, struct task_struct *tsk) { struct sp_proc_stat *stat; - int id, alloc_id, tgid = tsk->tgid; + int alloc_id, tgid = tsk->tgid;
down_write(&sp_proc_stat_sem); - id = master->sp_stat_id; - if (id) { - /* may have been initialized */ - stat = sp_get_proc_stat_locked(tgid); + stat = master->stat; + if (stat) { up_write(&sp_proc_stat_sem); - if (stat) { - return stat; - } else { - up_write(&sp_proc_stat_sem); - /* if enter this branch, that's our mistake */ - WARN(1, "proc stat invalid id %d\n", id); - return ERR_PTR(-EBUSY); - } + return stat; }
stat = create_proc_stat(mm, tsk); @@ -247,7 +227,7 @@ static struct sp_proc_stat *sp_init_proc_stat(struct sp_group_master *master, return ERR_PTR(alloc_id); }
- master->sp_stat_id = alloc_id; + master->stat = stat; up_write(&sp_proc_stat_sem);
return stat; @@ -3341,7 +3321,7 @@ static void free_sp_proc_stat(struct sp_proc_stat *stat) free_process_spg_proc_stat(stat);
down_write(&sp_proc_stat_sem); - stat->mm->sp_group_master->sp_stat_id = 0; + stat->mm->sp_group_master->stat = NULL; idr_remove(&sp_proc_stat_idr, stat->tgid); up_write(&sp_proc_stat_sem); kfree(stat); @@ -3372,7 +3352,7 @@ int proc_sp_group_state(struct seq_file *m, struct pid_namespace *ns, up_read(&spg->rw_lock);
/* eliminate potential ABBA deadlock */ - stat = sp_get_proc_stat_ref(task->mm->sp_group_master->sp_stat_id); + stat = sp_get_proc_stat_ref(task->mm); if (unlikely(!stat)) { sp_group_drop(spg); return 0; @@ -3889,7 +3869,7 @@ void sp_group_post_exit(struct mm_struct *mm) * A process not in an sp group doesn't need to print because there * wont't be any memory which is not freed. */ - stat = sp_get_proc_stat(master->sp_stat_id); + stat = sp_get_proc_stat(mm); if (stat) { alloc_size = atomic64_read(&stat->alloc_size); k2u_size = atomic64_read(&stat->k2u_size); @@ -3897,7 +3877,7 @@ void sp_group_post_exit(struct mm_struct *mm) if (alloc_size != 0 || k2u_size != 0) pr_info("process %s(%d) exits. " "It applied %ld aligned KB, k2u shared %ld aligned KB\n", - stat->comm, master->sp_stat_id, + stat->comm, stat->tgid, byte2kb(alloc_size), byte2kb(k2u_size));
/* match with sp_init_proc_stat, we expect stat is released after this call */