About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / prctl / disable-tsc-ctxt-sw-stress-test.c


Based on kernel version 4.8. Page generated on 2016-10-06 23:18 EST.

1	/*
2	 * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
3	 *
4	 * Tests if the control register is updated correctly
5	 * at context switches
6	 *
7	 * Warning: this test will cause a very high load for a few seconds
8	 *
9	 */
10	
11	#include <stdio.h>
12	#include <stdlib.h>
13	#include <unistd.h>
14	#include <signal.h>
15	#include <inttypes.h>
16	#include <wait.h>
17	
18	
19	#include <sys/prctl.h>
20	#include <linux/prctl.h>
21	
22	/* Get/set the process' ability to use the timestamp counter instruction */
23	#ifndef PR_GET_TSC
24	#define PR_GET_TSC 25
25	#define PR_SET_TSC 26
26	# define PR_TSC_ENABLE		1   /* allow the use of the timestamp counter */
27	# define PR_TSC_SIGSEGV		2   /* throw a SIGSEGV instead of reading the TSC */
28	#endif
29	
30	static uint64_t rdtsc(void)
31	{
32	uint32_t lo, hi;
33	/* We cannot use "=A", since this would use %rax on x86_64 */
34	__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
35	return (uint64_t)hi << 32 | lo;
36	}
37	
38	static void sigsegv_expect(int sig)
39	{
40		/* */
41	}
42	
43	static void segvtask(void)
44	{
45		if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
46		{
47			perror("prctl");
48			exit(0);
49		}
50		signal(SIGSEGV, sigsegv_expect);
51		alarm(10);
52		rdtsc();
53		fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
54		exit(0);
55	}
56	
57	
58	static void sigsegv_fail(int sig)
59	{
60		fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
61		exit(0);
62	}
63	
64	static void rdtsctask(void)
65	{
66		if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
67		{
68			perror("prctl");
69			exit(0);
70		}
71		signal(SIGSEGV, sigsegv_fail);
72		alarm(10);
73		for(;;) rdtsc();
74	}
75	
76	
77	int main(void)
78	{
79		int n_tasks = 100, i;
80	
81		fprintf(stderr, "[No further output means we're allright]\n");
82	
83		for (i=0; i<n_tasks; i++)
84			if (fork() == 0)
85			{
86				if (i & 1)
87					segvtask();
88				else
89					rdtsctask();
90			}
91	
92		for (i=0; i<n_tasks; i++)
93			wait(NULL);
94	
95		exit(0);
96	}
Hide Line Numbers


About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog