partitioned execution: order by process start time
This commit is contained in:
@ -64,7 +64,9 @@ reserve_user_space(struct mcctrl_usrdata *usrdata, unsigned long *startp, unsign
|
|||||||
unsigned long start = 0L;
|
unsigned long start = 0L;
|
||||||
unsigned long end;
|
unsigned long end;
|
||||||
|
|
||||||
mutex_lock(&usrdata->reserve_lock);
|
if (mutex_lock_killable(&usrdata->reserve_lock) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#define DESIRED_USER_END 0x800000000000
|
#define DESIRED_USER_END 0x800000000000
|
||||||
#define GAP_FOR_MCEXEC 0x008000000000UL
|
#define GAP_FOR_MCEXEC 0x008000000000UL
|
||||||
|
|||||||
@ -508,6 +508,9 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
|
|||||||
cpumask_t cpus_used;
|
cpumask_t cpus_used;
|
||||||
cpumask_t cpus_to_use;
|
cpumask_t cpus_to_use;
|
||||||
struct mcctrl_per_proc_data *ppd;
|
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) {
|
if (!udp) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -521,17 +524,14 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
|
|||||||
|
|
||||||
pe = &udp->part_exec;
|
pe = &udp->part_exec;
|
||||||
|
|
||||||
|
mutex_lock(&pe->lock);
|
||||||
|
|
||||||
if (copy_from_user(&req, (void *)arg, sizeof(req))) {
|
if (copy_from_user(&req, (void *)arg, sizeof(req))) {
|
||||||
printk("%s: error copying user request\n", __FUNCTION__);
|
printk("%s: error copying user request\n", __FUNCTION__);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto put_and_unlock_out;
|
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 */
|
/* First process to enter CPU partitioning */
|
||||||
if (pe->nr_processes == -1) {
|
if (pe->nr_processes == -1) {
|
||||||
pe->nr_processes = req.nr_processes;
|
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,
|
||||||
pe->nr_processes_left);
|
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;
|
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 */
|
/* Find the first unused CPU */
|
||||||
cpu = cpumask_next_zero(-1, &cpus_used);
|
cpu = cpumask_next_zero(-1, &cpus_used);
|
||||||
@ -712,7 +777,16 @@ next_cpu:
|
|||||||
pe->nr_processes = -1;
|
pe->nr_processes = -1;
|
||||||
memset(&pe->cpus_used, 0, sizeof(pe->cpus_used));
|
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;
|
ret = 0;
|
||||||
|
|
||||||
put_and_unlock_out:
|
put_and_unlock_out:
|
||||||
|
|||||||
@ -305,6 +305,7 @@ int prepare_ikc_channels(ihk_os_t os)
|
|||||||
INIT_LIST_HEAD(&usrdata->node_topology_list);
|
INIT_LIST_HEAD(&usrdata->node_topology_list);
|
||||||
|
|
||||||
mutex_init(&usrdata->part_exec.lock);
|
mutex_init(&usrdata->part_exec.lock);
|
||||||
|
INIT_LIST_HEAD(&usrdata->part_exec.pli_list);
|
||||||
usrdata->part_exec.nr_processes = -1;
|
usrdata->part_exec.nr_processes = -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -280,11 +280,19 @@ struct node_topology {
|
|||||||
struct list_head chain;
|
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 mcctrl_part_exec {
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
int nr_processes;
|
int nr_processes;
|
||||||
int nr_processes_left;
|
int nr_processes_left;
|
||||||
cpumask_t cpus_used;
|
cpumask_t cpus_used;
|
||||||
|
struct list_head pli_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CPU_LONGS (((NR_CPUS) + (BITS_PER_LONG) - 1) / (BITS_PER_LONG))
|
#define CPU_LONGS (((NR_CPUS) + (BITS_PER_LONG) - 1) / (BITS_PER_LONG))
|
||||||
|
|||||||
Reference in New Issue
Block a user