Commit 192ffb75 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tracing fixes from Steven Rostedt:

 - Fix bootconfig causing kernels to fail with CONFIG_BLK_DEV_RAM
   enabled

 - Fix allocation leaks in bootconfig tool

 - Fix a double initialization of a variable

 - Fix API bootconfig usage from kprobe boot time events

 - Reject NULL location for kprobes

 - Fix crash caused by preempt delay module not cleaning up kthread
   correctly

 - Add vmalloc_sync_mappings() to prevent x86_64 page faults from
   recursively faulting from tracing page faults

 - Fix comment in gpu/trace kerneldoc header

 - Fix documentation of how to create a trace event class

 - Make the local tracing_snapshot_instance_cond() function static

* tag 'trace-v5.7-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  tools/bootconfig: Fix resource leak in apply_xbc()
  tracing: Make tracing_snapshot_instance_cond() static
  tracing: Fix doc mistakes in trace sample
  gpu/trace: Minor comment updates for gpu_mem_total tracepoint
  tracing: Add a vmalloc_sync_mappings() for safe measure
  tracing: Wait for preempt irq delay thread to finish
  tracing/kprobes: Reject new event if loc is NULL
  tracing/boottime: Fix kprobe event API usage
  tracing/kprobes: Fix a double initialization typo
  bootconfig: Fix to remove bootconfig data from initrd while boot
parents 9ecc4d77 88426044
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
 *
 * @pid: Put 0 for global total, while positive pid for process total.
 *
 * @size: Virtual size of the allocation in bytes.
 * @size: Size of the allocation in bytes.
 *
 */
TRACE_EVENT(gpu_mem_total,
+52 −17
Original line number Diff line number Diff line
@@ -257,6 +257,47 @@ static int __init loglevel(char *str)

early_param("loglevel", loglevel);

#ifdef CONFIG_BLK_DEV_INITRD
static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
{
	u32 size, csum;
	char *data;
	u32 *hdr;

	if (!initrd_end)
		return NULL;

	data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN;
	if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN))
		return NULL;

	hdr = (u32 *)(data - 8);
	size = hdr[0];
	csum = hdr[1];

	data = ((void *)hdr) - size;
	if ((unsigned long)data < initrd_start) {
		pr_err("bootconfig size %d is greater than initrd size %ld\n",
			size, initrd_end - initrd_start);
		return NULL;
	}

	/* Remove bootconfig from initramfs/initrd */
	initrd_end = (unsigned long)data;
	if (_size)
		*_size = size;
	if (_csum)
		*_csum = csum;

	return data;
}
#else
static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
{
	return NULL;
}
#endif

#ifdef CONFIG_BOOT_CONFIG

char xbc_namebuf[XBC_KEYLEN_MAX] __initdata;
@@ -357,9 +398,12 @@ static void __init setup_boot_config(const char *cmdline)
	int pos;
	u32 size, csum;
	char *data, *copy;
	u32 *hdr;
	int ret;

	data = get_boot_config_from_initrd(&size, &csum);
	if (!data)
		goto not_found;

	strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
	parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
		   bootconfig_params);
@@ -367,27 +411,12 @@ static void __init setup_boot_config(const char *cmdline)
	if (!bootconfig_found)
		return;

	if (!initrd_end)
		goto not_found;

	data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN;
	if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN))
		goto not_found;

	hdr = (u32 *)(data - 8);
	size = hdr[0];
	csum = hdr[1];

	if (size >= XBC_DATA_MAX) {
		pr_err("bootconfig size %d greater than max size %d\n",
			size, XBC_DATA_MAX);
		return;
	}

	data = ((void *)hdr) - size;
	if ((unsigned long)data < initrd_start)
		goto not_found;

	if (boot_config_checksum((unsigned char *)data, size) != csum) {
		pr_err("bootconfig checksum failed\n");
		return;
@@ -420,8 +449,14 @@ static void __init setup_boot_config(const char *cmdline)
not_found:
	pr_err("'bootconfig' found on command line, but no bootconfig found\n");
}

#else
#define setup_boot_config(cmdline)	do { } while (0)

