On Mon, Mar 18, 2024 at 01:47:43AM +0800, Alan Huang wrote: > Hi, > > I’m playing with the LKMM, then I saw the ISA2+pooncelock+pooncelock+pombonce. > > The original litmus is as follows: > ------------------------------------------------------ > P0(int *x, int *y, spinlock_t *mylock) > { > spin_lock(mylock); > WRITE_ONCE(*x, 1); > WRITE_ONCE(*y, 1); > spin_unlock(mylock); > } > > P1(int *y, int *z, spinlock_t *mylock) > { > int r0; > > spin_lock(mylock); > r0 = READ_ONCE(*y); > WRITE_ONCE(*z, 1); > spin_unlock(mylock); > } > > P2(int *x, int *z) > { > int r1; > int r2; > > r2 = READ_ONCE(*z); > smp_mb(); > r1 = READ_ONCE(*x); > } > > exists (1:r0=1 /\ 2:r2=1 /\ 2:r1=0) > ------------------------------------------------------ > Of course, the result is Never. > > But when I delete P0’s spin_lock and P1’s spin_unlock: > ------------------------------------------------------- > P0(int *x, int *y, spinlock_t *mylock) > { > WRITE_ONCE(*x, 1); > WRITE_ONCE(*y, 1); > spin_unlock(mylock); > } > > P1(int *y, int *z, spinlock_t *mylock) > { > int r0; > > spin_lock(mylock); > r0 = READ_ONCE(*y); > WRITE_ONCE(*z, 1); > } > > P2(int *x, int *z) > { > int r1; > int r2; > > r2 = READ_ONCE(*z); > smp_mb(); > r1 = READ_ONCE(*x); > } > > exists (1:r0=1 /\ 2:r2=1 /\ 2:r1=0) > ------------------------------------------------------ > Then herd told me the result is Sometimes. You mean like this? Test ISA2+pooncelock+pooncelock+pombonce Allowed States 8 1:r0=0; 2:r1=0; 2:r2=0; 1:r0=0; 2:r1=0; 2:r2=1; 1:r0=0; 2:r1=1; 2:r2=0; 1:r0=0; 2:r1=1; 2:r2=1; 1:r0=1; 2:r1=0; 2:r2=0; 1:r0=1; 2:r1=0; 2:r2=1; 1:r0=1; 2:r1=1; 2:r2=0; 1:r0=1; 2:r1=1; 2:r2=1; Ok Witnesses Positive: 1 Negative: 7 Flag unmatched-unlock Condition exists (1:r0=1 /\ 2:r2=1 /\ 2:r1=0) Observation ISA2+pooncelock+pooncelock+pombonce Sometimes 1 7 Time ISA2+pooncelock+pooncelock+pombonce 0.01 Hash=f55b8515e48310f812aa676084f2cc88 > Is this expected? There are no locks held initially, so why can't the following sequence of events unfold: o P1() acquires the lock. o P0() does WRITE_ONCE(*y, 1). (Yes, out of order) o P1() does READ_ONCE(*y), and gets 1. o P1() does WRITE_ONCE(*z, 1). o P2() does READ_ONCE(*z) and gets 1. o P2() does smp_mb(), but there is nothing to order with. o P2() does READ_ONCE(*x) and gets 0. o P0() does WRITE_ONCE(*x, 1), but too late to affect P2(). o P0() releases the lock that is does not hold, which is why you see the "Flag unmatched-unlock" in the output. LKMM is complaining that the litmus test is not legitimate, and rightly so! Or am I missing your point? Thanx, Paul