uti: mcexec_uti_attr: Fix CPU binding decision

Change-Id: I4047858895503ae912e5575bb232dbbb2f915722
This commit is contained in:
Masamichi Takagi
2018-09-03 17:09:29 +09:00
parent fca02ee248
commit 8900c2cec5
3 changed files with 133 additions and 41 deletions

View File

@ -311,6 +311,10 @@ struct perf_ctrl_desc {
#define UTI_FLAG_HIGH_PRIORITY (1ULL<<12)
#define UTI_FLAG_NON_COOPERATIVE (1ULL<<13)
#define UTI_FLAG_PREFER_LWK (1ULL << 14)
#define UTI_FLAG_PREFER_FWK (1ULL << 15)
#define UTI_FLAG_FABRIC_INTR_AFFINITY (1ULL << 16)
/* Linux default value is used */
#define UTI_MAX_NUMA_DOMAINS (1024)
@ -329,6 +333,8 @@ struct kuti_attr {
struct uti_attr_desc {
unsigned long phys_attr;
char *uti_cpu_set_str; /* UTI_CPU_SET environmental variable */
size_t uti_cpu_set_len;
};
struct uti_ctx {

View File

@ -72,6 +72,14 @@
#define pr_ppd(msg, tid, ppd) do { } while(0)
#endif
#if defined(RHEL_RELEASE_CODE) || (LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0))
#define BITMAP_SCNLISTPRINTF(buf, buflen, maskp, nmaskbits) \
bitmap_scnlistprintf(buf, buflen, maskp, nmaskbits)
#else
#define BITMAP_SCNLISTPRINTF(buf, buflen, maskp, nmaskbits) \
scnprintf(buf, buflen, "%*pbl", nmaskbits, maskp)
#endif
//extern struct mcctrl_channel *channels;
int mcctrl_ikc_set_recv_cpu(ihk_os_t os, int cpu);
int syscall_backward(struct mcctrl_usrdata *, int, unsigned long, unsigned long,
@ -2862,12 +2870,35 @@ retry:
return cpumask;
}
int pr_cpumask(const char *msg, cpumask_t* cpumask) {
int ret;
char *buf;
if (!(buf = kmalloc(PAGE_SIZE * 2, GFP_KERNEL))) {
kprintf("%s: error: allocating buf\n",
__func__);
ret = -ENOMEM;
goto out;
}
BITMAP_SCNLISTPRINTF(buf, PAGE_SIZE * 2,
cpumask_bits(cpumask),
nr_cpumask_bits);
buf[PAGE_SIZE * 2 - 1] = 0;
pr_info("%s: info: cpuset: %s\n", msg, buf);
ret = 0;
out:
return ret;
}
static long
mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *arg)
mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *_desc)
{
struct uti_attr_desc desc;
char *uti_cpu_set_str;
struct kuti_attr *kattr;
cpumask_t *cpuset;
cpumask_t *cpuset = NULL, *env_cpuset = NULL;
struct mcctrl_usrdata *ud = ihk_host_os_get_usrdata(os);
ihk_device_t dev = ihk_os_to_dev(os);
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
@ -2886,30 +2917,44 @@ mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *arg)
int mask_size = cpumask_size();
if ((rc = uti_attr_init())) {
return rc;
pr_err("%s: error: uti_attr_init (%d)\n",
__func__, rc);
goto out;
}
if ((rc = copy_from_user(&desc, _desc, sizeof(desc)))) {
pr_err("%s: error: copy_from_user\n",
__func__);
rc = -EFAULT;
goto out;
}
if (!(uti_cpu_set_str = kmalloc(desc.uti_cpu_set_len, GFP_KERNEL))) {
pr_err("%s: error: allocating uti_cpu_set_str\n",
__func__);
rc = -ENOMEM;
goto out;
}
if ((rc = copy_from_user(uti_cpu_set_str, desc.uti_cpu_set_str, desc.uti_cpu_set_len))) {
pr_err("%s: error: copy_from_user\n",
__func__);
rc = -EFAULT;
goto out;
}
if (copy_from_user(&desc, arg, sizeof desc))
return -EFAULT;
kattr = phys_to_virt(desc.phys_attr);
if (((kattr->attr.flags & UTI_FLAG_SAME_L1) &&
(kattr->attr.flags & UTI_FLAG_DIFFERENT_L1)) ||
((kattr->attr.flags & UTI_FLAG_SAME_L2) &&
(kattr->attr.flags & UTI_FLAG_DIFFERENT_L2)) ||
((kattr->attr.flags & UTI_FLAG_SAME_L3) &&
(kattr->attr.flags & UTI_FLAG_DIFFERENT_L3)) ||
((kattr->attr.flags & UTI_FLAG_SAME_NUMA_DOMAIN) &&
(kattr->attr.flags & UTI_FLAG_DIFFERENT_NUMA_DOMAIN))) {
return -EINVAL;
}
/* Find caller cpu for later resolution of subgroups */
list_for_each_entry(cpu_topo, &ud->cpu_topology_list, chain) {
if (cpu_topo->mckernel_cpu_id == kattr->parent_cpuid) {
target_cpu = cpu_topo;
}
}
if (!target_cpu) {
printk("%s: errror: caller cpu not found\n",
__func__);
return -EINVAL;
}
@ -2918,6 +2963,7 @@ mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *arg)
}
wkmask = (cpumask_t *)(((char *)cpuset) + mask_size);
/* Initial cpuset */
memcpy(cpuset, cpu_active_mask, mask_size);
if (kattr->attr.flags & UTI_FLAG_NUMA_SET) {
@ -3016,37 +3062,69 @@ mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *arg)
}
}
/* UTI_CPU_SET, PREFER_FWK, PREFER_LWK */
if (uti_cpu_set_str) {
if (!(env_cpuset = kmalloc(mask_size, GFP_KERNEL))) {
pr_err("%s: error: allocating env_cpuset\n",
__func__);
rc = -ENOMEM;
goto out;
}
if (cpulist_parse(uti_cpu_set_str, env_cpuset) < 0) {
pr_err("%s: error: cpulist_parse: %s\n",
__func__, uti_cpu_set_str);
rc = -EINVAL;
goto out;
}
//pr_cpumask("cpuset", cpuset);
//pr_cpumask("env_cpuset", env_cpuset);
if ((kattr->attr.flags & UTI_FLAG_PREFER_LWK)) {
cpumask_andnot(cpuset, cpuset, env_cpuset);
} else { /* Including PREFER_FWK and !PREFER_FWK */
cpumask_and(cpuset, cpuset, env_cpuset);
}
}
if (kattr->attr.flags &
(UTI_FLAG_EXCLUSIVE_CPU | UTI_FLAG_CPU_INTENSIVE)) {
uti_cpu_select(cpuset);
}
//pr_cpumask("final cpuset", cpuset);
/* Setaffinity cpuset */
rc = cpumask_weight(cpuset);
if (!rc); /* do nothing */
else if (kattr->attr.flags & UTI_FLAG_EXCLUSIVE_CPU) {
if (rc > 0) {
if ((rc = mcctrl_sched_setaffinity(0, cpuset))) {
pr_err("%s: error: setaffinity (%d)\n",
__func__, rc);
goto out;
}
} else {
pr_warn("%s: warning: cpuset is empty\n", __func__);
}
/* Assign real-time scheduler */
if (kattr->attr.flags & UTI_FLAG_HIGH_PRIORITY) {
struct sched_param sp;
mcctrl_sched_setaffinity(0, uti_cpu_select(cpuset));
sp.sched_priority = 1;
mcctrl_sched_setscheduler_nocheck(current, SCHED_FIFO, &sp);
rc = 1;
}
else if (kattr->attr.flags & UTI_FLAG_CPU_INTENSIVE) {
mcctrl_sched_setaffinity(0, uti_cpu_select(cpuset));
rc = 1;
}
else if (kattr->attr.flags & UTI_FLAG_HIGH_PRIORITY) {
struct sched_param sp;
mcctrl_sched_setaffinity(0, uti_cpu_select(cpuset));
sp.sched_priority = 1;
mcctrl_sched_setscheduler_nocheck(current, SCHED_FIFO, &sp);
rc = 1;
}
else if (kattr->attr.flags & UTI_FLAG_NON_COOPERATIVE) {
mcctrl_sched_setaffinity(0, uti_cpu_select(cpuset));
rc = 1;
}
else {
mcctrl_sched_setaffinity(0, cpuset);
if ((rc = mcctrl_sched_setscheduler_nocheck(current, SCHED_FIFO, &sp))) {
pr_err("%s: error: setscheduler_nocheck (%d)\n",
__func__, rc);
goto out;
}
}
rc = 0;
out:
kfree(cpuset);
kfree(env_cpuset);
return rc;
}

View File

@ -2943,7 +2943,15 @@ static long util_thread(struct thread_data_s *my_thread, unsigned long rp_rctx,
struct uti_attr_desc desc;
desc.phys_attr = pattr;
ioctl(fd, MCEXEC_UP_UTI_ATTR, &desc);
desc.uti_cpu_set_str = getenv("UTI_CPU_SET");
desc.uti_cpu_set_len = strlen(desc.uti_cpu_set_str) + 1;
if ((rc = ioctl(fd, MCEXEC_UP_UTI_ATTR, &desc))) {
fprintf(stderr, "%s: error: MCEXEC_UP_UTI_ATTR: %s\n",
__func__, strerror(errno));
rc = -errno;
goto out;
}
}
/* Start intercepting syscalls. Note that it dereferences pointers in uti_desc. */