• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Unit tester for ring buffer code in mce.c */
2 #define DEFINE_PER_CPU(a,b) a b
3 #define __get_cpu_var(x) x
4 #define barrier() asm volatile("" ::: "memory")
5 #define rmb() barrier()
6 #define wmb() barrier()
7 
8 /*
9  * Simple lockless ring to communicate PFNs from the exception handler with the
10  * process context work function. This is vastly simplified because there's
11  * only a single reader and a single writer.
12  */
13 #define MCE_RING_SIZE 16	/* we use one entry less */
14 
15 struct mce_ring {
16 	unsigned short start;
17 	unsigned short end;
18 	unsigned long ring[MCE_RING_SIZE];
19 };
20 static DEFINE_PER_CPU(struct mce_ring, mce_ring);
21 
mce_ring_empty(void)22 static int mce_ring_empty(void)
23 {
24 	struct mce_ring *r = &__get_cpu_var(mce_ring);
25 
26 	return r->start == r->end;
27 }
28 
mce_ring_get(unsigned long * pfn)29 static int mce_ring_get(unsigned long *pfn)
30 {
31 	struct mce_ring *r = &__get_cpu_var(mce_ring);
32 
33 	if (r->start == r->end)
34 		return 0;
35 	*pfn = r->ring[r->start];
36 	r->start = (r->start + 1) % MCE_RING_SIZE;
37 	return 1;
38 }
39 
mce_ring_add(unsigned long pfn)40 static int mce_ring_add(unsigned long pfn)
41 {
42 	struct mce_ring *r = &__get_cpu_var(mce_ring);
43 	unsigned next;
44 
45 	next = (r->end + 1) % MCE_RING_SIZE;
46 	if (next == r->start)
47 		return -1;
48 	r->ring[r->end] = pfn;
49 	wmb();
50 	r->end = next;
51 	return 0;
52 }
53 
54 #include <stdio.h>
55 #include <assert.h>
56 #include <pthread.h>
57 
thread(void * arg)58 void *thread(void *arg)
59 {
60 	long i = 0;
61 	for (;;) {
62 		if (mce_ring_add(i) >= 0)
63 			i++;
64 	}
65 }
66 
main(void)67 int main(void)
68 {
69 	long k;
70 
71 	pthread_t thr;
72 	pthread_create(&thr, NULL, thread, NULL);
73 
74 	k = 0;
75 	for (;;) {
76 		while (!mce_ring_empty()) {
77 			unsigned long pfn;
78 			int r = mce_ring_get(&pfn);
79 			assert(r != 0);
80 			if (pfn != k)
81 				printf("got %lu expected %lu delta %ld\n", pfn, k, k-pfn);
82 			k++;
83 		}
84 	}
85 
86 	return 0;
87 }
88