.. | .. |
---|
23 | 23 | * will still exist later on and mmget_not_zero() has to be used before |
---|
24 | 24 | * accessing it. |
---|
25 | 25 | * |
---|
26 | | - * This is a preferred way to to pin @mm for a longer/unbounded amount |
---|
| 26 | + * This is a preferred way to pin @mm for a longer/unbounded amount |
---|
27 | 27 | * of time. |
---|
28 | 28 | * |
---|
29 | 29 | * Use mmdrop() to release the reference acquired by mmgrab(). |
---|
.. | .. |
---|
47 | 47 | */ |
---|
48 | 48 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) |
---|
49 | 49 | __mmdrop(mm); |
---|
50 | | -} |
---|
51 | | - |
---|
52 | | -void mmdrop(struct mm_struct *mm); |
---|
53 | | - |
---|
54 | | -/* |
---|
55 | | - * This has to be called after a get_task_mm()/mmget_not_zero() |
---|
56 | | - * followed by taking the mmap_sem for writing before modifying the |
---|
57 | | - * vmas or anything the coredump pretends not to change from under it. |
---|
58 | | - * |
---|
59 | | - * It also has to be called when mmgrab() is used in the context of |
---|
60 | | - * the process, but then the mm_count refcount is transferred outside |
---|
61 | | - * the context of the process to run down_write() on that pinned mm. |
---|
62 | | - * |
---|
63 | | - * NOTE: find_extend_vma() called from GUP context is the only place |
---|
64 | | - * that can modify the "mm" (notably the vm_start/end) under mmap_sem |
---|
65 | | - * for reading and outside the context of the process, so it is also |
---|
66 | | - * the only case that holds the mmap_sem for reading that must call |
---|
67 | | - * this function. Generally if the mmap_sem is hold for reading |
---|
68 | | - * there's no need of this check after get_task_mm()/mmget_not_zero(). |
---|
69 | | - * |
---|
70 | | - * This function can be obsoleted and the check can be removed, after |
---|
71 | | - * the coredump code will hold the mmap_sem for writing before |
---|
72 | | - * invoking the ->core_dump methods. |
---|
73 | | - */ |
---|
74 | | -static inline bool mmget_still_valid(struct mm_struct *mm) |
---|
75 | | -{ |
---|
76 | | - return likely(!mm->core_state); |
---|
77 | 50 | } |
---|
78 | 51 | |
---|
79 | 52 | /** |
---|
.. | .. |
---|
133 | 106 | #endif /* CONFIG_MEMCG */ |
---|
134 | 107 | |
---|
135 | 108 | #ifdef CONFIG_MMU |
---|
| 109 | +#ifndef arch_get_mmap_end |
---|
| 110 | +#define arch_get_mmap_end(addr) (TASK_SIZE) |
---|
| 111 | +#endif |
---|
| 112 | + |
---|
| 113 | +#ifndef arch_get_mmap_base |
---|
| 114 | +#define arch_get_mmap_base(addr, base) (base) |
---|
| 115 | +#endif |
---|
| 116 | + |
---|
136 | 117 | extern void arch_pick_mmap_layout(struct mm_struct *mm, |
---|
137 | 118 | struct rlimit *rlim_stack); |
---|
138 | 119 | extern unsigned long |
---|
.. | .. |
---|
181 | 162 | */ |
---|
182 | 163 | static inline gfp_t current_gfp_context(gfp_t flags) |
---|
183 | 164 | { |
---|
184 | | - /* |
---|
185 | | - * NOIO implies both NOIO and NOFS and it is a weaker context |
---|
186 | | - * so always make sure it makes precendence |
---|
187 | | - */ |
---|
188 | | - if (unlikely(current->flags & PF_MEMALLOC_NOIO)) |
---|
189 | | - flags &= ~(__GFP_IO | __GFP_FS); |
---|
190 | | - else if (unlikely(current->flags & PF_MEMALLOC_NOFS)) |
---|
191 | | - flags &= ~__GFP_FS; |
---|
| 165 | + unsigned int pflags = READ_ONCE(current->flags); |
---|
| 166 | + |
---|
| 167 | + if (unlikely(pflags & (PF_MEMALLOC_NOIO | PF_MEMALLOC_NOFS))) { |
---|
| 168 | + /* |
---|
| 169 | + * NOIO implies both NOIO and NOFS and it is a weaker context |
---|
| 170 | + * so always make sure it makes precedence |
---|
| 171 | + */ |
---|
| 172 | + if (pflags & PF_MEMALLOC_NOIO) |
---|
| 173 | + flags &= ~(__GFP_IO | __GFP_FS); |
---|
| 174 | + else if (pflags & PF_MEMALLOC_NOFS) |
---|
| 175 | + flags &= ~__GFP_FS; |
---|
| 176 | + } |
---|
192 | 177 | return flags; |
---|
193 | 178 | } |
---|
194 | 179 | |
---|
.. | .. |
---|
227 | 212 | * @flags: Flags to restore. |
---|
228 | 213 | * |
---|
229 | 214 | * Ends the implicit GFP_NOIO scope started by memalloc_noio_save function. |
---|
230 | | - * Always make sure that that the given flags is the return value from the |
---|
| 215 | + * Always make sure that the given flags is the return value from the |
---|
231 | 216 | * pairing memalloc_noio_save call. |
---|
232 | 217 | */ |
---|
233 | 218 | static inline void memalloc_noio_restore(unsigned int flags) |
---|
.. | .. |
---|
258 | 243 | * @flags: Flags to restore. |
---|
259 | 244 | * |
---|
260 | 245 | * Ends the implicit GFP_NOFS scope started by memalloc_nofs_save function. |
---|
261 | | - * Always make sure that that the given flags is the return value from the |
---|
| 246 | + * Always make sure that the given flags is the return value from the |
---|
262 | 247 | * pairing memalloc_nofs_save call. |
---|
263 | 248 | */ |
---|
264 | 249 | static inline void memalloc_nofs_restore(unsigned int flags) |
---|
.. | .. |
---|
278 | 263 | current->flags = (current->flags & ~PF_MEMALLOC) | flags; |
---|
279 | 264 | } |
---|
280 | 265 | |
---|
| 266 | +#ifdef CONFIG_CMA |
---|
| 267 | +static inline unsigned int memalloc_nocma_save(void) |
---|
| 268 | +{ |
---|
| 269 | + unsigned int flags = current->flags & PF_MEMALLOC_NOCMA; |
---|
| 270 | + |
---|
| 271 | + current->flags |= PF_MEMALLOC_NOCMA; |
---|
| 272 | + return flags; |
---|
| 273 | +} |
---|
| 274 | + |
---|
| 275 | +static inline void memalloc_nocma_restore(unsigned int flags) |
---|
| 276 | +{ |
---|
| 277 | + current->flags = (current->flags & ~PF_MEMALLOC_NOCMA) | flags; |
---|
| 278 | +} |
---|
| 279 | +#else |
---|
| 280 | +static inline unsigned int memalloc_nocma_save(void) |
---|
| 281 | +{ |
---|
| 282 | + return 0; |
---|
| 283 | +} |
---|
| 284 | + |
---|
| 285 | +static inline void memalloc_nocma_restore(unsigned int flags) |
---|
| 286 | +{ |
---|
| 287 | +} |
---|
| 288 | +#endif |
---|
| 289 | + |
---|
281 | 290 | #ifdef CONFIG_MEMCG |
---|
| 291 | +DECLARE_PER_CPU(struct mem_cgroup *, int_active_memcg); |
---|
282 | 292 | /** |
---|
283 | | - * memalloc_use_memcg - Starts the remote memcg charging scope. |
---|
| 293 | + * set_active_memcg - Starts the remote memcg charging scope. |
---|
284 | 294 | * @memcg: memcg to charge. |
---|
285 | 295 | * |
---|
286 | 296 | * This function marks the beginning of the remote memcg charging scope. All the |
---|
287 | 297 | * __GFP_ACCOUNT allocations till the end of the scope will be charged to the |
---|
288 | 298 | * given memcg. |
---|
289 | 299 | * |
---|
290 | | - * NOTE: This function is not nesting safe. |
---|
| 300 | + * NOTE: This function can nest. Users must save the return value and |
---|
| 301 | + * reset the previous value after their own charging scope is over. |
---|
291 | 302 | */ |
---|
292 | | -static inline void memalloc_use_memcg(struct mem_cgroup *memcg) |
---|
| 303 | +static inline struct mem_cgroup * |
---|
| 304 | +set_active_memcg(struct mem_cgroup *memcg) |
---|
293 | 305 | { |
---|
294 | | - WARN_ON_ONCE(current->active_memcg); |
---|
295 | | - current->active_memcg = memcg; |
---|
296 | | -} |
---|
| 306 | + struct mem_cgroup *old; |
---|
297 | 307 | |
---|
298 | | -/** |
---|
299 | | - * memalloc_unuse_memcg - Ends the remote memcg charging scope. |
---|
300 | | - * |
---|
301 | | - * This function marks the end of the remote memcg charging scope started by |
---|
302 | | - * memalloc_use_memcg(). |
---|
303 | | - */ |
---|
304 | | -static inline void memalloc_unuse_memcg(void) |
---|
305 | | -{ |
---|
306 | | - current->active_memcg = NULL; |
---|
| 308 | + if (in_interrupt()) { |
---|
| 309 | + old = this_cpu_read(int_active_memcg); |
---|
| 310 | + this_cpu_write(int_active_memcg, memcg); |
---|
| 311 | + } else { |
---|
| 312 | + old = current->active_memcg; |
---|
| 313 | + current->active_memcg = memcg; |
---|
| 314 | + } |
---|
| 315 | + |
---|
| 316 | + return old; |
---|
307 | 317 | } |
---|
308 | 318 | #else |
---|
309 | | -static inline void memalloc_use_memcg(struct mem_cgroup *memcg) |
---|
| 319 | +static inline struct mem_cgroup * |
---|
| 320 | +set_active_memcg(struct mem_cgroup *memcg) |
---|
310 | 321 | { |
---|
311 | | -} |
---|
312 | | - |
---|
313 | | -static inline void memalloc_unuse_memcg(void) |
---|
314 | | -{ |
---|
| 322 | + return NULL; |
---|
315 | 323 | } |
---|
316 | 324 | #endif |
---|
317 | 325 | |
---|
.. | .. |
---|
323 | 331 | MEMBARRIER_STATE_GLOBAL_EXPEDITED = (1U << 3), |
---|
324 | 332 | MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY = (1U << 4), |
---|
325 | 333 | MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE = (1U << 5), |
---|
| 334 | + MEMBARRIER_STATE_PRIVATE_EXPEDITED_RSEQ_READY = (1U << 6), |
---|
| 335 | + MEMBARRIER_STATE_PRIVATE_EXPEDITED_RSEQ = (1U << 7), |
---|
326 | 336 | }; |
---|
327 | 337 | |
---|
328 | 338 | enum { |
---|
329 | 339 | MEMBARRIER_FLAG_SYNC_CORE = (1U << 0), |
---|
| 340 | + MEMBARRIER_FLAG_RSEQ = (1U << 1), |
---|
330 | 341 | }; |
---|
331 | 342 | |
---|
332 | 343 | #ifdef CONFIG_ARCH_HAS_MEMBARRIER_CALLBACKS |
---|
.. | .. |
---|
343 | 354 | sync_core_before_usermode(); |
---|
344 | 355 | } |
---|
345 | 356 | |
---|
346 | | -static inline void membarrier_execve(struct task_struct *t) |
---|
347 | | -{ |
---|
348 | | - atomic_set(&t->mm->membarrier_state, 0); |
---|
349 | | -} |
---|
| 357 | +extern void membarrier_exec_mmap(struct mm_struct *mm); |
---|
| 358 | + |
---|
350 | 359 | #else |
---|
351 | 360 | #ifdef CONFIG_ARCH_HAS_MEMBARRIER_CALLBACKS |
---|
352 | 361 | static inline void membarrier_arch_switch_mm(struct mm_struct *prev, |
---|
.. | .. |
---|
355 | 364 | { |
---|
356 | 365 | } |
---|
357 | 366 | #endif |
---|
358 | | -static inline void membarrier_execve(struct task_struct *t) |
---|
| 367 | +static inline void membarrier_exec_mmap(struct mm_struct *mm) |
---|
359 | 368 | { |
---|
360 | 369 | } |
---|
361 | 370 | static inline void membarrier_mm_sync_core_before_usermode(struct mm_struct *mm) |
---|