From b87c06cbcba9f168b68c728ca42268a2f4ed8946 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Fri, 29 Jun 2018 13:49:36 +0900 Subject: [PATCH] mcctrl_ikc_send_wait: give possibility to use pre-allocated desc Change-Id: I1afbabe792648bbf2c5a9a38ebbfba8ea9060d06 --- executer/kernel/mcctrl/control.c | 4 ++-- executer/kernel/mcctrl/ikc.c | 29 ++++++++++++----------------- executer/kernel/mcctrl/mcctrl.h | 28 ++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 34f9d60e..564fb367 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -189,8 +189,8 @@ static long mcexec_prepare_image(ihk_os_t os, dprintk("# of sections: %d\n", pdesc->num_sections); dprintk("%p (%lx)\n", pdesc, isp.arg); - ret = mcctrl_ikc_send_wait(os, pdesc->cpu, &isp, 0, &free_ikc_pointers, - 3, pdesc, args, envs); + ret = mcctrl_ikc_send_wait(os, pdesc->cpu, &isp, 0, NULL, + &free_ikc_pointers, 3, pdesc, args, envs); if (ret < 0) { /* either send or remote prepare_process failed */ goto put_and_free_out; diff --git a/executer/kernel/mcctrl/ikc.c b/executer/kernel/mcctrl/ikc.c index c0b50a45..9eadda49 100644 --- a/executer/kernel/mcctrl/ikc.c +++ b/executer/kernel/mcctrl/ikc.c @@ -57,15 +57,6 @@ void mcctrl_os_read_write_cpu_response(ihk_os_t os, struct ikc_scd_packet *pisp); void mcctrl_eventfd(ihk_os_t os, struct ikc_scd_packet *pisp); -struct mcctrl_wakeup_desc { - int status; - int err; - wait_queue_head_t wq; - struct list_head chain; - int free_addrs_count; - void *free_addrs[]; -}; - /* Assumes usrdata->wakeup_descs_lock taken */ static void mcctrl_wakeup_desc_cleanup(ihk_os_t os, struct mcctrl_wakeup_desc *desc) @@ -109,16 +100,18 @@ static void mcctrl_wakeup_cb(ihk_os_t os, struct ikc_scd_packet *packet) } int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp, - long int timeout, int *do_frees, int free_addrs_count, ...) + long int timeout, struct mcctrl_wakeup_desc *desc, + int *do_frees, int free_addrs_count, ...) { int ret, i; + int alloc_desc = (desc == NULL); va_list ap; - struct mcctrl_wakeup_desc *desc; *do_frees = 1; - desc = kmalloc(sizeof(struct mcctrl_wakeup_desc) + - (free_addrs_count + 1) * sizeof(void *), - GFP_KERNEL); + if (alloc_desc) + desc = kmalloc(sizeof(struct mcctrl_wakeup_desc) + + (free_addrs_count + 1) * sizeof(void *), + GFP_KERNEL); if (!desc) { pr_warn("%s: Could not allocate wakeup descriptor", __func__); return -ENOMEM; @@ -128,9 +121,10 @@ int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp, for (i = 0; i < free_addrs_count; i++) { desc->free_addrs[i] = va_arg(ap, void*); } - desc->free_addrs[free_addrs_count] = desc; va_end(ap); - desc->free_addrs_count = free_addrs_count + 1; + if (alloc_desc) + desc->free_addrs[free_addrs_count++] = desc; + desc->free_addrs_count = free_addrs_count; init_waitqueue_head(&desc->wq); WRITE_ONCE(desc->err, 0); WRITE_ONCE(desc->status, 0); @@ -165,7 +159,8 @@ int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp, } ret = READ_ONCE(desc->err); - kfree(desc); + if (alloc_desc) + kfree(desc); return ret; } diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index fc51d51d..d1c37e26 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -369,9 +369,33 @@ int mcctrl_ikc_send(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp); int mcctrl_ikc_send_msg(ihk_os_t os, int cpu, int msg, int ref, unsigned long arg); int mcctrl_ikc_is_valid_thread(ihk_os_t os, int cpu); -/* ikc query-and-wait helper */ +struct mcctrl_wakeup_desc { + int status; + int err; + wait_queue_head_t wq; + struct list_head chain; + int free_addrs_count; + void *free_addrs[]; +}; + +/* ikc query-and-wait helper + * + * Arguments: + * - os, cpu and pisp as per mcctl_ikc_send() + * - timeout: time to wait for reply in ms + * - desc: if set, memory area to be used for desc. + * Care must be taken to leave room for variable-length array. + * - do_free: returns bool that specify if the caller should free + * its memory on error (e.g. if ikc_send failed in the first place, + * the reply has no chance of coming and memory should be free) + * Always true on success. + * - free_addrs_count & ...: addresses to kmalloc'd pointers that + * are referenced in the message and must be left intact if we + * abort to timeout/signal. + */ int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp, - long int timeout, int *do_frees, int free_addrs_count, ...); + long int timeout, struct mcctrl_wakeup_desc *desc, + int *do_frees, int free_addrs_count, ...); ihk_os_t osnum_to_os(int n);