Pull probes updates from Masami Hiramatsu: - BTF support for dereferencing pointers Add syntax to the parsing of eprobes to typecast structure pointer trace event fields, enabling BTF-based dereferencing instead of relying on manual offsets. - Improvements and robustness enhancements - Use flexible array for entry fetch code. Store probe entry fetch instructions in the probe_entry_arg allocation via a flexible array member to simplify memory allocation and lifetime management. - Replace BUG_ON with lockdep_assert_held in uprobe_buffer functions Replace BUG_ON() calls with lockdep_assert_held() in uprobe buffer enable/disable paths to prevent kernel crashes and better verify lock ownership. - Ensure the uprobe buffer size is bigger than event size. Add a BUILD_BUG_ON() assertion to guarantee that the per-CPU uprobe working buffer size is always larger than the maximum probe event size. * tag 'probes-v7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: tracing/eprobes: Allow use of BTF names to dereference pointers tracing: Replace BUG_ON with lockdep_assert_held in uprobe_buffer functions tracing: Use flexible array for entry fetch code tracing/probes: Ensure the uprobe buffer size is bigger than event size
Showing the changes to kernel (3 of 4 files). Show all
Unified · Split
| @@ -332,6 +332,23 @@ static int parse_trace_event_arg(char *arg, struct fetch_insn *code, · 331 unmodified lines | |||
| 332 | return -ENOENT; | 332 | return -ENOENT; |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | static int parse_trace_event(char *arg, struct fetch_insn *code, | ||
| 336 | struct traceprobe_parse_context *ctx) | ||
| 337 | { | ||
| 338 | int ret; | ||
| 339 | |||
| 340 | if (code->data) | ||
| 341 | return -EFAULT; | ||
| 342 | ret = parse_trace_event_arg(arg, code, ctx); | ||
| 343 | if (!ret) | ||
| 344 | return 0; | ||
| 345 | if (strcmp(arg, "comm") == 0 || strcmp(arg, "COMM") == 0) { | ||
| 346 | code->op = FETCH_OP_COMM; | ||
| 347 | return 0; | ||
| 348 | } | ||
| 349 | return -EINVAL; | ||
| 350 | } | ||
| 351 | |||
| 335 | #ifdef CONFIG_PROBE_EVENTS_BTF_ARGS | 352 | #ifdef CONFIG_PROBE_EVENTS_BTF_ARGS |
| 336 | 353 | ||
| 337 | static u32 btf_type_int(const struct btf_type *t) | 354 | static u32 btf_type_int(const struct btf_type *t) |
| @@ -376,11 +393,16 @@ static bool btf_type_is_char_array(struct btf *btf, const struct btf_type *type) · 38 unmodified lines | |||
| 376 | && BTF_INT_BITS(intdata) == 8; | 393 | && BTF_INT_BITS(intdata) == 8; |
| 377 | } | 394 | } |
| 378 | 395 | ||
| 396 | static struct btf *ctx_btf(struct traceprobe_parse_context *ctx) | ||
| 397 | { | ||
| 398 | return ctx->struct_btf ? : ctx->btf; | ||
| 399 | } | ||
| 400 | |||
| 379 | static int check_prepare_btf_string_fetch(char *typename, | 401 | static int check_prepare_btf_string_fetch(char *typename, |
| 380 | struct fetch_insn **pcode, | 402 | struct fetch_insn **pcode, |
| 381 | struct traceprobe_parse_context *ctx) | 403 | struct traceprobe_parse_context *ctx) |
| 382 | { | 404 | { |
| 383 | struct btf *btf = ctx->btf; | 405 | struct btf *btf = ctx_btf(ctx); |
| 384 | 406 | ||
| 385 | if (!btf || !ctx->last_type) | 407 | if (!btf || !ctx->last_type) |
| 386 | return 0; | 408 | return 0; |
| @@ -506,6 +528,15 @@ static int query_btf_context(struct traceprobe_parse_context *ctx) · 119 unmodified lines | |||
| 506 | return 0; | 528 | return 0; |
| 507 | } | 529 | } |
| 508 | 530 | ||
| 531 | static void clear_struct_btf(struct traceprobe_parse_context *ctx) | ||
| 532 | { | ||
| 533 | if (ctx->struct_btf) { | ||
| 534 | btf_put(ctx->struct_btf); | ||
| 535 | ctx->struct_btf = NULL; | ||
| 536 | ctx->last_struct = NULL; | ||
| 537 | } | ||
| 538 | } | ||
| 539 | |||
| 509 | static void clear_btf_context(struct traceprobe_parse_context *ctx) | 540 | static void clear_btf_context(struct traceprobe_parse_context *ctx) |
| 510 | { | 541 | { |
| 511 | if (ctx->btf) { | 542 | if (ctx->btf) { |
| @@ -554,22 +585,29 @@ static int parse_btf_field(char *fieldname, const struct btf_type *type, · 42 unmodified lines | |||
| 554 | struct fetch_insn *code = *pcode; | 585 | struct fetch_insn *code = *pcode; |
| 555 | const struct btf_member *field; | 586 | const struct btf_member *field; |
| 556 | u32 bitoffs, anon_offs; | 587 | u32 bitoffs, anon_offs; |
| 588 | bool is_struct = ctx->struct_btf != NULL; | ||
| 589 | struct btf *btf = ctx_btf(ctx); | ||
| 557 | char *next; | 590 | char *next; |
| 558 | int is_ptr; | 591 | int is_ptr; |
| 559 | s32 tid; | 592 | s32 tid; |
| 560 | 593 | ||
| 561 | do { | 594 | do { |
| 562 | /* Outer loop for solving arrow operator ('->') */ | 595 | if (!is_struct) { |
| 563 | if (BTF_INFO_KIND(type->info) != BTF_KIND_PTR) { | 596 | /* Outer loop for solving arrow operator ('->') */ |
| 564 | trace_probe_log_err(ctx->offset, NO_PTR_STRCT); | 597 | if (BTF_INFO_KIND(type->info) != BTF_KIND_PTR) { |
| 565 | return -EINVAL; | 598 | trace_probe_log_err(ctx->offset, NO_PTR_STRCT); |
| 566 | } | 599 | return -EINVAL; |
| 567 | /* Convert a struct pointer type to a struct type */ | 600 | } |
| 568 | type = btf_type_skip_modifiers(ctx->btf, type->type, &tid); | 601 | |
| 569 | if (!type) { | 602 | /* Convert a struct pointer type to a struct type */ |
| 570 | trace_probe_log_err(ctx->offset, BAD_BTF_TID); | 603 | type = btf_type_skip_modifiers(btf, type->type, &tid); |
| 571 | return -EINVAL; | 604 | if (!type) { |
| 605 | trace_probe_log_err(ctx->offset, BAD_BTF_TID); | ||
| 606 | return -EINVAL; | ||
| 607 | } | ||
| 572 | } | 608 | } |
| 609 | /* Only the first type can skip being a pointer */ | ||
| 610 | is_struct = false; | ||
| 573 | 611 | ||
| 574 | bitoffs = 0; | 612 | bitoffs = 0; |
| 575 | do { | 613 | do { |
| @@ -580,7 +618,7 @@ static int parse_btf_field(char *fieldname, const struct btf_type *type, · 4 unmodified lines | |||
| 580 | return is_ptr; | 618 | return is_ptr; |
| 581 | 619 | ||
| 582 | anon_offs = 0; | 620 | anon_offs = 0; |
| 583 | field = btf_find_struct_member(ctx->btf, type, fieldname, | 621 | field = btf_find_struct_member(btf, type, fieldname, |
| 584 | &anon_offs); | 622 | &anon_offs); |
| 585 | if (IS_ERR(field)) { | 623 | if (IS_ERR(field)) { |
| 586 | trace_probe_log_err(ctx->offset, BAD_BTF_TID); | 624 | trace_probe_log_err(ctx->offset, BAD_BTF_TID); |
| @@ -602,7 +640,7 @@ static int parse_btf_field(char *fieldname, const struct btf_type *type, · 15 unmodified lines | |||
| 602 | ctx->last_bitsize = 0; | 640 | ctx->last_bitsize = 0; |
| 603 | } | 641 | } |
| 604 | 642 | ||
| 605 | type = btf_type_skip_modifiers(ctx->btf, field->type, &tid); | 643 | type = btf_type_skip_modifiers(btf, field->type, &tid); |
| 606 | if (!type) { | 644 | if (!type) { |
| 607 | trace_probe_log_err(ctx->offset, BAD_BTF_TID); | 645 | trace_probe_log_err(ctx->offset, BAD_BTF_TID); |
| 608 | return -EINVAL; | 646 | return -EINVAL; |
| @@ -640,7 +678,7 @@ static int parse_btf_arg(char *varname, · 31 unmodified lines | |||
| 640 | int i, is_ptr, ret; | 678 | int i, is_ptr, ret; |
| 641 | u32 tid; | 679 | u32 tid; |
| 642 | 680 | ||
| 643 | if (WARN_ON_ONCE(!ctx->funcname)) | 681 | if (WARN_ON_ONCE(!ctx->funcname && !(ctx->flags & TPARG_FL_TEVENT))) |
| 644 | return -EINVAL; | 682 | return -EINVAL; |
| 645 | 683 | ||
| 646 | is_ptr = split_next_field(varname, &field, ctx); | 684 | is_ptr = split_next_field(varname, &field, ctx); |
| @@ -653,6 +691,19 @@ static int parse_btf_arg(char *varname, · 6 unmodified lines | |||
| 653 | return -EOPNOTSUPP; | 691 | return -EOPNOTSUPP; |
| 654 | } | 692 | } |
| 655 | 693 | ||
| 694 | if (ctx->flags & TPARG_FL_TEVENT) { | ||
| 695 | ret = parse_trace_event(varname, code, ctx); | ||
| 696 | if (ret < 0) { | ||
| 697 | trace_probe_log_err(ctx->offset, BAD_ATTACH_ARG); | ||
| 698 | return ret; | ||
| 699 | } | ||
| 700 | /* TEVENT is only here via a typecast */ | ||
| 701 | if (WARN_ON_ONCE(ctx->struct_btf == NULL)) | ||
| 702 | return -EINVAL; | ||
| 703 | type = ctx->last_struct; | ||
| 704 | goto found_type; | ||
| 705 | } | ||
| 706 | |||
| 656 | if (ctx->flags & TPARG_FL_RETURN && !strcmp(varname, "$retval")) { | 707 | if (ctx->flags & TPARG_FL_RETURN && !strcmp(varname, "$retval")) { |
| 657 | code->op = FETCH_OP_RETVAL; | 708 | code->op = FETCH_OP_RETVAL; |
| 658 | /* Check whether the function return type is not void */ | 709 | /* Check whether the function return type is not void */ |
| @@ -709,6 +760,7 @@ static int parse_btf_arg(char *varname, · 50 unmodified lines | |||
| 709 | 760 | ||
| 710 | found: | 761 | found: |
| 711 | type = btf_type_skip_modifiers(ctx->btf, tid, &tid); | 762 | type = btf_type_skip_modifiers(ctx->btf, tid, &tid); |
| 763 | found_type: | ||
| 712 | if (!type) { | 764 | if (!type) { |
| 713 | trace_probe_log_err(ctx->offset, BAD_BTF_TID); | 765 | trace_probe_log_err(ctx->offset, BAD_BTF_TID); |
| 714 | return -EINVAL; | 766 | return -EINVAL; |
| @@ -727,7 +779,7 @@ found: · 12 unmodified lines | |||
| 727 | static const struct fetch_type *find_fetch_type_from_btf_type( | 779 | static const struct fetch_type *find_fetch_type_from_btf_type( |
| 728 | struct traceprobe_parse_context *ctx) | 780 | struct traceprobe_parse_context *ctx) |
| 729 | { | 781 | { |
| 730 | struct btf *btf = ctx->btf; | 782 | struct btf *btf = ctx_btf(ctx); |
| 731 | const char *typestr = NULL; | 783 | const char *typestr = NULL; |
| 732 | 784 | ||
| 733 | if (btf && ctx->last_type) | 785 | if (btf && ctx->last_type) |
| @@ -758,7 +810,67 @@ static int parse_btf_bitfield(struct fetch_insn **pcode, · 24 unmodified lines | |||
| 758 | return 0; | 810 | return 0; |
| 759 | } | 811 | } |
| 760 | 812 | ||
| 761 | #else | 813 | static int query_btf_struct(const char *sname, struct traceprobe_parse_context *ctx) |
| 814 | { | ||
| 815 | struct btf *btf = NULL; | ||
| 816 | int id; | ||
| 817 | |||
| 818 | /* A struct_btf should only be used by a single argument */ | ||
| 819 | if (WARN_ON_ONCE(ctx->struct_btf)) { | ||
| 820 | btf_put(ctx->struct_btf); | ||
| 821 | ctx->struct_btf = NULL; | ||
| 822 | } | ||
| 823 | |||
| 824 | id = bpf_find_btf_id(sname, BTF_KIND_STRUCT, &btf); | ||
| 825 | if (id < 0) | ||
| 826 | return id; | ||
| 827 | ctx->struct_btf = btf; | ||
| 828 | ctx->last_struct = btf_type_by_id(ctx->struct_btf, id); | ||
| 829 | return 0; | ||
| 830 | } | ||
| 831 | |||
| 832 | static int handle_typecast(char *arg, struct fetch_insn **pcode, | ||
| 833 | struct fetch_insn *end, | ||
| 834 | struct traceprobe_parse_context *ctx) | ||
| 835 | { | ||
| 836 | char *tmp; | ||
| 837 | int ret; | ||
| 838 | |||
| 839 | /* Currently this only works for eprobes */ | ||
| 840 | if (!(ctx->flags & TPARG_FL_TEVENT)) { | ||
| 841 | trace_probe_log_err(ctx->offset, TYPECAST_NOT_EVENT); | ||
| 842 | return -EINVAL; | ||
| 843 | } | ||
| 844 | |||
| 845 | tmp = strchr(arg, ')'); | ||
| 846 | if (!tmp) { | ||
| 847 | trace_probe_log_err(ctx->offset + strlen(arg), | ||
| 848 | DEREF_OPEN_BRACE); | ||
| 849 | return -EINVAL; | ||
| 850 | } | ||
| 851 | *tmp = '\0'; | ||
| 852 | ret = query_btf_struct(arg + 1, ctx); | ||
| 853 | *tmp = ')'; | ||
| 854 | |||
| 855 | if (ret < 0) { | ||
| 856 | trace_probe_log_err(ctx->offset + 1, NO_PTR_STRCT); | ||
| 857 | return -EINVAL; | ||
| 858 | } | ||
| 859 | |||
| 860 | tmp++; | ||
| 861 | |||
| 862 | ctx->offset += tmp - arg; | ||
| 863 | ret = parse_btf_arg(tmp, pcode, end, ctx); | ||
| 864 | return ret; | ||
| 865 | } | ||
| 866 | |||
| 867 | #else /* !CONFIG_PROBE_EVENTS_BTF_ARGS */ | ||
| 868 | |||
| 869 | static void clear_struct_btf(struct traceprobe_parse_context *ctx) | ||
| 870 | { | ||
| 871 | ctx->struct_btf = NULL; | ||
| 872 | } | ||
| 873 | |||
| 762 | static void clear_btf_context(struct traceprobe_parse_context *ctx) | 874 | static void clear_btf_context(struct traceprobe_parse_context *ctx) |
| 763 | { | 875 | { |
| 764 | ctx->btf = NULL; | 876 | ctx->btf = NULL; |
| @@ -794,7 +906,15 @@ static int check_prepare_btf_string_fetch(char *typename, · 29 unmodified lines | |||
| 794 | return 0; | 906 | return 0; |
| 795 | } | 907 | } |
| 796 | 908 | ||
| 797 | #endif | 909 | static int handle_typecast(char *arg, struct fetch_insn **pcode, |
| 910 | struct fetch_insn *end, | ||
| 911 | struct traceprobe_parse_context *ctx) | ||
| 912 | { | ||
| 913 | trace_probe_log_err(ctx->offset, NOSUP_BTFARG); | ||
| 914 | return -EOPNOTSUPP; | ||
| 915 | } | ||
| 916 | |||
| 917 | #endif /* CONFIG_PROBE_EVENTS_BTF_ARGS */ | ||
| 798 | 918 | ||
| 799 | #ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API | 919 | #ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API |
| 800 | 920 | ||
| @@ -838,15 +958,10 @@ static int __store_entry_arg(struct trace_probe *tp, int argnum) · 37 unmodified lines | |||
| 838 | int i, offset, last_offset = 0; | 958 | int i, offset, last_offset = 0; |
| 839 | 959 | ||
| 840 | if (!earg) { | 960 | if (!earg) { |
| 841 | earg = kzalloc_obj(*tp->entry_arg); | 961 | earg = kzalloc_flex(*earg, code, 2 * tp->nr_args + 1); |
| 842 | if (!earg) | 962 | if (!earg) |
| 843 | return -ENOMEM; | 963 | return -ENOMEM; |
| 844 | earg->size = 2 * tp->nr_args + 1; | 964 | earg->size = 2 * tp->nr_args + 1; |
| 845 | earg->code = kzalloc_objs(struct fetch_insn, earg->size); | ||
| 846 | if (!earg->code) { | ||
| 847 | kfree(earg); | ||
| 848 | return -ENOMEM; | ||
| 849 | } | ||
| 850 | /* Fill the code buffer with 'end' to simplify it */ | 965 | /* Fill the code buffer with 'end' to simplify it */ |
| 851 | for (i = 0; i < earg->size; i++) | 966 | for (i = 0; i < earg->size; i++) |
| 852 | earg->code[i].op = FETCH_OP_END; | 967 | earg->code[i].op = FETCH_OP_END; |
| @@ -953,16 +1068,9 @@ static int parse_probe_vars(char *orig_arg, const struct fetch_type *t, · 100 unmodified lines | |||
| 953 | int len; | 1068 | int len; |
| 954 | 1069 | ||
| 955 | if (ctx->flags & TPARG_FL_TEVENT) { | 1070 | if (ctx->flags & TPARG_FL_TEVENT) { |
| 956 | if (code->data) | 1071 | if (parse_trace_event(arg, code, ctx) < 0) |
| 957 | return -EFAULT; | 1072 | goto inval; |
| 958 | ret = parse_trace_event_arg(arg, code, ctx); | 1073 | return 0; |
| 959 | if (!ret) | ||
| 960 | return 0; | ||
| 961 | if (strcmp(arg, "comm") == 0 || strcmp(arg, "COMM") == 0) { | ||
| 962 | code->op = FETCH_OP_COMM; | ||
| 963 | return 0; | ||
| 964 | } | ||
| 965 | goto inval; | ||
| 966 | } | 1074 | } |
| 967 | 1075 | ||
| 968 | if (str_has_prefix(arg, "retval")) { | 1076 | if (str_has_prefix(arg, "retval")) { |
| @@ -1229,6 +1337,9 @@ parse_probe_arg(char *arg, const struct fetch_type *type, · 260 unmodified lines | |||
| 1229 | code->op = FETCH_OP_IMM; | 1337 | code->op = FETCH_OP_IMM; |
| 1230 | } | 1338 | } |
| 1231 | break; | 1339 | break; |
| 1340 | case '(': | ||
| 1341 | ret = handle_typecast(arg, pcode, end, ctx); | ||
| 1342 | break; | ||
| 1232 | default: | 1343 | default: |
| 1233 | if (isalpha(arg[0]) || arg[0] == '_') { /* BTF variable */ | 1344 | if (isalpha(arg[0]) || arg[0] == '_') { /* BTF variable */ |
| 1234 | if (!tparg_is_function_entry(ctx->flags) && | 1345 | if (!tparg_is_function_entry(ctx->flags) && |
| @@ -1561,6 +1672,9 @@ fail: · 326 unmodified lines | |||
| 1561 | } | 1672 | } |
| 1562 | kfree(tmp); | 1673 | kfree(tmp); |
| 1563 | 1674 | ||
| 1675 | /* struct_btf should not be passed to other arguments */ | ||
| 1676 | clear_struct_btf(ctx); | ||
| 1677 | |||
| 1564 | return ret; | 1678 | return ret; |
| 1565 | } | 1679 | } |
| 1566 | 1680 | ||
| @@ -2049,7 +2163,6 @@ void trace_probe_cleanup(struct trace_probe *tp) · 482 unmodified lines | |||
| 2049 | traceprobe_free_probe_arg(&tp->args[i]); | 2163 | traceprobe_free_probe_arg(&tp->args[i]); |
| 2050 | 2164 | ||
| 2051 | if (tp->entry_arg) { | 2165 | if (tp->entry_arg) { |
| 2052 | kfree(tp->entry_arg->code); | ||
| 2053 | kfree(tp->entry_arg); | 2166 | kfree(tp->entry_arg); |
| 2054 | tp->entry_arg = NULL; | 2167 | tp->entry_arg = NULL; |
| 2055 | } | 2168 | } |
| @@ -238,8 +238,8 @@ struct probe_arg { · 237 unmodified lines | |||
| 238 | }; | 238 | }; |
| 239 | 239 | ||
| 240 | struct probe_entry_arg { | 240 | struct probe_entry_arg { |
| 241 | struct fetch_insn *code; | ||
| 242 | unsigned int size; /* The entry data size */ | 241 | unsigned int size; /* The entry data size */ |
| 242 | struct fetch_insn code[] __counted_by(size); | ||
| 243 | }; | 243 | }; |
| 244 | 244 | ||
| 245 | struct trace_uprobe_filter { | 245 | struct trace_uprobe_filter { |
| @@ -422,7 +422,9 @@ struct traceprobe_parse_context { · 176 unmodified lines | |||
| 422 | const struct btf_param *params; /* Parameter of the function */ | 422 | const struct btf_param *params; /* Parameter of the function */ |
| 423 | s32 nr_params; /* The number of the parameters */ | 423 | s32 nr_params; /* The number of the parameters */ |
| 424 | struct btf *btf; /* The BTF to be used */ | 424 | struct btf *btf; /* The BTF to be used */ |
| 425 | struct btf *struct_btf; /* The BTF to be used for structs */ | ||
| 425 | const struct btf_type *last_type; /* Saved type */ | 426 | const struct btf_type *last_type; /* Saved type */ |
| 427 | const struct btf_type *last_struct; /* Saved structure */ | ||
| 426 | u32 last_bitoffs; /* Saved bitoffs */ | 428 | u32 last_bitoffs; /* Saved bitoffs */ |
| 427 | u32 last_bitsize; /* Saved bitsize */ | 429 | u32 last_bitsize; /* Saved bitsize */ |
| 428 | struct trace_probe *tp; | 430 | struct trace_probe *tp; |
| @@ -563,7 +565,8 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, · 134 unmodified lines | |||
| 563 | C(NEED_STRING_TYPE, "$comm and immediate-string only accepts string type"),\ | 565 | C(NEED_STRING_TYPE, "$comm and immediate-string only accepts string type"),\ |
| 564 | C(TOO_MANY_ARGS, "Too many arguments are specified"), \ | 566 | C(TOO_MANY_ARGS, "Too many arguments are specified"), \ |
| 565 | C(TOO_MANY_EARGS, "Too many entry arguments specified"), \ | 567 | C(TOO_MANY_EARGS, "Too many entry arguments specified"), \ |
| 566 | C(EVENT_TOO_BIG, "Event too big (too many fields?)"), | 568 | C(EVENT_TOO_BIG, "Event too big (too many fields?)"), \ |
| 569 | C(TYPECAST_NOT_EVENT, "Typecasts are only for eprobe fields"), | ||
| 567 | 570 | ||
| 568 | #undef C | 571 | #undef C |
| 569 | #define C(a, b) TP_ERR_##a | 572 | #define C(a, b) TP_ERR_##a |
| @@ -912,7 +912,7 @@ static int uprobe_buffer_enable(void) · 911 unmodified lines | |||
| 912 | { | 912 | { |
| 913 | int ret = 0; | 913 | int ret = 0; |
| 914 | 914 | ||
| 915 | BUG_ON(!mutex_is_locked(&event_mutex)); | 915 | lockdep_assert_held(&event_mutex); |
| 916 | 916 | ||
| 917 | if (uprobe_buffer_refcnt++ == 0) { | 917 | if (uprobe_buffer_refcnt++ == 0) { |
| 918 | ret = uprobe_buffer_init(); | 918 | ret = uprobe_buffer_init(); |
| @@ -927,7 +927,7 @@ static void uprobe_buffer_disable(void) · 8 unmodified lines | |||
| 927 | { | 927 | { |
| 928 | int cpu; | 928 | int cpu; |
| 929 | 929 | ||
| 930 | BUG_ON(!mutex_is_locked(&event_mutex)); | 930 | lockdep_assert_held(&event_mutex); |
| 931 | 931 | ||
| 932 | if (--uprobe_buffer_refcnt == 0) { | 932 | if (--uprobe_buffer_refcnt == 0) { |
| 933 | for_each_possible_cpu(cpu) | 933 | for_each_possible_cpu(cpu) |
| @@ -979,6 +979,7 @@ static struct uprobe_cpu_buffer *prepare_uprobe_buffer(struct trace_uprobe *tu, · 45 unmodified lines | |||
| 979 | ucb = uprobe_buffer_get(); | 979 | ucb = uprobe_buffer_get(); |
| 980 | ucb->dsize = tu->tp.size + dsize; | 980 | ucb->dsize = tu->tp.size + dsize; |
| 981 | 981 | ||
| 982 | BUILD_BUG_ON(MAX_UCB_BUFFER_SIZE < MAX_PROBE_EVENT_SIZE); | ||
| 982 | if (WARN_ON_ONCE(ucb->dsize > MAX_UCB_BUFFER_SIZE)) { | 983 | if (WARN_ON_ONCE(ucb->dsize > MAX_UCB_BUFFER_SIZE)) { |
| 983 | ucb->dsize = MAX_UCB_BUFFER_SIZE; | 984 | ucb->dsize = MAX_UCB_BUFFER_SIZE; |
| 984 | dsize = MAX_UCB_BUFFER_SIZE - tu->tp.size; | 985 | dsize = MAX_UCB_BUFFER_SIZE - tu->tp.size; |