提交 d1adfa55 编写于 作者: W Wang Wensheng 提交者: Yongqiang Liu

mm/sharepool: Introduce SPG_NON_DVPP flag for sp_group_add_task

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5EORS
CVE: NA

--------------------------------

When SPG_NOD_DVPP is specified to sp_group_add_task, we don't create a
DVPP mapping for the newly created sp_group. And the new group cannot
support allocating DVPP memory.
Signed-off-by: NWang Wensheng <wangwensheng4@huawei.com>
Reviewed-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
上级 63e80e4f
...@@ -40,6 +40,9 @@ ...@@ -40,6 +40,9 @@
#define SPG_ID_LOCAL_MIN 200001 #define SPG_ID_LOCAL_MIN 200001
#define SPG_ID_LOCAL_MAX 299999 #define SPG_ID_LOCAL_MAX 299999
#define SPG_FLAG_NON_DVPP (1 << 0)
#define SPG_FLAG_MASK (SPG_FLAG_NON_DVPP)
#define MAX_DEVID 8 /* the max num of Da-vinci devices */ #define MAX_DEVID 8 /* the max num of Da-vinci devices */
extern int sysctl_share_pool_hugepage_enable; extern int sysctl_share_pool_hugepage_enable;
...@@ -150,6 +153,7 @@ struct sp_mapping { ...@@ -150,6 +153,7 @@ struct sp_mapping {
*/ */
struct sp_group { struct sp_group {
int id; int id;
unsigned long flag;
struct file *file; struct file *file;
struct file *file_hugetlb; struct file *file_hugetlb;
/* number of process in this group */ /* number of process in this group */
......
...@@ -221,31 +221,20 @@ static bool is_mapping_empty(struct sp_mapping *spm) ...@@ -221,31 +221,20 @@ static bool is_mapping_empty(struct sp_mapping *spm)
} }
/* /*
* When you set the address space of a group, the normal address space * 1. The mappings of local group is set on creating.
* is globally unified. When processing the DVPP address space, consider * 2. This is used to setup the mapping for groups created during add_task.
* the following situations: * 3. The normal mapping exists for all groups.
* 1. If a process is added to a non-new group, the DVPP address space * 4. The dvpp mappings for the new group and local group can merge _iff_ at
* must have been created. If the local group of the process also * least one of the mapping is empty.
* contains the DVPP address space and they are different, this
* scenario is not allowed to avoid address conflict.
* 2. If the DVPP address space does not exist in the local group of the
* process, attach the local group of the process to the DVPP address
* space of the group.
* 3. Add a new group. If the process has applied for the dvpp address
* space (sp_alloc or k2u), attach the new group to the dvpp address
* space of the current process.
* 4. If the process has not applied for the DVPP address space, attach
* the new group and the local group of the current process to the
* newly created DVPP address space.
*
* the caller must hold sp_group_sem * the caller must hold sp_group_sem
* NOTE: undo the mergeing when the later process failed.
*/ */
static int sp_mapping_group_setup(struct mm_struct *mm, struct sp_group *spg) static int sp_mapping_group_setup(struct mm_struct *mm, struct sp_group *spg)
{ {
struct sp_group_master *master = mm->sp_group_master; struct sp_group_master *master = mm->sp_group_master;
struct sp_group *local = master->local; struct sp_group *local = master->local;
if (!list_empty(&spg->procs)) { if (!list_empty(&spg->procs) && !(spg->flag & SPG_FLAG_NON_DVPP)) {
if (is_mapping_empty(local->dvpp)) if (is_mapping_empty(local->dvpp))
sp_mapping_merge(spg->dvpp, local->dvpp); sp_mapping_merge(spg->dvpp, local->dvpp);
else if (is_mapping_empty(spg->dvpp)) else if (is_mapping_empty(spg->dvpp))
...@@ -256,15 +245,17 @@ static int sp_mapping_group_setup(struct mm_struct *mm, struct sp_group *spg) ...@@ -256,15 +245,17 @@ static int sp_mapping_group_setup(struct mm_struct *mm, struct sp_group *spg)
return -EINVAL; return -EINVAL;
} }
} else { } else {
/* the mapping of local group is always set */ if (!(spg->flag & SPG_FLAG_NON_DVPP))
sp_mapping_attach(spg, local->dvpp); /* the mapping of local group is always set */
sp_mapping_attach(spg, sp_mapping_normal); sp_mapping_attach(spg, local->dvpp);
if (!spg->normal)
sp_mapping_attach(spg, sp_mapping_normal);
} }
return 0; return 0;
} }
static struct sp_group *create_spg(int spg_id); static struct sp_group *create_spg(int spg_id, unsigned long flag);
static void free_new_spg_id(bool new, int spg_id); static void free_new_spg_id(bool new, int spg_id);
static void free_sp_group_locked(struct sp_group *spg); static void free_sp_group_locked(struct sp_group *spg);
static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg); static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg);
...@@ -283,7 +274,7 @@ static int init_local_group(struct mm_struct *mm) ...@@ -283,7 +274,7 @@ static int init_local_group(struct mm_struct *mm)
return spg_id; return spg_id;
} }
spg = create_spg(spg_id); spg = create_spg(spg_id, 0);
if (IS_ERR(spg)) { if (IS_ERR(spg)) {
ret = PTR_ERR(spg); ret = PTR_ERR(spg);
goto free_spg_id; goto free_spg_id;
...@@ -1125,7 +1116,7 @@ static bool is_device_addr(unsigned long addr) ...@@ -1125,7 +1116,7 @@ static bool is_device_addr(unsigned long addr)
return false; return false;
} }
static struct sp_group *create_spg(int spg_id) static struct sp_group *create_spg(int spg_id, unsigned long flag)
{ {
int ret; int ret;
struct sp_group *spg; struct sp_group *spg;
...@@ -1139,6 +1130,11 @@ static struct sp_group *create_spg(int spg_id) ...@@ -1139,6 +1130,11 @@ static struct sp_group *create_spg(int spg_id)
return ERR_PTR(-ENOSPC); return ERR_PTR(-ENOSPC);
} }
if (flag & ~SPG_FLAG_MASK) {
pr_err_ratelimited("invalid flag:%#lx\n", flag);
return ERR_PTR(-EINVAL);
}
spg = kzalloc(sizeof(*spg), GFP_KERNEL); spg = kzalloc(sizeof(*spg), GFP_KERNEL);
if (spg == NULL) { if (spg == NULL) {
pr_err_ratelimited("no memory for spg\n"); pr_err_ratelimited("no memory for spg\n");
...@@ -1152,6 +1148,7 @@ static struct sp_group *create_spg(int spg_id) ...@@ -1152,6 +1148,7 @@ static struct sp_group *create_spg(int spg_id)
} }
spg->id = spg_id; spg->id = spg_id;
spg->flag = flag;
spg->is_alive = true; spg->is_alive = true;
spg->proc_num = 0; spg->proc_num = 0;
spg->owner = current->group_leader; spg->owner = current->group_leader;
...@@ -1199,14 +1196,14 @@ static struct sp_group *create_spg(int spg_id) ...@@ -1199,14 +1196,14 @@ static struct sp_group *create_spg(int spg_id)
} }
/* the caller must hold sp_group_sem */ /* the caller must hold sp_group_sem */
static struct sp_group *find_or_alloc_sp_group(int spg_id) static struct sp_group *find_or_alloc_sp_group(int spg_id, unsigned long flag)
{ {
struct sp_group *spg; struct sp_group *spg;
spg = __sp_find_spg_locked(current->pid, spg_id); spg = __sp_find_spg_locked(current->pid, spg_id);
if (!spg) { if (!spg) {
spg = create_spg(spg_id); spg = create_spg(spg_id, flag);
} else { } else {
down_read(&spg->rw_lock); down_read(&spg->rw_lock);
if (!spg_valid(spg)) { if (!spg_valid(spg)) {
...@@ -1362,10 +1359,11 @@ static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg) ...@@ -1362,10 +1359,11 @@ static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg)
} }
/** /**
* sp_group_add_task() - Add a process to an share group (sp_group). * mg_sp_group_add_task() - Add a process to an share group (sp_group).
* @pid: the pid of the task to be added. * @pid: the pid of the task to be added.
* @prot: the prot of task for this spg. * @prot: the prot of task for this spg.
* @spg_id: the ID of the sp_group. * @spg_id: the ID of the sp_group.
* @flag: to give some special message.
* *
* A process can't be added to more than one sp_group in single group mode * A process can't be added to more than one sp_group in single group mode
* and can in multiple group mode. * and can in multiple group mode.
...@@ -1378,6 +1376,7 @@ static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg) ...@@ -1378,6 +1376,7 @@ static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg)
*/ */
int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id) int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id)
{ {
unsigned long flag = 0;
struct task_struct *tsk; struct task_struct *tsk;
struct mm_struct *mm; struct mm_struct *mm;
struct sp_group *spg; struct sp_group *spg;
...@@ -1471,7 +1470,7 @@ int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id) ...@@ -1471,7 +1470,7 @@ int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id)
goto out_put_task; goto out_put_task;
} }
spg = find_or_alloc_sp_group(spg_id); spg = find_or_alloc_sp_group(spg_id, flag);
if (IS_ERR(spg)) { if (IS_ERR(spg)) {
up_write(&sp_group_sem); up_write(&sp_group_sem);
ret = PTR_ERR(spg); ret = PTR_ERR(spg);
...@@ -1845,6 +1844,11 @@ static struct sp_area *sp_alloc_area(unsigned long size, unsigned long flags, ...@@ -1845,6 +1844,11 @@ static struct sp_area *sp_alloc_area(unsigned long size, unsigned long flags,
else else
mapping = spg->normal; mapping = spg->normal;
if (!mapping) {
pr_err_ratelimited("non DVPP spg, id %d\n", spg->id);
return ERR_PTR(-EINVAL);
}
vstart = mapping->start[device_id]; vstart = mapping->start[device_id];
vend = mapping->end[device_id]; vend = mapping->end[device_id];
spa = __kmalloc_node(sizeof(struct sp_area), GFP_KERNEL, node_id); spa = __kmalloc_node(sizeof(struct sp_area), GFP_KERNEL, node_id);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册