From 69cca92b8e8460b98851b6104e6804e08548d609 Mon Sep 17 00:00:00 2001 From: Chao Bi Date: Tue, 24 Jul 2018 14:28:20 +0800 Subject: [PATCH] soc: qcom: hab: benchmark cross VM schdule latency Develop a mechanism to measure the latency of cross-vm scheduling. It makes use of mpm_timer and leverage hab driver to record the time when previous vm is scheduled out and when next vm is schduled in, and pass these values to habtest to calculate the latency of schduling. Change-Id: I0051d5a42979826b8e249ac704fcc7ed87d8d581 Signed-off-by: Chao Bi --- drivers/soc/qcom/hab/hab.c | 8 ++++++++ drivers/soc/qcom/hab/hab.h | 4 ++++ drivers/soc/qcom/hab/hab_msg.c | 16 ++++++++++++++++ drivers/soc/qcom/hab/qvm_comm.c | 12 ++++++++++++ include/linux/habmm.h | 31 +++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+) diff --git a/drivers/soc/qcom/hab/hab.c b/drivers/soc/qcom/hab/hab.c index ebe7dfc4a5b6..f239c5811e47 100644 --- a/drivers/soc/qcom/hab/hab.c +++ b/drivers/soc/qcom/hab/hab.c @@ -565,6 +565,14 @@ long hab_vchan_send(struct uhab_context *ctx, sizeof(struct habmm_xing_vm_stat)); return -EINVAL; } + } else if (flags & HABMM_SOCKET_XVM_SCHE_TEST) { + HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_SCHE_MSG); + } else if (flags & HABMM_SOCKET_XVM_SCHE_TEST_ACK) { + HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_SCHE_MSG_ACK); + } else if (flags & HABMM_SOCKET_XVM_SCHE_RESULT_REQ) { + HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_SCHE_RESULT_REQ); + } else if (flags & HABMM_SOCKET_XVM_SCHE_RESULT_RSP) { + HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_SCHE_RESULT_RSP); } else { HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_MSG); } diff --git a/drivers/soc/qcom/hab/hab.h b/drivers/soc/qcom/hab/hab.h index cbc049e89d63..fbcbf8b4bc86 100644 --- a/drivers/soc/qcom/hab/hab.h +++ b/drivers/soc/qcom/hab/hab.h @@ -58,6 +58,10 @@ enum hab_payload_type { HAB_PAYLOAD_TYPE_PROFILE, HAB_PAYLOAD_TYPE_CLOSE, HAB_PAYLOAD_TYPE_INIT_CANCEL, + HAB_PAYLOAD_TYPE_SCHE_MSG, + HAB_PAYLOAD_TYPE_SCHE_MSG_ACK, + HAB_PAYLOAD_TYPE_SCHE_RESULT_REQ, + HAB_PAYLOAD_TYPE_SCHE_RESULT_RSP, HAB_PAYLOAD_TYPE_MAX, }; #define LOOPBACK_DOM 0xFF diff --git a/drivers/soc/qcom/hab/hab_msg.c b/drivers/soc/qcom/hab/hab_msg.c index 61e658954312..8a52aa9634a9 100644 --- a/drivers/soc/qcom/hab/hab_msg.c +++ b/drivers/soc/qcom/hab/hab_msg.c @@ -183,6 +183,7 @@ int hab_msg_recv(struct physical_channel *pchan, struct virtual_channel *vchan = NULL; struct export_desc *exp_desc; struct timeval tv; + unsigned long long rx_mpm_tv; /* get the local virtual channel if it isn't an open message */ if (payload_type != HAB_PAYLOAD_TYPE_INIT && @@ -239,6 +240,8 @@ int hab_msg_recv(struct physical_channel *pchan, switch (payload_type) { case HAB_PAYLOAD_TYPE_MSG: + case HAB_PAYLOAD_TYPE_SCHE_RESULT_REQ: + case HAB_PAYLOAD_TYPE_SCHE_RESULT_RSP: message = hab_msg_alloc(pchan, sizebytes); if (!message) break; @@ -328,6 +331,19 @@ int hab_msg_recv(struct physical_channel *pchan, } break; + case HAB_PAYLOAD_TYPE_SCHE_MSG: + case HAB_PAYLOAD_TYPE_SCHE_MSG_ACK: + rx_mpm_tv = msm_timer_get_sclk_ticks(); + /* pull down the incoming data */ + message = hab_msg_alloc(pchan, sizebytes); + if (!message) + pr_err("failed to allocate msg Arrived msg will be lost\n"); + else { + ((unsigned long long *)message->data)[0] = rx_mpm_tv; + hab_msg_queue(vchan, message); + } + break; + default: pr_err("unknown msg received, payload type %d, vchan id %x, sizebytes %zx, session %d\n", payload_type, vchan_id, sizebytes, session_id); diff --git a/drivers/soc/qcom/hab/qvm_comm.c b/drivers/soc/qcom/hab/qvm_comm.c index cce24d72c28e..0b3560219728 100644 --- a/drivers/soc/qcom/hab/qvm_comm.c +++ b/drivers/soc/qcom/hab/qvm_comm.c @@ -13,6 +13,8 @@ #include "hab.h" #include "hab_qvm.h" +static unsigned long long xvm_sche_tx_tv_buffer[2]; + inline void habhyp_notify(void *commdev) { struct qvm_channel *dev = (struct qvm_channel *)commdev; @@ -78,6 +80,12 @@ int physical_channel_send(struct physical_channel *pchan, spin_unlock_bh(&dev->io_lock); return -EINVAL; } + } else if (HAB_HEADER_GET_TYPE(*header) + == HAB_PAYLOAD_TYPE_SCHE_RESULT_REQ) { + ((unsigned long long *)payload)[0] = xvm_sche_tx_tv_buffer[0]; + } else if (HAB_HEADER_GET_TYPE(*header) + == HAB_PAYLOAD_TYPE_SCHE_RESULT_RSP) { + ((unsigned long long *)payload)[2] = xvm_sche_tx_tv_buffer[1]; } if (sizebytes) { @@ -91,6 +99,10 @@ int physical_channel_send(struct physical_channel *pchan, hab_pipe_write_commit(dev->pipe_ep); spin_unlock_bh(&dev->io_lock); + if (HAB_HEADER_GET_TYPE(*header) == HAB_PAYLOAD_TYPE_SCHE_MSG) + xvm_sche_tx_tv_buffer[0] = msm_timer_get_sclk_ticks(); + else if (HAB_HEADER_GET_TYPE(*header) == HAB_PAYLOAD_TYPE_SCHE_MSG_ACK) + xvm_sche_tx_tv_buffer[1] = msm_timer_get_sclk_ticks(); habhyp_notify(dev); return 0; diff --git a/include/linux/habmm.h b/include/linux/habmm.h index cd4e2506f9ee..34ba1083a554 100644 --- a/include/linux/habmm.h +++ b/include/linux/habmm.h @@ -105,6 +105,37 @@ int32_t habmm_socket_close(int32_t handle); */ #define HABMM_SOCKET_SEND_FLAGS_XING_VM_STAT 0x00000002 +/* start to measure cross-vm schedule latency: VM1 send msg with this flag + * to VM2 to kick off the measurement. In the hab driver level, the VM1 hab + * driver shall record the time of schdule out with mpm_timer, and buffer + * it for later usage. The VM2 hab driver shall record the time of schedule + * in with mpm_timer and pass it to "habtest" application. + */ +#define HABMM_SOCKET_XVM_SCHE_TEST 0x00000004 + +/* VM2 responds this message to VM1 for HABMM_SOCKET_XVM_SCHE_TEST. + * In the hab driver level, the VM2 hab driver shall record the time of schedule + * out with mpm_timer, and buffer it for later usage; the VM1 hab driver + * shall record the time of schedule in with mpm_timer and pass it to "habtest" + * application. + */ +#define HABMM_SOCKET_XVM_SCHE_TEST_ACK 0x00000008 + +/* VM1 sends this message to VM2 asking for collect all the mpm_timer values + * to calculate the latency of schduling between VM1 and VM2. In the hab driver + * level, the VM1 hab driver shall save the previous restored schduling out + * time to the message buffer + */ +#define HABMM_SOCKET_XVM_SCHE_RESULT_REQ 0x00000010 + +/* VM2 responds this message to VM2 for HABMM_SOCKET_XVM_SCHE_RESULT_REQ. + * In the habtest application level, VM2 shall save the previous restored + * scheduling in time into message buffer, in the hab driver level, VM2 + * shall save the previous restored scheduling out time to the message + * buffer. + */ +#define HABMM_SOCKET_XVM_SCHE_RESULT_RSP 0x00000020 + struct habmm_xing_vm_stat { uint64_t tx_sec; uint64_t tx_usec;