diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-07-03 09:29:51 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2009-07-20 09:45:38 -0400 |
| commit | 15868172b33ea9006afd98b0089e5b4fdb3da2c7 (patch) | |
| tree | b866796f58f99db77a7e72c2b17871cdd970c2d9 /include/linux | |
| parent | 78af08d90b8f745044b1274430bc4bc6b2b27aca (diff) | |
percpu: add percpu locked infrastructure
RT needs per cpu data structures protected by per cpu locks instead of
disabling preemption. Add the infrastructure for per cpu locked data.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/percpu-defs.h | 18 | ||||
| -rw-r--r-- | include/linux/percpu.h | 23 |
2 files changed, 41 insertions, 0 deletions
diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h index 68438e18fff4..c02051de18d4 100644 --- a/include/linux/percpu-defs.h +++ b/include/linux/percpu-defs.h | |||
| @@ -38,6 +38,22 @@ | |||
| 38 | DEFINE_PER_CPU_SECTION(type, name, "") | 38 | DEFINE_PER_CPU_SECTION(type, name, "") |
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * next two added for RT patch | ||
| 42 | * (wonder if we need corresponding DECLARE_*'s?) (clrkwllms) | ||
| 43 | */ | ||
| 44 | #define DEFINE_PER_CPU_SPINLOCK(name, section) \ | ||
| 45 | __attribute__((__section__(PER_CPU_BASE_SECTION section))) \ | ||
| 46 | PER_CPU_ATTRIBUTES __DEFINE_SPINLOCK(per_cpu__lock_##name##_locked); | ||
| 47 | |||
| 48 | #define DECLARE_PER_CPU_LOCKED(type, name) \ | ||
| 49 | extern PER_CPU_ATTRIBUTES spinlock_t __per_cpu_var_lock(name); \ | ||
| 50 | extern PER_CPU_ATTRIBUTES __typeof__(type) __per_cpu_var_lock_var(name) | ||
| 51 | |||
| 52 | #define DEFINE_PER_CPU_LOCKED(type, name) \ | ||
| 53 | DEFINE_PER_CPU_SPINLOCK(name, "") \ | ||
| 54 | DEFINE_PER_CPU_SECTION(type, name##_locked, "") | ||
| 55 | |||
| 56 | /* | ||
| 41 | * Declaration/definition used for per-CPU variables that must come first in | 57 | * Declaration/definition used for per-CPU variables that must come first in |
| 42 | * the set of variables. | 58 | * the set of variables. |
| 43 | */ | 59 | */ |
| @@ -79,7 +95,9 @@ | |||
| 79 | * Intermodule exports for per-CPU variables. | 95 | * Intermodule exports for per-CPU variables. |
| 80 | */ | 96 | */ |
| 81 | #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) | 97 | #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) |
| 98 | #define EXPORT_PER_CPU_LOCKED_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var##_locked) | ||
| 82 | #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) | 99 | #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) |
| 100 | #define EXPORT_PER_CPU_LOCKED_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var##_locked) | ||
| 83 | 101 | ||
| 84 | 102 | ||
| 85 | #endif /* _LINUX_PERCPU_DEFS_H */ | 103 | #endif /* _LINUX_PERCPU_DEFS_H */ |
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 26fd9d12f050..39c4f01d2cd4 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
| @@ -32,6 +32,29 @@ | |||
| 32 | &__get_cpu_var(var); })) | 32 | &__get_cpu_var(var); })) |
| 33 | #define put_cpu_var(var) preempt_enable() | 33 | #define put_cpu_var(var) preempt_enable() |
| 34 | 34 | ||
| 35 | /* | ||
| 36 | * Per-CPU data structures with an additional lock - useful for | ||
| 37 | * PREEMPT_RT code that wants to reschedule but also wants | ||
| 38 | * per-CPU data structures. | ||
| 39 | * | ||
| 40 | * 'cpu' gets updated with the CPU the task is currently executing on. | ||
| 41 | * | ||
| 42 | * NOTE: on normal !PREEMPT_RT kernels these per-CPU variables | ||
| 43 | * are the same as the normal per-CPU variables, so there no | ||
| 44 | * runtime overhead. | ||
| 45 | */ | ||
| 46 | #define get_cpu_var_locked(var, cpuptr) \ | ||
| 47 | (*({ \ | ||
| 48 | int __cpu = raw_smp_processor_id(); \ | ||
| 49 | \ | ||
| 50 | *(cpuptr) = __cpu; \ | ||
| 51 | spin_lock(&__get_cpu_lock(var, __cpu)); \ | ||
| 52 | &__get_cpu_var_locked(var, __cpu); \ | ||
| 53 | })) | ||
| 54 | |||
| 55 | #define put_cpu_var_locked(var, cpu) \ | ||
| 56 | do { (void)cpu; spin_unlock(&__get_cpu_lock(var, cpu)); } while (0) | ||
| 57 | |||
| 35 | #ifdef CONFIG_SMP | 58 | #ifdef CONFIG_SMP |
| 36 | 59 | ||
| 37 | #ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA | 60 | #ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA |
