diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/gfp.h | 8 | ||||
-rw-r--r-- | include/linux/sched.h | 8 | ||||
-rw-r--r-- | include/linux/sched/mm.h | 26 |
3 files changed, 34 insertions, 8 deletions
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 978232a3b4ae..2bfcfd33e476 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
@@ -210,8 +210,16 @@ struct vm_area_struct; | |||
210 | * | 210 | * |
211 | * GFP_NOIO will use direct reclaim to discard clean pages or slab pages | 211 | * GFP_NOIO will use direct reclaim to discard clean pages or slab pages |
212 | * that do not require the starting of any physical IO. | 212 | * that do not require the starting of any physical IO. |
213 | * Please try to avoid using this flag directly and instead use | ||
214 | * memalloc_noio_{save,restore} to mark the whole scope which cannot | ||
215 | * perform any IO with a short explanation why. All allocation requests | ||
216 | * will inherit GFP_NOIO implicitly. | ||
213 | * | 217 | * |
214 | * GFP_NOFS will use direct reclaim but will not use any filesystem interfaces. | 218 | * GFP_NOFS will use direct reclaim but will not use any filesystem interfaces. |
219 | * Please try to avoid using this flag directly and instead use | ||
220 | * memalloc_nofs_{save,restore} to mark the whole scope which cannot/shouldn't | ||
221 | * recurse into the FS layer with a short explanation why. All allocation | ||
222 | * requests will inherit GFP_NOFS implicitly. | ||
215 | * | 223 | * |
216 | * GFP_USER is for userspace allocations that also need to be directly | 224 | * GFP_USER is for userspace allocations that also need to be directly |
217 | * accessibly by the kernel or hardware. It is typically used by hardware | 225 | * accessibly by the kernel or hardware. It is typically used by hardware |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 8ac11465ac5b..993e7e25a3a5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1224,9 +1224,9 @@ extern struct pid *cad_pid; | |||
1224 | #define PF_USED_ASYNC 0x00004000 /* Used async_schedule*(), used by module init */ | 1224 | #define PF_USED_ASYNC 0x00004000 /* Used async_schedule*(), used by module init */ |
1225 | #define PF_NOFREEZE 0x00008000 /* This thread should not be frozen */ | 1225 | #define PF_NOFREEZE 0x00008000 /* This thread should not be frozen */ |
1226 | #define PF_FROZEN 0x00010000 /* Frozen for system suspend */ | 1226 | #define PF_FROZEN 0x00010000 /* Frozen for system suspend */ |
1227 | #define PF_FSTRANS 0x00020000 /* Inside a filesystem transaction */ | 1227 | #define PF_KSWAPD 0x00020000 /* I am kswapd */ |
1228 | #define PF_KSWAPD 0x00040000 /* I am kswapd */ | 1228 | #define PF_MEMALLOC_NOFS 0x00040000 /* All allocation requests will inherit GFP_NOFS */ |
1229 | #define PF_MEMALLOC_NOIO 0x00080000 /* Allocating memory without IO involved */ | 1229 | #define PF_MEMALLOC_NOIO 0x00080000 /* All allocation requests will inherit GFP_NOIO */ |
1230 | #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ | 1230 | #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ |
1231 | #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ | 1231 | #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ |
1232 | #define PF_RANDOMIZE 0x00400000 /* Randomize virtual address space */ | 1232 | #define PF_RANDOMIZE 0x00400000 /* Randomize virtual address space */ |
@@ -1237,8 +1237,6 @@ extern struct pid *cad_pid; | |||
1237 | #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ | 1237 | #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ |
1238 | #define PF_SUSPEND_TASK 0x80000000 /* This thread called freeze_processes() and should not be frozen */ | 1238 | #define PF_SUSPEND_TASK 0x80000000 /* This thread called freeze_processes() and should not be frozen */ |
1239 | 1239 | ||
1240 | #define PF_MEMALLOC_NOFS PF_FSTRANS /* Transition to a more generic GFP_NOFS scope semantic */ | ||
1241 | |||
1242 | /* | 1240 | /* |
1243 | * Only the _current_ task can read/write to tsk->flags, but other | 1241 | * Only the _current_ task can read/write to tsk->flags, but other |
1244 | * tasks can access tsk->flags in readonly mode for example | 1242 | * tasks can access tsk->flags in readonly mode for example |
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 830953ebb391..9daabe138c99 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h | |||
@@ -149,13 +149,21 @@ static inline bool in_vfork(struct task_struct *tsk) | |||
149 | return ret; | 149 | return ret; |
150 | } | 150 | } |
151 | 151 | ||
152 | /* __GFP_IO isn't allowed if PF_MEMALLOC_NOIO is set in current->flags | 152 | /* |
153 | * __GFP_FS is also cleared as it implies __GFP_IO. | 153 | * Applies per-task gfp context to the given allocation flags. |
154 | * PF_MEMALLOC_NOIO implies GFP_NOIO | ||
155 | * PF_MEMALLOC_NOFS implies GFP_NOFS | ||
154 | */ | 156 | */ |
155 | static inline gfp_t memalloc_noio_flags(gfp_t flags) | 157 | static inline gfp_t current_gfp_context(gfp_t flags) |
156 | { | 158 | { |
159 | /* | ||
160 | * NOIO implies both NOIO and NOFS and it is a weaker context | ||
161 | * so always make sure it makes precendence | ||
162 | */ | ||
157 | if (unlikely(current->flags & PF_MEMALLOC_NOIO)) | 163 | if (unlikely(current->flags & PF_MEMALLOC_NOIO)) |
158 | flags &= ~(__GFP_IO | __GFP_FS); | 164 | flags &= ~(__GFP_IO | __GFP_FS); |
165 | else if (unlikely(current->flags & PF_MEMALLOC_NOFS)) | ||
166 | flags &= ~__GFP_FS; | ||
159 | return flags; | 167 | return flags; |
160 | } | 168 | } |
161 | 169 | ||
@@ -171,4 +179,16 @@ static inline void memalloc_noio_restore(unsigned int flags) | |||
171 | current->flags = (current->flags & ~PF_MEMALLOC_NOIO) | flags; | 179 | current->flags = (current->flags & ~PF_MEMALLOC_NOIO) | flags; |
172 | } | 180 | } |
173 | 181 | ||
182 | static inline unsigned int memalloc_nofs_save(void) | ||
183 | { | ||
184 | unsigned int flags = current->flags & PF_MEMALLOC_NOFS; | ||
185 | current->flags |= PF_MEMALLOC_NOFS; | ||
186 | return flags; | ||
187 | } | ||
188 | |||
189 | static inline void memalloc_nofs_restore(unsigned int flags) | ||
190 | { | ||
191 | current->flags = (current->flags & ~PF_MEMALLOC_NOFS) | flags; | ||
192 | } | ||
193 | |||
174 | #endif /* _LINUX_SCHED_MM_H */ | 194 | #endif /* _LINUX_SCHED_MM_H */ |