提交 12fba722 编写于 作者: T Tang Yizhou 提交者: Yang Yingliang

share_pool: Optimize compact procedure

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

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

We did an compaction experiment on Hi1951. First creating external
fragmentation, then echo 1 > /proc/sys/vm/compact_memory.

Fragmentation size | 0G   | 2G   | 4G  | 8G
Compaction time(s) | 0.07 | 0.85 | 1.7 | 3.4

Obviously, sysctl_compaction_handler has a big performance impact.

We optimize share pool compact procedure as follows:
1. At most one compact daemon is allowed.
2. Creating a compact daemon is only allowed when the last one is
finished at least *sysctl_sp_compact_interval* seconds ago.
Signed-off-by: NTang Yizhou <tangyizhou@huawei.com>
Reviewed-by: NDing Tianhong <dingtianhong@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>
上级 925b5be0
......@@ -40,6 +40,10 @@ extern int enable_ascend_share_pool;
extern int sysctl_share_pool_map_lock_enable;
extern int sysctl_sp_compact_enable;
extern unsigned long sysctl_sp_compact_interval;
extern unsigned long sysctl_sp_compact_interval_max;
#ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC
extern bool vmap_allow_huge;
#endif
......
......@@ -1789,6 +1789,24 @@ static struct ctl_table vm_table[] = {
.extra1 = &zero,
.extra2 = &one,
},
{
.procname = "sharepool_compact_enable",
.data = &sysctl_sp_compact_enable,
.maxlen = sizeof(sysctl_sp_compact_enable),
.mode = 0600,
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &one,
},
{
.procname = "sharepool_compact_interval",
.data = &sysctl_sp_compact_interval,
.maxlen = sizeof(sysctl_sp_compact_interval),
.mode = 0600,
.proc_handler = proc_doulongvec_minmax,
.extra1 = &zero_ul,
.extra2 = &sysctl_sp_compact_interval_max,
},
#endif
{ }
};
......
......@@ -1127,26 +1127,44 @@ void sp_area_drop(struct vm_area_struct *vma)
spin_unlock(&sp_area_lock);
}
static unsigned long last_jiffies;
int sysctl_sp_compact_enable;
unsigned long sysctl_sp_compact_interval = 30UL;
unsigned long sysctl_sp_compact_interval_max = 1000UL;
static unsigned long compact_last_jiffies;
static unsigned long compact_daemon_status;
#define COMPACT_START 1
#define COMPACT_STOP 0
static void sp_compact_nodes(struct work_struct *work)
{
sysctl_compaction_handler(NULL, 1, NULL, NULL, NULL);
kfree(work);
compact_last_jiffies = jiffies;
cmpxchg(&compact_daemon_status, COMPACT_START, COMPACT_STOP);
}
static void sp_add_work_compact(void)
{
struct work_struct *compact_work;
if (!time_after(jiffies, last_jiffies + 10 * HZ))
if (!sysctl_sp_compact_enable)
return;
/* experimental compaction time: 4GB->1.7s, 8GB->3.4s */
if (!time_after(jiffies,
compact_last_jiffies + sysctl_sp_compact_interval * HZ))
return;
if (cmpxchg(&compact_daemon_status, COMPACT_STOP, COMPACT_START) ==
COMPACT_START)
return;
compact_work = kzalloc(sizeof(*compact_work), GFP_KERNEL);
if (!compact_work)
return;
last_jiffies = jiffies;
INIT_WORK(compact_work, sp_compact_nodes);
schedule_work(compact_work);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册