Skip to content

Commit 34fee3a

Browse files
Namhyung Kimrostedt
authored andcommitted
tracing/probes: Split [ku]probes_fetch_type_table
Use separate fetch_type_table for kprobes and uprobes. It currently shares all fetch methods but some of them will be implemented differently later. This is not to break build if [ku]probes is configured alone (like !CONFIG_KPROBE_EVENT and CONFIG_UPROBE_EVENT). So I added '__weak' to the table declaration so that it can be safely omitted when it configured out. Acked-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Cc: zhangwei(Jovi) <jovi.zhangwei@huawei.com> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
1 parent b26c74e commit 34fee3a

File tree

4 files changed

+119
-39
lines changed

4 files changed

+119
-39
lines changed

kernel/trace/trace_kprobe.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,26 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
8888
static int kretprobe_dispatcher(struct kretprobe_instance *ri,
8989
struct pt_regs *regs);
9090

91+
/* Fetch type information table */
92+
const struct fetch_type kprobes_fetch_type_table[] = {
93+
/* Special types */
94+
[FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
95+
sizeof(u32), 1, "__data_loc char[]"),
96+
[FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
97+
string_size, sizeof(u32), 0, "u32"),
98+
/* Basic types */
99+
ASSIGN_FETCH_TYPE(u8, u8, 0),
100+
ASSIGN_FETCH_TYPE(u16, u16, 0),
101+
ASSIGN_FETCH_TYPE(u32, u32, 0),
102+
ASSIGN_FETCH_TYPE(u64, u64, 0),
103+
ASSIGN_FETCH_TYPE(s8, u8, 1),
104+
ASSIGN_FETCH_TYPE(s16, u16, 1),
105+
ASSIGN_FETCH_TYPE(s32, u32, 1),
106+
ASSIGN_FETCH_TYPE(s64, u64, 1),
107+
108+
ASSIGN_FETCH_TYPE_END
109+
};
110+
91111
/*
92112
* Allocate new trace_probe and initialize it (including kprobes).
93113
*/

kernel/trace/trace_probe.c

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d")
5454
DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%d")
5555
DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%Ld")
5656

57-
/* For defining macros, define string/string_size types */
58-
typedef u32 string;
59-
typedef u32 string_size;
60-
6157
/* Print type function for string type */
6258
__kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
6359
const char *name,
@@ -74,7 +70,6 @@ __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
7470

7571
const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
7672

77-
#define FETCH_FUNC_NAME(method, type) fetch_##method##_##type
7873
/*
7974
* Define macro for basic types - we don't need to define s* types, because
8075
* we have to care only about bitwidth at recording time.
@@ -359,25 +354,8 @@ free_bitfield_fetch_param(struct bitfield_fetch_param *data)
359354
kfree(data);
360355
}
361356

362-
/* Fetch type information table */
363-
static const struct fetch_type fetch_type_table[] = {
364-
/* Special types */
365-
[FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
366-
sizeof(u32), 1, "__data_loc char[]"),
367-
[FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
368-
string_size, sizeof(u32), 0, "u32"),
369-
/* Basic types */
370-
ASSIGN_FETCH_TYPE(u8, u8, 0),
371-
ASSIGN_FETCH_TYPE(u16, u16, 0),
372-
ASSIGN_FETCH_TYPE(u32, u32, 0),
373-
ASSIGN_FETCH_TYPE(u64, u64, 0),
374-
ASSIGN_FETCH_TYPE(s8, u8, 1),
375-
ASSIGN_FETCH_TYPE(s16, u16, 1),
376-
ASSIGN_FETCH_TYPE(s32, u32, 1),
377-
ASSIGN_FETCH_TYPE(s64, u64, 1),
378-
};
379-
380-
static const struct fetch_type *find_fetch_type(const char *type)
357+
static const struct fetch_type *find_fetch_type(const char *type,
358+
const struct fetch_type *ftbl)
381359
{
382360
int i;
383361

@@ -398,21 +376,22 @@ static const struct fetch_type *find_fetch_type(const char *type)
398376

399377
switch (bs) {
400378
case 8:
401-
return find_fetch_type("u8");
379+
return find_fetch_type("u8", ftbl);
402380
case 16:
403-
return find_fetch_type("u16");
381+
return find_fetch_type("u16", ftbl);
404382
case 32:
405-
return find_fetch_type("u32");
383+
return find_fetch_type("u32", ftbl);
406384
case 64:
407-
return find_fetch_type("u64");
385+
return find_fetch_type("u64", ftbl);
408386
default:
409387
goto fail;
410388
}
411389
}
412390

