All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Hocko <mhocko@kernel.org>
To: Mikulas Patocka <mpatocka@redhat.com>
Cc: linux-mm@kvack.org, Andrew Morton <akpm@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>, Shaohua Li <shli@kernel.org>,
	dm-devel@redhat.com
Subject: Re: [PATCH 17/19] dm: get rid of superfluous gfp flags
Date: Wed, 27 Apr 2016 10:35:30 +0200	[thread overview]
Message-ID: <20160427083530.GD2179@dhcp22.suse.cz> (raw)
In-Reply-To: <alpine.LRH.2.02.1604261307520.12205@file01.intranet.prod.int.rdu2.redhat.com>

[Adding dm-devel@redhat.com to CC]

On Tue 26-04-16 13:20:04, Mikulas Patocka wrote:
> On Fri, 22 Apr 2016, Michal Hocko wrote:
[...]
> > copy_params seems to be called only from the ioctl context which doesn't
> > hold any locks which would lockup during the direct reclaim AFAICS. The
> > git log shows that the code has used PF_MEMALLOC before which is even
> > bigger mystery to me. Could you please clarify why this is GFP_NOIO
> > restricted context? Maybe it needed to be in the past but I do not see
> > any reason for it to be now so unless I am missing something the
> > GFP_KERNEL should be perfectly OK. Also note that GFP_NOIO wouldn't work
> > properly because there are copy_from_user calls in the same path which
> > could page fault and do GFP_KERNEL allocations anyway. I can send follow
> > up cleanups unless I am missing something subtle here.
> 
> The LVM tool calls suspend and resume ioctls on device mapper block 
> devices.
>
> When a device is suspended, any bio sent to the device is held. If the 
> resume ioctl did GFP_KERNEL allocation, the allocation could get stuck 
> trying to write some dirty cached pages to the suspended device.
> 
> The LVM tool and the dmeventd daemon use mlock to lock its address space, 
> so the copy_from_user/copy_to_user call cannot trigger a page fault.

OK, I see, thanks for the clarification! This sounds fragile to me
though. Wouldn't it be better to use the memalloc_noio_save for the
whole copy_params instead? That would force all possible allocations to
not trigger any IO. Something like the following.
---
From dbb2338bb88d2da1ff24cee59cbffd120b119e3b Mon Sep 17 00:00:00 2001
From: Michal Hocko <mhocko@suse.com>
Date: Wed, 27 Apr 2016 10:26:13 +0200
Subject: [PATCH] dm: clean up GFP_NIO usage

copy_params uses GFP_NOIO for explicit allocation requests because this
might be called from the suspend path. To quote Mikulas:
: The LVM tool calls suspend and resume ioctls on device mapper block
: devices.
:
: When a device is suspended, any bio sent to the device is held. If the
: resume ioctl did GFP_KERNEL allocation, the allocation could get stuck
: trying to write some dirty cached pages to the suspended device.
:
: The LVM tool and the dmeventd daemon use mlock to lock its address space,
: so the copy_from_user/copy_to_user call cannot trigger a page fault.

Relying on the mlock is quite fragile and we have a better way in kernel
to enfore NOIO which is already used for the vmalloc fallback. Just use
memalloc_noio_{save,restore} around the whole copy_params function which
will force the same also to the page fult paths via copy_{from,to}_user.

While we are there we can also remove __GFP_NOMEMALLOC because copy_params
is never called from MEMALLOC context (e.g. during the reclaim).

