提交 c9034750 编写于 作者: D Ding Tianhong 提交者: Yang Yingliang

share pool: Clean sp_mutex for sp_add_group_task

ascend inclusion
category: perf
bugzilla: https://gitee.com/openeuler/kernel/issues/I4EUVI
CVE: NA

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

We decide to remove sp_mutex thoroughly and use sp_group_sem instead.

Moreover, we use down_read(&spg->rw_lock) instead of down_write(), this
increases parallelism of sp_add_group_task(), especially when there are
many normal pages in the target sp_group.

Test: First a process is added into sp_group 1, then it calls sp_alloc()
to get 3.5G normal page memory and 5.5G hugepage memory. Then 30
processes are created and added to sp_group 1 concurrently. The result
is as follows.

without this patch: 15.0s
with this patch:    4.5s
gain:               70%
Tested-by: NTang Yizhou <tangyizhou@huawei.com>
Signed-off-by: NDing Tianhong <dingtianhong@huawei.com>
Signed-off-by: NTang Yizhou <tangyizhou@huawei.com>
Reviewed-by: NKefeng  Wang <wangkefeng.wang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Reviewed-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 cc1092a7
...@@ -71,9 +71,6 @@ int sysctl_sp_debug_mode; ...@@ -71,9 +71,6 @@ int sysctl_sp_debug_mode;
int sysctl_share_pool_map_lock_enable; int sysctl_share_pool_map_lock_enable;
/* for inter-group operations */
static DEFINE_MUTEX(sp_mutex);
/* idr of all sp_groups */ /* idr of all sp_groups */
static DEFINE_IDR(sp_group_idr); static DEFINE_IDR(sp_group_idr);
/* rw semaphore for sp_group_idr */ /* rw semaphore for sp_group_idr */
...@@ -412,13 +409,13 @@ int sp_group_id_by_pid(int pid) ...@@ -412,13 +409,13 @@ int sp_group_id_by_pid(int pid)
} }
EXPORT_SYMBOL_GPL(sp_group_id_by_pid); EXPORT_SYMBOL_GPL(sp_group_id_by_pid);
/* 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)
{ {
struct sp_group *spg; struct sp_group *spg;
int ret; int ret;
char name[20]; char name[20];
down_write(&sp_group_sem);
spg = __sp_find_spg_locked(current->pid, spg_id); spg = __sp_find_spg_locked(current->pid, spg_id);
if (!spg) { if (!spg) {
...@@ -432,7 +429,6 @@ static struct sp_group *find_or_alloc_sp_group(int spg_id) ...@@ -432,7 +429,6 @@ static struct sp_group *find_or_alloc_sp_group(int spg_id)
} }
ret = idr_alloc(&sp_group_idr, spg, spg_id, spg_id + 1, ret = idr_alloc(&sp_group_idr, spg, spg_id, spg_id + 1,
GFP_KERNEL); GFP_KERNEL);
up_write(&sp_group_sem);
if (ret < 0) { if (ret < 0) {
pr_err_ratelimited("share pool: create group idr alloc failed\n"); pr_err_ratelimited("share pool: create group idr alloc failed\n");
goto out_kfree; goto out_kfree;
...@@ -472,7 +468,6 @@ static struct sp_group *find_or_alloc_sp_group(int spg_id) ...@@ -472,7 +468,6 @@ static struct sp_group *find_or_alloc_sp_group(int spg_id)
goto out_fput; goto out_fput;
} }
} else { } else {
up_write(&sp_group_sem);
down_read(&spg->rw_lock); down_read(&spg->rw_lock);
if (!spg_valid(spg)) { if (!spg_valid(spg)) {
up_read(&spg->rw_lock); up_read(&spg->rw_lock);
...@@ -488,9 +483,7 @@ static struct sp_group *find_or_alloc_sp_group(int spg_id) ...@@ -488,9 +483,7 @@ static struct sp_group *find_or_alloc_sp_group(int spg_id)
out_fput: out_fput:
fput(spg->file); fput(spg->file);
out_idr: out_idr:
down_write(&sp_group_sem);
idr_remove(&sp_group_idr, spg_id); idr_remove(&sp_group_idr, spg_id);
up_write(&sp_group_sem);
out_kfree: out_kfree:
kfree(spg); kfree(spg);
return ERR_PTR(ret); return ERR_PTR(ret);
...@@ -604,7 +597,7 @@ int sp_group_add_task(int pid, int spg_id) ...@@ -604,7 +597,7 @@ int sp_group_add_task(int pid, int spg_id)
id_newly_generated = true; id_newly_generated = true;
} }
mutex_lock(&sp_mutex); down_write(&sp_group_sem);
rcu_read_lock(); rcu_read_lock();
...@@ -618,6 +611,7 @@ int sp_group_add_task(int pid, int spg_id) ...@@ -618,6 +611,7 @@ int sp_group_add_task(int pid, int spg_id)
if (ret) { if (ret) {
if (id_newly_generated) if (id_newly_generated)
free_sp_group_id((unsigned int)spg_id); free_sp_group_id((unsigned int)spg_id);
up_write(&sp_group_sem);
goto out_unlock; goto out_unlock;
} }
...@@ -636,9 +630,11 @@ int sp_group_add_task(int pid, int spg_id) ...@@ -636,9 +630,11 @@ int sp_group_add_task(int pid, int spg_id)
mm = get_task_mm(tsk->group_leader); mm = get_task_mm(tsk->group_leader);
if (!mm) { if (!mm) {
ret = -ESRCH; ret = -ESRCH;
up_write(&sp_group_sem);
goto out_put_task; goto out_put_task;
} else if (mm->sp_group) { } else if (mm->sp_group) {
ret = -EEXIST; ret = -EEXIST;
up_write(&sp_group_sem);
goto out_put_mm; goto out_put_mm;
} }
...@@ -647,6 +643,7 @@ int sp_group_add_task(int pid, int spg_id) ...@@ -647,6 +643,7 @@ int sp_group_add_task(int pid, int spg_id)
ret = PTR_ERR(spg); ret = PTR_ERR(spg);
if (id_newly_generated) if (id_newly_generated)
free_sp_group_id((unsigned int)spg_id); free_sp_group_id((unsigned int)spg_id);
up_write(&sp_group_sem);
goto out_put_mm; goto out_put_mm;
} }
...@@ -654,10 +651,14 @@ int sp_group_add_task(int pid, int spg_id) ...@@ -654,10 +651,14 @@ int sp_group_add_task(int pid, int spg_id)
if (sysctl_ac_mode == AC_SINGLE_OWNER) { if (sysctl_ac_mode == AC_SINGLE_OWNER) {
if (spg->owner != current->group_leader) { if (spg->owner != current->group_leader) {
ret = -EPERM; ret = -EPERM;
up_write(&sp_group_sem);
goto out_drop_group; goto out_drop_group;
} }
} }
mm->sp_group = spg;
up_write(&sp_group_sem);
/* per process statistics initialization */ /* per process statistics initialization */
stat = sp_init_proc_stat(tsk, mm); stat = sp_init_proc_stat(tsk, mm);
if (IS_ERR(stat)) { if (IS_ERR(stat)) {
...@@ -666,10 +667,7 @@ int sp_group_add_task(int pid, int spg_id) ...@@ -666,10 +667,7 @@ int sp_group_add_task(int pid, int spg_id)
goto out_drop_group; goto out_drop_group;
} }
mm->sp_group = spg; down_read(&spg->rw_lock);
down_write(&spg->rw_lock);
list_add_tail(&mm->sp_node, &spg->procs);
/* /*
* create mappings of existing shared memory segments into this * create mappings of existing shared memory segments into this
* new process' page table. * new process' page table.
...@@ -735,22 +733,25 @@ int sp_group_add_task(int pid, int spg_id) ...@@ -735,22 +733,25 @@ int sp_group_add_task(int pid, int spg_id)
} }
__sp_area_drop_locked(prev); __sp_area_drop_locked(prev);
spin_unlock(&sp_area_lock); spin_unlock(&sp_area_lock);
up_read(&spg->rw_lock);
if (unlikely(ret)) { sp_proc_stat_drop(stat); /* match with sp_init_proc_stat */
/* spg->procs is modified, spg->rw_lock should be put below */
list_del(&mm->sp_node);
mm->sp_group = NULL;
}
up_write(&spg->rw_lock);
/* double drop when fail: ensure release stat */ /* double drop when fail: ensure release stat */
if (unlikely(ret)) if (unlikely(ret))
sp_proc_stat_drop(stat); sp_proc_stat_drop(stat);
sp_proc_stat_drop(stat); /* match with sp_init_proc_stat */
out_drop_group: out_drop_group:
if (unlikely(ret)) if (unlikely(ret)) {
down_write(&sp_group_sem);
mm->sp_group = NULL;
up_write(&sp_group_sem);
sp_group_drop(spg); sp_group_drop(spg);
} else {
down_write(&spg->rw_lock);
list_add_tail(&mm->sp_node, &spg->procs);
up_write(&spg->rw_lock);
}
out_put_mm: out_put_mm:
/* No need to put the mm if the sp group adds this mm successfully */ /* No need to put the mm if the sp group adds this mm successfully */
if (unlikely(ret)) if (unlikely(ret))
...@@ -758,7 +759,6 @@ int sp_group_add_task(int pid, int spg_id) ...@@ -758,7 +759,6 @@ int sp_group_add_task(int pid, int spg_id)
out_put_task: out_put_task:
put_task_struct(tsk); put_task_struct(tsk);
out_unlock: out_unlock:
mutex_unlock(&sp_mutex);
return ret == 0 ? spg_id : ret; return ret == 0 ? spg_id : ret;
} }
EXPORT_SYMBOL_GPL(sp_group_add_task); EXPORT_SYMBOL_GPL(sp_group_add_task);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册