1 #include "barrier.h"
2 #include "util.h"
3 #include "mce.h"
4 
mce_barrier_init(struct mce_softirq_barrier * bar)5 void mce_barrier_init(struct mce_softirq_barrier *bar)
6 {
7     atomic_set(&bar->val, 0);
8     atomic_set(&bar->ingen, 0);
9     atomic_set(&bar->outgen, 0);
10 }
11 
mce_barrier_dec(struct mce_softirq_barrier * bar)12 void mce_barrier_dec(struct mce_softirq_barrier *bar)
13 {
14     atomic_inc(&bar->outgen);
15     wmb();
16     atomic_dec(&bar->val);
17 }
18 
mce_barrier_enter(struct mce_softirq_barrier * bar,bool wait)19 void mce_barrier_enter(struct mce_softirq_barrier *bar, bool wait)
20 {
21     int gen;
22 
23     if ( !wait )
24         return;
25     atomic_inc(&bar->ingen);
26     gen = atomic_read(&bar->outgen);
27     mb();
28     atomic_inc(&bar->val);
29     while ( atomic_read(&bar->val) != num_online_cpus() &&
30             atomic_read(&bar->outgen) == gen )
31     {
32             mb();
33             mce_panic_check();
34     }
35 }
36 
mce_barrier_exit(struct mce_softirq_barrier * bar,bool wait)37 void mce_barrier_exit(struct mce_softirq_barrier *bar, bool wait)
38 {
39     int gen;
40 
41     if ( !wait )
42         return;
43     atomic_inc(&bar->outgen);
44     gen = atomic_read(&bar->ingen);
45     mb();
46     atomic_dec(&bar->val);
47     while ( atomic_read(&bar->val) != 0 &&
48             atomic_read(&bar->ingen) == gen )
49     {
50             mb();
51             mce_panic_check();
52     }
53 }
54 
mce_barrier(struct mce_softirq_barrier * bar)55 void mce_barrier(struct mce_softirq_barrier *bar)
56 {
57     mce_barrier_enter(bar, mce_broadcast);
58     mce_barrier_exit(bar, mce_broadcast);
59 }
60