From: Wang Wensheng wangwensheng4@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4EUVI CVE: NA
-------------------
Since a process could be added to multiple groups, we should return an array of spg_ids to cover all the groups.
Signed-off-by: Wang Wensheng wangwensheng4@huawei.com Signed-off-by: Zhou Guanghui zhouguanghui1@huawei.com Reviewed-by: Weilong Chen chenweilong@huawei.com Reviewed-by: Ding Tianhong dingtianhong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- include/linux/share_pool.h | 2 +- mm/share_pool.c | 56 +++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 14 deletions(-)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index 40ccab0e77fad..403221c9ac931 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -203,7 +203,7 @@ static inline void sp_init_mm(struct mm_struct *mm) extern int sp_group_add_task(int pid, unsigned long prot, int spg_id); extern int sp_group_exit(struct mm_struct *mm); extern void sp_group_post_exit(struct mm_struct *mm); -extern int sp_group_id_by_pid(int pid); +extern int sp_group_id_by_pid(int pid, int *spg_ids, int *num); extern int sp_group_walk(int spg_id, void *data, int (*func)(struct mm_struct *mm, void *)); extern int proc_sp_group_state(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task); diff --git a/mm/share_pool.c b/mm/share_pool.c index 1cc2d3eba264e..70ff1cb2393c6 100644 --- a/mm/share_pool.c +++ b/mm/share_pool.c @@ -814,31 +814,61 @@ static struct sp_group *__sp_find_spg(int pid, int spg_id) }
/** - * sp_group_id_by_pid() - Get the sp_group ID of a process. + * sp_group_id_by_pid() - Get the sp_group ID array of a process. * @pid: pid of target process. + * @spg_ids point to an array to save the group ids the process belongs to + * @num input the spg_ids array size; output the spg number of the process * * Return: * >0 - the sp_group ID. * -ENODEV - target process doesn't belong to any sp_group. + * -EINVAL - spg_ids or num is NULL. + * -E2BIG - the num of groups process belongs to is larger than *num */ -int sp_group_id_by_pid(int pid) +int sp_group_id_by_pid(int pid, int *spg_ids, int *num) { - struct sp_group *spg; - int spg_id = -ENODEV; + int ret = 0; + struct sp_group_node *node; + struct sp_group_master *master = NULL; + struct task_struct *tsk;
check_interrupt_context();
- spg = __sp_find_spg(pid, SPG_ID_DEFAULT); - if (!spg) - return -ENODEV; + if (!spg_ids || num <= 0) + return -EINVAL;
- down_read(&spg->rw_lock); - if (spg_valid(spg)) - spg_id = spg->id; - up_read(&spg->rw_lock); + ret = get_task(pid, &tsk); + if (ret) + return ret;
- sp_group_drop(spg); - return spg_id; + down_read(&sp_group_sem); + task_lock(tsk); + if (tsk->mm) + master = tsk->mm->sp_group_master; + task_unlock(tsk); + + if (!master) { + ret = -ENODEV; + goto out_up_read; + } + + if (!master->count) { + ret = -ENODEV; + goto out_up_read; + } + if ((unsigned int)*num < master->count) { + ret = -E2BIG; + goto out_up_read; + } + *num = master->count; + + list_for_each_entry(node, &master->node_list, group_node) + *(spg_ids++) = node->spg->id; + +out_up_read: + up_read(&sp_group_sem); + put_task_struct(tsk); + return ret; } EXPORT_SYMBOL_GPL(sp_group_id_by_pid);