aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/gfp.h8
-rw-r--r--include/linux/sched.h8
-rw-r--r--include/linux/sched/mm.h26
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 */
155static inline gfp_t memalloc_noio_flags(gfp_t flags) 157static 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
182static 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
189static 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 */