hash_add(gvt->cmd_table, &e->hlist, e->info->opcode);
}
-#define GVT_MAX_CMD_LENGTH 20 /* In Dword */
-
-static void trace_cs_command(struct parser_exec_state *s,
- cycles_t cost_pre_cmd_handler, cycles_t cost_cmd_handler)
-{
- /* This buffer is used by ftrace to store all commands copied from
- * guest gma space. Sometimes commands can cross pages, this should
- * not be handled in ftrace logic. So this is just used as a
- * 'bounce buffer'
- */
- u32 cmd_trace_buf[GVT_MAX_CMD_LENGTH];
- int i;
- u32 cmd_len = cmd_length(s);
- /* The chosen value of GVT_MAX_CMD_LENGTH are just based on
- * following two considerations:
- * 1) From observation, most common ring commands is not that long.
- * But there are execeptions. So it indeed makes sence to observe
- * longer commands.
- * 2) From the performance and debugging point of view, dumping all
- * contents of very commands is not necessary.
- * We mgith shrink GVT_MAX_CMD_LENGTH or remove this trace event in
- * future for performance considerations.
- */
- if (unlikely(cmd_len > GVT_MAX_CMD_LENGTH)) {
- gvt_dbg_cmd("cmd length exceed tracing limitation!\n");
- cmd_len = GVT_MAX_CMD_LENGTH;
- }
-
- for (i = 0; i < cmd_len; i++)
- cmd_trace_buf[i] = cmd_val(s, i);
-
- trace_gvt_command(s->vgpu->id, s->ring_id, s->ip_gma, cmd_trace_buf,
- cmd_len, s->buf_type == RING_BUFFER_INSTRUCTION,
- cost_pre_cmd_handler, cost_cmd_handler);
-}
-
/* call the cmd handler, and advance ip */
static int cmd_parser_exec(struct parser_exec_state *s)
{
+ struct intel_vgpu *vgpu = s->vgpu;
struct cmd_info *info;
u32 cmd;
int ret = 0;
- cycles_t t0, t1, t2;
- struct parser_exec_state s_before_advance_custom;
- struct intel_vgpu *vgpu = s->vgpu;
-
- t0 = get_cycles();
cmd = cmd_val(s, 0);
s->info = info;
- t1 = get_cycles();
-
- s_before_advance_custom = *s;
+ trace_gvt_command(vgpu->id, s->ring_id, s->ip_gma, s->ip_va,
+ cmd_length(s), s->buf_type);
if (info->handler) {
ret = info->handler(s);
return ret;
}
}
- t2 = get_cycles();
-
- trace_cs_command(&s_before_advance_custom, t1 - t0, t2 - t1);
if (!(info->flag & F_IP_ADVANCE_CUSTOM)) {
ret = cmd_advance_default(s);
TP_printk("%s", __entry->buf)
);
-#define MAX_CMD_STR_LEN 256
TRACE_EVENT(gvt_command,
- TP_PROTO(u8 vm_id, u8 ring_id, u32 ip_gma, u32 *cmd_va, u32 cmd_len, bool ring_buffer_cmd, cycles_t cost_pre_cmd_handler, cycles_t cost_cmd_handler),
-
- TP_ARGS(vm_id, ring_id, ip_gma, cmd_va, cmd_len, ring_buffer_cmd, cost_pre_cmd_handler, cost_cmd_handler),
-
- TP_STRUCT__entry(
- __field(u8, vm_id)
- __field(u8, ring_id)
- __field(int, i)
- __array(char, tmp_buf, MAX_CMD_STR_LEN)
- __array(char, cmd_str, MAX_CMD_STR_LEN)
- ),
-
- TP_fast_assign(
- __entry->vm_id = vm_id;
- __entry->ring_id = ring_id;
- __entry->cmd_str[0] = '\0';
- snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "VM(%d) Ring(%d): %s ip(%08x) pre handler cost (%llu), handler cost (%llu) ", vm_id, ring_id, ring_buffer_cmd ? "RB":"BB", ip_gma, cost_pre_cmd_handler, cost_cmd_handler);
- strcat(__entry->cmd_str, __entry->tmp_buf);
- entry->i = 0;
- while (cmd_len > 0) {
- if (cmd_len >= 8) {
- snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "%08x %08x %08x %08x %08x %08x %08x %08x ",
- cmd_va[__entry->i], cmd_va[__entry->i+1], cmd_va[__entry->i+2], cmd_va[__entry->i+3],
- cmd_va[__entry->i+4], cmd_va[__entry->i+5], cmd_va[__entry->i+6], cmd_va[__entry->i+7]);
- __entry->i += 8;
- cmd_len -= 8;
- strcat(__entry->cmd_str, __entry->tmp_buf);
- } else if (cmd_len >= 4) {
- snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "%08x %08x %08x %08x ",
- cmd_va[__entry->i], cmd_va[__entry->i+1], cmd_va[__entry->i+2], cmd_va[__entry->i+3]);
- __entry->i += 4;
- cmd_len -= 4;
- strcat(__entry->cmd_str, __entry->tmp_buf);
- } else if (cmd_len >= 2) {
- snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "%08x %08x ", cmd_va[__entry->i], cmd_va[__entry->i+1]);
- __entry->i += 2;
- cmd_len -= 2;
- strcat(__entry->cmd_str, __entry->tmp_buf);
- } else if (cmd_len == 1) {
- snprintf(__entry->tmp_buf, MAX_CMD_STR_LEN, "%08x ", cmd_va[__entry->i]);
- __entry->i += 1;
- cmd_len -= 1;
- strcat(__entry->cmd_str, __entry->tmp_buf);
- }
- }
- strcat(__entry->cmd_str, "\n");
- ),
+ TP_PROTO(u8 vgpu_id, u8 ring_id, u32 ip_gma, u32 *cmd_va, u32 cmd_len,
+ u32 buf_type),
+
+ TP_ARGS(vgpu_id, ring_id, ip_gma, cmd_va, cmd_len, buf_type),
+
+ TP_STRUCT__entry(
+ __field(u8, vgpu_id)
+ __field(u8, ring_id)
+ __field(u32, ip_gma)
+ __field(u32, buf_type)
+ __field(u32, cmd_len)
+ __dynamic_array(u32, raw_cmd, cmd_len)
+ ),
+
+ TP_fast_assign(
+ __entry->vgpu_id = vgpu_id;
+ __entry->ring_id = ring_id;
+ __entry->ip_gma = ip_gma;
+ __entry->buf_type = buf_type;
+ __entry->cmd_len = cmd_len;
+ memcpy(__get_dynamic_array(raw_cmd), cmd_va, cmd_len * sizeof(*cmd_va));
+ ),
+
- TP_printk("%s", __entry->cmd_str)
+ TP_printk("vgpu%d ring %d: buf_type %u, ip_gma %08x, raw cmd %s",
+ __entry->vgpu_id,
+ __entry->ring_id,
+ __entry->buf_type,
+ __entry->ip_gma,
+ __print_array(__get_dynamic_array(raw_cmd), __entry->cmd_len, 4))
);
#endif /* _GVT_TRACE_H_ */