From nobody Mon Sep 15 01:54:07 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B1CE4C3DA78 for ; Tue, 17 Jan 2023 04:41:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235448AbjAQElU (ORCPT ); Mon, 16 Jan 2023 23:41:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235214AbjAQElH (ORCPT ); Mon, 16 Jan 2023 23:41:07 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 169F53ABE; Mon, 16 Jan 2023 20:41:03 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A0D78611AF; Tue, 17 Jan 2023 04:41:02 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0F2CDC433EF; Tue, 17 Jan 2023 04:41:02 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pHdmO-001rrf-32; Mon, 16 Jan 2023 23:41:00 -0500 Message-ID: <20230117044100.805996885@goodmis.org> User-Agent: quilt/0.66 Date: Mon, 16 Jan 2023 23:40:11 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Andrew Morton , Ross Zwisler Subject: [PATCH 1/5] tracing: Simplify calculating entry size using struct_size() References: <20230117044010.838685230@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Steven Rostedt (Google)" When tracing a dynamic string field for a synthetic event, the offset calculation for where to write the next event can use struct_size() to find what the current size of the structure is. This simplifies the code and makes it less error prone. Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_synth.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_= synth.c index 67592eed0be8..9f79cd689b79 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -416,8 +416,7 @@ static unsigned int trace_string(struct synth_trace_eve= nt *entry, if (is_dynamic) { u32 data_offset; =20 - data_offset =3D offsetof(typeof(*entry), fields); - data_offset +=3D event->n_u64 * sizeof(u64); + data_offset =3D struct_size(entry, fields, event->n_u64); data_offset +=3D data_size; =20 len =3D kern_fetch_store_strlen((unsigned long)str_val); --=20 2.39.0 From nobody Mon Sep 15 01:54:07 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EBCAFC63797 for ; Tue, 17 Jan 2023 04:41:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234808AbjAQEld (ORCPT ); Mon, 16 Jan 2023 23:41:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235385AbjAQElL (ORCPT ); Mon, 16 Jan 2023 23:41:11 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A5DA223102; Mon, 16 Jan 2023 20:41:04 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 5BD5FB80DFA; Tue, 17 Jan 2023 04:41:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1365EC433D2; Tue, 17 Jan 2023 04:41:02 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pHdmP-001rsA-0I; Mon, 16 Jan 2023 23:41:01 -0500 Message-ID: <20230117044100.962605301@goodmis.org> User-Agent: quilt/0.66 Date: Mon, 16 Jan 2023 23:40:12 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Andrew Morton , Ross Zwisler Subject: [PATCH 2/5] tracing: Allow stacktraces to be saved as histogram variables References: <20230117044010.838685230@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Steven Rostedt (Google)" Allow to save stacktraces into a histogram variable. This will be used by synthetic events to allow a stacktrace from one event to be passed and displayed by another event. The special keyword "stacktrace" is to be used to trigger a stack trace for the event that the histogram trigger is attached to. echo 'hist:keys=3Dpid:st=3Dstacktrace" > events/sched/sched_waking/trigger Currently nothing can get access to the "$st" variable above that contains the stack trace, but that will soon change. Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_events_hist.c | 35 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_h= ist.c index fcaf226b7744..5cc7873983ee 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -1360,6 +1360,8 @@ static const char *hist_field_name(struct hist_field = *field, field_name =3D field->name; } else if (field->flags & HIST_FIELD_FL_TIMESTAMP) field_name =3D "common_timestamp"; + else if (field->flags & HIST_FIELD_FL_STACKTRACE) + field_name =3D "stacktrace"; else if (field->flags & HIST_FIELD_FL_HITCOUNT) field_name =3D "hitcount"; =20 @@ -1980,6 +1982,10 @@ static struct hist_field *create_hist_field(struct h= ist_trigger_data *hist_data, =20 if (flags & HIST_FIELD_FL_STACKTRACE) { hist_field->fn_num =3D HIST_FIELD_FN_NOP; + hist_field->size =3D HIST_STACKTRACE_SIZE; + hist_field->type =3D kstrdup_const("unsigned long[]", GFP_KERNEL); + if (!hist_field->type) + goto free; goto out; } =20 @@ -2349,6 +2355,8 @@ parse_field(struct hist_trigger_data *hist_data, stru= ct trace_event_file *file, hist_data->enable_timestamps =3D true; if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS) hist_data->attrs->ts_in_usecs =3D true; + } else if (strcmp(field_name, "stacktrace") =3D=3D 0) { + *flags |=3D HIST_FIELD_FL_STACKTRACE; } else if (strcmp(field_name, "common_cpu") =3D=3D 0) *flags |=3D HIST_FIELD_FL_CPU; else if (strcmp(field_name, "hitcount") =3D=3D 0) @@ -3822,7 +3830,8 @@ static void save_field_var(struct hist_trigger_data *= hist_data, { hist_data->field_vars[hist_data->n_field_vars++] =3D field_var; =20 - if (field_var->val->flags & HIST_FIELD_FL_STRING) + /* Stack traces are saved in the string storage too */ + if (field_var->val->flags & (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTR= ACE)) hist_data->n_field_var_str++; } =20 @@ -4101,7 +4110,8 @@ static int action_create(struct hist_trigger_data *hi= st_data, } =20 hist_data->save_vars[hist_data->n_save_vars++] =3D field_var; - if (field_var->val->flags & HIST_FIELD_FL_STRING) + if (field_var->val->flags & + (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE)) hist_data->n_save_var_str++; kfree(param); } @@ -4349,7 +4359,8 @@ static int create_var_field(struct hist_trigger_data = *hist_data, if (!ret && hist_data->fields[val_idx]->flags & HIST_FIELD_FL_EXECNAME) update_var_execname(hist_data->fields[val_idx]); =20 - if (!ret && hist_data->fields[val_idx]->flags & HIST_FIELD_FL_STRING) + if (!ret && hist_data->fields[val_idx]->flags & + (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE)) hist_data->fields[val_idx]->var_str_idx =3D hist_data->n_var_str++; =20 return ret; @@ -5090,7 +5101,8 @@ static void hist_trigger_elt_update(struct hist_trigg= er_data *hist_data, if (hist_field->flags & HIST_FIELD_FL_VAR) { var_idx =3D hist_field->var.idx; =20 - if (hist_field->flags & HIST_FIELD_FL_STRING) { + if (hist_field->flags & + (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE)) { unsigned int str_start, var_str_idx, idx; char *str, *val_str; unsigned int size; @@ -5103,9 +5115,18 @@ static void hist_trigger_elt_update(struct hist_trig= ger_data *hist_data, str =3D elt_data->field_var_str[idx]; val_str =3D (char *)(uintptr_t)hist_val; =20 - size =3D min(hist_field->size, STR_VAR_LEN_MAX); - strscpy(str, val_str, size); - + if (hist_field->flags & HIST_FIELD_FL_STRING) { + size =3D min(hist_field->size, STR_VAR_LEN_MAX); + strscpy(str, val_str, size); + } else { + int e; + + e =3D stack_trace_save((void *)str, + HIST_STACKTRACE_DEPTH, + HIST_STACKTRACE_SKIP); + if (e < HIST_STACKTRACE_DEPTH - 1) + ((unsigned long *)str)[e] =3D 0; + } hist_val =3D (u64)(uintptr_t)str; } tracing_map_set_var(elt, var_idx, hist_val); --=20 2.39.0 From nobody Mon Sep 15 01:54:07 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA1F6C3DA78 for ; Tue, 17 Jan 2023 04:41:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235200AbjAQEl3 (ORCPT ); Mon, 16 Jan 2023 23:41:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59388 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235364AbjAQElL (ORCPT ); Mon, 16 Jan 2023 23:41:11 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82FA81A4AE; Mon, 16 Jan 2023 20:41:03 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 09501611B3; Tue, 17 Jan 2023 04:41:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 60D1CC43398; Tue, 17 Jan 2023 04:41:02 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pHdmP-001rse-0o; Mon, 16 Jan 2023 23:41:01 -0500 Message-ID: <20230117044101.111658742@goodmis.org> User-Agent: quilt/0.66 Date: Mon, 16 Jan 2023 23:40:13 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Andrew Morton , Ross Zwisler Subject: [PATCH 3/5] tracing: Allow synthetic events to pass around stacktraces References: <20230117044010.838685230@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Steven Rostedt (Google)" Allow a stacktrace from one event to be displayed by the end event of a synthetic event. This is very useful when looking for the longest latency of a sleep or something blocked on I/O. # cd /sys/kernel/tracing/ # echo 's:block_lat pid_t pid; u64 delta; unsigned long[] stack;' > dynami= c_events # echo 'hist:keys=3Dnext_pid:ts=3Dcommon_timestamp.usecs,st=3Dstacktrace = if prev_state =3D=3D 1||prev_state =3D=3D 2' > events/sched/sched_switch/tr= igger # echo 'hist:keys=3Dprev_pid:delta=3Dcommon_timestamp.usecs-$ts,s=3D$st:on= max($delta).trace(block_lat,prev_pid,$delta,$s)' >> events/sched/sched_swit= ch/trigger The above creates a "block_lat" synthetic event that take the stacktrace of when a task schedules out in either the interruptible or uninterruptible states, and on a new per process max $delta (the time it was scheduled out), will print the process id and the stacktrace. # echo 1 > events/synthetic/block_lat/enable # cat trace # TASK-PID CPU# ||||| TIMESTAMP FUNCTION # | | | ||||| | | kworker/u16:0-767 [006] d..4. 560.645045: block_lat: pid=3D767 de= lta=3D66 stack=3DSTACK: =3D> __schedule =3D> schedule =3D> pipe_read =3D> vfs_read =3D> ksys_read =3D> do_syscall_64 =3D> 0x966000aa -0 [003] d..4. 561.132117: block_lat: pid=3D0 delt= a=3D413787 stack=3DSTACK: =3D> __schedule =3D> schedule =3D> schedule_hrtimeout_range_clock =3D> do_sys_poll =3D> __x64_sys_poll =3D> do_syscall_64 =3D> 0x966000aa <...>-153 [006] d..4. 562.068407: block_lat: pid=3D153 de= lta=3D54 stack=3DSTACK: =3D> __schedule =3D> schedule =3D> io_schedule =3D> rq_qos_wait =3D> wbt_wait =3D> __rq_qos_throttle =3D> blk_mq_submit_bio =3D> submit_bio_noacct_nocheck =3D> ext4_bio_write_page =3D> mpage_submit_page =3D> mpage_process_page_bufs =3D> mpage_prepare_extent_to_map =3D> ext4_do_writepages =3D> ext4_writepages =3D> do_writepages =3D> __writeback_single_inode Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.h | 4 ++ kernel/trace/trace_events_hist.c | 7 ++- kernel/trace/trace_events_synth.c | 80 ++++++++++++++++++++++++++++++- kernel/trace/trace_synth.h | 1 + 4 files changed, 87 insertions(+), 5 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index a56b0b7d23ef..28294f6e15b9 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -113,6 +113,10 @@ enum trace_type { #define MEM_FAIL(condition, fmt, ...) \ DO_ONCE_LITE_IF(condition, pr_err, "ERROR: " fmt, ##__VA_ARGS__) =20 +#define HIST_STACKTRACE_DEPTH 16 +#define HIST_STACKTRACE_SIZE (HIST_STACKTRACE_DEPTH * sizeof(unsigned long= )) +#define HIST_STACKTRACE_SKIP 5 + /* * syscalls are special, and need special handling, this is why * they are not included in trace_entries.h diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_h= ist.c index 5cc7873983ee..d88c8e798ea4 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -480,10 +480,6 @@ DEFINE_HIST_FIELD_FN(u8); #define for_each_hist_key_field(i, hist_data) \ for ((i) =3D (hist_data)->n_vals; (i) < (hist_data)->n_fields; (i)++) =20 -#define HIST_STACKTRACE_DEPTH 16 -#define HIST_STACKTRACE_SIZE (HIST_STACKTRACE_DEPTH * sizeof(unsigned long= )) -#define HIST_STACKTRACE_SKIP 5 - #define HITCOUNT_IDX 0 #define HIST_KEY_SIZE_MAX (MAX_FILTER_STR_VAL + HIST_STACKTRACE_SIZE) =20 @@ -3856,6 +3852,9 @@ static int check_synth_field(struct synth_event *even= t, && field->is_dynamic) return 0; =20 + if (strstr(hist_field->type, "long[") && field->is_stack) + return 0; + if (strcmp(field->type, hist_field->type) !=3D 0) { if (field->size !=3D hist_field->size || (!field->is_string && field->is_signed !=3D hist_field->is_signed)) diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_= synth.c index 9f79cd689b79..1cfba626ea1e 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -173,6 +173,14 @@ static int synth_field_is_string(char *type) return false; } =20 +static int synth_field_is_stack(char *type) +{ + if (strstr(type, "long[") !=3D NULL) + return true; + + return false; +} + static int synth_field_string_size(char *type) { char buf[4], *end, *start; @@ -248,6 +256,8 @@ static int synth_field_size(char *type) size =3D sizeof(gfp_t); else if (synth_field_is_string(type)) size =3D synth_field_string_size(type); + else if (synth_field_is_stack(type)) + size =3D 0; =20 return size; } @@ -292,6 +302,8 @@ static const char *synth_field_fmt(char *type) fmt =3D "%x"; else if (synth_field_is_string(type)) fmt =3D "%.*s"; + else if (synth_field_is_stack(type)) + fmt =3D "%s"; =20 return fmt; } @@ -371,6 +383,23 @@ static enum print_line_t print_synth_event(struct trac= e_iterator *iter, i =3D=3D se->n_fields - 1 ? "" : " "); n_u64 +=3D STR_VAR_LEN_MAX / sizeof(u64); } + } else if (se->fields[i]->is_stack) { + u32 offset, data_offset, len; + unsigned long *p, *end; + + offset =3D (u32)entry->fields[n_u64]; + data_offset =3D offset & 0xffff; + len =3D offset >> 16; + + p =3D (void *)entry + data_offset; + end =3D (void *)p + len - (sizeof(long) - 1); + + trace_seq_printf(s, "%s=3DSTACK:\n", se->fields[i]->name); + + for (; *p && p < end; p++) + trace_seq_printf(s, "=3D> %pS\n", (void *)*p); + n_u64++; + } else { struct trace_print_flags __flags[] =3D { __def_gfpflag_names, {-1, NULL} }; @@ -446,6 +475,43 @@ static unsigned int trace_string(struct synth_trace_ev= ent *entry, return len; } =20 +static unsigned int trace_stack(struct synth_trace_event *entry, + struct synth_event *event, + long *stack, + unsigned int data_size, + unsigned int *n_u64) +{ + unsigned int len; + u32 data_offset; + void *data_loc; + + data_offset =3D struct_size(entry, fields, event->n_u64); + data_offset +=3D data_size; + + for (len =3D 0; len < HIST_STACKTRACE_DEPTH; len++) { + if (!stack[len]) + break; + } + + /* Include the zero'd element if it fits */ + if (len < HIST_STACKTRACE_DEPTH) + len++; + + len *=3D sizeof(long); + + /* Find the dynamic section to copy the stack into. */ + data_loc =3D (void *)entry + data_offset; + memcpy(data_loc, stack, len); + + /* Fill in the field that holds the offset/len combo */ + data_offset |=3D len << 16; + *(u32 *)&entry->fields[*n_u64] =3D data_offset; + + (*n_u64)++; + + return len; +} + static notrace void trace_event_raw_event_synth(void *__data, u64 *var_ref_vals, unsigned int *var_ref_idx) @@ -498,6 +564,12 @@ static notrace void trace_event_raw_event_synth(void *= __data, event->fields[i]->is_dynamic, data_size, &n_u64); data_size +=3D len; /* only dynamic string increments */ + } if (event->fields[i]->is_stack) { + long *stack =3D (long *)var_ref_vals[val_idx]; + + len =3D trace_stack(entry, event, stack, + data_size, &n_u64); + data_size +=3D len; } else { struct synth_field *field =3D event->fields[i]; u64 val =3D var_ref_vals[val_idx]; @@ -560,6 +632,9 @@ static int __set_synth_event_print_fmt(struct synth_eve= nt *event, event->fields[i]->is_dynamic) pos +=3D snprintf(buf + pos, LEN_OR_ZERO, ", __get_str(%s)", event->fields[i]->name); + else if (event->fields[i]->is_stack) + pos +=3D snprintf(buf + pos, LEN_OR_ZERO, + ", __get_stacktrace(%s)", event->fields[i]->name); else pos +=3D snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s", event->fields[i]->name); @@ -696,7 +771,8 @@ static struct synth_field *parse_synth_field(int argc, = char **argv, ret =3D -EINVAL; goto free; } else if (size =3D=3D 0) { - if (synth_field_is_string(field->type)) { + if (synth_field_is_string(field->type) || + synth_field_is_stack(field->type)) { char *type; =20 len =3D sizeof("__data_loc ") + strlen(field->type) + 1; @@ -727,6 +803,8 @@ static struct synth_field *parse_synth_field(int argc, = char **argv, =20 if (synth_field_is_string(field->type)) field->is_string =3D true; + else if (synth_field_is_stack(field->type)) + field->is_stack =3D true; =20 field->is_signed =3D synth_field_signed(field->type); out: diff --git a/kernel/trace/trace_synth.h b/kernel/trace/trace_synth.h index b29595fe3ac5..43f6fb6078db 100644 --- a/kernel/trace/trace_synth.h +++ b/kernel/trace/trace_synth.h @@ -18,6 +18,7 @@ struct synth_field { bool is_signed; bool is_string; bool is_dynamic; + bool is_stack; }; =20 struct synth_event { --=20 2.39.0 From nobody Mon Sep 15 01:54:07 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32068C63797 for ; Tue, 17 Jan 2023 04:41:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235450AbjAQEl0 (ORCPT ); Mon, 16 Jan 2023 23:41:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235362AbjAQElL (ORCPT ); Mon, 16 Jan 2023 23:41:11 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 655211A48D; Mon, 16 Jan 2023 20:41:03 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id F280C611B6; Tue, 17 Jan 2023 04:41:02 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 60D40C4339B; Tue, 17 Jan 2023 04:41:02 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pHdmP-001rt8-1K; Mon, 16 Jan 2023 23:41:01 -0500 Message-ID: <20230117044101.274203396@goodmis.org> User-Agent: quilt/0.66 Date: Mon, 16 Jan 2023 23:40:14 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Andrew Morton , Ross Zwisler Subject: [PATCH 4/5] tracing/histogram: Document variable stacktrace References: <20230117044010.838685230@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Steven Rostedt (Google)" Add a little documentation (and a useful example) of how a stacktrace can be used within a histogram variable. Signed-off-by: Steven Rostedt (Google) --- Documentation/trace/histogram.rst | 49 +++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/Documentation/trace/histogram.rst b/Documentation/trace/histog= ram.rst index f95459aa984f..5b7f985f35d9 100644 --- a/Documentation/trace/histogram.rst +++ b/Documentation/trace/histogram.rst @@ -1786,6 +1786,8 @@ or assigned to a variable and referenced in a subsequ= ent expression:: # echo 'hist:keys=3Dnext_pid:us_per_sec=3D1000000 ...' >> event/trigger # echo 'hist:keys=3Dnext_pid:timestamp_secs=3Dcommon_timestamp/$us_per_s= ec ...' >> event/trigger =20 +Variables can even hold stacktraces, which are useful with synthetic event= s. + 2.2.2 Synthetic Events ---------------------- =20 @@ -1940,6 +1942,53 @@ the ".buckets" modifier and specify a size (in this = case groups of 10). Entries: 16 Dropped: 0 =20 +To save stacktraces, create a synthetic event with a field of type "unsign= ed long[]" +or even just "long[]". For example, to see how long a task is blocked in an +uninterruptible state: + + # cd /sys/kernel/tracing + # echo 's:block_lat pid_t pid; u64 delta; unsigned long[] stack;' > dyna= mic_events + # echo 'hist:keys=3Dnext_pid:ts=3Dcommon_timestamp.usecs,st=3Dstacktrace= if prev_state =3D=3D 2' >> events/sched/sched_switch/trigger + # echo 'hist:keys=3Dprev_pid:delta=3Dcommon_timestamp.usecs-$ts,s=3D$st:= onmax($delta).trace(block_lat,prev_pid,$delta,$s)' >> events/sched/sched_sw= itch/trigger + # echo 1 > events/synthetic/block_lat/enable + # cat trace + + # tracer: nop + # + # entries-in-buffer/entries-written: 2/2 #P:8 + # + # _-----=3D> irqs-off/BH-disabled + # / _----=3D> need-resched + # | / _---=3D> hardirq/softirq + # || / _--=3D> preempt-depth + # ||| / _-=3D> migrate-disable + # |||| / delay + # TASK-PID CPU# ||||| TIMESTAMP FUNCTION + # | | | ||||| | | + -0 [005] d..4. 521.164922: block_lat: pid=3D0 de= lta=3D8322 stack=3DSTACK: + =3D> __schedule+0x448/0x7b0 + =3D> schedule+0x5a/0xb0 + =3D> io_schedule+0x42/0x70 + =3D> bit_wait_io+0xd/0x60 + =3D> __wait_on_bit+0x4b/0x140 + =3D> out_of_line_wait_on_bit+0x91/0xb0 + =3D> jbd2_journal_commit_transaction+0x1679/0x1a70 + =3D> kjournald2+0xa9/0x280 + =3D> kthread+0xe9/0x110 + =3D> ret_from_fork+0x2c/0x50 + + <...>-2 [004] d..4. 525.184257: block_lat: pid=3D2 de= lta=3D76 stack=3DSTACK: + =3D> __schedule+0x448/0x7b0 + =3D> schedule+0x5a/0xb0 + =3D> schedule_timeout+0x11a/0x150 + =3D> wait_for_completion_killable+0x144/0x1f0 + =3D> __kthread_create_on_node+0xe7/0x1e0 + =3D> kthread_create_on_node+0x51/0x70 + =3D> create_worker+0xcc/0x1a0 + =3D> worker_thread+0x2ad/0x380 + =3D> kthread+0xe9/0x110 + =3D> ret_from_fork+0x2c/0x50 + 2.2.3 Hist trigger 'handlers' and 'actions' ------------------------------------------- =20 --=20 2.39.0 From nobody Mon Sep 15 01:54:07 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 15EE8C3DA78 for ; Tue, 17 Jan 2023 04:41:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235542AbjAQEln (ORCPT ); Mon, 16 Jan 2023 23:41:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59390 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235368AbjAQElL (ORCPT ); Mon, 16 Jan 2023 23:41:11 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 947D523101; Mon, 16 Jan 2023 20:41:04 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 2CF50611B7; Tue, 17 Jan 2023 04:41:04 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 95312C433EF; Tue, 17 Jan 2023 04:41:03 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pHdmP-001rtc-1q; Mon, 16 Jan 2023 23:41:01 -0500 Message-ID: <20230117044101.434296637@goodmis.org> User-Agent: quilt/0.66 Date: Mon, 16 Jan 2023 23:40:15 -0500 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Andrew Morton , Ross Zwisler Subject: [PATCH 5/5] tracing/histogram: Add simple tests for stacktrace usage of synthetic events References: <20230117044010.838685230@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Steven Rostedt (Google)" Update the selftests to include a test of passing a stacktrace between the events of a synthetic event. Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 2 +- .../trigger-synthetic-event-stack.tc | 24 +++++++++++++++++++ .../trigger-synthetic-event-syntax.tc | 6 +++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/inter-eve= nt/trigger-synthetic-event-stack.tc diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d445789dc247..beb7b0e77874 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5803,7 +5803,7 @@ static const char readme_msg[] =3D #ifdef CONFIG_SYNTH_EVENTS " events/synthetic_events\t- Create/append/remove/show synthetic events\= n" "\t Write into this file to define/undefine new synthetic events.\n" - "\t example: echo 'myevent u64 lat; char name[]' >> synthetic_events\= n" + "\t example: echo 'myevent u64 lat; char name[]; long[] stack' >> syn= thetic_events\n" #endif #endif ; diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trig= ger-synthetic-event-stack.tc b/tools/testing/selftests/ftrace/test.d/trigge= r/inter-event/trigger-synthetic-event-stack.tc new file mode 100644 index 000000000000..755dbe94ccf4 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-syn= thetic-event-stack.tc @@ -0,0 +1,24 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: event trigger - test inter-event histogram trigger trace ac= tion with dynamic string param +# requires: set_event synthetic_events events/sched/sched_process_exec/his= t "long[]' >> synthetic_events":README + +fail() { #msg + echo $1 + exit_fail +} + +echo "Test create synthetic event with stack" + + +echo 's:wake_lat pid_t pid; u64 delta; unsigned long[] stack;' > dynamic_e= vents +echo 'hist:keys=3Dnext_pid:ts=3Dcommon_timestamp.usecs,st=3Dstacktrace if= prev_state =3D=3D 1||prev_state =3D=3D 2' >> events/sched/sched_switch/tri= gger +echo 'hist:keys=3Dprev_pid:delta=3Dcommon_timestamp.usecs-$ts,s=3D$st:onma= x($delta).trace(wake_lat,prev_pid,$delta,$s)' >> events/sched/sched_switch/= trigger +echo 1 > events/synthetic/wake_lat/enable +sleep 1 + +if ! grep -q "=3D>.*sched" trace; then + fail "Failed to create synthetic event with stack" +fi + +exit 0 diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trig= ger-synthetic-event-syntax.tc b/tools/testing/selftests/ftrace/test.d/trigg= er/inter-event/trigger-synthetic-event-syntax.tc index 2968cdc7df30..366f1f3ad906 100644 --- a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-syn= thetic-event-syntax.tc +++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-syn= thetic-event-syntax.tc @@ -70,6 +70,12 @@ grep "myevent[[:space:]]unsigned long var" synthetic_eve= nts echo "myevent char var[10]" > synthetic_events grep "myevent[[:space:]]char\[10\] var" synthetic_events =20 +if grep -q 'long\[\]' README; then + # test stacktrace type + echo "myevent unsigned long[] var" > synthetic_events + grep "myevent[[:space:]]unsigned long\[\] var" synthetic_events +fi + do_reset =20 exit 0 --=20 2.39.0