diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index 9615352a..e590fd22 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -251,7 +251,6 @@ enum perf_ctrl_type { struct perf_ctrl_desc { enum perf_ctrl_type ctrl_type; - int status; union { /* for SET, GET */ struct { diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 564fb367..3700c3d0 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -2009,58 +2009,65 @@ long mcctrl_perf_num(ihk_os_t os, unsigned long arg) return 0; } +struct mcctrl_perf_ctrl_desc { + struct perf_ctrl_desc desc; + struct mcctrl_wakeup_desc wakeup; + void *addrs[1]; +}; +#define wakeup_desc_of_perf_desc(_desc) \ + (&container_of((_desc), struct mcctrl_perf_ctrl_desc, desc)->wakeup) + long mcctrl_perf_set(ihk_os_t os, struct ihk_perf_event_attr *__user arg) { struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct ikc_scd_packet isp; - struct perf_ctrl_desc *perf_desc = NULL; + struct perf_ctrl_desc *perf_desc; struct ihk_perf_event_attr attr; struct ihk_cpu_info *info = ihk_os_get_cpu_info(os); int ret = 0; int i = 0, j = 0; + int need_free; for (i = 0; i < usrdata->perf_event_num; i++) { - if (copy_from_user(&attr, &arg[i], sizeof(struct ihk_perf_event_attr))) { - printk("%s: error: copying ihk_perf_event_attr from user\n", - __FUNCTION__); + ret = copy_from_user(&attr, &arg[i], + sizeof(struct ihk_perf_event_attr)); + if (ret) { + pr_err("%s: error: copying ihk_perf_event_attr from user\n", + __func__); return -EINVAL; } - for (j = 0; j < info->n_cpus; j++) { - perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL); - if (!perf_desc) { - printk("%s: error: allocating perf_ctrl_desc\n", - __FUNCTION__); - return -ENOMEM; - } - memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc)); - - perf_desc->ctrl_type = PERF_CTRL_SET; - perf_desc->status = 0; - perf_desc->target_cntr = i; - perf_desc->config = attr.config; - perf_desc->exclude_kernel = attr.exclude_kernel; - perf_desc->exclude_user = attr.exclude_user; - - memset(&isp, '\0', sizeof(struct ikc_scd_packet)); - isp.msg = SCD_MSG_PERF_CTRL; - isp.arg = virt_to_phys(perf_desc); - - if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) { - printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret); - kfree(perf_desc); - return -EINVAL; - } - - ret = wait_event_interruptible(perfctrlq, perf_desc->status); - if (ret < 0) { - printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret); - kfree(perf_desc); - return -EINVAL; - } - - kfree(perf_desc); + perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc), + GFP_KERNEL); + if (!perf_desc) { + return -ENOMEM; } + memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc)); + + perf_desc->ctrl_type = PERF_CTRL_SET; + perf_desc->target_cntr = i; + perf_desc->config = attr.config; + perf_desc->exclude_kernel = attr.exclude_kernel; + perf_desc->exclude_user = attr.exclude_user; + + memset(&isp, '\0', sizeof(struct ikc_scd_packet)); + isp.msg = SCD_MSG_PERF_CTRL; + isp.arg = virt_to_phys(perf_desc); + + for (j = 0; j < info->n_cpus; j++) { + ret = mcctrl_ikc_send_wait(os, j, &isp, 0, + wakeup_desc_of_perf_desc(perf_desc), + &need_free, 1, perf_desc); + if (ret < 0) { + pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n", + __func__, ret); + if (need_free) + kfree(perf_desc); + return -EINVAL; + } + } + + kfree(perf_desc); } return usrdata->perf_event_num; @@ -2070,48 +2077,46 @@ long mcctrl_perf_get(ihk_os_t os, unsigned long *__user arg) { struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct ikc_scd_packet isp; - struct perf_ctrl_desc *perf_desc = NULL; + struct perf_ctrl_desc *perf_desc; struct ihk_cpu_info *info = ihk_os_get_cpu_info(os); unsigned long value_sum = 0; int ret = 0; int i = 0, j = 0; + int need_free; for (i = 0; i < usrdata->perf_event_num; i++) { - for (j = 0; j < info->n_cpus; j++) { - perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL); - if (!perf_desc) { - printk("%s: error: allocating perf_ctrl_desc\n", - __FUNCTION__); - return -ENOMEM; - } - memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc)); - - perf_desc->ctrl_type = PERF_CTRL_GET; - perf_desc->status = 0; - perf_desc->target_cntr = i; - - memset(&isp, '\0', sizeof(struct ikc_scd_packet)); - isp.msg = SCD_MSG_PERF_CTRL; - isp.arg = virt_to_phys(perf_desc); - - if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) { - printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret); - kfree(perf_desc); - return -EINVAL; - } - - ret = wait_event_interruptible(perfctrlq, perf_desc->status); - if (ret < 0) { - printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret); - kfree(perf_desc); - return -EINVAL; - } - value_sum += perf_desc->read_value; - kfree(perf_desc); + perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc), + GFP_KERNEL); + if (!perf_desc) { + return -ENOMEM; } + memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc)); + + perf_desc->ctrl_type = PERF_CTRL_GET; + perf_desc->target_cntr = i; + + memset(&isp, '\0', sizeof(struct ikc_scd_packet)); + isp.msg = SCD_MSG_PERF_CTRL; + isp.arg = virt_to_phys(perf_desc); + + for (j = 0; j < info->n_cpus; j++) { + ret = mcctrl_ikc_send_wait(os, j, &isp, 0, + wakeup_desc_of_perf_desc(perf_desc), + &need_free, 1, perf_desc); + if (ret < 0) { + pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n", + __func__, ret); + if (need_free) + kfree(perf_desc); + return -EINVAL; + } + + value_sum += perf_desc->read_value; + } + kfree(perf_desc); if (copy_to_user(&arg[i], &value_sum, sizeof(unsigned long))) { printk("%s: error: copying read_value to user\n", - __FUNCTION__); + __func__); return -EINVAL; } value_sum = 0; @@ -2124,46 +2129,44 @@ long mcctrl_perf_enable(ihk_os_t os) { struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct ikc_scd_packet isp; - struct perf_ctrl_desc *perf_desc = NULL; + struct perf_ctrl_desc *perf_desc; struct ihk_cpu_info *info = ihk_os_get_cpu_info(os); unsigned int cntr_mask = 0; int ret = 0; int i = 0, j = 0; + int need_free; for (i = 0; i < usrdata->perf_event_num; i++) { cntr_mask |= 1 << i; } - for (j = 0; j < info->n_cpus; j++) { - perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL); - if (!perf_desc) { - printk("%s: error: allocating perf_ctrl_desc\n", - __FUNCTION__); - return -ENOMEM; - } - memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc)); - - perf_desc->ctrl_type = PERF_CTRL_ENABLE; - perf_desc->status = 0; - perf_desc->target_cntr_mask = cntr_mask; - - memset(&isp, '\0', sizeof(struct ikc_scd_packet)); - isp.msg = SCD_MSG_PERF_CTRL; - isp.arg = virt_to_phys(perf_desc); - - if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) { - printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret); - kfree(perf_desc); - return -EINVAL; - } - - ret = wait_event_interruptible(perfctrlq, perf_desc->status); - if (ret < 0) { - printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret); - kfree(perf_desc); - return -EINVAL; - } - kfree(perf_desc); + perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc), GFP_KERNEL); + if (!perf_desc) { + return -ENOMEM; } + memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc)); + + perf_desc->ctrl_type = PERF_CTRL_ENABLE; + perf_desc->target_cntr_mask = cntr_mask; + + memset(&isp, '\0', sizeof(struct ikc_scd_packet)); + isp.msg = SCD_MSG_PERF_CTRL; + isp.arg = virt_to_phys(perf_desc); + + for (j = 0; j < info->n_cpus; j++) { + ret = mcctrl_ikc_send_wait(os, j, &isp, 0, + wakeup_desc_of_perf_desc(perf_desc), + &need_free, 1, perf_desc); + + if (ret < 0) { + pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n", + __func__, ret); + if (need_free) + kfree(perf_desc); + return -EINVAL; + } + + } + kfree(perf_desc); return 0; } @@ -2172,46 +2175,43 @@ long mcctrl_perf_disable(ihk_os_t os) { struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct ikc_scd_packet isp; - struct perf_ctrl_desc *perf_desc = NULL; + struct perf_ctrl_desc *perf_desc; struct ihk_cpu_info *info = ihk_os_get_cpu_info(os); unsigned int cntr_mask = 0; int ret = 0; int i = 0, j = 0; + int need_free; for (i = 0; i < usrdata->perf_event_num; i++) { cntr_mask |= 1 << i; } - for (j = 0; j < info->n_cpus; j++) { - perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL); - if (!perf_desc) { - printk("%s: error: allocating perf_ctrl_desc\n", - __FUNCTION__); - return -ENOMEM; - } - memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc)); - - perf_desc->ctrl_type = PERF_CTRL_DISABLE; - perf_desc->status = 0; - perf_desc->target_cntr_mask = cntr_mask; - - memset(&isp, '\0', sizeof(struct ikc_scd_packet)); - isp.msg = SCD_MSG_PERF_CTRL; - isp.arg = virt_to_phys(perf_desc); - - if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) { - printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret); - kfree(perf_desc); - return -EINVAL; - } - - ret = wait_event_interruptible(perfctrlq, perf_desc->status); - if (ret < 0) { - printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret); - kfree(perf_desc); - return -EINVAL; - } - kfree(perf_desc); + perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc), GFP_KERNEL); + if (!perf_desc) { + return -ENOMEM; } + memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc)); + + perf_desc->ctrl_type = PERF_CTRL_DISABLE; + perf_desc->target_cntr_mask = cntr_mask; + + memset(&isp, '\0', sizeof(struct ikc_scd_packet)); + isp.msg = SCD_MSG_PERF_CTRL; + isp.arg = virt_to_phys(perf_desc); + + for (j = 0; j < info->n_cpus; j++) { + ret = mcctrl_ikc_send_wait(os, j, &isp, 0, + wakeup_desc_of_perf_desc(perf_desc), + &need_free, 1, perf_desc); + if (ret < 0) { + pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n", + __func__, ret); + if (need_free) + kfree(perf_desc); + return -EINVAL; + } + + } + kfree(perf_desc); return 0; } @@ -2223,15 +2223,6 @@ long mcctrl_perf_destroy(ihk_os_t os) return 0; } -void mcctrl_perf_ack(ihk_os_t os, struct ikc_scd_packet *packet) -{ - struct perf_ctrl_desc *perf_desc = phys_to_virt(packet->arg); - - perf_desc->status = 1; - wake_up_interruptible(&perfctrlq); - -} - /* Compose LWK-specific rusage structure */ long mcctrl_getrusage(ihk_os_t ihk_os, struct mcctrl_ioctl_getrusage_desc *__user _desc) { diff --git a/executer/kernel/mcctrl/ikc.c b/executer/kernel/mcctrl/ikc.c index 9eadda49..acf88860 100644 --- a/executer/kernel/mcctrl/ikc.c +++ b/executer/kernel/mcctrl/ikc.c @@ -52,7 +52,6 @@ static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys, struct ihk_ikc_channel_desc *c); int mcexec_syscall(struct mcctrl_usrdata *ud, struct ikc_scd_packet *packet); void sig_done(unsigned long arg, int err); -void mcctrl_perf_ack(ihk_os_t os, struct ikc_scd_packet *packet); 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); @@ -179,6 +178,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, break; case SCD_MSG_PREPARE_PROCESS_ACKED: + case SCD_MSG_PERF_ACK: mcctrl_wakeup_cb(__os, pisp); break; @@ -216,10 +216,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, get_vdso_info(__os, pisp->arg); break; - case SCD_MSG_PERF_ACK: - mcctrl_perf_ack(__os, pisp); - break; - case SCD_MSG_CPU_RW_REG_RESP: mcctrl_os_read_write_cpu_response(__os, pisp); break; diff --git a/kernel/host.c b/kernel/host.c index 24f8af7c..d34a0346 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -731,6 +731,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, pckt.msg = SCD_MSG_PERF_ACK; pckt.err = 0; pckt.arg = packet->arg; + pckt.reply = packet->reply; ihk_ikc_send(resp_channel, &pckt, 0); ret = 0; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 111f730e..e18b13d5 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -518,7 +518,6 @@ enum perf_ctrl_type { struct perf_ctrl_desc { enum perf_ctrl_type ctrl_type; - int status; union { /* for SET, GET */ struct {