Commit 23488ec6 authored by Marco Elver's avatar Marco Elver Committed by Peter Zijlstra
Browse files

selftests/perf_events: Add a SIGTRAP stress test with disables



Add a SIGTRAP stress test that exercises repeatedly enabling/disabling
an event while it concurrently keeps firing.

Signed-off-by: default avatarMarco Elver <elver@google.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/Y0E3uG7jOywn7vy3@elver.google.com/
parent ca6c2132
Loading
Loading
Loading
Loading
+32 −3
Original line number Original line Diff line number Diff line
@@ -62,6 +62,8 @@ static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr,
		.remove_on_exec = 1, /* Required by sigtrap. */
		.remove_on_exec = 1, /* Required by sigtrap. */
		.sigtrap	= 1, /* Request synchronous SIGTRAP on event. */
		.sigtrap	= 1, /* Request synchronous SIGTRAP on event. */
		.sig_data	= TEST_SIG_DATA(addr, id),
		.sig_data	= TEST_SIG_DATA(addr, id),
		.exclude_kernel = 1, /* To allow */
		.exclude_hv     = 1, /* running as !root */
	};
	};
	return attr;
	return attr;
}
}
@@ -93,10 +95,14 @@ static void *test_thread(void *arg)


	__atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED);
	__atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED);
	iter = ctx.iterate_on; /* read */
	iter = ctx.iterate_on; /* read */
	if (iter >= 0) {
		for (i = 0; i < iter - 1; i++) {
		for (i = 0; i < iter - 1; i++) {
			__atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED);
			__atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED);
			ctx.iterate_on = iter; /* idempotent write */
			ctx.iterate_on = iter; /* idempotent write */
		}
		}
	} else {
		while (ctx.iterate_on);
	}


	return NULL;
	return NULL;
}
}
@@ -208,4 +214,27 @@ TEST_F(sigtrap_threads, signal_stress)
	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
}
}


TEST_F(sigtrap_threads, signal_stress_with_disable)
{
	const int target_count = NUM_THREADS * 3000;
	int i;

	ctx.iterate_on = -1;

	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
	pthread_barrier_wait(&self->barrier);
	while (__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED) < target_count) {
		EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0);
		EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
	}
	ctx.iterate_on = 0;
	for (i = 0; i < NUM_THREADS; i++)
		ASSERT_EQ(pthread_join(self->threads[i], NULL), 0);
	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0);

	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
}

TEST_HARNESS_MAIN
TEST_HARNESS_MAIN