diff options
| author | Namhyung Kim <namhyung.kim@lge.com> | 2013-11-26 00:56:28 -0500 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2014-01-02 16:17:39 -0500 |
| commit | 34fee3a104cea1c4b658e51836e4bcd99bd76c70 (patch) | |
| tree | 4b73d864e468c395f6c9d484bef5a8f138a02b5e /kernel/trace/trace_probe.c | |
| parent | b26c74e116ad8433da22a72f03d148f88aab36e5 (diff) | |
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>
Diffstat (limited to 'kernel/trace/trace_probe.c')
| -rw-r--r-- | kernel/trace/trace_probe.c | 65 |
1 files changed, 26 insertions, 39 deletions
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index c26bc9eaa2ac..541036ec7392 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c | |||
| @@ -54,10 +54,6 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d") | |||
| 54 | DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%d") | 54 | DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%d") |
| 55 | DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%Ld") | 55 | DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%Ld") |
| 56 | 56 | ||
| 57 | /* For defining macros, define string/string_size types */ | ||
| 58 | typedef u32 string; | ||
| 59 | typedef u32 string_size; | ||
| 60 | |||
| 61 | /* Print type function for string type */ | 57 | /* Print type function for string type */ |
| 62 | __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, | 58 | __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, |
| 63 | const char *name, | 59 | const char *name, |
| @@ -74,7 +70,6 @@ __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, | |||
| 74 | 70 | ||
| 75 | const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; | 71 | const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; |
| 76 | 72 | ||
| 77 | #define FETCH_FUNC_NAME(method, type) fetch_##method##_##type | ||
| 78 | /* | 73 | /* |
| 79 | * Define macro for basic types - we don't need to define s* types, because | 74 | * Define macro for basic types - we don't need to define s* types, because |
| 80 | * we have to care only about bitwidth at recording time. | 75 | * we have to care only about bitwidth at recording time. |
| @@ -359,25 +354,8 @@ free_bitfield_fetch_param(struct bitfield_fetch_param *data) | |||
| 359 | kfree(data); | 354 | kfree(data); |
| 360 | } | 355 | } |
| 361 | 356 | ||
| 362 | /* Fetch type information table */ | 357 | static const struct fetch_type *find_fetch_type(const char *type, |
| 363 | static const struct fetch_type fetch_type_table[] = { | 358 | const struct fetch_type *ftbl) |
| 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) | ||
| 381 | { | 359 | { |
| 382 | int i; | 360 | int i; |
| 383 | 361 | ||
| @@ -398,21 +376,22 @@ static const struct fetch_type *find_fetch_type(const char *type) | |||
| 398 | 376 | ||
| 399 | switch (bs) { | 377 | switch (bs) { |
| 400 | case 8: | 378 | case 8: |
| 401 | return find_fetch_type("u8"); | 379 | return find_fetch_type("u8", ftbl); |
| 402 | case 16: | 380 | case 16: |
| 403 | return find_fetch_type("u16"); | 381 | return find_fetch_type("u16", ftbl); |
| 404 | case 32: | 382 | case 32: |
| 405 | return find_fetch_type("u32"); | 383 | return find_fetch_type("u32", ftbl); |
| 406 | case 64: | 384 | case 64: |
| 407 | return find_fetch_type("u64"); | 385 | return find_fetch_type("u64", ftbl); |
| 408 | default: | 386 | default: |
| 409 | goto fail; | 387 | goto fail; |
| 410 | } | 388 | } |
| 411 | } | 389 | } |
| 412 | 390 | ||
| 413 | for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++) | 391 | for (i = 0; ftbl[i].name; i++) { |
| 414 | if (strcmp(type, fetch_type_table[i].name) == 0) | 392 | if (strcmp(type, ftbl[i].name) == 0) |
| 415 | return &fetch_type_table[i]; | 393 | return &ftbl[i]; |
| 394 | } | ||
| 416 | 395 | ||
| 417 | fail: | 396 | fail: |
| 418 | return NULL; | 397 | return NULL; |
| @@ -426,16 +405,17 @@ static __kprobes void fetch_stack_address(struct pt_regs *regs, | |||
| 426 | } | 405 | } |
| 427 | 406 | ||
| 428 | static fetch_func_t get_fetch_size_function(const struct fetch_type *type, | 407 | 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) | ||
| 430 | { | 410 | { |
| 431 | int i; | 411 | int i; |
| 432 | 412 | ||
| 433 | if (type != &fetch_type_table[FETCH_TYPE_STRING]) | 413 | if (type != &ftbl[FETCH_TYPE_STRING]) |
| 434 | return NULL; /* Only string type needs size function */ | 414 | return NULL; /* Only string type needs size function */ |
| 435 | 415 | ||
| 436 | for (i = 0; i < FETCH_MTD_END; i++) | 416 | for (i = 0; i < FETCH_MTD_END; i++) |
| 437 | if (type->fetch[i] == orig_fn) | 417 | if (type->fetch[i] == orig_fn) |
| 438 | return fetch_type_table[FETCH_TYPE_STRSIZE].fetch[i]; | 418 | return ftbl[FETCH_TYPE_STRSIZE].fetch[i]; |
| 439 | 419 | ||
| 440 | WARN_ON(1); /* This should not happen */ | 420 | WARN_ON(1); /* This should not happen */ |
| 441 | 421 | ||
| @@ -504,12 +484,14 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, | |||
| 504 | static int parse_probe_arg(char *arg, const struct fetch_type *t, | 484 | static int parse_probe_arg(char *arg, const struct fetch_type *t, |
| 505 | struct fetch_param *f, bool is_return, bool is_kprobe) | 485 | struct fetch_param *f, bool is_return, bool is_kprobe) |
| 506 | { | 486 | { |
| 487 | const struct fetch_type *ftbl; | ||
| 507 | unsigned long param; | 488 | unsigned long param; |
| 508 | long offset; | 489 | long offset; |
| 509 | char *tmp; | 490 | char *tmp; |
| 510 | int ret; | 491 | int ret = 0; |
| 511 | 492 | ||
| 512 | ret = 0; | 493 | ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table; |
| 494 | BUG_ON(ftbl == NULL); | ||
| 513 | 495 | ||
| 514 | /* Until uprobe_events supports only reg arguments */ | 496 | /* Until uprobe_events supports only reg arguments */ |
| 515 | if (!is_kprobe && arg[0] != '%') | 497 | if (!is_kprobe && arg[0] != '%') |
| @@ -568,7 +550,7 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t, | |||
| 568 | struct deref_fetch_param *dprm; | 550 | struct deref_fetch_param *dprm; |
| 569 | const struct fetch_type *t2; | 551 | const struct fetch_type *t2; |
| 570 | 552 | ||
| 571 | t2 = find_fetch_type(NULL); | 553 | t2 = find_fetch_type(NULL, ftbl); |
| 572 | *tmp = '\0'; | 554 | *tmp = '\0'; |
| 573 | dprm = kzalloc(sizeof(struct deref_fetch_param), GFP_KERNEL); | 555 | dprm = kzalloc(sizeof(struct deref_fetch_param), GFP_KERNEL); |
| 574 | 556 | ||
| @@ -637,9 +619,13 @@ static int __parse_bitfield_probe_arg(const char *bf, | |||
| 637 | int traceprobe_parse_probe_arg(char *arg, ssize_t *size, | 619 | int traceprobe_parse_probe_arg(char *arg, ssize_t *size, |
| 638 | struct probe_arg *parg, bool is_return, bool is_kprobe) | 620 | struct probe_arg *parg, bool is_return, bool is_kprobe) |
| 639 | { | 621 | { |
| 622 | const struct fetch_type *ftbl; | ||
| 640 | const char *t; | 623 | const char *t; |
| 641 | int ret; | 624 | int ret; |
| 642 | 625 | ||
| 626 | ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table; | ||
| 627 | BUG_ON(ftbl == NULL); | ||
| 628 | |||
| 643 | if (strlen(arg) > MAX_ARGSTR_LEN) { | 629 | if (strlen(arg) > MAX_ARGSTR_LEN) { |
| 644 | pr_info("Argument is too long.: %s\n", arg); | 630 | pr_info("Argument is too long.: %s\n", arg); |
| 645 | return -ENOSPC; | 631 | return -ENOSPC; |
| @@ -654,7 +640,7 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, | |||
| 654 | arg[t - parg->comm] = '\0'; | 640 | arg[t - parg->comm] = '\0'; |
| 655 | t++; | 641 | t++; |
| 656 | } | 642 | } |
| 657 | parg->type = find_fetch_type(t); | 643 | parg->type = find_fetch_type(t, ftbl); |
| 658 | if (!parg->type) { | 644 | if (!parg->type) { |
| 659 | pr_info("Unsupported type: %s\n", t); | 645 | pr_info("Unsupported type: %s\n", t); |
| 660 | return -EINVAL; | 646 | return -EINVAL; |
| @@ -668,7 +654,8 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, | |||
| 668 | 654 | ||
| 669 | if (ret >= 0) { | 655 | if (ret >= 0) { |
| 670 | parg->fetch_size.fn = get_fetch_size_function(parg->type, | 656 | parg->fetch_size.fn = get_fetch_size_function(parg->type, |
| 671 | parg->fetch.fn); | 657 | parg->fetch.fn, |
| 658 | ftbl); | ||
| 672 | parg->fetch_size.data = parg->fetch.data; | 659 | parg->fetch_size.data = parg->fetch.data; |
| 673 | } | 660 | } |
| 674 | 661 | ||