Signed-off-by: Michal Hocko <mhocko@suse.com>
---
 drivers/md/dm-ioctl.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 2c7ca258c4e4..fe0b57d7573c 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1715,16 +1715,13 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
 	 */
 	dmi = NULL;
 	if (param_kernel->data_size <= KMALLOC_MAX_SIZE) {
-		dmi = kmalloc(param_kernel->data_size, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
+		dmi = kmalloc(param_kernel->data_size, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
 		if (dmi)
 			*param_flags |= DM_PARAMS_KMALLOC;
 	}
 
 	if (!dmi) {
-		unsigned noio_flag;
-		noio_flag = memalloc_noio_save();
-		dmi = __vmalloc(param_kernel->data_size, GFP_NOIO | __GFP_HIGH | __GFP_HIGHMEM, PAGE_KERNEL);
-		memalloc_noio_restore(noio_flag);
+		dmi = __vmalloc(param_kernel->data_size, GFP_KERNEL | __GFP_HIGH | __GFP_HIGHMEM, PAGE_KERNEL);
 		if (dmi)
 			*param_flags |= DM_PARAMS_VMALLOC;
 	}
@@ -1801,6 +1798,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
 	ioctl_fn fn = NULL;
 	size_t input_param_size;
 	struct dm_ioctl param_kernel;
+	unsigned noio_flag;
 
 	/* only root can play with this */
 	if (!capable(CAP_SYS_ADMIN))
@@ -1832,9 +1830,12 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
 	}
 
 	/*
-	 * Copy the parameters into kernel space.
+	 * Copy the parameters into kernel space. Make sure that no IO is triggered
+	 * from the allocation paths because this might be called during the suspend.
 	 */
+	noio_flag = memalloc_noio_save();
 	r = copy_params(user, &param_kernel, ioctl_flags, &param, &param_flags);
+	memalloc_noio_restore(noio_flag);
 
 	if (r)
 		return r;
-- 
2.8.0.rc3

-- 
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

WARNING: multiple messages have this Message-ID (diff)
From: Michal Hocko <mhocko@kernel.org>
To: Mikulas Patocka <mpatocka@redhat.com>
Cc: linux-mm@kvack.org, Andrew Morton <akpm@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>, Shaohua Li <shli@kernel.org>,
	dm-devel@redhat.com
Subject: Re: [PATCH 17/19] dm: get rid of superfluous gfp flags
Date: Wed, 27 Apr 2016 10:35:30 +0200	[thread overview]
Message-ID: <20160427083530.GD2179@dhcp22.suse.cz> (raw)
In-Reply-To: <alpine.LRH.2.02.1604261307520.12205@file01.intranet.prod.int.rdu2.redhat.com>

[Adding dm-devel@redhat.com to CC]

On Tue 26-04-16 13:20:04, Mikulas Patocka wrote:
> On Fri, 22 Apr 2016, Michal Hocko wrote:
[...]
> > copy_params seems to be called only from the ioctl context which doesn't
> > hold any locks which would lockup during the direct reclaim AFAICS. The
> > git log shows that the code has used PF_MEMALLOC before which is even
> > bigger mystery to me. Could you please clarify why this is GFP_NOIO
> > restricted context? Maybe it needed to be in the past but I do not see
> > any reason for it to be now so unless I am missing something the
> > GFP_KERNEL should be perfectly OK. Also note that GFP_NOIO wouldn't work
> > properly because there are copy_from_user calls in the same path which
> > could page fault and do GFP_KERNEL allocations anyway. I can send follow
> > up cleanups unless I am missing something subtle here.
> 
> The LVM tool calls suspend and resume ioctls on device mapper block 
> devices.
>
> When a device is suspended, any bio sent to the device is held. If the 
> resume ioctl did GFP_KERNEL allocation, the allocation could get stuck 
> trying to write some dirty cached pages to the suspended device.
> 
> The LVM tool and the dmeventd daemon use mlock to lock its address space, 
> so the copy_from_user/copy_to_user call cannot trigger a page fault.

OK, I see, thanks for the clarification! This sounds fragile to me
though. Wouldn't it be better to use the memalloc_noio_save for the
whole copy_params instead? That would force all possible allocations to
not trigger any IO. Something like the following.
---

WARNING: multiple messages have this Message-ID (diff)
From: Michal Hocko <mhocko@kernel.org>
To: Mikulas Patocka <mpatocka@redhat.com>
Cc: linux-mm@kvack.org, Andrew Morton <akpm@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>, Shaohua Li <shli@kernel.org>,
	dm-devel@redhat.com
Subject: Re: [PATCH 17/19] dm: get rid of superfluous gfp flags
Date: Wed, 27 Apr 2016 10:35:30 +0200	[thread overview]
Message-ID: <20160427083530.GD2179@dhcp22.suse.cz> (raw)
In-Reply-To: <alpine.LRH.2.02.1604261307520.12205@file01.intranet.prod.int.rdu2.redhat.com>

[Adding dm-devel@redhat.com to CC]

On Tue 26-04-16 13:20:04, Mikulas Patocka wrote:
> On Fri, 22 Apr 2016, Michal Hocko wrote:
[...]
> > copy_params seems to be called only from the ioctl context which doesn't
> > hold any locks which would lockup during the direct reclaim AFAICS. The
> > git log shows that the code has used PF_MEMALLOC before which is even
> > bigger mystery to me. Could you please clarify why this is GFP_NOIO
> > restricted context? Maybe it needed to be in the past but I do not see
> > any reason for it to be now so unless I am missing something the
> > GFP_KERNEL should be perfectly OK. Also note that GFP_NOIO wouldn't work
> > properly because there are copy_from_user calls in the same path which
> > could page fault and do GFP_KERNEL allocations anyway. I can send follow
> > up cleanups unless I am missing something subtle here.
> 
> The LVM tool calls suspend and resume ioctls on device mapper block 
> devices.
>
> When a device is suspended, any bio sent to the device is held. If the 
> resume ioctl did GFP_KERNEL allocation, the allocation could get stuck 
> trying to write some dirty cached pages to the suspended device.
> 
> The LVM tool and the dmeventd daemon use mlock to lock its address space, 
> so the copy_from_user/copy_to_user call cannot trigger a page fault.

OK, I see, thanks for the clarification! This sounds fragile to me
though. Wouldn't it be better to use the memalloc_noio_save for the
whole copy_params instead? That would force all possible allocations to
not trigger any IO. Something like the following.
---
>From dbb2338bb88d2da1ff24cee59cbffd120b119e3b Mon Sep 17 00:00:00 2001
From: Michal Hocko <mhocko@suse.com>
Date: Wed, 27 Apr 2016 10:26:13 +0200
Subject: [PATCH] dm: clean up GFP_NIO usage

copy_params uses GFP_NOIO for explicit allocation requests because this
might be called from the suspend path. To quote Mikulas:
: The LVM tool calls suspend and resume ioctls on device mapper block
: devices.
:
: When a device is suspended, any bio sent to the device is held. If the
: resume ioctl did GFP_KERNEL allocation, the allocation could get stuck
: trying to write some dirty cached pages to the suspended device.
:
: The LVM tool and the dmeventd daemon use mlock to lock its address space,
: so the copy_from_user/copy_to_user call cannot trigger a page fault.

Relying on the mlock is quite fragile and we have a better way in kernel
to enfore NOIO which is already used for the vmalloc fallback. Just use
memalloc_noio_{save,restore} around the whole copy_params function which
will force the same also to the page fult paths via copy_{from,to}_user.

While we are there we can also remove __GFP_NOMEMALLOC because copy_params
is never called from MEMALLOC context (e.g. during the reclaim).

Signed-off-by: Michal Hocko <mhocko@suse.com>
---
 drivers/md/dm-ioctl.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 2c7ca258c4e4..fe0b57d7573c 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1715,16 +1715,13 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
 	 */
 	dmi = NULL;
 	if (param_kernel->data_size <= KMALLOC_MAX_SIZE) {
-		dmi = kmalloc(param_kernel->data_size, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
+		dmi = kmalloc(param_kernel->data_size, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
 		if (dmi)
 			*param_flags |= DM_PARAMS_KMALLOC;
 	}
 
 	if (!dmi) {
-		unsigned noio_flag;
-		noio_flag = memalloc_noio_save();
-		dmi = __vmalloc(param_kernel->data_size, GFP_NOIO | __GFP_HIGH | __GFP_HIGHMEM, PAGE_KERNEL);
-		memalloc_noio_restore(noio_flag);
+		dmi = __vmalloc(param_kernel->data_size, GFP_KERNEL | __GFP_HIGH | __GFP_HIGHMEM, PAGE_KERNEL);
 		if (dmi)
 			*param_flags |= DM_PARAMS_VMALLOC;
 	}
@@ -1801,6 +1798,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
 	ioctl_fn fn = NULL;
 	size_t input_param_size;
 	struct dm_ioctl param_kernel;
+	unsigned noio_flag;
 
 	/* only root can play with this */
 	if (!capable(CAP_SYS_ADMIN))
@@ -1832,9 +1830,12 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
 	}
 
 	/*
-	 * Copy the parameters into kernel space.
+	 * Copy the parameters into kernel space. Make sure that no IO is triggered
+	 * from the allocation paths because this might be called during the suspend.
 	 */
+	noio_flag = memalloc_noio_save();
 	r = copy_params(user, &param_kernel, ioctl_flags, &param, &param_flags);
+	memalloc_noio_restore(noio_flag);
 
 	if (r)
 		return r;
-- 
2.8.0.rc3

-- 
Michal Hocko
SUSE Labs

  reply	other threads:[~2016-04-27  8:35 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-11 11:07 [PATCH 0/19] get rid of superfluous __GFP_REPORT Michal Hocko
2016-04-11 11:07 ` Michal Hocko
2016-04-11 11:07 ` [PATCH 01/19] tree wide: get rid of __GFP_REPEAT for order-0 allocations part I Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-14 19:56   ` David Rientjes
2016-04-14 19:56     ` David Rientjes
2016-04-15  7:44     ` Michal Hocko
2016-04-15  7:44       ` Michal Hocko
2016-04-15  7:44       ` Michal Hocko
2016-04-15  7:44       ` Michal Hocko
2016-04-11 11:07 ` [PATCH 02/19] x86: get rid of superfluous __GFP_REPEAT Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 11:07 ` [PATCH 03/19] x86/efi: " Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-12 15:53   ` Matt Fleming
2016-04-12 15:53     ` Matt Fleming
2016-04-11 11:07 ` [PATCH 04/19] arm: " Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 11:07 ` [PATCH 05/19] arm64: " Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 15:49   ` Will Deacon
2016-04-11 15:49     ` Will Deacon
2016-04-11 11:07 ` [PATCH 06/19] arc: " Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 11:07   ` Michal Hocko
2016-04-11 14:23   ` Vineet Gupta
2016-04-11 14:23     ` Vineet Gupta
2016-04-11 11:08 ` [PATCH 07/19] mips: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08 ` [PATCH 08/19] nios2: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08 ` [PATCH 09/19] parisc: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08 ` [PATCH 10/19] score: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08 ` [PATCH 11/19] powerpc: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08 ` [PATCH 12/19] sparc: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08 ` [PATCH 13/19] s390: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:28   ` Cornelia Huck
2016-04-11 11:28     ` Cornelia Huck
2016-04-11 11:28     ` Cornelia Huck
2016-04-11 12:47     ` Heiko Carstens
2016-04-11 12:47       ` Heiko Carstens
2016-04-11 11:08 ` [PATCH 14/19] sh: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08 ` [PATCH 15/19] tile: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08 ` [PATCH 16/19] unicore32: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-11 11:08 ` [PATCH 17/19] dm: get rid of superfluous gfp flags Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-15 12:29   ` Mikulas Patocka
2016-04-15 12:29     ` Mikulas Patocka
2016-04-15 13:08     ` Michal Hocko
2016-04-15 13:08       ` Michal Hocko
2016-04-15 18:41       ` Mikulas Patocka
2016-04-15 18:41         ` Mikulas Patocka
2016-04-16 20:31         ` Michal Hocko
2016-04-16 20:31           ` Michal Hocko
2016-04-22 12:47           ` Michal Hocko
2016-04-22 12:47             ` Michal Hocko
2016-04-26 17:20             ` Mikulas Patocka
2016-04-26 17:20               ` Mikulas Patocka
2016-04-27  8:35               ` Michal Hocko [this message]
2016-04-27  8:35                 ` Michal Hocko
2016-04-27  8:35                 ` Michal Hocko
2016-04-11 11:08 ` [PATCH 18/19] crypto: get rid of superfluous __GFP_REPEAT Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-14  6:27   ` Herbert Xu
2016-04-14  6:27     ` Herbert Xu
2016-04-14  7:02     ` Michal Hocko
2016-04-14  7:02       ` Michal Hocko
2016-04-14  8:16       ` Herbert Xu
2016-04-14  8:16         ` Herbert Xu
2016-04-14  8:51   ` [PATCH resend] " Michal Hocko
2016-04-14  8:51     ` Michal Hocko
2016-04-15 14:37     ` Herbert Xu
2016-04-15 14:37       ` Herbert Xu
2016-04-11 11:08 ` [PATCH 19/19] jbd2: " Michal Hocko
2016-04-11 11:08   ` Michal Hocko
2016-04-13 11:21 ` CC in git cover letter vs patches (was Re: [PATCH 0/19] get rid of superfluous __GFP_REPORT) Vineet Gupta
2016-04-13 11:21   ` Vineet Gupta
2016-04-13 11:21   ` Vineet Gupta
2016-04-13 13:33   ` Michal Hocko
2016-04-13 13:33     ` Michal Hocko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160427083530.GD2179@dhcp22.suse.cz \
    --to=mhocko@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=dm-devel@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mpatocka@redhat.com \
    --cc=shli@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.