mcctrl+mcexec: fix per-proc data allocation for fork()

This commit is contained in:
Balazs Gerofi
2016-09-02 15:04:35 +09:00
parent d550bced78
commit bfbc94dfb0
4 changed files with 61 additions and 56 deletions

View File

@@ -83,7 +83,6 @@ static long mcexec_prepare_image(ihk_os_t os,
long ret = 0; long ret = 0;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
struct mcctrl_per_proc_data *ppd = NULL; struct mcctrl_per_proc_data *ppd = NULL;
int i;
if (copy_from_user(&desc, udesc, if (copy_from_user(&desc, udesc,
sizeof(struct program_load_desc))) { sizeof(struct program_load_desc))) {
@@ -148,30 +147,15 @@ static long mcexec_prepare_image(ihk_os_t os,
goto free_out; goto free_out;
} }
ppd = kmalloc(sizeof(*ppd), GFP_KERNEL); ppd = mcctrl_get_per_proc_data(usrdata, task_tgid_vnr(current));
if (!ppd) { if (!ppd) {
printk("ERROR: allocating per process data\n"); printk("ERROR: no per process data for PID %d\n", task_tgid_vnr(current));
ret = -ENOMEM;
goto free_out;
}
ppd->pid = pdesc->pid;
ppd->rpgtable = pdesc->rpgtable;
INIT_LIST_HEAD(&ppd->wq_list);
INIT_LIST_HEAD(&ppd->wq_req_list);
INIT_LIST_HEAD(&ppd->wq_list_exact);
spin_lock_init(&ppd->wq_list_lock);
for (i = 0; i < MCCTRL_PER_THREAD_DATA_HASH_SIZE; ++i) {
INIT_LIST_HEAD(&ppd->per_thread_data_hash[i]);
rwlock_init(&ppd->per_thread_data_hash_lock[i]);
}
if (mcctrl_add_per_proc_data(usrdata, ppd->pid, ppd) < 0) {
printk("%s: error adding per process data\n", __FUNCTION__);
ret = -EINVAL; ret = -EINVAL;
goto free_out; goto free_out;
} }
/* Update rpgtable */
ppd->rpgtable = pdesc->rpgtable;
if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) + if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) +
sizeof(struct program_image_section) * desc.num_sections)) { sizeof(struct program_image_section) * desc.num_sections)) {
@@ -185,10 +169,6 @@ static long mcexec_prepare_image(ihk_os_t os,
ret = 0; ret = 0;
free_out: free_out:
/* Only free ppd if error */
if (ret != 0 && ppd) {
kfree(ppd);
}
kfree(args); kfree(args);
kfree(pdesc); kfree(pdesc);
kfree(envs); kfree(envs);
@@ -924,14 +904,53 @@ int mcexec_open_exec(ihk_os_t os, char * __user filename)
int retval; int retval;
int os_ind = ihk_host_os_get_index(os); int os_ind = ihk_host_os_get_index(os);
char *pathbuf, *fullpath; char *pathbuf, *fullpath;
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
struct mcctrl_per_proc_data *ppd = NULL;
int i;
if (os_ind < 0) { if (os_ind < 0) {
return EINVAL; return EINVAL;
} }
ppd = mcctrl_get_per_proc_data(usrdata, task_tgid_vnr(current));
if (!ppd) {
ppd = kmalloc(sizeof(*ppd), GFP_KERNEL);
if (!ppd) {
printk("ERROR: allocating per process data\n");
return -ENOMEM;
}
ppd->pid = task_tgid_vnr(current);
/*
* XXX: rpgtable will be updated in __do_in_kernel_syscall()
* under case __NR_munmap
*/
INIT_LIST_HEAD(&ppd->wq_list);
INIT_LIST_HEAD(&ppd->wq_req_list);
INIT_LIST_HEAD(&ppd->wq_list_exact);
spin_lock_init(&ppd->wq_list_lock);
for (i = 0; i < MCCTRL_PER_THREAD_DATA_HASH_SIZE; ++i) {
INIT_LIST_HEAD(&ppd->per_thread_data_hash[i]);
rwlock_init(&ppd->per_thread_data_hash_lock[i]);
}
if (mcctrl_add_per_proc_data(usrdata, ppd->pid, ppd) < 0) {
printk("%s: error adding per process data\n", __FUNCTION__);
retval = EINVAL;
goto out_free_ppd;
}
}
else {
/* Only deallocate in case of an error if we added it above */
ppd = NULL;
}
pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY); pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
if (!pathbuf) { if (!pathbuf) {
return ENOMEM; retval = ENOMEM;
goto out_error_drop_ppd;
} }
file = open_exec(filename); file = open_exec(filename);
@@ -963,7 +982,7 @@ int mcexec_open_exec(ihk_os_t os, char * __user filename)
break; break;
} }
} }
/* Add new exec file to the list */ /* Add new exec file to the list */
mcef->os = os; mcef->os = os;
mcef->pid = task_tgid_vnr(current); mcef->pid = task_tgid_vnr(current);
@@ -980,12 +999,15 @@ int mcexec_open_exec(ihk_os_t os, char * __user filename)
kfree(pathbuf); kfree(pathbuf);
return 0; return 0;
out_put_file: out_put_file:
fput(file); fput(file);
out_error_free: out_error_free:
kfree(pathbuf); kfree(pathbuf);
out_error_drop_ppd:
if (ppd) mcctrl_delete_per_proc_data(usrdata, ppd->pid);
out_free_ppd:
if (ppd) kfree(ppd);
return -retval; return -retval;
} }

