Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3a68eef9 authored by Markus Metzger's avatar Markus Metzger Committed by Ingo Molnar
Browse files

x86, ds: add task tracing selftest



Add selftests to cover per-task branch tracing.

Signed-off-by: default avatarMarkus Metzger <markus.t.metzger@intel.com>
Cc: roland@redhat.com
Cc: eranian@googlemail.com
Cc: oleg@redhat.com
Cc: juan.villacis@intel.com
Cc: ak@linux.jf.intel.com
LKML-Reference: <20090403144600.329346000@intel.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 01f6569e
Loading
Loading
Loading
Loading
+71 −0
Original line number Diff line number Diff line
@@ -280,10 +280,51 @@ static int ds_selftest_bts_bad_release_noirq(int cpu,
	return error ? 0 : -1;
}

static int ds_selftest_bts_bad_request_cpu(int cpu, void *buffer)
{
	struct bts_tracer *tracer;
	int error;

	/* Try to request cpu tracing while task tracing is active. */
	tracer = ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, NULL,
				    (size_t)-1, BTS_KERNEL);
	error = PTR_ERR(tracer);
	if (!IS_ERR(tracer)) {
		ds_release_bts(tracer);
		error = 0;
	}

	if (error != -EPERM)
		printk(KERN_CONT "cpu/task tracing overlap...");

	return error ? 0 : -1;
}

static int ds_selftest_bts_bad_request_task(void *buffer)
{
	struct bts_tracer *tracer;
	int error;

	/* Try to request cpu tracing while task tracing is active. */
	tracer = ds_request_bts_task(current, buffer, BUFFER_SIZE, NULL,
				    (size_t)-1, BTS_KERNEL);
	error = PTR_ERR(tracer);
	if (!IS_ERR(tracer)) {
		error = 0;
		ds_release_bts(tracer);
	}

	if (error != -EPERM)
		printk(KERN_CONT "task/cpu tracing overlap...");

	return error ? 0 : -1;
}

int ds_selftest_bts(void)
{
	struct ds_selftest_bts_conf conf;
	unsigned char buffer[BUFFER_SIZE];
	unsigned long irq;
	int cpu;

	printk(KERN_INFO "[ds] bts selftest...");
@@ -297,6 +338,8 @@ int ds_selftest_bts(void)
			ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE,
					   NULL, (size_t)-1, BTS_KERNEL);
		ds_selftest_bts_cpu(&conf);
		if (conf.error >= 0)
			conf.error = ds_selftest_bts_bad_request_task(buffer);
		ds_release_bts(conf.tracer);
		if (conf.error < 0)
			goto out;
@@ -315,12 +358,40 @@ int ds_selftest_bts(void)
			if (conf.error < 0)
				conf.tracer = NULL;
		}
		if (conf.error >= 0)
			conf.error = ds_selftest_bts_bad_request_task(buffer);
		smp_call_function_single(cpu, ds_release_bts_noirq_wrap,
					 conf.tracer, 1);
		if (conf.error < 0)
			goto out;
	}

	conf.suspend = ds_suspend_bts_wrap;
	conf.resume = ds_resume_bts_wrap;
	conf.tracer =
		ds_request_bts_task(current, buffer, BUFFER_SIZE,
				    NULL, (size_t)-1, BTS_KERNEL);
	ds_selftest_bts_cpu(&conf);
	if (conf.error >= 0)
		conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
	ds_release_bts(conf.tracer);
	if (conf.error < 0)
		goto out;

	conf.suspend = ds_suspend_bts_noirq;
	conf.resume = ds_resume_bts_noirq;
	conf.tracer =
		ds_request_bts_task(current, buffer, BUFFER_SIZE,
				   NULL, (size_t)-1, BTS_KERNEL);
	local_irq_save(irq);
	ds_selftest_bts_cpu(&conf);
	if (conf.error >= 0)
		conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
	ds_release_bts_noirq(conf.tracer);
	local_irq_restore(irq);
	if (conf.error < 0)
		goto out;

	conf.error = 0;
 out:
	put_online_cpus();