Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752645Ab2JOFPQ (ORCPT ); Mon, 15 Oct 2012 01:15:16 -0400 Received: from mail-pa0-f46.google.com ([209.85.220.46]:48125 "EHLO mail-pa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752312Ab2JOFPN (ORCPT ); Mon, 15 Oct 2012 01:15:13 -0400 From: Ming Lei To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-pm@vger.kernel.org, Ming Lei , Alan Stern , Oliver Neukum , Jiri Kosina , Andrew Morton , Mel Gorman , Minchan Kim , KAMEZAWA Hiroyuki , Michal Hocko , Ingo Molnar , Peter Zijlstra , "Rafael J. Wysocki" , linux-mm Subject: [RFC PATCH 1/3] mm: teach mm by current context info to not do I/O during memory allocation Date: Mon, 15 Oct 2012 13:14:17 +0800 Message-Id: <1350278059-14904-2-git-send-email-ming.lei@canonical.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1350278059-14904-1-git-send-email-ming.lei@canonical.com> References: <1350278059-14904-1-git-send-email-ming.lei@canonical.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4222 Lines: 95 This patch introduces PF_MEMALLOC_NOIO on process flag('flags' field of 'struct task_struct'), so that the flag can be set by one task to avoid doing I/O inside memory allocation in the task's context. The patch trys to solve one deadlock problem caused by block device, and the problem can be occured at least in the below situations: - during block device runtime resume situation, if memory allocation with GFP_KERNEL is called inside runtime resume callback of any one of its ancestors(or the block device itself), the deadlock may be triggered inside the memory allocation since it might not complete until the block device becomes active and the involed page I/O finishes. The situation is pointed out first by Alan Stern. It is not a good approach to convert all GFP_KERNEL in the path into GFP_NOIO because several subsystems may be involved(for example, PCI, USB and SCSI may be involved for usb mass stoarage device) - during error handling situation of usb mass storage deivce, USB bus reset will be put on the device, so there shouldn't have any memory allocation with GFP_KERNEL during USB bus reset, otherwise the deadlock similar with above may be triggered. Unfortunately, any usb device may include one mass storage interface in theory, so it requires all usb interface drivers to handle the situation. In fact, most usb drivers don't know how to handle bus reset on the device and don't provide .pre_set() and .post_reset() callback at all, so USB core has to unbind and bind driver for these devices. So it is still not practical to resort to GFP_NOIO for solving the problem. Also the introduced solution can be used by block subsystem or block drivers too, for example, set the PF_MEMALLOC_NOIO flag before doing actual I/O transfer. Cc: Alan Stern Cc: Oliver Neukum Cc: Jiri Kosina Cc: Andrew Morton Cc: Mel Gorman Cc: Minchan Kim Cc: KAMEZAWA Hiroyuki Cc: Michal Hocko Cc: Ingo Molnar Cc: Peter Zijlstra Cc: "Rafael J. Wysocki" Cc: linux-mm Signed-off-by: Ming Lei --- include/linux/sched.h | 5 +++++ mm/page_alloc.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/include/linux/sched.h b/include/linux/sched.h index f6961c9..33be290 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1811,6 +1811,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define PF_FROZEN 0x00010000 /* frozen for system suspend */ #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ #define PF_KSWAPD 0x00040000 /* I am kswapd */ +#define PF_MEMALLOC_NOIO 0x00080000 /* Allocating memory without IO involved */ #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ @@ -1848,6 +1849,10 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) #define used_math() tsk_used_math(current) +#define tsk_memalloc_no_io(p) ((p)->flags & PF_MEMALLOC_NOIO) +#define tsk_memalloc_allow_io(p) do { (p)->flags &= ~PF_MEMALLOC_NOIO; } while (0) +#define tsk_memalloc_forbid_io(p) do { (p)->flags |= PF_MEMALLOC_NOIO; } while (0) + /* * task->jobctl flags */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8e1be1c..e15381f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2596,6 +2596,8 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int alloc_flags = ALLOC_WMARK_LOW|ALLOC_CPUSET; gfp_mask &= gfp_allowed_mask; + if (unlikely(tsk_memalloc_no_io(current))) + gfp_mask &= ~GFP_IOFS; lockdep_trace_alloc(gfp_mask); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/