]>
Commit | Line | Data |
---|---|---|
9740ca4e ML |
1 | #ifndef _LINUX_MMAP_LOCK_H |
2 | #define _LINUX_MMAP_LOCK_H | |
3 | ||
2b5067a8 AR |
4 | #include <linux/lockdep.h> |
5 | #include <linux/mm_types.h> | |
42fc5414 | 6 | #include <linux/mmdebug.h> |
2b5067a8 AR |
7 | #include <linux/rwsem.h> |
8 | #include <linux/tracepoint-defs.h> | |
9 | #include <linux/types.h> | |
42fc5414 | 10 | |
14c3656b | 11 | #define MMAP_LOCK_INITIALIZER(name) \ |
da1c55f1 | 12 | .mmap_lock = __RWSEM_INITIALIZER((name).mmap_lock), |
14c3656b | 13 | |
2b5067a8 AR |
14 | DECLARE_TRACEPOINT(mmap_lock_start_locking); |
15 | DECLARE_TRACEPOINT(mmap_lock_acquire_returned); | |
16 | DECLARE_TRACEPOINT(mmap_lock_released); | |
17 | ||
18 | #ifdef CONFIG_TRACING | |
19 | ||
20 | void __mmap_lock_do_trace_start_locking(struct mm_struct *mm, bool write); | |
21 | void __mmap_lock_do_trace_acquire_returned(struct mm_struct *mm, bool write, | |
22 | bool success); | |
23 | void __mmap_lock_do_trace_released(struct mm_struct *mm, bool write); | |
24 | ||
25 | static inline void __mmap_lock_trace_start_locking(struct mm_struct *mm, | |
26 | bool write) | |
27 | { | |
28 | if (tracepoint_enabled(mmap_lock_start_locking)) | |
29 | __mmap_lock_do_trace_start_locking(mm, write); | |
30 | } | |
31 | ||
32 | static inline void __mmap_lock_trace_acquire_returned(struct mm_struct *mm, | |
33 | bool write, bool success) | |
34 | { | |
35 | if (tracepoint_enabled(mmap_lock_acquire_returned)) | |
36 | __mmap_lock_do_trace_acquire_returned(mm, write, success); | |
37 | } | |
38 | ||
39 | static inline void __mmap_lock_trace_released(struct mm_struct *mm, bool write) | |
40 | { | |
41 | if (tracepoint_enabled(mmap_lock_released)) | |
42 | __mmap_lock_do_trace_released(mm, write); | |
43 | } | |
44 | ||
45 | #else /* !CONFIG_TRACING */ | |
46 | ||
47 | static inline void __mmap_lock_trace_start_locking(struct mm_struct *mm, | |
48 | bool write) | |
49 | { | |
50 | } | |
51 | ||
52 | static inline void __mmap_lock_trace_acquire_returned(struct mm_struct *mm, | |
53 | bool write, bool success) | |
54 | { | |
55 | } | |
56 | ||
57 | static inline void __mmap_lock_trace_released(struct mm_struct *mm, bool write) | |
58 | { | |
59 | } | |
60 | ||
61 | #endif /* CONFIG_TRACING */ | |
62 | ||
9740ca4e ML |
63 | static inline void mmap_init_lock(struct mm_struct *mm) |
64 | { | |
da1c55f1 | 65 | init_rwsem(&mm->mmap_lock); |
9740ca4e ML |
66 | } |
67 | ||
68 | static inline void mmap_write_lock(struct mm_struct *mm) | |
69 | { | |
2b5067a8 | 70 | __mmap_lock_trace_start_locking(mm, true); |
da1c55f1 | 71 | down_write(&mm->mmap_lock); |
2b5067a8 | 72 | __mmap_lock_trace_acquire_returned(mm, true, true); |
9740ca4e ML |
73 | } |
74 | ||
aaa2cc56 ML |
75 | static inline void mmap_write_lock_nested(struct mm_struct *mm, int subclass) |
76 | { | |
2b5067a8 | 77 | __mmap_lock_trace_start_locking(mm, true); |
da1c55f1 | 78 | down_write_nested(&mm->mmap_lock, subclass); |
2b5067a8 | 79 | __mmap_lock_trace_acquire_returned(mm, true, true); |
aaa2cc56 ML |
80 | } |
81 | ||
9740ca4e ML |
82 | static inline int mmap_write_lock_killable(struct mm_struct *mm) |
83 | { | |
2b5067a8 AR |
84 | int ret; |
85 | ||
86 | __mmap_lock_trace_start_locking(mm, true); | |
87 | ret = down_write_killable(&mm->mmap_lock); | |
88 | __mmap_lock_trace_acquire_returned(mm, true, ret == 0); | |
89 | return ret; | |
9740ca4e ML |
90 | } |
91 | ||
92 | static inline bool mmap_write_trylock(struct mm_struct *mm) | |
93 | { | |
2b5067a8 AR |
94 | bool ret; |
95 | ||
96 | __mmap_lock_trace_start_locking(mm, true); | |
97 | ret = down_write_trylock(&mm->mmap_lock) != 0; | |
98 | __mmap_lock_trace_acquire_returned(mm, true, ret); | |
99 | return ret; | |
9740ca4e ML |
100 | } |
101 | ||
102 | static inline void mmap_write_unlock(struct mm_struct *mm) | |
103 | { | |
da1c55f1 | 104 | up_write(&mm->mmap_lock); |
2b5067a8 | 105 | __mmap_lock_trace_released(mm, true); |
9740ca4e ML |
106 | } |
107 | ||
108 | static inline void mmap_write_downgrade(struct mm_struct *mm) | |
109 | { | |
da1c55f1 | 110 | downgrade_write(&mm->mmap_lock); |
2b5067a8 | 111 | __mmap_lock_trace_acquire_returned(mm, false, true); |
9740ca4e ML |
112 | } |
113 | ||
114 | static inline void mmap_read_lock(struct mm_struct *mm) | |
115 | { | |
2b5067a8 | 116 | __mmap_lock_trace_start_locking(mm, false); |
da1c55f1 | 117 | down_read(&mm->mmap_lock); |
2b5067a8 | 118 | __mmap_lock_trace_acquire_returned(mm, false, true); |
9740ca4e ML |
119 | } |
120 | ||
121 | static inline int mmap_read_lock_killable(struct mm_struct *mm) | |
122 | { | |
2b5067a8 AR |
123 | int ret; |
124 | ||
125 | __mmap_lock_trace_start_locking(mm, false); | |
126 | ret = down_read_killable(&mm->mmap_lock); | |
127 | __mmap_lock_trace_acquire_returned(mm, false, ret == 0); | |
128 | return ret; | |
9740ca4e ML |
129 | } |
130 | ||
131 | static inline bool mmap_read_trylock(struct mm_struct *mm) | |
132 | { | |
2b5067a8 AR |
133 | bool ret; |
134 | ||
135 | __mmap_lock_trace_start_locking(mm, false); | |
136 | ret = down_read_trylock(&mm->mmap_lock) != 0; | |
137 | __mmap_lock_trace_acquire_returned(mm, false, ret); | |
138 | return ret; | |
9740ca4e ML |
139 | } |
140 | ||
141 | static inline void mmap_read_unlock(struct mm_struct *mm) | |
142 | { | |
da1c55f1 | 143 | up_read(&mm->mmap_lock); |
2b5067a8 | 144 | __mmap_lock_trace_released(mm, false); |
9740ca4e ML |
145 | } |
146 | ||
0cc55a02 ML |
147 | static inline bool mmap_read_trylock_non_owner(struct mm_struct *mm) |
148 | { | |
2b5067a8 | 149 | if (mmap_read_trylock(mm)) { |
da1c55f1 | 150 | rwsem_release(&mm->mmap_lock.dep_map, _RET_IP_); |
0cc55a02 ML |
151 | return true; |
152 | } | |
153 | return false; | |
154 | } | |
155 | ||
156 | static inline void mmap_read_unlock_non_owner(struct mm_struct *mm) | |
157 | { | |
da1c55f1 | 158 | up_read_non_owner(&mm->mmap_lock); |
2b5067a8 | 159 | __mmap_lock_trace_released(mm, false); |
0cc55a02 ML |
160 | } |
161 | ||
42fc5414 ML |
162 | static inline void mmap_assert_locked(struct mm_struct *mm) |
163 | { | |
da1c55f1 ML |
164 | lockdep_assert_held(&mm->mmap_lock); |
165 | VM_BUG_ON_MM(!rwsem_is_locked(&mm->mmap_lock), mm); | |
42fc5414 ML |
166 | } |
167 | ||
168 | static inline void mmap_assert_write_locked(struct mm_struct *mm) | |
169 | { | |
da1c55f1 ML |
170 | lockdep_assert_held_write(&mm->mmap_lock); |
171 | VM_BUG_ON_MM(!rwsem_is_locked(&mm->mmap_lock), mm); | |
42fc5414 ML |
172 | } |
173 | ||
07e5bfe6 CC |
174 | static inline int mmap_lock_is_contended(struct mm_struct *mm) |
175 | { | |
176 | return rwsem_is_contended(&mm->mmap_lock); | |
177 | } | |
178 | ||
9740ca4e | 179 | #endif /* _LINUX_MMAP_LOCK_H */ |