partitioned execution: order by process start time

This commit is contained in:
Balazs Gerofi
2017-02-08 07:49:45 +09:00
parent bf036f19f7
commit b4aecfd43c
4 changed files with 91 additions and 6 deletions

View File

@ -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

View File

@ -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:

View File

@ -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;

View File

@ -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))