View File

@@ -1566,36 +1566,18 @@ int __do_in_kernel_syscall(ihk_os_t os, struct ikc_scd_packet *packet)
/* Set new remote page table if not zero */ /* Set new remote page table if not zero */
if (sc->args[2]) { if (sc->args[2]) {
struct mcctrl_per_proc_data *ppd = NULL; struct mcctrl_per_proc_data *ppd = NULL;
int i;
ppd = kmalloc(sizeof(*ppd), GFP_ATOMIC); ppd = mcctrl_get_per_proc_data(usrdata, sc->args[3]);
if (!ppd) { if (unlikely(!ppd)) {
printk("ERROR: allocating per process data\n"); kprintf("%s: ERROR: no per-process structure for PID %d??\n",
error = -ENOMEM; __FUNCTION__, task_tgid_vnr(current));
goto out; return -1;
} }
ppd->pid = task_tgid_vnr(current);
ppd->rpgtable = sc->args[2]; ppd->rpgtable = sc->args[2];
INIT_LIST_HEAD(&ppd->wq_list);
INIT_LIST_HEAD(&ppd->wq_req_list);
INIT_LIST_HEAD(&ppd->wq_list_exact);
spin_lock_init(&ppd->wq_list_lock);
for (i = 0; i < MCCTRL_PER_THREAD_DATA_HASH_SIZE; ++i) { dprintk("%s: pid: %d, rpgtable: 0x%lx updated\n",
INIT_LIST_HEAD(&ppd->per_thread_data_hash[i]); __FUNCTION__, ppd->pid, ppd->rpgtable);
rwlock_init(&ppd->per_thread_data_hash_lock[i]);
}
if (mcctrl_add_per_proc_data(usrdata, ppd->pid, ppd) < 0) {
printk("%s: error adding per process data\n", __FUNCTION__);
error = -EBUSY;
kfree(ppd);
goto out;
}
dprintk("pid: %d, rpgtable: 0x%lx added\n",
ppd->pid, ppd->rpgtable);
} }
ret = clear_pte_range(sc->args[0], sc->args[1]); ret = clear_pte_range(sc->args[0], sc->args[1]);

View File

@@ -2088,7 +2088,6 @@ gettid_out:
/* Reinit signals and syscall threads */ /* Reinit signals and syscall threads */
init_sigaction(); init_sigaction();
init_worker_threads(fd);
__dprintf("pid(%d): signals and syscall threads OK\n", __dprintf("pid(%d): signals and syscall threads OK\n",
getpid()); getpid());
@@ -2102,6 +2101,8 @@ gettid_out:
goto fork_child_sync_pipe; goto fork_child_sync_pipe;
} }
init_worker_threads(fd);
fork_child_sync_pipe: fork_child_sync_pipe:
sem_post(&fs->sem); sem_post(&fs->sem);
if (fs->status) if (fs->status)

View File

@@ -1981,7 +1981,7 @@ retry_tid:
} }
/* In a single threaded process TID equals to PID */ /* In a single threaded process TID equals to PID */
settid(new, 0, cpuid, -1, 0, NULL); new->tid = newproc->pid;
new->vm->address_space->pids[0] = new->proc->pid; new->vm->address_space->pids[0] = new->proc->pid;
dkprintf("fork(): new pid: %d\n", new->proc->pid); dkprintf("fork(): new pid: %d\n", new->proc->pid);