diff options
author | Richard Braun <rbraun@sceen.net> | 2013-05-24 00:03:20 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2013-05-24 00:03:20 +0200 |
commit | 809082a3520480925def38e10272440ef68a455b (patch) | |
tree | 24e7721d0fd72c0e313aa4b4ac413f2cf47137a5 | |
parent | b6b7c519edefe21b43e816f7e6d48fdb70f1eb8d (diff) |
kern/llsync: improve concurrency
Keep a local copy of a processor registration state to avoid acquiring the
global lock when attempting to commit a checkpoint from an unregistered
processor.
-rw-r--r-- | kern/llsync.c | 15 | ||||
-rw-r--r-- | kern/llsync.h | 4 | ||||
-rw-r--r-- | kern/llsync_i.h | 7 |
3 files changed, 14 insertions, 12 deletions
diff --git a/kern/llsync.c b/kern/llsync.c index d43bcefd..0fd973d0 100644 --- a/kern/llsync.c +++ b/kern/llsync.c @@ -51,7 +51,7 @@ #define LLSYNC_NR_WORKS_WARN 10000 -struct llsync_cpu_checkpoint llsync_cpu_checkpoints[MAX_CPUS]; +struct llsync_cpu llsync_cpus[MAX_CPUS]; /* * Global lock protecting the remaining module data. @@ -208,6 +208,9 @@ llsync_register_cpu(unsigned int cpu) llsync_process_global_checkpoint(cpu); spinlock_unlock_intr_restore(&llsync_lock, flags); + + assert(!llsync_cpus[cpu].registered); + llsync_cpus[cpu].registered = 1; } static void @@ -232,7 +235,8 @@ llsync_unregister_cpu(unsigned int cpu) { unsigned long flags; - llsync_reset_checkpoint(cpu); + assert(llsync_cpus[cpu].registered); + llsync_cpus[cpu].registered = 0; spinlock_lock_intr_save(&llsync_lock, &flags); @@ -256,14 +260,11 @@ llsync_commit_checkpoint(unsigned int cpu) { unsigned long flags; - if (!llsync_cpu_checkpoints[cpu].checked) + if (!(llsync_cpus[cpu].registered && llsync_cpus[cpu].checked)) return; spinlock_lock_intr_save(&llsync_lock, &flags); - - if (bitmap_test(llsync_registered_cpus, cpu)) - llsync_commit_checkpoint_common(cpu); - + llsync_commit_checkpoint_common(cpu); spinlock_unlock_intr_restore(&llsync_lock, flags); } diff --git a/kern/llsync.h b/kern/llsync.h index 273346fb..c58030d0 100644 --- a/kern/llsync.h +++ b/kern/llsync.h @@ -90,7 +90,7 @@ llsync_read_unlock(void) static inline void llsync_reset_checkpoint(unsigned int cpu) { - llsync_cpu_checkpoints[cpu].checked = 0; + llsync_cpus[cpu].checked = 0; } /* @@ -101,7 +101,7 @@ llsync_reset_checkpoint(unsigned int cpu) static inline void llsync_checkin(unsigned int cpu) { - llsync_cpu_checkpoints[cpu].checked = 1; + llsync_cpus[cpu].checked = 1; } /* diff --git a/kern/llsync_i.h b/kern/llsync_i.h index 89a7fe83..034e368b 100644 --- a/kern/llsync_i.h +++ b/kern/llsync_i.h @@ -21,12 +21,13 @@ #include <kern/param.h> /* - * Per-processor flag indicating if a processor checked in. + * Per-processor data. */ -struct llsync_cpu_checkpoint { +struct llsync_cpu { + int registered; int checked; } __aligned(CPU_L1_SIZE); -extern struct llsync_cpu_checkpoint llsync_cpu_checkpoints[MAX_CPUS]; +extern struct llsync_cpu llsync_cpus[MAX_CPUS]; #endif /* _KERN_LLSYNC_I_H */ |