diff options
author | Richard Braun <rbraun@sceen.net> | 2013-05-24 20:24:10 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2013-05-24 20:25:43 +0200 |
commit | 2587e7386bf87c79da9dd804e082079fbe16f0a6 (patch) | |
tree | 1d7b5744db8e96913a1b5a2016c9fd987688569f /kern/llsync.h | |
parent | 47713dee27ac3fee0d8a6dee1c104fa48b88c299 (diff) |
kern/llsync: fix checkpoint reset interrupt handling
This change makes reset requests write both the per-processor flag as well as
the checkpoint bitmap atomically, and adjusts the module logic accordingly.
It fixes a race between checkpoint reset and system timer interrupts where
the timer interrupt would make the local processor commit its checkpoint
although it can't be reliably determined that it reached a checkpoint since
the last global checkpoint, because the reset interrupt wasn't received yet.
This problem would rarely happen on real hardware because of the near-instant
handling of IPIs, but it was observed on virtual machines.
Diffstat (limited to 'kern/llsync.h')
-rw-r--r-- | kern/llsync.h | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/kern/llsync.h b/kern/llsync.h index c58030d0..e00baa44 100644 --- a/kern/llsync.h +++ b/kern/llsync.h @@ -83,17 +83,6 @@ llsync_read_unlock(void) } /* - * Reset the checkpoint flag of a processor. - * - * Called from interrupt context. - */ -static inline void -llsync_reset_checkpoint(unsigned int cpu) -{ - llsync_cpus[cpu].checked = 0; -} - -/* * Report that a processor has reached a checkpoint. * * Called during context switch. @@ -111,6 +100,9 @@ void llsync_setup(void); /* * Report that a processor will be regularly checking in. + * + * Registered processors perform checkpoint commits and receive checkpoint + * reset interrupts. */ void llsync_register_cpu(unsigned int cpu); @@ -130,6 +122,13 @@ void llsync_unregister_cpu(unsigned int cpu); void llsync_commit_checkpoint(unsigned int cpu); /* + * Reset the checkpoint pending state of a processor. + * + * Called from interrupt context. + */ +void llsync_reset_checkpoint(unsigned int cpu); + +/* * Defer an operation until all existing read-side references are dropped, * without blocking. */ |