static void __init setup_boot_config(const char *cmdline)
{
	/* Remove bootconfig data from initrd */
	get_boot_config_from_initrd(NULL, NULL);
}

static int __init warn_bootconfig(char *str)
{
+24 −6
Original line number Diff line number Diff line
@@ -113,22 +113,42 @@ static int preemptirq_delay_run(void *data)

	for (i = 0; i < s; i++)
		(testfuncs[i])(i);

	set_current_state(TASK_INTERRUPTIBLE);
	while (!kthread_should_stop()) {
		schedule();
		set_current_state(TASK_INTERRUPTIBLE);
	}

	__set_current_state(TASK_RUNNING);

	return 0;
}

static struct task_struct *preemptirq_start_test(void)
static int preemptirq_run_test(void)
{
	struct task_struct *task;

	char task_name[50];

	snprintf(task_name, sizeof(task_name), "%s_test", test_mode);
	return kthread_run(preemptirq_delay_run, NULL, task_name);
	task =  kthread_run(preemptirq_delay_run, NULL, task_name);
	if (IS_ERR(task))
		return PTR_ERR(task);
	if (task)
		kthread_stop(task);
	return 0;
}


static ssize_t trigger_store(struct kobject *kobj, struct kobj_attribute *attr,
			 const char *buf, size_t count)
{
	preemptirq_start_test();
	ssize_t ret;

	ret = preemptirq_run_test();
	if (ret)
		return ret;
	return count;
}

@@ -148,11 +168,9 @@ static struct kobject *preemptirq_delay_kobj;

static int __init preemptirq_delay_init(void)
{
	struct task_struct *test_task;
	int retval;

	test_task = preemptirq_start_test();
	retval = PTR_ERR_OR_ZERO(test_task);
	retval = preemptirq_run_test();
	if (retval != 0)
		return retval;

+15 −1
Original line number Diff line number Diff line
@@ -947,7 +947,8 @@ int __trace_bputs(unsigned long ip, const char *str)
EXPORT_SYMBOL_GPL(__trace_bputs);

#ifdef CONFIG_TRACER_SNAPSHOT
void tracing_snapshot_instance_cond(struct trace_array *tr, void *cond_data)
static void tracing_snapshot_instance_cond(struct trace_array *tr,
					   void *cond_data)
{
	struct tracer *tracer = tr->current_trace;
	unsigned long flags;
@@ -8525,6 +8526,19 @@ static int allocate_trace_buffers(struct trace_array *tr, int size)
	 */
	allocate_snapshot = false;
#endif

	/*
	 * Because of some magic with the way alloc_percpu() works on
	 * x86_64, we need to synchronize the pgd of all the tables,
	 * otherwise the trace events that happen in x86_64 page fault
	 * handlers can't cope with accessing the chance that a
	 * alloc_percpu()'d memory might be touched in the page fault trace
	 * event. Oh, and we need to audit all other alloc_percpu() and vmalloc()
	 * calls in tracing, because something might get triggered within a
	 * page fault trace event!
	 */
	vmalloc_sync_mappings();

	return 0;
}

+8 −12
Original line number Diff line number Diff line
@@ -95,23 +95,19 @@ trace_boot_add_kprobe_event(struct xbc_node *node, const char *event)
	struct xbc_node *anode;
	char buf[MAX_BUF_LEN];
	const char *val;
	int ret;
	int ret = 0;

	xbc_node_for_each_array_value(node, "probes", anode, val) {
		kprobe_event_cmd_init(&cmd, buf, MAX_BUF_LEN);

	ret = kprobe_event_gen_cmd_start(&cmd, event, NULL);
		ret = kprobe_event_gen_cmd_start(&cmd, event, val);
		if (ret)
		return ret;

	xbc_node_for_each_array_value(node, "probes", anode, val) {
		ret = kprobe_event_add_field(&cmd, val);
		if (ret)
			return ret;
	}
			break;

		ret = kprobe_event_gen_cmd_end(&cmd);
		if (ret)
			pr_err("Failed to add probe: %s\n", buf);
	}

	return ret;
}
Loading