diff options
Diffstat (limited to 'include/linux/lglock.h')
-rw-r--r-- | include/linux/lglock.h | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/include/linux/lglock.h b/include/linux/lglock.h index 87f402ccec55..cdfcef312c79 100644 --- a/include/linux/lglock.h +++ b/include/linux/lglock.h @@ -71,6 +71,8 @@ extern void name##_global_lock_online(void); \ extern void name##_global_unlock_online(void); \ +#ifndef CONFIG_PREEMPT_RT_FULL + #define DEFINE_LGLOCK(name) \ \ DEFINE_SPINLOCK(name##_cpu_lock); \ @@ -197,4 +199,130 @@ preempt_enable(); \ } \ EXPORT_SYMBOL(name##_global_unlock); + +#else /* !PREEMPT_RT_FULL */ +#define DEFINE_LGLOCK(name) \ + \ + DEFINE_PER_CPU(struct rt_mutex, name##_lock); \ + DEFINE_SPINLOCK(name##_cpu_lock); \ + cpumask_t name##_cpus __read_mostly; \ + DEFINE_LGLOCK_LOCKDEP(name); \ + \ + static int \ + name##_lg_cpu_callback(struct notifier_block *nb, \ + unsigned long action, void *hcpu) \ + { \ + switch (action & ~CPU_TASKS_FROZEN) { \ + case CPU_UP_PREPARE: \ + spin_lock(&name##_cpu_lock); \ + cpu_set((unsigned long)hcpu, name##_cpus); \ + spin_unlock(&name##_cpu_lock); \ + break; \ + case CPU_UP_CANCELED: case CPU_DEAD: \ + spin_lock(&name##_cpu_lock); \ + cpu_clear((unsigned long)hcpu, name##_cpus); \ + spin_unlock(&name##_cpu_lock); \ + } \ + return NOTIFY_OK; \ + } \ + static struct notifier_block name##_lg_cpu_notifier = { \ + .notifier_call = name##_lg_cpu_callback, \ + }; \ + void name##_lock_init(void) { \ + int i; \ + LOCKDEP_INIT_MAP(&name##_lock_dep_map, #name, &name##_lock_key, 0); \ + for_each_possible_cpu(i) { \ + struct rt_mutex *lock; \ + lock = &per_cpu(name##_lock, i); \ + rt_mutex_init(lock); \ + } \ + register_hotcpu_notifier(&name##_lg_cpu_notifier); \ + get_online_cpus(); \ + for_each_online_cpu(i) \ + cpu_set(i, name##_cpus); \ + put_online_cpus(); \ + } \ + EXPORT_SYMBOL(name##_lock_init); \ + \ + void name##_local_lock(void) { \ + struct rt_mutex *lock; \ + migrate_disable(); \ + rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_); \ + lock = &__get_cpu_var(name##_lock); \ + __rt_spin_lock(lock); \ + } \ + EXPORT_SYMBOL(name##_local_lock); \ + \ + void name##_local_unlock(void) { \ + struct rt_mutex *lock; \ + rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_); \ + lock = &__get_cpu_var(name##_lock); \ + __rt_spin_unlock(lock); \ + migrate_enable(); \ + } \ + EXPORT_SYMBOL(name##_local_unlock); \ + \ + void name##_local_lock_cpu(int cpu) { \ + struct rt_mutex *lock; \ + rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_); \ + lock = &per_cpu(name##_lock, cpu); \ + __rt_spin_lock(lock); \ + } \ + EXPORT_SYMBOL(name##_local_lock_cpu); \ + \ + void name##_local_unlock_cpu(int cpu) { \ + struct rt_mutex *lock; \ + rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_); \ + lock = &per_cpu(name##_lock, cpu); \ + __rt_spin_unlock(lock); \ + } \ + EXPORT_SYMBOL(name##_local_unlock_cpu); \ + \ + void name##_global_lock_online(void) { \ + int i; \ + rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \ + spin_lock(&name##_cpu_lock); \ + for_each_cpu(i, &name##_cpus) { \ + struct rt_mutex *lock; \ + lock = &per_cpu(name##_lock, i); \ + __rt_spin_lock(lock); \ + } \ + } \ + EXPORT_SYMBOL(name##_global_lock_online); \ + \ + void name##_global_unlock_online(void) { \ + int i; \ + rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \ + for_each_cpu(i, &name##_cpus) { \ + struct rt_mutex *lock; \ + lock = &per_cpu(name##_lock, i); \ + __rt_spin_unlock(lock); \ + } \ + spin_unlock(&name##_cpu_lock); \ + } \ + EXPORT_SYMBOL(name##_global_unlock_online); \ + \ + void name##_global_lock(void) { \ + int i; \ + rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \ + for_each_possible_cpu(i) { \ + struct rt_mutex *lock; \ + lock = &per_cpu(name##_lock, i); \ + __rt_spin_lock(lock); \ + } \ + } \ + EXPORT_SYMBOL(name##_global_lock); \ + \ + void name##_global_unlock(void) { \ + int i; \ + rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \ + for_each_possible_cpu(i) { \ + struct rt_mutex *lock; \ + lock = &per_cpu(name##_lock, i); \ + __rt_spin_unlock(lock); \ + } \ + } \ + EXPORT_SYMBOL(name##_global_unlock); +#endif /* PRREMPT_RT_FULL */ + #endif |