From ab915f3331c7c32e99db23749c1a5e9c4d001785 Mon Sep 17 00:00:00 2001 From: Balazs Gerofi Date: Sun, 11 Jun 2017 17:07:47 +0900 Subject: [PATCH] mcctrl: clean up pagers for file objects to avoid memory leak --- executer/kernel/mcctrl/control.c | 4 +++ executer/kernel/mcctrl/mcctrl.h | 3 ++ executer/kernel/mcctrl/syscall.c | 49 ++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 966ae6aa..f5f19dc1 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -970,6 +970,8 @@ void mcctrl_put_per_proc_data(struct mcctrl_per_proc_data *ppd) ihk_ikc_spinlock_unlock(&ppd->wq_list_lock, flags); kfree(ppd); + + pager_remove_process(); } @@ -1468,6 +1470,8 @@ int mcexec_create_per_process_data(ihk_os_t os) return -EINVAL; } + pager_add_process(); + dprintk("%s: PID: %d, counter: %d\n", __FUNCTION__, ppd->pid, atomic_read(&ppd->refcount)); diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index 6c470773..0e75cb9b 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -344,6 +344,9 @@ int mcctrl_ikc_is_valid_thread(ihk_os_t os, int cpu); ihk_os_t osnum_to_os(int n); /* syscall.c */ +void pager_add_process(void); +void pager_remove_process(void); + 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 f09dc7a0..4285dcd6 100644 --- a/executer/kernel/mcctrl/syscall.c +++ b/executer/kernel/mcctrl/syscall.c @@ -760,6 +760,55 @@ struct pager { static DEFINE_SEMAPHORE(pager_sem); 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; + } + + ++pager_nr_processes; + + up(&pager_sem); +} + +void pager_remove_process(void) +{ + int error; + struct pager *pager_next, *pager; + error = down_interruptible(&pager_sem); + + if (error) { + return; + } + + --pager_nr_processes; + if (pager_nr_processes > 0) { + goto out; + } + + list_for_each_entry_safe(pager, pager_next, &pager_list, list) { + list_del(&pager->list); + + if (pager->rofile) { + fput(pager->rofile); + } + + if (pager->rwfile) { + fput(pager->rwfile); + } + + dprintk("%s: pager 0x%lx removed\n", __FUNCTION__, pager); + kfree(pager); + } + +out: + up(&pager_sem); +} + struct pager_create_result { uintptr_t handle; int maxprot;