aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sched.h7
-rw-r--r--kernel/softirq.c9
-rw-r--r--mm/page_alloc.c6
3 files changed, 21 insertions, 1 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 865725adb9d3..c147e7024f11 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1894,6 +1894,13 @@ static inline void rcu_copy_process(struct task_struct *p)
1894 1894
1895#endif 1895#endif
1896 1896
1897static inline void tsk_restore_flags(struct task_struct *task,
1898 unsigned long orig_flags, unsigned long flags)
1899{
1900 task->flags &= ~flags;
1901 task->flags |= orig_flags & flags;
1902}
1903
1897#ifdef CONFIG_SMP 1904#ifdef CONFIG_SMP
1898extern void do_set_cpus_allowed(struct task_struct *p, 1905extern void do_set_cpus_allowed(struct task_struct *p,
1899 const struct cpumask *new_mask); 1906 const struct cpumask *new_mask);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 671f9594e368..b73e681df09e 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -210,6 +210,14 @@ asmlinkage void __do_softirq(void)
210 __u32 pending; 210 __u32 pending;
211 int max_restart = MAX_SOFTIRQ_RESTART; 211 int max_restart = MAX_SOFTIRQ_RESTART;
212 int cpu; 212 int cpu;
213 unsigned long old_flags = current->flags;
214
215 /*
216 * Mask out PF_MEMALLOC s current task context is borrowed for the
217 * softirq. A softirq handled such as network RX might set PF_MEMALLOC
218 * again if the socket is related to swap
219 */
220 current->flags &= ~PF_MEMALLOC;
213 221
214 pending = local_softirq_pending(); 222 pending = local_softirq_pending();
215 account_system_vtime(current); 223 account_system_vtime(current);
@@ -265,6 +273,7 @@ restart:
265 273
266 account_system_vtime(current); 274 account_system_vtime(current);
267 __local_bh_enable(SOFTIRQ_OFFSET); 275 __local_bh_enable(SOFTIRQ_OFFSET);
276 tsk_restore_flags(current, old_flags, PF_MEMALLOC);
268} 277}
269 278
270#ifndef __ARCH_HAS_DO_SOFTIRQ 279#ifndef __ARCH_HAS_DO_SOFTIRQ
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8f65abeb9ad6..cd5390f2f18d 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2296,7 +2296,11 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
2296 if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) { 2296 if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) {
2297 if (gfp_mask & __GFP_MEMALLOC) 2297 if (gfp_mask & __GFP_MEMALLOC)
2298 alloc_flags |= ALLOC_NO_WATERMARKS; 2298 alloc_flags |= ALLOC_NO_WATERMARKS;
2299 else if (likely(!(gfp_mask & __GFP_NOMEMALLOC)) && !in_interrupt()) 2299 else if (in_serving_softirq() && (current->flags & PF_MEMALLOC))
2300 alloc_flags |= ALLOC_NO_WATERMARKS;
2301 else if (!in_interrupt() &&
2302 ((current->flags & PF_MEMALLOC) ||
2303 unlikely(test_thread_flag(TIF_MEMDIE))))
2300 alloc_flags |= ALLOC_NO_WATERMARKS; 2304 alloc_flags |= ALLOC_NO_WATERMARKS;
2301 } 2305 }
2302 2306