These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / include / linux / rwsem_rt.h
1 #ifndef _LINUX_RWSEM_RT_H
2 #define _LINUX_RWSEM_RT_H
3
4 #ifndef _LINUX_RWSEM_H
5 #error "Include rwsem.h"
6 #endif
7
8 /*
9  * RW-semaphores are a spinlock plus a reader-depth count.
10  *
11  * Note that the semantics are different from the usual
12  * Linux rw-sems, in PREEMPT_RT mode we do not allow
13  * multiple readers to hold the lock at once, we only allow
14  * a read-lock owner to read-lock recursively. This is
15  * better for latency, makes the implementation inherently
16  * fair and makes it simpler as well.
17  */
18
19 #include <linux/rtmutex.h>
20
21 struct rw_semaphore {
22         struct rt_mutex         lock;
23         int                     read_depth;
24 #ifdef CONFIG_DEBUG_LOCK_ALLOC
25         struct lockdep_map      dep_map;
26 #endif
27 };
28
29 #define __RWSEM_INITIALIZER(name) \
30         { .lock = __RT_MUTEX_INITIALIZER(name.lock), \
31           RW_DEP_MAP_INIT(name) }
32
33 #define DECLARE_RWSEM(lockname) \
34         struct rw_semaphore lockname = __RWSEM_INITIALIZER(lockname)
35
36 extern void  __rt_rwsem_init(struct rw_semaphore *rwsem, const char *name,
37                                      struct lock_class_key *key);
38
39 #define __rt_init_rwsem(sem, name, key)                 \
40         do {                                            \
41                 rt_mutex_init(&(sem)->lock);            \
42                 __rt_rwsem_init((sem), (name), (key));\
43         } while (0)
44
45 #define __init_rwsem(sem, name, key) __rt_init_rwsem(sem, name, key)
46
47 # define rt_init_rwsem(sem)                             \
48 do {                                                    \
49         static struct lock_class_key __key;             \
50                                                         \
51         __rt_init_rwsem((sem), #sem, &__key);           \
52 } while (0)
53
54 extern void rt_down_write(struct rw_semaphore *rwsem);
55 extern void rt_down_read_nested(struct rw_semaphore *rwsem, int subclass);
56 extern void rt_down_write_nested(struct rw_semaphore *rwsem, int subclass);
57 extern void rt_down_write_nested_lock(struct rw_semaphore *rwsem,
58                                       struct lockdep_map *nest);
59 extern void rt__down_read(struct rw_semaphore *rwsem);
60 extern void rt_down_read(struct rw_semaphore *rwsem);
61 extern int  rt_down_write_trylock(struct rw_semaphore *rwsem);
62 extern int  rt__down_read_trylock(struct rw_semaphore *rwsem);
63 extern int  rt_down_read_trylock(struct rw_semaphore *rwsem);
64 extern void __rt_up_read(struct rw_semaphore *rwsem);
65 extern void rt_up_read(struct rw_semaphore *rwsem);
66 extern void rt_up_write(struct rw_semaphore *rwsem);
67 extern void rt_downgrade_write(struct rw_semaphore *rwsem);
68
69 #define init_rwsem(sem)         rt_init_rwsem(sem)
70 #define rwsem_is_locked(s)      rt_mutex_is_locked(&(s)->lock)
71
72 static inline int rwsem_is_contended(struct rw_semaphore *sem)
73 {
74         /* rt_mutex_has_waiters() */
75         return !RB_EMPTY_ROOT(&sem->lock.waiters);
76 }
77
78 static inline void __down_read(struct rw_semaphore *sem)
79 {
80         rt__down_read(sem);
81 }
82
83 static inline void down_read(struct rw_semaphore *sem)
84 {
85         rt_down_read(sem);
86 }
87
88 static inline int __down_read_trylock(struct rw_semaphore *sem)
89 {
90         return rt__down_read_trylock(sem);
91 }
92
93 static inline int down_read_trylock(struct rw_semaphore *sem)
94 {
95         return rt_down_read_trylock(sem);
96 }
97
98 static inline void down_write(struct rw_semaphore *sem)
99 {
100         rt_down_write(sem);
101 }
102
103 static inline int down_write_trylock(struct rw_semaphore *sem)
104 {
105         return rt_down_write_trylock(sem);
106 }
107
108 static inline void __up_read(struct rw_semaphore *sem)
109 {
110         __rt_up_read(sem);
111 }
112
113 static inline void up_read(struct rw_semaphore *sem)
114 {
115         rt_up_read(sem);
116 }
117
118 static inline void up_write(struct rw_semaphore *sem)
119 {
120         rt_up_write(sem);
121 }
122
123 static inline void downgrade_write(struct rw_semaphore *sem)
124 {
125         rt_downgrade_write(sem);
126 }
127
128 static inline void down_read_nested(struct rw_semaphore *sem, int subclass)
129 {
130         return rt_down_read_nested(sem, subclass);
131 }
132
133 static inline void down_write_nested(struct rw_semaphore *sem, int subclass)
134 {
135         rt_down_write_nested(sem, subclass);
136 }
137 #ifdef CONFIG_DEBUG_LOCK_ALLOC
138 static inline void down_write_nest_lock(struct rw_semaphore *sem,
139                 struct rw_semaphore *nest_lock)
140 {
141         rt_down_write_nested_lock(sem, &nest_lock->dep_map);
142 }
143
144 #else
145
146 static inline void down_write_nest_lock(struct rw_semaphore *sem,
147                 struct rw_semaphore *nest_lock)
148 {
149         rt_down_write_nested_lock(sem, NULL);
150 }
151 #endif
152 #endif