413-
for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++)
414-
if (strcmp(type, fetch_type_table[i].name) == 0)
415-
return &fetch_type_table[i];
391+
for (i = 0; ftbl[i].name; i++) {
392+
if (strcmp(type, ftbl[i].name) == 0)
393+
return &ftbl[i];
394+
}
416395

417396
fail:
418397
return NULL;
@@ -426,16 +405,17 @@ static __kprobes void fetch_stack_address(struct pt_regs *regs,
426405
}
427406

428407
static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
429-
fetch_func_t orig_fn)
408+
fetch_func_t orig_fn,
409+
const struct fetch_type *ftbl)
430410
{
431411
int i;
432412

433-
if (type != &fetch_type_table[FETCH_TYPE_STRING])
413+
if (type != &ftbl[FETCH_TYPE_STRING])
434414
return NULL; /* Only string type needs size function */
435415

436416
for (i = 0; i < FETCH_MTD_END; i++)
437417
if (type->fetch[i] == orig_fn)
438-
return fetch_type_table[FETCH_TYPE_STRSIZE].fetch[i];
418+
return ftbl[FETCH_TYPE_STRSIZE].fetch[i];
439419

440420
WARN_ON(1); /* This should not happen */
441421

@@ -504,12 +484,14 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
504484
static int parse_probe_arg(char *arg, const struct fetch_type *t,
505485
struct fetch_param *f, bool is_return, bool is_kprobe)
506486
{
487+
const struct fetch_type *ftbl;
507488
unsigned long param;
508489
long offset;
509490
char *tmp;
510-
int ret;
491+
int ret = 0;
511492

512-
ret = 0;
493+
ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table;
494+
BUG_ON(ftbl == NULL);
513495

514496
/* Until uprobe_events supports only reg arguments */
515497
if (!is_kprobe && arg[0] != '%')
@@ -568,7 +550,7 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
568550
struct deref_fetch_param *dprm;
569551
const struct fetch_type *t2;
570552

571-
t2 = find_fetch_type(NULL);
553+
t2 = find_fetch_type(NULL, ftbl);
572554
*tmp = '\0';
573555
dprm = kzalloc(sizeof(struct deref_fetch_param), GFP_KERNEL);
574556

@@ -637,9 +619,13 @@ static int __parse_bitfield_probe_arg(const char *bf,
637619
int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
638620
struct probe_arg *parg, bool is_return, bool is_kprobe)
639621
{
622+
const struct fetch_type *ftbl;
640623
const char *t;
641624
int ret;
642625

626+
ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table;
627+
BUG_ON(ftbl == NULL);
628+
643629
if (strlen(arg) > MAX_ARGSTR_LEN) {
644630
pr_info("Argument is too long.: %s\n", arg);
645631
return -ENOSPC;
@@ -654,7 +640,7 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
654640
arg[t - parg->comm] = '\0';
655641
t++;
656642
}
657-
parg->type = find_fetch_type(t);
643+
parg->type = find_fetch_type(t, ftbl);
658644
if (!parg->type) {
659645
pr_info("Unsupported type: %s\n", t);
660646
return -EINVAL;
@@ -668,7 +654,8 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
668654

669655
if (ret >= 0) {
670656
parg->fetch_size.fn = get_fetch_size_function(parg->type,
671-
parg->fetch.fn);
657+
parg->fetch.fn,
658+
ftbl);
672659
parg->fetch_size.data = parg->fetch.data;
673660
}
674661

kernel/trace/trace_probe.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ struct fetch_param {
126126
void *data;
127127
};
128128

129+
/* For defining macros, define string/string_size types */
130+
typedef u32 string;
131+
typedef u32 string_size;
132+
129133
#define PRINT_TYPE_FUNC_NAME(type) print_type_##type
130134
#define PRINT_TYPE_FMT_NAME(type) print_type_format_##type
131135

@@ -146,6 +150,47 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(s32);
146150
DECLARE_BASIC_PRINT_TYPE_FUNC(s64);
147151
DECLARE_BASIC_PRINT_TYPE_FUNC(string);
148152

153+
#define FETCH_FUNC_NAME(method, type) fetch_##method##_##type
154+
155+
/* Declare macro for basic types */
156+
#define DECLARE_FETCH_FUNC(method, type) \
157+
extern void FETCH_FUNC_NAME(method, type)(struct pt_regs *regs, \
158+
void *data, void *dest)
159+
160+
#define DECLARE_BASIC_FETCH_FUNCS(method) \
161+
DECLARE_FETCH_FUNC(method, u8); \
162+
DECLARE_FETCH_FUNC(method, u16); \
163+
DECLARE_FETCH_FUNC(method, u32); \
164+
DECLARE_FETCH_FUNC(method, u64)
165+
166+
DECLARE_BASIC_FETCH_FUNCS(reg);
167+
#define fetch_reg_string NULL
168+
#define fetch_reg_string_size NULL
169+
170+
DECLARE_BASIC_FETCH_FUNCS(stack);
171+
#define fetch_stack_string NULL
172+
#define fetch_stack_string_size NULL
173+
174+
DECLARE_BASIC_FETCH_FUNCS(retval);
175+
#define fetch_retval_string NULL
176+
#define fetch_retval_string_size NULL
177+
178+
DECLARE_BASIC_FETCH_FUNCS(memory);
179+
DECLARE_FETCH_FUNC(memory, string);
180+
DECLARE_FETCH_FUNC(memory, string_size);
181+
182+
DECLARE_BASIC_FETCH_FUNCS(symbol);
183+
DECLARE_FETCH_FUNC(symbol, string);
184+
DECLARE_FETCH_FUNC(symbol, string_size);
185+
186+
DECLARE_BASIC_FETCH_FUNCS(deref);
187+
DECLARE_FETCH_FUNC(deref, string);
188+
DECLARE_FETCH_FUNC(deref, string_size);
189+
190+
DECLARE_BASIC_FETCH_FUNCS(bitfield);
191+
#define fetch_bitfield_string NULL
192+
#define fetch_bitfield_string_size NULL
193+
149194
/* Default (unsigned long) fetch type */
150195
#define __DEFAULT_FETCH_TYPE(t) u##t
151196
#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t)
@@ -176,9 +221,17 @@ ASSIGN_FETCH_FUNC(bitfield, ftype), \
176221
#define ASSIGN_FETCH_TYPE(ptype, ftype, sign) \
177222
__ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype)
178223

224+
#define ASSIGN_FETCH_TYPE_END {}
225+
179226
#define FETCH_TYPE_STRING 0
180227
#define FETCH_TYPE_STRSIZE 1
181228

229+
/*
230+
* Fetch type information table.
231+
* It's declared as a weak symbol due to conditional compilation.
232+
*/
233+
extern __weak const struct fetch_type kprobes_fetch_type_table[];
234+
extern __weak const struct fetch_type uprobes_fetch_type_table[];
182235

183236
struct probe_arg {
184237
struct fetch_param fetch;

kernel/trace/trace_uprobe.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,26 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs);
7474
static int uretprobe_dispatcher(struct uprobe_consumer *con,
7575
unsigned long func, struct pt_regs *regs);
7676

77+
/* Fetch type information table */
78+
const struct fetch_type uprobes_fetch_type_table[] = {
79+
/* Special types */
80+
[FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
81+
sizeof(u32), 1, "__data_loc char[]"),
82+
[FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
83+
string_size, sizeof(u32), 0, "u32"),
84+
/* Basic types */
85+
ASSIGN_FETCH_TYPE(u8, u8, 0),
86+
ASSIGN_FETCH_TYPE(u16, u16, 0),
87+
ASSIGN_FETCH_TYPE(u32, u32, 0),
88+
ASSIGN_FETCH_TYPE(u64, u64, 0),
89+
ASSIGN_FETCH_TYPE(s8, u8, 1),
90+
ASSIGN_FETCH_TYPE(s16, u16, 1),
91+
ASSIGN_FETCH_TYPE(s32, u32, 1),
92+
ASSIGN_FETCH_TYPE(s64, u64, 1),
93+
94+
ASSIGN_FETCH_TYPE_END
95+
};
96+
7797
static inline void init_trace_uprobe_filter(struct trace_uprobe_filter *filter)
7898
{
7999
rwlock_init(&filter->rwlock);

0 commit comments

Comments
 (0)