Currently, memalloc_nocma_{save/restore} API that prevents CMA area in page allocation is implemented by using current_gfp_context(). However, there are two problems of this implementation. First, this doesn't work for allocation fastpath. In the fastpath, original gfp_mask is used since current_gfp_context() is introduced in order to control reclaim and it is on slowpath. So, CMA area can be allocated through the allocation fastpath even if memalloc_nocma_{save/restore} APIs are used. Currently, there is just one user for these APIs and it has a fallback method to prevent actual problem. Second, clearing __GFP_MOVABLE in current_gfp_context() has a side effect to exclude the memory on the ZONE_MOVABLE for allocation target. To fix these problems, this patch changes the implementation to exclude CMA area in page allocation. Main point of this change is using the alloc_flags. alloc_flags is mainly used to control allocation so it fits for excluding CMA area in allocation.
Showing the changes to include/linux (1 of 2 files). Show all
Unified · Split
| @@ -175,12 +175,10 @@ static inline bool in_vfork(struct task_struct *tsk) · 174 unmodified lines | |||
| 175 | * Applies per-task gfp context to the given allocation flags. | 175 | * Applies per-task gfp context to the given allocation flags. |
| 176 | * PF_MEMALLOC_NOIO implies GFP_NOIO | 176 | * PF_MEMALLOC_NOIO implies GFP_NOIO |
| 177 | * PF_MEMALLOC_NOFS implies GFP_NOFS | 177 | * PF_MEMALLOC_NOFS implies GFP_NOFS |
| 178 | * PF_MEMALLOC_NOCMA implies no allocation from CMA region. | ||
| 179 | */ | 178 | */ |
| 180 | static inline gfp_t current_gfp_context(gfp_t flags) | 179 | static inline gfp_t current_gfp_context(gfp_t flags) |
| 181 | { | 180 | { |
| 182 | if (unlikely(current->flags & | 181 | if (unlikely(current->flags & (PF_MEMALLOC_NOIO | PF_MEMALLOC_NOFS))) { |
| 183 | (PF_MEMALLOC_NOIO | PF_MEMALLOC_NOFS | PF_MEMALLOC_NOCMA))) { | ||
| 184 | /* | 182 | /* |
| 185 | * NOIO implies both NOIO and NOFS and it is a weaker context | 183 | * NOIO implies both NOIO and NOFS and it is a weaker context |
| 186 | * so always make sure it makes precedence | 184 | * so always make sure it makes precedence |
| @@ -189,10 +187,6 @@ static inline gfp_t current_gfp_context(gfp_t flags) · 2 unmodified lines | |||
| 189 | flags &= ~(__GFP_IO | __GFP_FS); | 187 | flags &= ~(__GFP_IO | __GFP_FS); |
| 190 | else if (current->flags & PF_MEMALLOC_NOFS) | 188 | else if (current->flags & PF_MEMALLOC_NOFS) |
| 191 | flags &= ~__GFP_FS; | 189 | flags &= ~__GFP_FS; |
| 192 | #ifdef CONFIG_CMA | ||
| 193 | if (current->flags & PF_MEMALLOC_NOCMA) | ||
| 194 | flags &= ~__GFP_MOVABLE; | ||
| 195 | #endif | ||
| 196 | } | 190 | } |
| 197 | return flags; | 191 | return flags; |
| 198 | } | 192 | } |