netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] tcp: perform DMA to userspace only if there is a task waiting for it
@ 2012-07-27 14:05 Jiri Kosina
  2012-07-27 20:31 ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Jiri Kosina @ 2012-07-27 14:05 UTC (permalink / raw)
  To: Chris Leech, David S. Miller; +Cc: linux-kernel, netdev, Jiri Bohac

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 the data have already been 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>
---
 net/ipv4/tcp_input.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 3e07a64..f8059f9 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5475,7 +5475,10 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 			if (tp->copied_seq == tp->rcv_nxt &&
 			    len - tcp_header_len <= tp->ucopy.len) {
 #ifdef CONFIG_NET_DMA
-				if (tcp_dma_try_early_copy(sk, skb, tcp_header_len)) {
+				if (tp->ucopy.task == current &&
+						sock_owned_by_user(sk) &&
+						tcp_dma_try_early_copy(sk,
+							skb, tcp_header_len)) {
 					copied_early = 1;
 					eaten = 1;
 				}
-- 
Jiri Kosina
SUSE Labs

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

end of thread, other threads:[~2012-07-27 20:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-27 14:05 [PATCH] tcp: perform DMA to userspace only if there is a task waiting for it Jiri Kosina
2012-07-27 20:31 ` David Miller
2012-07-27 20:38   ` [PATCH v2] " Jiri Kosina
2012-07-27 20:48     ` David Miller

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).