From b4aecfd43ce56283f4464252b0288cb36f8804e8 Mon Sep 17 00:00:00 2001 From: Balazs Gerofi Date: Wed, 8 Feb 2017 07:49:45 +0900 Subject: [PATCH] partitioned execution: order by process start time --- executer/kernel/mcctrl/arch/x86_64/archdeps.c | 4 +- executer/kernel/mcctrl/control.c | 84 +++++++++++++++++-- executer/kernel/mcctrl/ikc.c | 1 + executer/kernel/mcctrl/mcctrl.h | 8 ++ 4 files changed, 91 insertions(+), 6 deletions(-) diff --git a/executer/kernel/mcctrl/arch/x86_64/archdeps.c b/executer/kernel/mcctrl/arch/x86_64/archdeps.c index 2179f160..0a96b397 100644 --- a/executer/kernel/mcctrl/arch/x86_64/archdeps.c +++ b/executer/kernel/mcctrl/arch/x86_64/archdeps.c @@ -64,7 +64,9 @@ reserve_user_space(struct mcctrl_usrdata *usrdata, unsigned long *startp, unsign unsigned long start = 0L; unsigned long end; - mutex_lock(&usrdata->reserve_lock); + if (mutex_lock_killable(&usrdata->reserve_lock) < 0) { + return -1; + } #define DESIRED_USER_END 0x800000000000 #define GAP_FOR_MCEXEC 0x008000000000UL diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 458d2de2..978fe707 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -508,6 +508,9 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg) cpumask_t cpus_used; cpumask_t cpus_to_use; struct mcctrl_per_proc_data *ppd; + struct process_list_item *pli; + struct process_list_item *pli_next = NULL; + struct process_list_item *pli_iter; if (!udp) { return -EINVAL; @@ -521,17 +524,14 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg) pe = &udp->part_exec; + mutex_lock(&pe->lock); + if (copy_from_user(&req, (void *)arg, sizeof(req))) { printk("%s: error copying user request\n", __FUNCTION__); ret = -EINVAL; goto put_and_unlock_out; } - mutex_lock(&pe->lock); - - memcpy(&cpus_used, &pe->cpus_used, sizeof(cpumask_t)); - memset(&cpus_to_use, 0, sizeof(cpus_to_use)); - /* First process to enter CPU partitioning */ if (pe->nr_processes == -1) { pe->nr_processes = req.nr_processes; @@ -555,7 +555,72 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg) pe->nr_processes, pe->nr_processes_left); + /* Wait for all processes */ + pli = kmalloc(sizeof(*pli), GFP_KERNEL); + if (!pli) { + printk("%s: error: allocating pli\n", __FUNCTION__); + goto put_and_unlock_out; + } + + pli->task = current; + pli->ready = 0; + init_waitqueue_head(&pli->pli_wq); + + pli_next = NULL; + /* Add ourself to the list in order of start time */ + list_for_each_entry(pli_iter, &pe->pli_list, list) { + if ((pli_iter->task->start_time.tv_sec > + current->start_time.tv_sec) || + ((pli_iter->task->start_time.tv_sec == + current->start_time.tv_sec) && + ((pli_iter->task->start_time.tv_nsec > + current->start_time.tv_nsec)))) { + pli_next = pli_iter; + break; + } + } + + /* Add in front of next */ + if (pli_next) { + list_add_tail(&pli->list, &pli_next->list); + } + else { + list_add_tail(&pli->list, &pe->pli_list); + } + pli_next = NULL; + + /* Last process? Wake up first in list */ + if (pe->nr_processes_left == 0) { + pli_next = list_first_entry(&pe->pli_list, + struct process_list_item, list); + list_del(&pli_next->list); + pli_next->ready = 1; + wake_up_interruptible(&pli_next->pli_wq); + /* Reset process counter */ + pe->nr_processes_left = pe->nr_processes; + } + + /* Wait for the rest if not the last or if the last but + * the woken process is different than the last */ + if (pe->nr_processes_left || (pli_next && pli_next != pli)) { + dprintk("%s: pid: %d, waiting in list\n", + __FUNCTION__, task_tgid_vnr(current)); + mutex_unlock(&pe->lock); + ret = wait_event_interruptible(pli->pli_wq, pli->ready); + mutex_lock(&pe->lock); + if (ret != 0) { + goto put_and_unlock_out; + } + dprintk("%s: pid: %d, woken up\n", + __FUNCTION__, task_tgid_vnr(current)); + } + + --pe->nr_processes_left; + kfree(pli); + cpus_to_assign = udp->cpu_info->n_cpus / req.nr_processes; + memcpy(&cpus_used, &pe->cpus_used, sizeof(cpumask_t)); + memset(&cpus_to_use, 0, sizeof(cpus_to_use)); /* Find the first unused CPU */ cpu = cpumask_next_zero(-1, &cpus_used); @@ -712,7 +777,16 @@ next_cpu: pe->nr_processes = -1; memset(&pe->cpus_used, 0, sizeof(pe->cpus_used)); } + /* Otherwise wake up next process in list */ + else { + pli_next = list_first_entry(&pe->pli_list, + struct process_list_item, list); + list_del(&pli_next->list); + pli_next->ready = 1; + wake_up_interruptible(&pli_next->pli_wq); + } + dprintk("%s: pid: %d, ret: 0\n", __FUNCTION__, task_tgid_vnr(current)); ret = 0; put_and_unlock_out: diff --git a/executer/kernel/mcctrl/ikc.c b/executer/kernel/mcctrl/ikc.c index 60174335..cbbcc4d1 100644 --- a/executer/kernel/mcctrl/ikc.c +++ b/executer/kernel/mcctrl/ikc.c @@ -305,6 +305,7 @@ int prepare_ikc_channels(ihk_os_t os) INIT_LIST_HEAD(&usrdata->node_topology_list); mutex_init(&usrdata->part_exec.lock); + INIT_LIST_HEAD(&usrdata->part_exec.pli_list); usrdata->part_exec.nr_processes = -1; return 0; diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index ee497163..6c470773 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -280,11 +280,19 @@ struct node_topology { struct list_head chain; }; +struct process_list_item { + int ready; + struct task_struct *task; + struct list_head list; + wait_queue_head_t pli_wq; +}; + struct mcctrl_part_exec { struct mutex lock; int nr_processes; int nr_processes_left; cpumask_t cpus_used; + struct list_head pli_list; }; #define CPU_LONGS (((NR_CPUS) + (BITS_PER_LONG) - 1) / (BITS_PER_LONG))