These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / tools / testing / selftests / powerpc / dscr / dscr_default_test.c
1 /*
2  * POWER Data Stream Control Register (DSCR) default test
3  *
4  * This test modifies the system wide default DSCR through
5  * it's sysfs interface and then verifies that all threads
6  * see the correct changed DSCR value immediately.
7  *
8  * Copyright 2012, Anton Blanchard, IBM Corporation.
9  * Copyright 2015, Anshuman Khandual, IBM Corporation.
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License version 2 as published
13  * by the Free Software Foundation.
14  */
15 #include "dscr.h"
16
17 static unsigned long dscr;              /* System DSCR default */
18 static unsigned long sequence;
19 static unsigned long result[THREADS];
20
21 static void *do_test(void *in)
22 {
23         unsigned long thread = (unsigned long)in;
24         unsigned long i;
25
26         for (i = 0; i < COUNT; i++) {
27                 unsigned long d, cur_dscr, cur_dscr_usr;
28                 unsigned long s1, s2;
29
30                 s1 = ACCESS_ONCE(sequence);
31                 if (s1 & 1)
32                         continue;
33                 rmb();
34
35                 d = dscr;
36                 cur_dscr = get_dscr();
37                 cur_dscr_usr = get_dscr_usr();
38
39                 rmb();
40                 s2 = sequence;
41
42                 if (s1 != s2)
43                         continue;
44
45                 if (cur_dscr != d) {
46                         fprintf(stderr, "thread %ld kernel DSCR should be %ld "
47                                 "but is %ld\n", thread, d, cur_dscr);
48                         result[thread] = 1;
49                         pthread_exit(&result[thread]);
50                 }
51
52                 if (cur_dscr_usr != d) {
53                         fprintf(stderr, "thread %ld user DSCR should be %ld "
54                                 "but is %ld\n", thread, d, cur_dscr_usr);
55                         result[thread] = 1;
56                         pthread_exit(&result[thread]);
57                 }
58         }
59         result[thread] = 0;
60         pthread_exit(&result[thread]);
61 }
62
63 int dscr_default(void)
64 {
65         pthread_t threads[THREADS];
66         unsigned long i, *status[THREADS];
67         unsigned long orig_dscr_default;
68
69         orig_dscr_default = get_default_dscr();
70
71         /* Initial DSCR default */
72         dscr = 1;
73         set_default_dscr(dscr);
74
75         /* Spawn all testing threads */
76         for (i = 0; i < THREADS; i++) {
77                 if (pthread_create(&threads[i], NULL, do_test, (void *)i)) {
78                         perror("pthread_create() failed");
79                         goto fail;
80                 }
81         }
82
83         srand(getpid());
84
85         /* Keep changing the DSCR default */
86         for (i = 0; i < COUNT; i++) {
87                 double ret = uniform_deviate(rand());
88
89                 if (ret < 0.0001) {
90                         sequence++;
91                         wmb();
92
93                         dscr++;
94                         if (dscr > DSCR_MAX)
95                                 dscr = 0;
96
97                         set_default_dscr(dscr);
98
99                         wmb();
100                         sequence++;
101                 }
102         }
103
104         /* Individual testing thread exit status */
105         for (i = 0; i < THREADS; i++) {
106                 if (pthread_join(threads[i], (void **)&(status[i]))) {
107                         perror("pthread_join() failed");
108                         goto fail;
109                 }
110
111                 if (*status[i]) {
112                         printf("%ldth thread failed to join with %ld status\n",
113                                                                 i, *status[i]);
114                         goto fail;
115                 }
116         }
117         set_default_dscr(orig_dscr_default);
118         return 0;
119 fail:
120         set_default_dscr(orig_dscr_default);
121         return 1;
122 }
123
124 int main(int argc, char *argv[])
125 {
126         return test_harness(dscr_default, "dscr_default_test");
127 }