soc: qcom: hab: add HAB runtime profiling support

Add trace points with TRACE_EVENT() inside the HAB
message send and receive paths. These tracing events
could be switched on and off w/ the standard ways.
When they are on, the tracing events could include the
MPM physical timer's counter values(useful for performance
profiling) if the timer is available.

Change-Id: Ide02263f85a61c88bf1aa8f464512756ae17d7a9
Signed-off-by: Yong Ding <yongding@codeaurora.org>
This commit is contained in:
Yong Ding 2021-03-29 14:29:56 +08:00
commit eafdae80ea
7 changed files with 193 additions and 5 deletions

View file

@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
CFLAGS_hab.o := -I$(src)
msm_hab-objs = \
hab.o \
hab_msg.o \

View file

@ -4,6 +4,9 @@
*/
#include "hab.h"
#define CREATE_TRACE_POINTS
#include "hab_trace_os.h"
#define HAB_DEVICE_CNSTR(__name__, __id__, __num__) { \
.name = __name__,\
.id = __id__,\
@ -555,6 +558,9 @@ long hab_vchan_send(struct uhab_context *ctx,
goto err;
}
/* log msg send timestamp: enter hab_vchan_send */
trace_hab_vchan_send_start(vchan);
HAB_HEADER_SET_SIZE(header, sizebytes);
if (flags & HABMM_SOCKET_SEND_FLAGS_XING_VM_STAT) {
HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_PROFILE);
@ -595,6 +601,10 @@ long hab_vchan_send(struct uhab_context *ctx,
if (!ret)
vchan->tx_cnt++;
err:
/* log msg send timestamp: exit hab_vchan_send */
trace_hab_vchan_send_done(vchan);
if (vchan)
hab_vchan_put(vchan);
@ -638,6 +648,9 @@ int hab_vchan_recv(struct uhab_context *ctx,
else if (ret == -ERESTARTSYS)
ret = -EINTR;
} else if (!ret) {
/* log msg recv timestamp: exit hab_vchan_recv */
trace_hab_vchan_recv_done(vchan, *message);
/*
* Here, it is for sure that a message was received from the
* hab_vchan_recv()'s view w/ the ret as 0 and *message as

View file

@ -224,6 +224,7 @@ struct hab_export_ack_recvd {
struct hab_message {
struct list_head node;
size_t sizebytes;
uint32_t sequence_rx;
uint32_t data[];
};

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*/
#include "hab.h"
@ -34,6 +34,8 @@ hab_msg_alloc(struct physical_channel *pchan, size_t sizebytes)
message->sizebytes =
physical_channel_read(pchan, message->data, sizebytes);
message->sequence_rx = pchan->sequence_rx;
return message;
}

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#ifndef __HAB_OS_H
#define __HAB_OS_H
@ -41,7 +41,7 @@
#include <linux/version.h>
#include <linux/devcoredump.h>
#ifdef CONFIG_MSM_BOOT_STATS
#if IS_ENABLED(CONFIG_MSM_BOOT_TIME_MARKER)
#include <soc/qcom/boot_stats.h>
#else
static inline unsigned long long msm_timer_get_sclk_ticks(void)

View file

@ -0,0 +1,159 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM hab
#if !defined(_TRACE_HAB_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HAB_H
#include <linux/tracepoint.h>
#include "hab.h"
/* send path */
TRACE_EVENT(hab_pchan_send_start,
TP_PROTO(struct physical_channel *pchan),
TP_ARGS(pchan),
TP_STRUCT__entry(
__array(char, pchan_name, MAX_VMID_NAME_SIZE)
__field(uint32_t, seq_tx)
__field(unsigned long long, mpm_tv)
),
TP_fast_assign(
memcpy(__entry->pchan_name, pchan->name, MAX_VMID_NAME_SIZE);
__entry->seq_tx = pchan->sequence_tx + 1;
__entry->mpm_tv = msm_timer_get_sclk_ticks();
),
TP_printk("PTI:%s:%u:%llu\n", __entry->pchan_name,
__entry->seq_tx, __entry->mpm_tv)
);
TRACE_EVENT(hab_pchan_send_done,
TP_PROTO(struct physical_channel *pchan),
TP_ARGS(pchan),
TP_STRUCT__entry(
__array(char, pchan_name, MAX_VMID_NAME_SIZE)
__field(uint32_t, seq_tx)
__field(unsigned long long, mpm_tv)
),
TP_fast_assign(
memcpy(__entry->pchan_name, pchan->name, MAX_VMID_NAME_SIZE);
__entry->seq_tx = pchan->sequence_tx;
__entry->mpm_tv = msm_timer_get_sclk_ticks();
),
TP_printk("PTO:%s:%u:%llu\n", __entry->pchan_name,
__entry->seq_tx, __entry->mpm_tv)
);
TRACE_EVENT(hab_vchan_send_start,
TP_PROTO(struct virtual_channel *vchan),
TP_ARGS(vchan),
TP_STRUCT__entry(
__array(char, pchan_name, MAX_VMID_NAME_SIZE)
__field(uint32_t, seq_tx)
__field(unsigned long long, mpm_tv)
),
TP_fast_assign(
memcpy(__entry->pchan_name, vchan->pchan->name,
MAX_VMID_NAME_SIZE);
__entry->seq_tx = vchan->pchan->sequence_tx + 1;
__entry->mpm_tv = msm_timer_get_sclk_ticks();
),
TP_printk("VTI:%s:%u:%llu\n", __entry->pchan_name,
__entry->seq_tx, __entry->mpm_tv)
);
TRACE_EVENT(hab_vchan_send_done,
TP_PROTO(struct virtual_channel *vchan),
TP_ARGS(vchan),
TP_STRUCT__entry(
__array(char, pchan_name, MAX_VMID_NAME_SIZE)
__field(uint32_t, seq_tx)
__field(unsigned long long, mpm_tv)
),
TP_fast_assign(
memcpy(__entry->pchan_name, vchan->pchan->name,
MAX_VMID_NAME_SIZE);
__entry->seq_tx = vchan->pchan->sequence_tx;
__entry->mpm_tv = msm_timer_get_sclk_ticks();
),
TP_printk("VTO:%s:%u:%llu\n", __entry->pchan_name,
__entry->seq_tx, __entry->mpm_tv)
);
/* receive path */
TRACE_EVENT(hab_pchan_recv_start,
TP_PROTO(struct physical_channel *pchan),
TP_ARGS(pchan),
TP_STRUCT__entry(
__array(char, pchan_name, MAX_VMID_NAME_SIZE)
__field(uint32_t, seq_rx)
__field(unsigned long long, mpm_tv)
),
TP_fast_assign(
memcpy(__entry->pchan_name, pchan->name, MAX_VMID_NAME_SIZE);
__entry->seq_rx = pchan->sequence_rx;
__entry->mpm_tv = msm_timer_get_sclk_ticks();
),
TP_printk("PRI:%s:%u:%llu\n", __entry->pchan_name,
__entry->seq_rx, __entry->mpm_tv)
);
TRACE_EVENT(hab_vchan_recv_done,
TP_PROTO(struct virtual_channel *vchan,
struct hab_message *msg),
TP_ARGS(vchan, msg),
TP_STRUCT__entry(
__array(char, pchan_name, MAX_VMID_NAME_SIZE)
__field(uint32_t, seq_rx)
__field(unsigned long long, mpm_tv)
),
TP_fast_assign(
memcpy(__entry->pchan_name, vchan->pchan->name,
MAX_VMID_NAME_SIZE);
__entry->seq_rx = msg->sequence_rx;
__entry->mpm_tv = msm_timer_get_sclk_ticks();
),
TP_printk("VRO:%s:%u:%llu\n", __entry->pchan_name,
__entry->seq_rx, __entry->mpm_tv)
);
#endif /* _TRACE_HAB_H */
/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE hab_trace_os
#include <trace/define_trace.h>

View file

@ -1,9 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*/
#include "hab.h"
#include "hab_qvm.h"
#include "hab_trace_os.h"
static unsigned long long xvm_sche_tx_tv_buffer[2];
@ -60,6 +61,8 @@ int physical_channel_send(struct physical_channel *pchan,
hab_spin_lock(&dev->io_lock, irqs_disabled);
trace_hab_pchan_send_start(pchan);
if ((dev->pipe_ep->tx_info.sh_buf->size -
(dev->pipe_ep->tx_info.wr_count -
dev->pipe_ep->tx_info.sh_buf->rd_count)) < total_size) {
@ -117,13 +120,18 @@ int physical_channel_send(struct physical_channel *pchan,
}
hab_pipe_write_commit(dev->pipe_ep);
/* locally +1 as late as possible but before unlock */
++pchan->sequence_tx;
trace_hab_pchan_send_done(pchan);
hab_spin_unlock(&dev->io_lock, irqs_disabled);
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);
++pchan->sequence_tx;
return 0;
}
@ -174,6 +182,9 @@ void physical_channel_rx_dispatch(unsigned long data)
pchan->sequence_rx = header.sequence;
/* log msg recv timestamp: enter pchan dispatcher */
trace_hab_pchan_recv_start(pchan);
hab_msg_recv(pchan, &header);
i++;
}