From 7d9bbecd7a139a563ccf0a68be4cd0769fb21419 Mon Sep 17 00:00:00 2001 From: Balazs Gerofi Date: Mon, 11 Jul 2016 16:22:50 +0900 Subject: [PATCH] mcctrl: use IHK OS notifiers to establish/tear down syscall channels This patch eliminates the need for rmmod/insmod the mcctrl module every time an OS instance is rebooted. --- arch/x86/tools/mcreboot-smp-x86.sh.in | 11 +-- executer/kernel/mcctrl/binfmt_mcexec.c | 2 +- executer/kernel/mcctrl/driver.c | 124 +++++++++++++++---------- 3 files changed, 83 insertions(+), 54 deletions(-) diff --git a/arch/x86/tools/mcreboot-smp-x86.sh.in b/arch/x86/tools/mcreboot-smp-x86.sh.in index 9cb6131e..f1f6e985 100644 --- a/arch/x86/tools/mcreboot-smp-x86.sh.in +++ b/arch/x86/tools/mcreboot-smp-x86.sh.in @@ -87,11 +87,6 @@ if [ "$cpus" == "" ]; then if [ "$cpus" == "" ]; then echo "error: no available CPUs on NUMA node 0?"; exit; fi fi -# Remove delegator if loaded -if [ "`lsmod | grep mcctrl`" != "" ]; then - if ! rmmod mcctrl; then echo "error: removing mcctrl"; exit; fi -fi - # Remove mcoverlay if loaded if [ "$enable_mcoverlay" == "yes" ]; then if [ "`lsmod | grep mcoverlay`" != "" ]; then @@ -137,6 +132,11 @@ else fi fi +# Load mcctrl if not loaded +if [ "`lsmod | grep mcctrl`" == "" ]; then + if ! insmod ${KMODDIR}/mcctrl.ko; then echo "error: inserting mcctrl.ko"; exit; fi +fi + # Check for existing OS instance and destroy if [ -c /dev/mcos0 ]; then # Query CPU cores and memory of OS instance so that the same values are used as previously @@ -160,7 +160,6 @@ if ! ${SBINDIR}/ihkosctl 0 assign mem ${mem}; then echo "error: assign memory"; if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then echo "error: loading kernel image"; exit; fi if ! ${SBINDIR}/ihkosctl 0 kargs "hidos ksyslogd=${LOGMODE}"; then echo "error: setting kernel arguments"; exit; fi if ! ${SBINDIR}/ihkosctl 0 boot; then echo "error: booting"; exit; fi -if ! insmod ${KMODDIR}/mcctrl.ko; then echo "error: inserting mcctrl.ko"; exit; fi if ! chown `logname` /dev/mcd* /dev/mcos*; then echo "error: chowning device files"; exit; fi if [ "$enable_mcoverlay" == "yes" ]; then diff --git a/executer/kernel/mcctrl/binfmt_mcexec.c b/executer/kernel/mcctrl/binfmt_mcexec.c index 6d7d3717..971944b2 100644 --- a/executer/kernel/mcctrl/binfmt_mcexec.c +++ b/executer/kernel/mcctrl/binfmt_mcexec.c @@ -255,7 +255,7 @@ void __init binfmt_mcexec_init(void) insert_binfmt(&mcexec_format); } -void __exit binfmt_mcexec_exit(void) +void binfmt_mcexec_exit(void) { unregister_binfmt(&mcexec_format); } diff --git a/executer/kernel/mcctrl/driver.c b/executer/kernel/mcctrl/driver.c index 1b681eeb..b4ea568d 100644 --- a/executer/kernel/mcctrl/driver.c +++ b/executer/kernel/mcctrl/driver.c @@ -82,79 +82,109 @@ static struct ihk_os_user_call mcctrl_uc[OS_MAX_MINOR]; static ihk_os_t os[OS_MAX_MINOR]; -ihk_os_t -osnum_to_os(int n) +ihk_os_t osnum_to_os(int n) { return os[n]; } -static int __init mcctrl_init(void) +/* OS event notifier implementation */ +int mcctrl_os_boot_notifier(int os_index) { - int i; int rc; - rc = -ENOENT; - for(i = 0; i < OS_MAX_MINOR; i++){ - os[i] = ihk_host_find_os(i, NULL); - if (os[i]) { - printk("OS #%d found.\n", i); - rc = 0; - } - } - if(rc){ - printk("OS not found.\n"); - return rc; + os[os_index] = ihk_host_find_os(os_index, NULL); + if (!os[os_index]) { + printk("mcctrl: error: OS ID %d couldn't be found\n", os_index); + return -EINVAL; } - for(i = 0; i < OS_MAX_MINOR; i++){ - if (os[i]) { - if (prepare_ikc_channels(os[i]) != 0) { - printk("Preparing syscall channels failed.\n"); - os[i] = NULL; - } - } + if (prepare_ikc_channels(os[os_index]) != 0) { + printk("mcctrl: error: preparing IKC channels for OS %d\n", os_index); + + os[os_index] = NULL; + return -EFAULT; } + memcpy(mcctrl_uc + os_index, &mcctrl_uc_proto, sizeof mcctrl_uc_proto); + + rc = ihk_os_register_user_call_handlers(os[os_index], mcctrl_uc + os_index); + if (rc < 0) { + destroy_ikc_channels(os[os_index]); + printk("mcctrl: error: registering callbacks for OS %d\n", os_index); + + goto error_cleanup_channels; + } + + procfs_init(os_index); + printk("mcctrl: OS ID %d boot event handled\n", os_index); + + return 0; + +error_cleanup_channels: + destroy_ikc_channels(os[os_index]); + + os[os_index] = NULL; + return rc; +} + +int mcctrl_os_shutdown_notifier(int os_index) +{ + sysfsm_cleanup(os[os_index]); + free_topology_info(os[os_index]); + ihk_os_unregister_user_call_handlers(os[os_index], mcctrl_uc + os_index); + destroy_ikc_channels(os[os_index]); + procfs_exit(os_index); + + printk("mcctrl: OS ID %d shutdown event handled\n", os_index); + return 0; +} + +static struct ihk_os_notifier_ops mcctrl_os_notifier_ops = { + .boot = mcctrl_os_boot_notifier, + .shutdown = mcctrl_os_shutdown_notifier, +}; + +static struct ihk_os_notifier mcctrl_os_notifier = { + .ops = &mcctrl_os_notifier_ops, +}; + +static int __init mcctrl_init(void) +{ + int ret = 0; + #ifndef DO_USER_MODE mcctrl_syscall_init(); #endif rus_page_hash_init(); - for(i = 0; i < OS_MAX_MINOR; i++){ - if (os[i]) { - memcpy(mcctrl_uc + i, &mcctrl_uc_proto, sizeof mcctrl_uc_proto); - rc = ihk_os_register_user_call_handlers(os[i], mcctrl_uc + i); - if(rc < 0){ - destroy_ikc_channels(os[i]); - os[i] = NULL; - } - procfs_init(i); - } - } - binfmt_mcexec_init(); - return 0; + if ((ret = ihk_host_register_os_notifier(&mcctrl_os_notifier)) != 0) { + printk("mcctrl: error: registering OS notifier\n"); + goto error; + } + + printk("mcctrl: initialized successfully.\n"); + return ret; + +error: + binfmt_mcexec_exit(); + rus_page_hash_put_pages(); + + return ret; } static void __exit mcctrl_exit(void) { - int i; - - binfmt_mcexec_exit(); - printk("mcctrl: unregistered.\n"); - for(i = 0; i < OS_MAX_MINOR; i++){ - if(os[i]){ - sysfsm_cleanup(os[i]); - free_topology_info(os[i]); - ihk_os_unregister_user_call_handlers(os[i], mcctrl_uc + i); - destroy_ikc_channels(os[i]); - procfs_exit(i); - } + if (ihk_host_deregister_os_notifier(&mcctrl_os_notifier) != 0) { + printk("mcctrl: warning: failed to deregister OS notifier??\n"); } + binfmt_mcexec_exit(); rus_page_hash_put_pages(); + + printk("mcctrl: unregistered.\n"); } MODULE_LICENSE("GPL v2");