netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Fix broken zero-copy on vmalloc() buffers (4th and hopefully final submission)
@ 2014-02-09  0:32 Richard Yao
  2014-02-09  0:32 ` [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers Richard Yao
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Yao @ 2014-02-09  0:32 UTC (permalink / raw)
  To: David S. Miller
  Cc: Eric Van Hensbergen, Ron Minnich, Latchesar Ionkov,
	V9FS Develooper Mailing List, Linux Netdev Mailing List,
	Linux Kernel Mailing List, Aneesh Kumar K.V, Will Deacon,
	Christopher Covington, Matthew Thode

This patch has been submitted for a few times.

The first time was my first time doing any sort of Linux patch
submission. At the time, I was unaware of ./scripts/get_maintainer.pl
and sent the patch to only a subset of the correct people. Consequently,
it was not submitted properly for acceptance by the subsystem maintainer.

The second time was a week ago. I had taken advice from Greg Koah-Hartman to
use ./scripts/get_maintainer.pl to determine the correct recipients. It was
initially accepted by the subsystem maintainer and then rejected. This patch
uses is_vmalloc_or_module_addr(), which is not exported for use in kernel
modules. Using it causes a build failure when CONFIG_NET_9P_VIRTIO=m is set in
.config.

The third time was earlier today, when I sent it straight to Linus Torvalds
because merging it required exporting is_vmalloc_or_module_addr(), which he
wrote. A brief correspondence with Linus revealed that my earlier belief that
it would be better to use is_vmalloc_or_module_addr() instead of
is_vmalloc_addr() was incorrect.

I expect this submission to be the last. I have changed the patch to use
is_vmalloc_addr() as Linus Torvalds suggested. This resolves the build
regression the problem David S. Miller found when CONFIG_NET_9P_VIRTIO=m was
set and should resolve all criticism.

Richard Yao (1):
  9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers

 net/9p/trans_virtio.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers
  2014-02-09  0:32 [PATCH] Fix broken zero-copy on vmalloc() buffers (4th and hopefully final submission) Richard Yao
@ 2014-02-09  0:32 ` Richard Yao
  0 siblings, 0 replies; 6+ messages in thread
From: Richard Yao @ 2014-02-09  0:32 UTC (permalink / raw)
  To: David S. Miller
  Cc: Eric Van Hensbergen, Ron Minnich, Latchesar Ionkov,
	V9FS Develooper Mailing List, Linux Netdev Mailing List,
	Linux Kernel Mailing List, Aneesh Kumar K.V, Will Deacon,
	Christopher Covington, Matthew Thode

The 9p-virtio transport does zero copy on things larger than 1024 bytes
in size. It accomplishes this by returning the physical addresses of
pages to the virtio-pci device. At present, the translation is usually a
bit shift.

That approach produces an invalid page address when we read/write to
vmalloc buffers, such as those used for Linux kernel modules. Any
attempt to load a Linux kernel module from 9p-virtio produces the
following stack.

[<ffffffff814878ce>] p9_virtio_zc_request+0x45e/0x510
[<ffffffff814814ed>] p9_client_zc_rpc.constprop.16+0xfd/0x4f0
[<ffffffff814839dd>] p9_client_read+0x15d/0x240
[<ffffffff811c8440>] v9fs_fid_readn+0x50/0xa0
[<ffffffff811c84a0>] v9fs_file_readn+0x10/0x20
[<ffffffff811c84e7>] v9fs_file_read+0x37/0x70
[<ffffffff8114e3fb>] vfs_read+0x9b/0x160
[<ffffffff81153571>] kernel_read+0x41/0x60
[<ffffffff810c83ab>] copy_module_from_fd.isra.34+0xfb/0x180

Subsequently, QEMU will die printing:

qemu-system-x86_64: virtio: trying to map MMIO memory

This patch enables 9p-virtio to correctly handle this case. This not
only enables us to load Linux kernel modules off virtfs, but also
enables ZFS file-based vdevs on virtfs to be used without killing QEMU.

Special thanks to both Avi Kivity and Alexander Graf for their
interpretation of QEMU backtraces. Without their guidence, tracking down
this bug would have taken much longer. Also, special thanks to Linus
Torvalds for his insightful explanation of why this should use
is_vmalloc_addr() instead of is_vmalloc_or_module_addr():

https://lkml.org/lkml/2014/2/8/272

