mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 12:52:30 +00:00
More tracing updates for 5.15:
- Add migrate-disable counter to tracing header - Fix error handling in event probes - Fix missed unlock in osnoise in error path - Fix merge issue with tools/bootconfig - Clean up bootconfig data when init memory is removed - Fix bootconfig to loop only on subkeys - Have kernel command lines override bootconfig options - Increase field counts for synthetic events - Have histograms dynamic allocate event elements to save space - Fixes in testing and documentation -----BEGIN PGP SIGNATURE----- iIoEABYIADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCYToFZBQccm9zdGVkdEBn b29kbWlzLm9yZwAKCRAp5XQQmuv6qtg5AP44U3Dn1m1lQo3y1DJ9kUP3HsAsDofS Cv7ZM9tLV2p4MQEA9KJc3/B/5BZEK1kso3uLeLT+WxJOC4YStXY19WwmjAI= =Wuo+ -----END PGP SIGNATURE----- Merge tag 'trace-v5.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace Pull more tracing updates from Steven Rostedt: - Add migrate-disable counter to tracing header - Fix error handling in event probes - Fix missed unlock in osnoise in error path - Fix merge issue with tools/bootconfig - Clean up bootconfig data when init memory is removed - Fix bootconfig to loop only on subkeys - Have kernel command lines override bootconfig options - Increase field counts for synthetic events - Have histograms dynamic allocate event elements to save space - Fixes in testing and documentation * tag 'trace-v5.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing/boot: Fix to loop on only subkeys selftests/ftrace: Exclude "(fault)" in testing add/remove eprobe events tracing: Dynamically allocate the per-elt hist_elt_data array tracing: synth events: increase max fields count tools/bootconfig: Show whole test command for each test case bootconfig: Fix missing return check of xbc_node_compose_key function tools/bootconfig: Fix tracing_on option checking in ftrace2bconf.sh docs: bootconfig: Add how to use bootconfig for kernel parameters init/bootconfig: Reorder init parameter from bootconfig and cmdline init: bootconfig: Remove all bootconfig data when the init memory is removed tracing/osnoise: Fix missed cpus_read_unlock() in start_per_cpu_kthreads() tracing: Fix some alloc_event_probe() error handling bugs tracing: Add migrate-disabled counter to tracing output.
This commit is contained in:
commit
43175623dd
@ -178,7 +178,7 @@ update the boot loader and the kernel image itself as long as the boot
|
||||
loader passes the correct initrd file size. If by any chance, the boot
|
||||
loader passes a longer size, the kernel fails to find the bootconfig data.
|
||||
|
||||
To do this operation, Linux kernel provides "bootconfig" command under
|
||||
To do this operation, Linux kernel provides ``bootconfig`` command under
|
||||
tools/bootconfig, which allows admin to apply or delete the config file
|
||||
to/from initrd image. You can build it by the following command::
|
||||
|
||||
@ -196,6 +196,43 @@ To remove the config from the image, you can use -d option as below::
|
||||
Then add "bootconfig" on the normal kernel command line to tell the
|
||||
kernel to look for the bootconfig at the end of the initrd file.
|
||||
|
||||
|
||||
Kernel parameters via Boot Config
|
||||
=================================
|
||||
|
||||
In addition to the kernel command line, the boot config can be used for
|
||||
passing the kernel parameters. All the key-value pairs under ``kernel``
|
||||
key will be passed to kernel cmdline directly. Moreover, the key-value
|
||||
pairs under ``init`` will be passed to init process via the cmdline.
|
||||
The parameters are concatinated with user-given kernel cmdline string
|
||||
as the following order, so that the command line parameter can override
|
||||
bootconfig parameters (this depends on how the subsystem handles parameters
|
||||
but in general, earlier parameter will be overwritten by later one.)::
|
||||
|
||||
[bootconfig params][cmdline params] -- [bootconfig init params][cmdline init params]
|
||||
|
||||
Here is an example of the bootconfig file for kernel/init parameters.::
|
||||
|
||||
kernel {
|
||||
root = 01234567-89ab-cdef-0123-456789abcd
|
||||
}
|
||||
init {
|
||||
splash
|
||||
}
|
||||
|
||||
This will be copied into the kernel cmdline string as the following::
|
||||
|
||||
root="01234567-89ab-cdef-0123-456789abcd" -- splash
|
||||
|
||||
If user gives some other command line like,::
|
||||
|
||||
ro bootconfig -- quiet
|
||||
|
||||
The final kernel cmdline will be the following::
|
||||
|
||||
root="01234567-89ab-cdef-0123-456789abcd" ro bootconfig -- splash quiet
|
||||
|
||||
|
||||
Config File Limitation
|
||||
======================
|
||||
|
||||
|
37
init/main.c
37
init/main.c
@ -153,10 +153,10 @@ static char *extra_init_args;
|
||||
#ifdef CONFIG_BOOT_CONFIG
|
||||
/* Is bootconfig on command line? */
|
||||
static bool bootconfig_found;
|
||||
static bool initargs_found;
|
||||
static size_t initargs_offs;
|
||||
#else
|
||||
# define bootconfig_found false
|
||||
# define initargs_found false
|
||||
# define initargs_offs 0
|
||||
#endif
|
||||
|
||||
static char *execute_command;
|
||||
@ -422,9 +422,9 @@ static void __init setup_boot_config(void)
|
||||
if (IS_ERR(err) || !bootconfig_found)
|
||||
return;
|
||||
|
||||
/* parse_args() stops at '--' and returns an address */
|
||||
/* parse_args() stops at the next param of '--' and returns an address */
|
||||
if (err)
|
||||
initargs_found = true;
|
||||
initargs_offs = err - tmp_cmdline;
|
||||
|
||||
if (!data) {
|
||||
pr_err("'bootconfig' found on command line, but no bootconfig found\n");
|
||||
@ -468,7 +468,12 @@ static void __init setup_boot_config(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
static void __init exit_boot_config(void)
|
||||
{
|
||||
xbc_destroy_all();
|
||||
}
|
||||
|
||||
#else /* !CONFIG_BOOT_CONFIG */
|
||||
|
||||
static void __init setup_boot_config(void)
|
||||
{
|
||||
@ -481,7 +486,11 @@ static int __init warn_bootconfig(char *str)
|
||||
pr_warn("WARNING: 'bootconfig' found on the kernel command line but CONFIG_BOOT_CONFIG is not set.\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define exit_boot_config() do {} while (0)
|
||||
|
||||
#endif /* CONFIG_BOOT_CONFIG */
|
||||
|
||||
early_param("bootconfig", warn_bootconfig);
|
||||
|
||||
/* Change NUL term back to "=", to make "param" the whole string. */
|
||||
@ -646,16 +655,21 @@ static void __init setup_command_line(char *command_line)
|
||||
* Append supplemental init boot args to saved_command_line
|
||||
* so that user can check what command line options passed
|
||||
* to init.
|
||||
* The order should always be
|
||||
* " -- "[bootconfig init-param][cmdline init-param]
|
||||
*/
|
||||
len = strlen(saved_command_line);
|
||||
if (initargs_found) {
|
||||
saved_command_line[len++] = ' ';
|
||||
if (initargs_offs) {
|
||||
len = xlen + initargs_offs;
|
||||
strcpy(saved_command_line + len, extra_init_args);
|
||||
len += ilen - 4; /* strlen(extra_init_args) */
|
||||
strcpy(saved_command_line + len,
|
||||
boot_command_line + initargs_offs - 1);
|
||||
} else {
|
||||
len = strlen(saved_command_line);
|
||||
strcpy(saved_command_line + len, " -- ");
|
||||
len += 4;
|
||||
strcpy(saved_command_line + len, extra_init_args);
|
||||
}
|
||||
|
||||
strcpy(saved_command_line + len, extra_init_args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1494,6 +1508,7 @@ static int __ref kernel_init(void *unused)
|
||||
kprobe_free_init_mem();
|
||||
ftrace_free_init_mem();
|
||||
kgdb_free_init_mem();
|
||||
exit_boot_config();
|
||||
free_initmem();
|
||||
mark_readonly();
|
||||
|
||||
|
@ -2603,6 +2603,15 @@ enum print_line_t trace_handle_return(struct trace_seq *s)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(trace_handle_return);
|
||||
|
||||
static unsigned short migration_disable_value(void)
|
||||
{
|
||||
#if defined(CONFIG_SMP)
|
||||
return current->migration_disabled;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status)
|
||||
{
|
||||
unsigned int trace_flags = irqs_status;
|
||||
@ -2621,7 +2630,8 @@ unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status)
|
||||
trace_flags |= TRACE_FLAG_NEED_RESCHED;
|
||||
if (test_preempt_need_resched())
|
||||
trace_flags |= TRACE_FLAG_PREEMPT_RESCHED;
|
||||
return (trace_flags << 16) | (pc & 0xff);
|
||||
return (trace_flags << 16) | (min_t(unsigned int, pc & 0xff, 0xf)) |
|
||||
(min_t(unsigned int, migration_disable_value(), 0xf)) << 4;
|
||||
}
|
||||
|
||||
struct ring_buffer_event *
|
||||
@ -4189,9 +4199,10 @@ static void print_lat_help_header(struct seq_file *m)
|
||||
"# | / _----=> need-resched \n"
|
||||
"# || / _---=> hardirq/softirq \n"
|
||||
"# ||| / _--=> preempt-depth \n"
|
||||
"# |||| / delay \n"
|
||||
"# cmd pid ||||| time | caller \n"
|
||||
"# \\ / ||||| \\ | / \n");
|
||||
"# |||| / _-=> migrate-disable \n"
|
||||
"# ||||| / delay \n"
|
||||
"# cmd pid |||||| time | caller \n"
|
||||
"# \\ / |||||| \\ | / \n");
|
||||
}
|
||||
|
||||
static void print_event_info(struct array_buffer *buf, struct seq_file *m)
|
||||
@ -4229,9 +4240,10 @@ static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file
|
||||
seq_printf(m, "# %.*s / _----=> need-resched\n", prec, space);
|
||||
seq_printf(m, "# %.*s| / _---=> hardirq/softirq\n", prec, space);
|
||||
seq_printf(m, "# %.*s|| / _--=> preempt-depth\n", prec, space);
|
||||
seq_printf(m, "# %.*s||| / delay\n", prec, space);
|
||||
seq_printf(m, "# TASK-PID %.*s CPU# |||| TIMESTAMP FUNCTION\n", prec, " TGID ");
|
||||
seq_printf(m, "# | | %.*s | |||| | |\n", prec, " | ");
|
||||
seq_printf(m, "# %.*s||| / _-=> migrate-disable\n", prec, space);
|
||||
seq_printf(m, "# %.*s|||| / delay\n", prec, space);
|
||||
seq_printf(m, "# TASK-PID %.*s CPU# ||||| TIMESTAMP FUNCTION\n", prec, " TGID ");
|
||||
seq_printf(m, "# | | %.*s | ||||| | |\n", prec, " | ");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -522,14 +522,14 @@ trace_boot_init_events(struct trace_array *tr, struct xbc_node *node)
|
||||
if (!node)
|
||||
return;
|
||||
/* per-event key starts with "event.GROUP.EVENT" */
|
||||
xbc_node_for_each_child(node, gnode) {
|
||||
xbc_node_for_each_subkey(node, gnode) {
|
||||
data = xbc_node_get_data(gnode);
|
||||
if (!strcmp(data, "enable")) {
|
||||
enable_all = true;
|
||||
continue;
|
||||
}
|
||||
enable = false;
|
||||
xbc_node_for_each_child(gnode, enode) {
|
||||
xbc_node_for_each_subkey(gnode, enode) {
|
||||
data = xbc_node_get_data(enode);
|
||||
if (!strcmp(data, "enable")) {
|
||||
enable = true;
|
||||
@ -625,7 +625,7 @@ trace_boot_init_instances(struct xbc_node *node)
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
xbc_node_for_each_child(node, inode) {
|
||||
xbc_node_for_each_subkey(node, inode) {
|
||||
p = xbc_node_get_data(inode);
|
||||
if (!p || *p == '\0')
|
||||
continue;
|
||||
|
@ -151,7 +151,7 @@ static struct trace_eprobe *alloc_event_probe(const char *group,
|
||||
|
||||
ep = kzalloc(struct_size(ep, tp.args, nargs), GFP_KERNEL);
|
||||
if (!ep) {
|
||||
trace_event_put_ref(ep->event);
|
||||
trace_event_put_ref(event);
|
||||
goto error;
|
||||
}
|
||||
ep->event = event;
|
||||
@ -851,7 +851,8 @@ static int __trace_eprobe_create(int argc, const char *argv[])
|
||||
ret = PTR_ERR(ep);
|
||||
/* This must return -ENOMEM, else there is a bug */
|
||||
WARN_ON_ONCE(ret != -ENOMEM);
|
||||
goto error; /* We know ep is not allocated */
|
||||
ep = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
argc -= 2; argv += 2;
|
||||
|
@ -181,6 +181,7 @@ static int trace_define_common_fields(void)
|
||||
|
||||
__common_field(unsigned short, type);
|
||||
__common_field(unsigned char, flags);
|
||||
/* Holds both preempt_count and migrate_disable */
|
||||
__common_field(unsigned char, preempt_count);
|
||||
__common_field(int, pid);
|
||||
|
||||
|
@ -508,7 +508,8 @@ struct track_data {
|
||||
struct hist_elt_data {
|
||||
char *comm;
|
||||
u64 *var_ref_vals;
|
||||
char *field_var_str[SYNTH_FIELDS_MAX];
|
||||
char **field_var_str;
|
||||
int n_field_var_str;
|
||||
};
|
||||
|
||||
struct snapshot_context {
|
||||
@ -1401,9 +1402,11 @@ static void hist_elt_data_free(struct hist_elt_data *elt_data)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < SYNTH_FIELDS_MAX; i++)
|
||||
for (i = 0; i < elt_data->n_field_var_str; i++)
|
||||
kfree(elt_data->field_var_str[i]);
|
||||
|
||||
kfree(elt_data->field_var_str);
|
||||
|
||||
kfree(elt_data->comm);
|
||||
kfree(elt_data);
|
||||
}
|
||||
@ -1451,6 +1454,13 @@ static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt)
|
||||
|
||||
size = STR_VAR_LEN_MAX;
|
||||
|
||||
elt_data->field_var_str = kcalloc(n_str, sizeof(char *), GFP_KERNEL);
|
||||
if (!elt_data->field_var_str) {
|
||||
hist_elt_data_free(elt_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
elt_data->n_field_var_str = n_str;
|
||||
|
||||
for (i = 0; i < n_str; i++) {
|
||||
elt_data->field_var_str[i] = kzalloc(size, GFP_KERNEL);
|
||||
if (!elt_data->field_var_str[i]) {
|
||||
|
@ -1548,7 +1548,7 @@ static int start_kthread(unsigned int cpu)
|
||||
static int start_per_cpu_kthreads(struct trace_array *tr)
|
||||
{
|
||||
struct cpumask *current_mask = &save_cpumask;
|
||||
int retval;
|
||||
int retval = 0;
|
||||
int cpu;
|
||||
|
||||
cpus_read_lock();
|
||||
@ -1568,13 +1568,13 @@ static int start_per_cpu_kthreads(struct trace_array *tr)
|
||||
retval = start_kthread(cpu);
|
||||
if (retval) {
|
||||
stop_per_cpu_kthreads();
|
||||
return retval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cpus_read_unlock();
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
@ -492,8 +492,13 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
|
||||
trace_seq_printf(s, "%c%c%c",
|
||||
irqs_off, need_resched, hardsoft_irq);
|
||||
|
||||
if (entry->preempt_count)
|
||||
trace_seq_printf(s, "%x", entry->preempt_count);
|
||||
if (entry->preempt_count & 0xf)
|
||||
trace_seq_printf(s, "%x", entry->preempt_count & 0xf);
|
||||
else
|
||||
trace_seq_putc(s, '.');
|
||||
|
||||
if (entry->preempt_count & 0xf0)
|
||||
trace_seq_printf(s, "%x", entry->preempt_count >> 4);
|
||||
else
|
||||
trace_seq_putc(s, '.');
|
||||
|
||||
@ -656,7 +661,7 @@ int trace_print_lat_context(struct trace_iterator *iter)
|
||||
trace_seq_printf(
|
||||
s, "%16s %7d %3d %d %08x %08lx ",
|
||||
comm, entry->pid, iter->cpu, entry->flags,
|
||||
entry->preempt_count, iter->idx);
|
||||
entry->preempt_count & 0xf, iter->idx);
|
||||
} else {
|
||||
lat_print_generic(s, entry, iter->cpu);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "trace_dynevent.h"
|
||||
|
||||
#define SYNTH_SYSTEM "synthetic"
|
||||
#define SYNTH_FIELDS_MAX 32
|
||||
#define SYNTH_FIELDS_MAX 64
|
||||
|
||||
#define STR_VAR_LEN_MAX MAX_FILTER_STR_VAL /* must be multiple of sizeof(u64) */
|
||||
|
||||
|
@ -111,9 +111,11 @@ static void xbc_show_list(void)
|
||||
char key[XBC_KEYLEN_MAX];
|
||||
struct xbc_node *leaf;
|
||||
const char *val;
|
||||
int ret;
|
||||
|
||||
xbc_for_each_key_value(leaf, val) {
|
||||
if (xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX) < 0) {
|
||||
ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to compose key %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
@ -239,8 +239,8 @@ instance_options() { # [instance-name]
|
||||
emit_kv $PREFIX.cpumask = $val
|
||||
fi
|
||||
val=`cat $INSTANCE/tracing_on`
|
||||
if [ `echo $val | sed -e s/f//g`x != x ]; then
|
||||
emit_kv $PREFIX.tracing_on = $val
|
||||
if [ "$val" = "0" ]; then
|
||||
emit_kv $PREFIX.tracing_on = 0
|
||||
fi
|
||||
|
||||
val=`cat $INSTANCE/current_tracer`
|
||||
|
@ -26,7 +26,7 @@ trap cleanup EXIT TERM
|
||||
NO=1
|
||||
|
||||
xpass() { # pass test command
|
||||
echo "test case $NO ($3)... "
|
||||
echo "test case $NO ($*)... "
|
||||
if ! ($@ && echo "\t\t[OK]"); then
|
||||
echo "\t\t[NG]"; NG=$((NG + 1))
|
||||
fi
|
||||
@ -34,7 +34,7 @@ xpass() { # pass test command
|
||||
}
|
||||
|
||||
xfail() { # fail test command
|
||||
echo "test case $NO ($3)... "
|
||||
echo "test case $NO ($*)... "
|
||||
if ! (! $@ && echo "\t\t[OK]"); then
|
||||
echo "\t\t[NG]"; NG=$((NG + 1))
|
||||
fi
|
||||
|
@ -22,7 +22,7 @@ ls
|
||||
echo 0 > events/eprobes/$EPROBE/enable
|
||||
|
||||
content=`grep '^ *ls-' trace | grep 'file='`
|
||||
nocontent=`grep '^ *ls-' trace | grep 'file=' | grep -v -e '"/' -e '"."'` || true
|
||||
nocontent=`grep '^ *ls-' trace | grep 'file=' | grep -v -e '"/' -e '"."' -e '(fault)' ` || true
|
||||
|
||||
if [ -z "$content" ]; then
|
||||
exit_fail
|
||||
|
Loading…
Reference in New Issue
Block a user