]> www.infradead.org Git - users/jedix/linux-maple.git/commit
tcp: perform DMA to userspace only if there is a task waiting for it
authorJiri Kosina <jkosina@suse.cz>
Fri, 27 Jul 2012 10:38:50 +0000 (10:38 +0000)
committerJerry Snitselaar <jerry.snitselaar@oracle.com>
Sun, 7 Oct 2012 06:29:39 +0000 (23:29 -0700)
commit610d3fc3b02200026398139e629c16002f6f15e7
treea3b89c8d604de426203dad968e39832e5919af98
parenta93bd8b6be1187a9f2f6190601c44cd11a0152aa
tcp: perform DMA to userspace only if there is a task waiting for it

[ Upstream commit 59ea33a68a9083ac98515e4861c00e71efdc49a1 ]

Back in 2006, commit 1a2449a87b ("[I/OAT]: TCP recv offload to I/OAT")
added support for receive offloading to IOAT dma engine if available.

The code in tcp_rcv_established() tries to perform early DMA copy if
applicable. It however does so without checking whether the userspace
task is actually expecting the data in the buffer.

This is not a problem under normal circumstances, but there is a corner
case where this doesn't work -- and that's when MSG_TRUNC flag to
recvmsg() is used.

If the IOAT dma engine is not used, the code properly checks whether
there is a valid ucopy.task and the socket is owned by userspace, but
misses the check in the dmaengine case.

This problem can be observed in real trivially -- for example 'tbench' is a
good reproducer, as it makes a heavy use of MSG_TRUNC. On systems utilizing
IOAT, you will soon find tbench waiting indefinitely in sk_wait_data(), as they
have been already early-copied in tcp_rcv_established() using dma engine.

This patch introduces the same check we are performing in the simple
iovec copy case to the IOAT case as well. It fixes the indefinite
recvmsg(MSG_TRUNC) hangs.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 41f079a0e1089bf0ed2b795cc427bf40b72efe0e)

Signed-off-by: Jerry Snitselaar <jerry.snitselaar@oracle.com>
net/ipv4/tcp_input.c