Signed-off-by: Richard Yao <ryao@gentoo.org>
---
 net/9p/trans_virtio.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index cd1e1ed..ac2666c 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -340,7 +340,10 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
 		int count = nr_pages;
 		while (nr_pages) {
 			s = rest_of_page(data);
-			pages[index++] = kmap_to_page(data);
+			if (is_vmalloc_addr(data))
+				pages[index++] = vmalloc_to_page(data);
+			else
+				pages[index++] = kmap_to_page(data);
 			data += s;
 			nr_pages--;
 		}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers
  2014-01-31  0:44     ` David Miller
@ 2014-01-31  1:02       ` Richard Yao
  0 siblings, 0 replies; 6+ messages in thread
From: Richard Yao @ 2014-01-31  1:02 UTC (permalink / raw)
  To: David Miller
  Cc: ericvh, rminnich, lucho, v9fs-developer, netdev, linux-kernel,
	kernel, aneesh.kumar, will.deacon, cov, behlendorf1, mthode

On Jan 30, 2014, at 7:44 PM, David Miller <davem@davemloft.net> wrote:

> From: David Miller <davem@davemloft.net>
> Date: Thu, 30 Jan 2014 16:29:26 -0800 (PST)
> 
>> From: Richard Yao <ryao@gentoo.org>
>> Date: Thu, 30 Jan 2014 13:02:48 -0500
>> 
>>> The 9p-virtio transport does zero copy on things larger than 1024 bytes
>>> in size. It accomplishes this by returning the physical addresses of
>>> pages to the virtio-pci device. At present, the translation is usually a
>>> bit shift.
>>> 
>>> However, that approach produces an invalid page address when we
>>> read/write to vmalloc buffers, such as those used for Linux kernle
>>> modules. This causes QEMU to die printing:
>>> 
>>> qemu-system-x86_64: virtio: trying to map MMIO memory
>>> 
>>> This patch enables 9p-virtio to correctly handle this case. This not
>>> only enables us to load Linux kernel modules off virtfs, but also
>>> enables ZFS file-based vdevs on virtfs to be used without killing QEMU.
>>> 
>>> Also, special thanks to both Avi Kivity and Alexander Graf for their
>>> interpretation of QEMU backtraces. Without their guidence, tracking down
>>> this bug would have taken much longer.
>>> 
>>> Signed-off-by: Richard Yao <ryao@gentoo.org>
>>> Acked-by: Alexander Graf <agraf@suse.de>
>>> Reviewed-by: Will Deacon <will.deacon@arm.com>
>> 
>> Applied, thanks.
> 
> Actually I had to revert, is_vmalloc_or_malloc_addr() is not exported to
> modules, so this change breaks the build.

