diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 542306aa..5b4483fb 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -1133,6 +1133,17 @@ int mcexec_syscall(struct mcctrl_usrdata *ud, struct ikc_scd_packet *packet) int pid = packet->pid; unsigned long flags; struct mcctrl_per_proc_data *ppd; + int ret; + + /* Handle requests that do not need the proxy process right now */ + ret = __do_in_kernel_irq_syscall(ud->os, packet); + if (ret != -ENOSYS) { + ihk_ikc_release_packet((struct ihk_ikc_free_packet *)packet, + (ud->ikc2linux[smp_processor_id()] ? + ud->ikc2linux[smp_processor_id()] : + ud->ikc2linux[0])); + return ret; + } /* Get a reference to per-process structure */ ppd = mcctrl_get_per_proc_data(ud, pid); diff --git a/executer/kernel/mcctrl/driver.c b/executer/kernel/mcctrl/driver.c index 61b66e6a..ae735c32 100644 --- a/executer/kernel/mcctrl/driver.c +++ b/executer/kernel/mcctrl/driver.c @@ -177,6 +177,7 @@ int mcctrl_os_shutdown_notifier(int os_index) mdelay(200); } + pager_cleanup(); sysfsm_cleanup(os[os_index]); free_topology_info(os[os_index]); ihk_os_unregister_user_call_handlers(os[os_index], mcctrl_uc + os_index); diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index 8172e38b..06e099ac 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -420,7 +420,9 @@ extern void (*mcctrl_zap_page_range)(struct vm_area_struct *vma, /* syscall.c */ void pager_add_process(void); void pager_remove_process(struct mcctrl_per_proc_data *ppd); +void pager_cleanup(void); +int __do_in_kernel_irq_syscall(ihk_os_t os, struct ikc_scd_packet *packet); int __do_in_kernel_syscall(ihk_os_t os, struct ikc_scd_packet *packet); int mcctrl_add_per_proc_data(struct mcctrl_usrdata *ud, int pid, struct mcctrl_per_proc_data *ppd); diff --git a/executer/kernel/mcctrl/syscall.c b/executer/kernel/mcctrl/syscall.c index cfba8386..78b65300 100644 --- a/executer/kernel/mcctrl/syscall.c +++ b/executer/kernel/mcctrl/syscall.c @@ -64,6 +64,7 @@ #endif +static long pager_call_irq(ihk_os_t os, struct syscall_request *req); static long pager_call(ihk_os_t os, struct syscall_request *req); #ifdef SC_DEBUG @@ -962,35 +963,28 @@ struct pager { off_t map_off; }; -/* - * for linux v2.6.35 or prior - */ -#ifndef DEFINE_SEMAPHORE -#define DEFINE_SEMAPHORE(...) DECLARE_MUTEX(__VA_ARGS__) -#endif -static DEFINE_SEMAPHORE(pager_sem); +static DEFINE_SPINLOCK(pager_lock); static struct list_head pager_list = LIST_HEAD_INIT(pager_list); int pager_nr_processes = 0; void pager_add_process(void) { - int error; - error = down_interruptible(&pager_sem); - if (error) { - return; - } + unsigned long flags; + + spin_lock_irqsave(&pager_lock, flags); ++pager_nr_processes; - up(&pager_sem); + spin_unlock_irqrestore(&pager_lock, flags); } void pager_remove_process(struct mcctrl_per_proc_data *ppd) { int error; struct pager *pager_next, *pager; + unsigned long flags; if (in_atomic() || in_interrupt()) { printk("%s: WARNING: shouldn't be called in IRQ context..\n", @@ -1015,15 +1009,17 @@ void pager_remove_process(struct mcctrl_per_proc_data *ppd) /* Clean up global pagers for regular file mappings if this * was the last process */ - error = down_interruptible(&pager_sem); - if (error) { - return; - } - + spin_lock_irqsave(&pager_lock, flags); --pager_nr_processes; - if (pager_nr_processes > 0) { - goto out; - } + spin_unlock_irqrestore(&pager_lock, flags); +} + +void pager_cleanup(void) +{ + unsigned long flags; + struct pager *pager_next, *pager; + + spin_lock_irqsave(&pager_lock, flags); list_for_each_entry_safe(pager, pager_next, &pager_list, list) { list_del(&pager->list); @@ -1040,8 +1036,7 @@ void pager_remove_process(struct mcctrl_per_proc_data *ppd) kfree(pager); } -out: - up(&pager_sem); + spin_unlock_irqrestore(&pager_lock, flags); } struct pager_create_result { @@ -1108,6 +1103,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa) uintptr_t phys; struct kstat st; int mf_flags = 0; + unsigned long irqflags; dprintk("pager_req_create(%d,%lx)\n", fd, (long)result_pa); @@ -1156,12 +1152,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa) } for (;;) { - error = down_interruptible(&pager_sem); - if (error) { - error = -EINTR; - printk("pager_req_create(%d,%lx):signaled. %d\n", fd, (long)result_pa, error); - goto out; - } + spin_lock_irqsave(&pager_lock, irqflags); list_for_each_entry(pager, &pager_list, list) { if (pager->inode == inode) { @@ -1180,7 +1171,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa) { char *pathbuf, *fullpath; - pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); + pathbuf = kmalloc(PATH_MAX, GFP_ATOMIC); if (pathbuf) { fullpath = d_path(&file->f_path, pathbuf, PATH_MAX); if (!IS_ERR(fullpath)) { @@ -1206,7 +1197,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa) break; } - up(&pager_sem); + spin_unlock_irqrestore(&pager_lock, irqflags); newpager = kzalloc(sizeof(*newpager), GFP_ATOMIC); if (!newpager) { @@ -1226,7 +1217,7 @@ found: get_file(file); pager->rofile = file; } - up(&pager_sem); + spin_unlock_irqrestore(&pager_lock, irqflags); phys = ihk_device_map_memory(dev, result_pa, sizeof(*resp)); resp = ihk_device_map_virtual(dev, phys, sizeof(*resp), NULL, 0); @@ -1271,14 +1262,11 @@ static int pager_req_release(ihk_os_t os, uintptr_t handle, int unref) int error; struct pager *p; struct pager *free_pager = NULL; + unsigned long flags; dprintk("pager_req_relase(%p,%lx,%d)\n", os, handle, unref); - error = down_interruptible(&pager_sem); - if (error) { - printk("pager_req_relase(%p,%lx,%d):signaled. %d\n", os, handle, unref, error); - goto out; - } + spin_lock_irqsave(&pager_lock, flags); error = -EBADF; list_for_each_entry(p, &pager_list, list) { @@ -1293,7 +1281,7 @@ static int pager_req_release(ihk_os_t os, uintptr_t handle, int unref) } } - up(&pager_sem); + spin_unlock_irqrestore(&pager_lock, flags); if (error) { printk("pager_req_relase(%p,%lx,%d):pager not found. %d\n", os, handle, unref, error); @@ -1325,15 +1313,11 @@ static int pager_req_read(ihk_os_t os, uintptr_t handle, off_t off, size_t size, ihk_device_t dev = ihk_os_to_dev(os); void *buf = NULL; loff_t pos; + unsigned long flags; dprintk("pager_req_read(%lx,%lx,%lx,%lx)\n", handle, off, size, rpa); - ss = down_interruptible(&pager_sem); - if (ss) { - pr_debug("%s(%lx,%lx,%lx,%lx): signaled. %ld\n", - __func__, handle, off, size, rpa, ss); - goto out; - } + spin_lock_irqsave(&pager_lock, flags); list_for_each_entry(pager, &pager_list, list) { if ((uintptr_t)pager == handle) { @@ -1342,7 +1326,7 @@ static int pager_req_read(ihk_os_t os, uintptr_t handle, off_t off, size_t size, break; } } - up(&pager_sem); + spin_unlock_irqrestore(&pager_lock, flags); if (!file) { ss = -EBADF; @@ -1416,14 +1400,11 @@ static int pager_req_write(ihk_os_t os, uintptr_t handle, off_t off, size_t size loff_t pos; loff_t fsize; size_t len; + unsigned long flags; dprintk("pager_req_write(%lx,%lx,%lx,%lx)\n", handle, off, size, rpa); - ss = down_interruptible(&pager_sem); - if (ss) { - printk("pager_req_write(%lx,%lx,%lx,%lx): signaled. %ld\n", handle, off, size, rpa, ss); - goto out; - } + spin_lock_irqsave(&pager_lock, flags); list_for_each_entry(pager, &pager_list, list) { if ((uintptr_t)pager == handle) { @@ -1434,7 +1415,7 @@ static int pager_req_write(ihk_os_t os, uintptr_t handle, off_t off, size_t size if (file) { get_file(file); } - up(&pager_sem); + spin_unlock_irqrestore(&pager_lock, flags); if (!file) { ss = -EBADF; @@ -1829,12 +1810,6 @@ full: return cnt; } -static long pager_call(ihk_os_t os, struct syscall_request *req) -{ - long ret; - - dprintk("pager_call(%#lx)\n", req->args[0]); - switch (req->args[0]) { #define PAGER_REQ_CREATE 0x0001 #define PAGER_REQ_RELEASE 0x0002 #define PAGER_REQ_READ 0x0003 @@ -1843,13 +1818,28 @@ static long pager_call(ihk_os_t os, struct syscall_request *req) #define PAGER_REQ_PFN 0x0006 #define PAGER_REQ_UNMAP 0x0007 #define PAGER_REQ_MLOCK_LIST 0x0008 - case PAGER_REQ_CREATE: - ret = pager_req_create(os, req->args[1], req->args[2]); - break; +static long pager_call_irq(ihk_os_t os, struct syscall_request *req) +{ + long ret = -ENOSYS; + switch (req->args[0]) { case PAGER_REQ_RELEASE: ret = pager_req_release(os, req->args[1], req->args[2]); break; + } + + return ret; +} + +static long pager_call(ihk_os_t os, struct syscall_request *req) +{ + long ret; + + dprintk("pager_call(%#lx)\n", req->args[0]); + switch (req->args[0]) { + case PAGER_REQ_CREATE: + ret = pager_req_create(os, req->args[1], req->args[2]); + break; case PAGER_REQ_READ: ret = pager_req_read(os, req->args[1], req->args[2], req->args[3], req->args[4]); @@ -1871,6 +1861,7 @@ static long pager_call(ihk_os_t os, struct syscall_request *req) case PAGER_REQ_UNMAP: ret = pager_req_unmap(os, req->args[1]); break; + case PAGER_REQ_MLOCK_LIST: ret = pager_req_mlock_list(os, (unsigned long) req->args[1], (unsigned long) req->args[2], @@ -2138,6 +2129,27 @@ fail: #define SCHED_CHECK_SAME_OWNER 0x01 #define SCHED_CHECK_ROOT 0x02 +int __do_in_kernel_irq_syscall(ihk_os_t os, struct ikc_scd_packet *packet) +{ + struct syscall_request *sc = &packet->req; + int ret; + + switch (sc->number) { + case __NR_mmap: + ret = pager_call_irq(os, sc); + break; + default: + ret = -ENOSYS; + } + + if (ret == -ENOSYS) + return -ENOSYS; + + __return_syscall(os, packet, ret, 0); + + return 0; +} + int __do_in_kernel_syscall(ihk_os_t os, struct ikc_scd_packet *packet) { struct syscall_request *sc = &packet->req; diff --git a/kernel/process.c b/kernel/process.c index cbb10ed0..4b6593a2 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -2510,9 +2510,6 @@ free_all_process_memory_range(struct process_vm *vm) range = rb_entry(node, struct vm_range, vm_rb_node); next = rb_next(node); - if (range->memobj) { - range->memobj->flags |= MF_HOST_RELEASED; - } error = free_process_memory_range(vm, range); if (error) { ekprintf("free_process_memory(%p):"