summaryrefslogtreecommitdiff
path: root/kernel/trace/trace_probe_tmpl.h
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@kernel.org>2018-04-25 21:19:01 +0900
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2018-10-10 22:19:08 -0400
commit9178412ddf5a98feba0ad3986111c5ad10eb9e59 (patch)
treebe30e4d4b0028e7ae7c8c1e21d5155cb1dbcc891 /kernel/trace/trace_probe_tmpl.h
parentf451bc89d8357f010304564728ba7c5d38a1d4d5 (diff)
tracing: probeevent: Return consumed bytes of dynamic area
Cleanup string fetching routine so that returns the consumed bytes of dynamic area and store the string information as data_loc format instead of data_rloc. This simplifies the fetcharg loop. Link: http://lkml.kernel.org/r/152465874163.26224.12125143907501289031.stgit@devbox Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_probe_tmpl.h')
-rw-r--r--kernel/trace/trace_probe_tmpl.h54
1 files changed, 25 insertions, 29 deletions
diff --git a/kernel/trace/trace_probe_tmpl.h b/kernel/trace/trace_probe_tmpl.h
index c8a5272abf01..3b4aba6f84cc 100644
--- a/kernel/trace/trace_probe_tmpl.h
+++ b/kernel/trace/trace_probe_tmpl.h
@@ -48,24 +48,28 @@ fetch_apply_bitfield(struct fetch_insn *code, void *buf)
}
}
-/* Define this for each callsite */
+/*
+ * This must be defined for each callsite.
+ * Return consumed dynamic data size (>= 0), or error (< 0).
+ * If dest is NULL, don't store result and return required dynamic data size.
+ */
static int
process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs,
- void *dest, bool pre);
+ void *dest, void *base);
/* Sum up total data length for dynamic arraies (strings) */
static nokprobe_inline int
__get_data_size(struct trace_probe *tp, struct pt_regs *regs)
{
struct probe_arg *arg;
- int i, ret = 0;
- u32 len;
+ int i, len, ret = 0;
for (i = 0; i < tp->nr_args; i++) {
arg = tp->args + i;
if (unlikely(arg->dynamic)) {
- process_fetch_insn(arg->code, regs, &len, true);
- ret += len;
+ len = process_fetch_insn(arg->code, regs, NULL, NULL);
+ if (len > 0)
+ ret += len;
}
}
@@ -74,34 +78,26 @@ __get_data_size(struct trace_probe *tp, struct pt_regs *regs)
/* Store the value of each argument */
static nokprobe_inline void
-store_trace_args(int ent_size, struct trace_probe *tp, struct pt_regs *regs,
- u8 *data, int maxlen)
+store_trace_args(void *data, struct trace_probe *tp, struct pt_regs *regs,
+ int header_size, int maxlen)
{
struct probe_arg *arg;
- u32 end = tp->size;
- u32 *dl; /* Data (relative) location */
- int i;
+ void *base = data - header_size;
+ void *dyndata = data + tp->size;
+ u32 *dl; /* Data location */
+ int ret, i;
for (i = 0; i < tp->nr_args; i++) {
arg = tp->args + i;
- if (unlikely(arg->dynamic)) {
- /*
- * First, we set the relative location and
- * maximum data length to *dl
- */
- dl = (u32 *)(data + arg->offset);
- *dl = make_data_rloc(maxlen, end - arg->offset);
- /* Then try to fetch string or dynamic array data */
- process_fetch_insn(arg->code, regs, dl, false);
- /* Reduce maximum length */
- end += get_rloc_len(*dl);
- maxlen -= get_rloc_len(*dl);
- /* Trick here, convert data_rloc to data_loc */
- *dl = convert_rloc_to_loc(*dl, ent_size + arg->offset);
- } else
- /* Just fetching data normally */
- process_fetch_insn(arg->code, regs, data + arg->offset,
- false);
+ dl = data + arg->offset;
+ /* Point the dynamic data area if needed */
+ if (unlikely(arg->dynamic))
+ *dl = make_data_loc(maxlen, dyndata - base);
+ ret = process_fetch_insn(arg->code, regs, dl, base);
+ if (unlikely(ret < 0 && arg->dynamic))
+ *dl = make_data_loc(0, dyndata - base);
+ else
+ dyndata += ret;
}
}