Thanks for catching that. I had originally used is_vmalloc_addr() instead of is_vmalloc_or_malloc_addr(), but changed it after realizing this did not correct the problem on all architectures. The is_vmalloc_addr() lives in headers. I will send out a patch to get that symbol exported and resubmit this after it is merged.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers
  2014-01-31  0:29   ` David Miller
@ 2014-01-31  0:44     ` David Miller
  2014-01-31  1:02       ` Richard Yao
  0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2014-01-31  0:44 UTC (permalink / raw)
  To: ryao
  Cc: ericvh, rminnich, lucho, v9fs-developer, netdev, linux-kernel,
	kernel, aneesh.kumar, will.deacon, cov, behlendorf1, mthode

From: David Miller <davem@davemloft.net>
Date: Thu, 30 Jan 2014 16:29:26 -0800 (PST)

> From: Richard Yao <ryao@gentoo.org>
> Date: Thu, 30 Jan 2014 13:02:48 -0500
> 
>> The 9p-virtio transport does zero copy on things larger than 1024 bytes
>> in size. It accomplishes this by returning the physical addresses of
>> pages to the virtio-pci device. At present, the translation is usually a
>> bit shift.
>> 
>> However, that approach produces an invalid page address when we
>> read/write to vmalloc buffers, such as those used for Linux kernle
>> modules. This causes QEMU to die printing:
>> 
>> qemu-system-x86_64: virtio: trying to map MMIO memory
>> 
>> This patch enables 9p-virtio to correctly handle this case. This not
>> only enables us to load Linux kernel modules off virtfs, but also
>> enables ZFS file-based vdevs on virtfs to be used without killing QEMU.
>> 
>> Also, special thanks to both Avi Kivity and Alexander Graf for their
>> interpretation of QEMU backtraces. Without their guidence, tracking down
>> this bug would have taken much longer.
>> 
>> Signed-off-by: Richard Yao <ryao@gentoo.org>
>> Acked-by: Alexander Graf <agraf@suse.de>
>> Reviewed-by: Will Deacon <will.deacon@arm.com>
> 
> Applied, thanks.

Actually I had to revert, is_vmalloc_or_malloc_addr() is not exported to
modules, so this change breaks the build.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers
  2014-01-30 18:02 ` [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers Richard Yao
@ 2014-01-31  0:29   ` David Miller
  2014-01-31  0:44     ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2014-01-31  0:29 UTC (permalink / raw)
  To: ryao
  Cc: ericvh, rminnich, lucho, v9fs-developer, netdev, linux-kernel,
	kernel, aneesh.kumar, will.deacon, cov, behlendorf1, mthode

From: Richard Yao <ryao@gentoo.org>
Date: Thu, 30 Jan 2014 13:02:48 -0500

> The 9p-virtio transport does zero copy on things larger than 1024 bytes
> in size. It accomplishes this by returning the physical addresses of
> pages to the virtio-pci device. At present, the translation is usually a
> bit shift.
> 
> However, that approach produces an invalid page address when we
> read/write to vmalloc buffers, such as those used for Linux kernle
> modules. This causes QEMU to die printing:
> 
> qemu-system-x86_64: virtio: trying to map MMIO memory
> 
> This patch enables 9p-virtio to correctly handle this case. This not
> only enables us to load Linux kernel modules off virtfs, but also
> enables ZFS file-based vdevs on virtfs to be used without killing QEMU.
> 
> Also, special thanks to both Avi Kivity and Alexander Graf for their
> interpretation of QEMU backtraces. Without their guidence, tracking down
> this bug would have taken much longer.
> 
> Signed-off-by: Richard Yao <ryao@gentoo.org>
> Acked-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Will Deacon <will.deacon@arm.com>

Applied, thanks.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers
  2014-01-30 18:02 [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers (second submission) Richard Yao
@ 2014-01-30 18:02 ` Richard Yao
  2014-01-31  0:29   ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Yao @ 2014-01-30 18:02 UTC (permalink / raw)
  To: Eric Van Hensbergen
  Cc: Ron Minnich, Latchesar Ionkov, David S. Miller,
	V9FS Develooper Mailing List, Linux Netdev Mailing List,
	Linux Kernel Mailing List, Gentoo Kernel Team, Aneesh Kumar K.V,
	Will Deacon, Christopher Covington, Brian Behlendorf,
	Matthew Thode, Richard Yao

The 9p-virtio transport does zero copy on things larger than 1024 bytes
in size. It accomplishes this by returning the physical addresses of
pages to the virtio-pci device. At present, the translation is usually a
bit shift.

However, that approach produces an invalid page address when we
read/write to vmalloc buffers, such as those used for Linux kernle
modules. This causes QEMU to die printing:

qemu-system-x86_64: virtio: trying to map MMIO memory

This patch enables 9p-virtio to correctly handle this case. This not
only enables us to load Linux kernel modules off virtfs, but also
enables ZFS file-based vdevs on virtfs to be used without killing QEMU.

Also, special thanks to both Avi Kivity and Alexander Graf for their
interpretation of QEMU backtraces. Without their guidence, tracking down
this bug would have taken much longer.

Signed-off-by: Richard Yao <ryao@gentoo.org>
Acked-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Will Deacon <will.deacon@arm.com>
---
 net/9p/trans_virtio.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index cd1e1ed..b2009bc 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -340,7 +340,10 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
 		int count = nr_pages;
 		while (nr_pages) {
 			s = rest_of_page(data);
-			pages[index++] = kmap_to_page(data);
+			if (is_vmalloc_or_module_addr(data))
+				pages[index++] = vmalloc_to_page(data);
+			else
+				pages[index++] = kmap_to_page(data);
 			data += s;
 			nr_pages--;
 		}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-02-09  0:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-09  0:32 [PATCH] Fix broken zero-copy on vmalloc() buffers (4th and hopefully final submission) Richard Yao
2014-02-09  0:32 ` [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers Richard Yao
  -- strict thread matches above, loose matches on Subject: below --
2014-01-30 18:02 [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers (second submission) Richard Yao
2014-01-30 18:02 ` [PATCH] 9p/trans_virtio.c: Fix broken zero-copy on vmalloc() buffers Richard Yao
2014-01-31  0:29   ` David Miller
2014-01-31  0:44     ` David Miller
2014-01-31  1:02       ` Richard Yao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).