.. | .. |
---|
11 | 11 | #include <linux/tracepoint.h> |
---|
12 | 12 | |
---|
13 | 13 | struct trace_array; |
---|
14 | | -struct trace_buffer; |
---|
| 14 | +struct array_buffer; |
---|
15 | 15 | struct tracer; |
---|
16 | 16 | struct dentry; |
---|
17 | 17 | struct bpf_prog; |
---|
.. | .. |
---|
45 | 45 | const void *buf, int count, |
---|
46 | 46 | size_t el_size); |
---|
47 | 47 | |
---|
| 48 | +const char * |
---|
| 49 | +trace_print_hex_dump_seq(struct trace_seq *p, const char *prefix_str, |
---|
| 50 | + int prefix_type, int rowsize, int groupsize, |
---|
| 51 | + const void *buf, size_t len, bool ascii); |
---|
| 52 | + |
---|
48 | 53 | struct trace_iterator; |
---|
49 | 54 | struct trace_event; |
---|
50 | 55 | |
---|
.. | .. |
---|
62 | 67 | unsigned char flags; |
---|
63 | 68 | unsigned char preempt_count; |
---|
64 | 69 | int pid; |
---|
| 70 | + unsigned char migrate_disable; |
---|
| 71 | + unsigned char preempt_lazy_count; |
---|
65 | 72 | }; |
---|
66 | 73 | |
---|
67 | 74 | #define TRACE_EVENT_TYPE_MAX \ |
---|
.. | .. |
---|
74 | 81 | struct trace_iterator { |
---|
75 | 82 | struct trace_array *tr; |
---|
76 | 83 | struct tracer *trace; |
---|
77 | | - struct trace_buffer *trace_buffer; |
---|
| 84 | + struct array_buffer *array_buffer; |
---|
78 | 85 | void *private; |
---|
79 | 86 | int cpu_file; |
---|
80 | 87 | struct mutex mutex; |
---|
81 | 88 | struct ring_buffer_iter **buffer_iter; |
---|
82 | 89 | unsigned long iter_flags; |
---|
| 90 | + void *temp; /* temp holder */ |
---|
| 91 | + unsigned int temp_size; |
---|
83 | 92 | |
---|
84 | 93 | /* trace_seq for __print_flags() and __print_symbolic() etc. */ |
---|
85 | 94 | struct trace_seq tmp_seq; |
---|
.. | .. |
---|
141 | 150 | |
---|
142 | 151 | enum print_line_t trace_handle_return(struct trace_seq *s); |
---|
143 | 152 | |
---|
144 | | -void tracing_generic_entry_update(struct trace_entry *entry, |
---|
145 | | - unsigned long flags, |
---|
146 | | - int pc); |
---|
| 153 | +static inline void tracing_generic_entry_update(struct trace_entry *entry, |
---|
| 154 | + unsigned short type, |
---|
| 155 | + unsigned int trace_ctx) |
---|
| 156 | +{ |
---|
| 157 | + entry->preempt_count = trace_ctx & 0xff; |
---|
| 158 | + entry->migrate_disable = (trace_ctx >> 8) & 0xff; |
---|
| 159 | + entry->preempt_lazy_count = (trace_ctx >> 16) & 0xff; |
---|
| 160 | + entry->pid = current->pid; |
---|
| 161 | + entry->type = type; |
---|
| 162 | + entry->flags = trace_ctx >> 24; |
---|
| 163 | +} |
---|
| 164 | + |
---|
| 165 | +unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status); |
---|
| 166 | + |
---|
| 167 | +enum trace_flag_type { |
---|
| 168 | + TRACE_FLAG_IRQS_OFF = 0x01, |
---|
| 169 | + TRACE_FLAG_IRQS_NOSUPPORT = 0x02, |
---|
| 170 | + TRACE_FLAG_NEED_RESCHED = 0x04, |
---|
| 171 | + TRACE_FLAG_HARDIRQ = 0x08, |
---|
| 172 | + TRACE_FLAG_SOFTIRQ = 0x10, |
---|
| 173 | + TRACE_FLAG_PREEMPT_RESCHED = 0x20, |
---|
| 174 | + TRACE_FLAG_NMI = 0x40, |
---|
| 175 | + TRACE_FLAG_NEED_RESCHED_LAZY = 0x80, |
---|
| 176 | +}; |
---|
| 177 | + |
---|
| 178 | +#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT |
---|
| 179 | +static inline unsigned int tracing_gen_ctx_flags(unsigned long irqflags) |
---|
| 180 | +{ |
---|
| 181 | + unsigned int irq_status = irqs_disabled_flags(irqflags) ? |
---|
| 182 | + TRACE_FLAG_IRQS_OFF : 0; |
---|
| 183 | + return tracing_gen_ctx_irq_test(irq_status); |
---|
| 184 | +} |
---|
| 185 | +static inline unsigned int tracing_gen_ctx(void) |
---|
| 186 | +{ |
---|
| 187 | + unsigned long irqflags; |
---|
| 188 | + |
---|
| 189 | + local_save_flags(irqflags); |
---|
| 190 | + return tracing_gen_ctx_flags(irqflags); |
---|
| 191 | +} |
---|
| 192 | +#else |
---|
| 193 | + |
---|
| 194 | +static inline unsigned int tracing_gen_ctx_flags(unsigned long irqflags) |
---|
| 195 | +{ |
---|
| 196 | + return tracing_gen_ctx_irq_test(TRACE_FLAG_IRQS_NOSUPPORT); |
---|
| 197 | +} |
---|
| 198 | +static inline unsigned int tracing_gen_ctx(void) |
---|
| 199 | +{ |
---|
| 200 | + return tracing_gen_ctx_irq_test(TRACE_FLAG_IRQS_NOSUPPORT); |
---|
| 201 | +} |
---|
| 202 | +#endif |
---|
| 203 | + |
---|
| 204 | +static inline unsigned int tracing_gen_ctx_dec(void) |
---|
| 205 | +{ |
---|
| 206 | + unsigned int trace_ctx; |
---|
| 207 | + |
---|
| 208 | + trace_ctx = tracing_gen_ctx(); |
---|
| 209 | + /* |
---|
| 210 | + * Subtract one from the preeption counter if preemption is enabled, |
---|
| 211 | + * see trace_event_buffer_reserve()for details. |
---|
| 212 | + */ |
---|
| 213 | + if (IS_ENABLED(CONFIG_PREEMPTION)) |
---|
| 214 | + trace_ctx--; |
---|
| 215 | + return trace_ctx; |
---|
| 216 | +} |
---|
| 217 | + |
---|
147 | 218 | struct trace_event_file; |
---|
148 | 219 | |
---|
149 | 220 | struct ring_buffer_event * |
---|
150 | | -trace_event_buffer_lock_reserve(struct ring_buffer **current_buffer, |
---|
| 221 | +trace_event_buffer_lock_reserve(struct trace_buffer **current_buffer, |
---|
151 | 222 | struct trace_event_file *trace_file, |
---|
152 | 223 | int type, unsigned long len, |
---|
153 | | - unsigned long flags, int pc); |
---|
| 224 | + unsigned int trace_ctx); |
---|
154 | 225 | |
---|
155 | 226 | #define TRACE_RECORD_CMDLINE BIT(0) |
---|
156 | 227 | #define TRACE_RECORD_TGID BIT(1) |
---|
.. | .. |
---|
186 | 257 | |
---|
187 | 258 | struct trace_event_call; |
---|
188 | 259 | |
---|
| 260 | +#define TRACE_FUNCTION_TYPE ((const char *)~0UL) |
---|
| 261 | + |
---|
| 262 | +struct trace_event_fields { |
---|
| 263 | + const char *type; |
---|
| 264 | + union { |
---|
| 265 | + struct { |
---|
| 266 | + const char *name; |
---|
| 267 | + const int size; |
---|
| 268 | + const int align; |
---|
| 269 | + const int is_signed; |
---|
| 270 | + const int filter_type; |
---|
| 271 | + }; |
---|
| 272 | + int (*define_fields)(struct trace_event_call *); |
---|
| 273 | + }; |
---|
| 274 | +}; |
---|
| 275 | + |
---|
189 | 276 | struct trace_event_class { |
---|
190 | 277 | const char *system; |
---|
191 | 278 | void *probe; |
---|
.. | .. |
---|
194 | 281 | #endif |
---|
195 | 282 | int (*reg)(struct trace_event_call *event, |
---|
196 | 283 | enum trace_reg type, void *data); |
---|
197 | | - int (*define_fields)(struct trace_event_call *); |
---|
| 284 | + struct trace_event_fields *fields_array; |
---|
198 | 285 | struct list_head *(*get_fields)(struct trace_event_call *); |
---|
199 | 286 | struct list_head fields; |
---|
200 | 287 | int (*raw_init)(struct trace_event_call *); |
---|
.. | .. |
---|
204 | 291 | enum trace_reg type, void *data); |
---|
205 | 292 | |
---|
206 | 293 | struct trace_event_buffer { |
---|
207 | | - struct ring_buffer *buffer; |
---|
| 294 | + struct trace_buffer *buffer; |
---|
208 | 295 | struct ring_buffer_event *event; |
---|
209 | 296 | struct trace_event_file *trace_file; |
---|
210 | 297 | void *entry; |
---|
211 | | - unsigned long flags; |
---|
212 | | - int pc; |
---|
| 298 | + unsigned int trace_ctx; |
---|
| 299 | + struct pt_regs *regs; |
---|
213 | 300 | }; |
---|
214 | 301 | |
---|
215 | 302 | void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer, |
---|
.. | .. |
---|
317 | 404 | return call->name; |
---|
318 | 405 | } |
---|
319 | 406 | |
---|
| 407 | +static inline struct list_head * |
---|
| 408 | +trace_get_fields(struct trace_event_call *event_call) |
---|
| 409 | +{ |
---|
| 410 | + if (!event_call->class->get_fields) |
---|
| 411 | + return &event_call->class->fields; |
---|
| 412 | + return event_call->class->get_fields(event_call); |
---|
| 413 | +} |
---|
| 414 | + |
---|
320 | 415 | struct trace_array; |
---|
321 | 416 | struct trace_subsystem_dir; |
---|
322 | 417 | |
---|
.. | .. |
---|
333 | 428 | EVENT_FILE_FL_PID_FILTER_BIT, |
---|
334 | 429 | EVENT_FILE_FL_WAS_ENABLED_BIT, |
---|
335 | 430 | }; |
---|
| 431 | + |
---|
| 432 | +extern struct trace_event_file *trace_get_event_file(const char *instance, |
---|
| 433 | + const char *system, |
---|
| 434 | + const char *event); |
---|
| 435 | +extern void trace_put_event_file(struct trace_event_file *file); |
---|
| 436 | + |
---|
| 437 | +#define MAX_DYNEVENT_CMD_LEN (2048) |
---|
| 438 | + |
---|
| 439 | +enum dynevent_type { |
---|
| 440 | + DYNEVENT_TYPE_SYNTH = 1, |
---|
| 441 | + DYNEVENT_TYPE_KPROBE, |
---|
| 442 | + DYNEVENT_TYPE_NONE, |
---|
| 443 | +}; |
---|
| 444 | + |
---|
| 445 | +struct dynevent_cmd; |
---|
| 446 | + |
---|
| 447 | +typedef int (*dynevent_create_fn_t)(struct dynevent_cmd *cmd); |
---|
| 448 | + |
---|
| 449 | +struct dynevent_cmd { |
---|
| 450 | + struct seq_buf seq; |
---|
| 451 | + const char *event_name; |
---|
| 452 | + unsigned int n_fields; |
---|
| 453 | + enum dynevent_type type; |
---|
| 454 | + dynevent_create_fn_t run_command; |
---|
| 455 | + void *private_data; |
---|
| 456 | +}; |
---|
| 457 | + |
---|
| 458 | +extern int dynevent_create(struct dynevent_cmd *cmd); |
---|
| 459 | + |
---|
| 460 | +extern int synth_event_delete(const char *name); |
---|
| 461 | + |
---|
| 462 | +extern void synth_event_cmd_init(struct dynevent_cmd *cmd, |
---|
| 463 | + char *buf, int maxlen); |
---|
| 464 | + |
---|
| 465 | +extern int __synth_event_gen_cmd_start(struct dynevent_cmd *cmd, |
---|
| 466 | + const char *name, |
---|
| 467 | + struct module *mod, ...); |
---|
| 468 | + |
---|
| 469 | +#define synth_event_gen_cmd_start(cmd, name, mod, ...) \ |
---|
| 470 | + __synth_event_gen_cmd_start(cmd, name, mod, ## __VA_ARGS__, NULL) |
---|
| 471 | + |
---|
| 472 | +struct synth_field_desc { |
---|
| 473 | + const char *type; |
---|
| 474 | + const char *name; |
---|
| 475 | +}; |
---|
| 476 | + |
---|
| 477 | +extern int synth_event_gen_cmd_array_start(struct dynevent_cmd *cmd, |
---|
| 478 | + const char *name, |
---|
| 479 | + struct module *mod, |
---|
| 480 | + struct synth_field_desc *fields, |
---|
| 481 | + unsigned int n_fields); |
---|
| 482 | +extern int synth_event_create(const char *name, |
---|
| 483 | + struct synth_field_desc *fields, |
---|
| 484 | + unsigned int n_fields, struct module *mod); |
---|
| 485 | + |
---|
| 486 | +extern int synth_event_add_field(struct dynevent_cmd *cmd, |
---|
| 487 | + const char *type, |
---|
| 488 | + const char *name); |
---|
| 489 | +extern int synth_event_add_field_str(struct dynevent_cmd *cmd, |
---|
| 490 | + const char *type_name); |
---|
| 491 | +extern int synth_event_add_fields(struct dynevent_cmd *cmd, |
---|
| 492 | + struct synth_field_desc *fields, |
---|
| 493 | + unsigned int n_fields); |
---|
| 494 | + |
---|
| 495 | +#define synth_event_gen_cmd_end(cmd) \ |
---|
| 496 | + dynevent_create(cmd) |
---|
| 497 | + |
---|
| 498 | +struct synth_event; |
---|
| 499 | + |
---|
| 500 | +struct synth_event_trace_state { |
---|
| 501 | + struct trace_event_buffer fbuffer; |
---|
| 502 | + struct synth_trace_event *entry; |
---|
| 503 | + struct trace_buffer *buffer; |
---|
| 504 | + struct synth_event *event; |
---|
| 505 | + unsigned int cur_field; |
---|
| 506 | + unsigned int n_u64; |
---|
| 507 | + bool disabled; |
---|
| 508 | + bool add_next; |
---|
| 509 | + bool add_name; |
---|
| 510 | +}; |
---|
| 511 | + |
---|
| 512 | +extern int synth_event_trace(struct trace_event_file *file, |
---|
| 513 | + unsigned int n_vals, ...); |
---|
| 514 | +extern int synth_event_trace_array(struct trace_event_file *file, u64 *vals, |
---|
| 515 | + unsigned int n_vals); |
---|
| 516 | +extern int synth_event_trace_start(struct trace_event_file *file, |
---|
| 517 | + struct synth_event_trace_state *trace_state); |
---|
| 518 | +extern int synth_event_add_next_val(u64 val, |
---|
| 519 | + struct synth_event_trace_state *trace_state); |
---|
| 520 | +extern int synth_event_add_val(const char *field_name, u64 val, |
---|
| 521 | + struct synth_event_trace_state *trace_state); |
---|
| 522 | +extern int synth_event_trace_end(struct synth_event_trace_state *trace_state); |
---|
| 523 | + |
---|
| 524 | +extern int kprobe_event_delete(const char *name); |
---|
| 525 | + |
---|
| 526 | +extern void kprobe_event_cmd_init(struct dynevent_cmd *cmd, |
---|
| 527 | + char *buf, int maxlen); |
---|
| 528 | + |
---|
| 529 | +#define kprobe_event_gen_cmd_start(cmd, name, loc, ...) \ |
---|
| 530 | + __kprobe_event_gen_cmd_start(cmd, false, name, loc, ## __VA_ARGS__, NULL) |
---|
| 531 | + |
---|
| 532 | +#define kretprobe_event_gen_cmd_start(cmd, name, loc, ...) \ |
---|
| 533 | + __kprobe_event_gen_cmd_start(cmd, true, name, loc, ## __VA_ARGS__, NULL) |
---|
| 534 | + |
---|
| 535 | +extern int __kprobe_event_gen_cmd_start(struct dynevent_cmd *cmd, |
---|
| 536 | + bool kretprobe, |
---|
| 537 | + const char *name, |
---|
| 538 | + const char *loc, ...); |
---|
| 539 | + |
---|
| 540 | +#define kprobe_event_add_fields(cmd, ...) \ |
---|
| 541 | + __kprobe_event_add_fields(cmd, ## __VA_ARGS__, NULL) |
---|
| 542 | + |
---|
| 543 | +#define kprobe_event_add_field(cmd, field) \ |
---|
| 544 | + __kprobe_event_add_fields(cmd, field, NULL) |
---|
| 545 | + |
---|
| 546 | +extern int __kprobe_event_add_fields(struct dynevent_cmd *cmd, ...); |
---|
| 547 | + |
---|
| 548 | +#define kprobe_event_gen_cmd_end(cmd) \ |
---|
| 549 | + dynevent_create(cmd) |
---|
| 550 | + |
---|
| 551 | +#define kretprobe_event_gen_cmd_end(cmd) \ |
---|
| 552 | + dynevent_create(cmd) |
---|
336 | 553 | |
---|
337 | 554 | /* |
---|
338 | 555 | * Event file flags: |
---|
.. | .. |
---|
416 | 633 | |
---|
417 | 634 | #define PERF_MAX_TRACE_SIZE 2048 |
---|
418 | 635 | |
---|
419 | | -#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */ |
---|
| 636 | +#define MAX_FILTER_STR_VAL 256U /* Should handle KSYM_SYMBOL_LEN */ |
---|
420 | 637 | |
---|
421 | 638 | enum event_trigger_type { |
---|
422 | 639 | ETT_NONE = (0), |
---|
.. | .. |
---|
471 | 688 | int perf_event_query_prog_array(struct perf_event *event, void __user *info); |
---|
472 | 689 | int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog); |
---|
473 | 690 | int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog); |
---|
474 | | -struct bpf_raw_event_map *bpf_find_raw_tracepoint(const char *name); |
---|
| 691 | +struct bpf_raw_event_map *bpf_get_raw_tracepoint(const char *name); |
---|
| 692 | +void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp); |
---|
475 | 693 | int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, |
---|
476 | 694 | u32 *fd_type, const char **buf, |
---|
477 | 695 | u64 *probe_offset, u64 *probe_addr); |
---|
.. | .. |
---|
502 | 720 | { |
---|
503 | 721 | return -EOPNOTSUPP; |
---|
504 | 722 | } |
---|
505 | | -static inline struct bpf_raw_event_map *bpf_find_raw_tracepoint(const char *name) |
---|
| 723 | +static inline struct bpf_raw_event_map *bpf_get_raw_tracepoint(const char *name) |
---|
506 | 724 | { |
---|
507 | 725 | return NULL; |
---|
| 726 | +} |
---|
| 727 | +static inline void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp) |
---|
| 728 | +{ |
---|
508 | 729 | } |
---|
509 | 730 | static inline int bpf_get_perf_event_info(const struct perf_event *event, |
---|
510 | 731 | u32 *prog_id, u32 *fd_type, |
---|
.. | .. |
---|
529 | 750 | extern int trace_define_field(struct trace_event_call *call, const char *type, |
---|
530 | 751 | const char *name, int offset, int size, |
---|
531 | 752 | int is_signed, int filter_type); |
---|
532 | | -extern int trace_add_event_call_nolock(struct trace_event_call *call); |
---|
533 | | -extern int trace_remove_event_call_nolock(struct trace_event_call *call); |
---|
534 | 753 | extern int trace_add_event_call(struct trace_event_call *call); |
---|
535 | 754 | extern int trace_remove_event_call(struct trace_event_call *call); |
---|
536 | 755 | extern int trace_event_get_offsets(struct trace_event_call *call); |
---|
537 | 756 | |
---|
538 | 757 | #define is_signed_type(type) (((type)(-1)) < (type)1) |
---|
539 | 758 | |
---|
| 759 | +int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set); |
---|
540 | 760 | int trace_set_clr_event(const char *system, const char *event, int set); |
---|
541 | | - |
---|
| 761 | +int trace_array_set_clr_event(struct trace_array *tr, const char *system, |
---|
| 762 | + const char *event, bool enable); |
---|
542 | 763 | /* |
---|
543 | 764 | * The double __builtin_constant_p is because gcc will give us an error |
---|
544 | 765 | * if we try to allocate the static variable to fmt if it is not a |
---|
.. | .. |
---|
550 | 771 | tracing_record_cmdline(current); \ |
---|
551 | 772 | if (__builtin_constant_p(fmt)) { \ |
---|
552 | 773 | static const char *trace_printk_fmt \ |
---|
553 | | - __attribute__((section("__trace_printk_fmt"))) = \ |
---|
| 774 | + __section("__trace_printk_fmt") = \ |
---|
554 | 775 | __builtin_constant_p(fmt) ? fmt : NULL; \ |
---|
555 | 776 | \ |
---|
556 | 777 | __trace_bprintk(ip, trace_printk_fmt, ##args); \ |
---|
.. | .. |
---|
577 | 798 | bool perf_type_tracepoint); |
---|
578 | 799 | #endif |
---|
579 | 800 | #ifdef CONFIG_UPROBE_EVENTS |
---|
580 | | -extern int perf_uprobe_init(struct perf_event *event, bool is_retprobe); |
---|
| 801 | +extern int perf_uprobe_init(struct perf_event *event, |
---|
| 802 | + unsigned long ref_ctr_offset, bool is_retprobe); |
---|
581 | 803 | extern void perf_uprobe_destroy(struct perf_event *event); |
---|
582 | 804 | extern int bpf_get_uprobe_info(const struct perf_event *event, |
---|
583 | 805 | u32 *fd_type, const char **filename, |
---|