~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * POWER Data Stream Control Register (DSCR) explicit test
  4  *
  5  * This test modifies the DSCR value using mtspr instruction and
  6  * verifies the change with mfspr instruction. It uses both the
  7  * privilege state SPR and the problem state SPR for this purpose.
  8  *
  9  * When using the privilege state SPR, the instructions such as
 10  * mfspr or mtspr are privileged and the kernel emulates them
 11  * for us. Instructions using problem state SPR can be executed
 12  * directly without any emulation if the HW supports them. Else
 13  * they also get emulated by the kernel.
 14  *
 15  * Copyright 2012, Anton Blanchard, IBM Corporation.
 16  * Copyright 2015, Anshuman Khandual, IBM Corporation.
 17  */
 18 
 19 #define _GNU_SOURCE
 20 
 21 #include "dscr.h"
 22 #include "utils.h"
 23 
 24 #include <pthread.h>
 25 #include <sched.h>
 26 #include <semaphore.h>
 27 
 28 void *dscr_explicit_lockstep_thread(void *args)
 29 {
 30         sem_t *prev = (sem_t *)args;
 31         sem_t *next = (sem_t *)args + 1;
 32         unsigned long expected_dscr = 0;
 33 
 34         set_dscr(expected_dscr);
 35         srand(gettid());
 36 
 37         for (int i = 0; i < COUNT; i++) {
 38                 FAIL_IF_EXIT(sem_wait(prev));
 39 
 40                 FAIL_IF_EXIT(expected_dscr != get_dscr());
 41                 FAIL_IF_EXIT(expected_dscr != get_dscr_usr());
 42 
 43                 expected_dscr = (expected_dscr + 1) % DSCR_MAX;
 44                 set_dscr(expected_dscr);
 45 
 46                 FAIL_IF_EXIT(sem_post(next));
 47         }
 48 
 49         return NULL;
 50 }
 51 
 52 int dscr_explicit_lockstep_test(void)
 53 {
 54         pthread_t thread;
 55         sem_t semaphores[2];
 56         sem_t *prev = &semaphores[1];  /* reversed prev/next than for the other thread */
 57         sem_t *next = &semaphores[0];
 58         unsigned long expected_dscr = 0;
 59 
 60         SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
 61 
 62         srand(gettid());
 63         set_dscr(expected_dscr);
 64 
 65         FAIL_IF(sem_init(prev, 0, 0));
 66         FAIL_IF(sem_init(next, 0, 1));  /* other thread starts first */
 67         FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0);
 68         FAIL_IF(pthread_create(&thread, NULL, dscr_explicit_lockstep_thread, (void *)semaphores));
 69 
 70         for (int i = 0; i < COUNT; i++) {
 71                 FAIL_IF(sem_wait(prev));
 72 
 73                 FAIL_IF(expected_dscr != get_dscr());
 74                 FAIL_IF(expected_dscr != get_dscr_usr());
 75 
 76                 expected_dscr = (expected_dscr - 1) % DSCR_MAX;
 77                 set_dscr(expected_dscr);
 78 
 79                 FAIL_IF(sem_post(next));
 80         }
 81 
 82         FAIL_IF(pthread_join(thread, NULL));
 83         FAIL_IF(sem_destroy(prev));
 84         FAIL_IF(sem_destroy(next));
 85 
 86         return 0;
 87 }
 88 
 89 struct random_thread_args {
 90         pthread_t thread_id;
 91         bool do_yields;
 92         pthread_barrier_t *barrier;
 93 };
 94 
 95 void *dscr_explicit_random_thread(void *in)
 96 {
 97         struct random_thread_args *args = (struct random_thread_args *)in;
 98         unsigned long expected_dscr = 0;
 99         int err;
100 
101         srand(gettid());
102 
103         err = pthread_barrier_wait(args->barrier);
104         FAIL_IF_EXIT(err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD);
105 
106         for (int i = 0; i < COUNT; i++) {
107                 expected_dscr = rand() % DSCR_MAX;
108                 set_dscr(expected_dscr);
109 
110                 for (int j = rand() % 5; j > 0; --j) {
111                         FAIL_IF_EXIT(get_dscr() != expected_dscr);
112                         FAIL_IF_EXIT(get_dscr_usr() != expected_dscr);
113 
114                         if (args->do_yields && rand() % 2)
115                                 sched_yield();
116                 }
117 
118                 expected_dscr = rand() % DSCR_MAX;
119                 set_dscr_usr(expected_dscr);
120 
121                 for (int j = rand() % 5; j > 0; --j) {
122                         FAIL_IF_EXIT(get_dscr() != expected_dscr);
123                         FAIL_IF_EXIT(get_dscr_usr() != expected_dscr);
124 
125                         if (args->do_yields && rand() % 2)
126                                 sched_yield();
127                 }
128         }
129 
130         return NULL;
131 }
132 
133 int dscr_explicit_random_test(void)
134 {
135         struct random_thread_args threads[THREADS];
136         pthread_barrier_t barrier;
137 
138         SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
139 
140         FAIL_IF(pthread_barrier_init(&barrier, NULL, THREADS));
141 
142         for (int i = 0; i < THREADS; i++) {
143                 threads[i].do_yields = i % 2 == 0;
144                 threads[i].barrier = &barrier;
145 
146                 FAIL_IF(pthread_create(&threads[i].thread_id, NULL,
147                                        dscr_explicit_random_thread, (void *)&threads[i]));
148         }
149 
150         for (int i = 0; i < THREADS; i++)
151                 FAIL_IF(pthread_join(threads[i].thread_id, NULL));
152 
153         FAIL_IF(pthread_barrier_destroy(&barrier));
154 
155         return 0;
156 }
157 
158 int main(int argc, char *argv[])
159 {
160         unsigned long orig_dscr_default = 0;
161         int err = 0;
162 
163         if (have_hwcap2(PPC_FEATURE2_DSCR))
164                 orig_dscr_default = get_default_dscr();
165 
166         err |= test_harness(dscr_explicit_lockstep_test, "dscr_explicit_lockstep_test");
167         err |= test_harness(dscr_explicit_random_test, "dscr_explicit_random_test");
168 
169         if (have_hwcap2(PPC_FEATURE2_DSCR))
170                 set_default_dscr(orig_dscr_default);
171 
172         return err;
173 }
174 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php