I/OAT DMA support and TCP acceleration
Subsystems (3)
RFC PATCH 4/5 I/OAT DMA support and TCP acceleration
Structure changes for TCP recv offload to I/OAT
Adds an async_wait_queue and some additional fields to tcp_sock, a copied_early flag to sb_buff and a dma_cookie_t to tcp_skb_cb
Renames cleanup_rbuf to tcp_cleanup_rbuf and makes it non-static so we can call it from tcp_input.c
---
include/linux/skbuff.h | 5 +++-- include/linux/tcp.h | 9 +++++++++ include/net/tcp.h | 10 ++++++++++ net/core/skbuff.c | 1 + net/ipv4/tcp.c | 11 ++++++----- net/ipv4/tcp_ipv4.c | 4 ++++ net/ipv4/tcp_minisocks.c | 1 + net/ipv6/tcp_ipv6.c | 1 + 8 files changed, 35 insertions(+), 7 deletions(-)
include/linux/skbuff.h +3 -2
@@ -248,7 +248,7 @@ struct sk_buff {* want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. */ -char cb[40 ]; +char cb[44 ];unsigned int len, data_len,
@@ -261,7 +261,8 @@ struct sk_buff { nohdr:1 , nfctinfo:3; __u8 pkt_type:3, - fclone:2; + fclone:2, + copied_early:1;__be16 protocol;void (*destructor)(struct sk_buff *skb);
include/linux/tcp.h +9 -0
@@ -18,6 +18,7 @@#define _LINUX_TCP_H#include <linux/types.h> +#include <linux/dmaengine.h> #include <asm/byteorder.h> struct tcphdr {
@@ -249,6 +250,13 @@ struct tcp_sock {struct iovec *iov;int memory;int len; + +/* members for async copy */ +int wakeup; +struct dma_chan *dma_chan; +int bytes_early_copied; +struct dma_locked_list *locked_list; +dma_cookie_t dma_cookie; } ucopy;__u32 snd_wl1;/* Sequence for window update */
@@ -294,6 +302,7 @@ struct tcp_sock {__u32 snd_cwnd_stamp;struct sk_buff_head out_of_order_queue;/* Out of order segments go here */ +struct sk_buff_head async_wait_queue;/* DMA unfinished segments go here */ struct tcp_func *af_specific;/* Operations which are AF_INET{4,6} specific */
include/net/tcp.h +10 -0
@@ -563,6 +563,9 @@ extern u32 __tcp_select_window(struct so* 40 bytes on 64-bit machines, if this grows please adjust * skbuff.h:skbuff->cb[xxx] size appropriately. */ + +#include <linux/dmaengine.h> + struct tcp_skb_cb { union { struct inet_skb_parm h4;
@@ -602,6 +605,7 @@ struct tcp_skb_cb {__u16 urg_ptr;/* Valid w/URG flags is set. */ __u32 ack_seq;/* Sequence number ACK'd */ +dma_cookie_t dma_cookie;/* async copy token */ };#define TCP_SKB_CB (__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0]))
@@ -867,8 +871,14 @@ static __inline__ void tcp_prequeue_init { tp->ucopy.task =NULL ; tp->ucopy.len =0 ; + tp->ucopy.wakeup =0 ; tp->ucopy.memory =0 ;skb_queue_head_init (&tp->ucopy.prequeue); + + tp->ucopy.dma_chan =NULL ; + tp->ucopy.bytes_early_copied =0 ; + tp->ucopy.locked_list =NULL ; + tp->ucopy.dma_cookie =0 ; }/* Packet is added to VJ-style prequeue for processing in process
net/core/skbuff.c +1 -0
@@ -400,6 +400,7 @@ struct sk_buff *skb_clone(struct sk_buffC (local_df); n->cloned =1 ; n->nohdr =0 ; +C (copied_early);C (pkt_type);C (ip_summed);C (priority);
net/ipv4/tcp.c +6 -5
@@ -936,7 +936,7 @@ static int tcp_recv_urg(struct sock *sk,* calculation of whether or not we must ACK for the sake of * a window update. */ -static void cleanup_rbuf (struct sock *sk,int copied) +void tcp_cleanup_rbuf (struct sock *sk,int copied) {struct tcp_sock *tp =tcp_sk (sk);int time_to_ack =0 ;
@@ -1085,7 +1085,7 @@ int tcp_read_sock(struct sock *sk, read_/* Clean up data we have read: This will do ACK frames. */ if (copied) -cleanup_rbuf (sk, copied); +tcp_cleanup_rbuf (sk, copied);return copied; }
@@ -1219,7 +1219,7 @@ int tcp_recvmsg(struct kiocb *iocb, stru } } -cleanup_rbuf (sk, copied); +tcp_cleanup_rbuf (sk, copied);if (!sysctl_tcp_low_latency && tp->ucopy.task == user_recv) {/* Install new reader */
@@ -1390,7 +1390,7 @@ skip_copy:*/ /* Clean up data we have read: This will do ACK frames. */ -cleanup_rbuf (sk, copied); +tcp_cleanup_rbuf (sk, copied);TCP_CHECK_TIMER (sk);release_sock (sk);
@@ -1652,6 +1652,7 @@ int tcp_disconnect(struct sock *sk, int__skb_queue_purge (&sk->sk_receive_queue);sk_stream_writequeue_purge (sk);__skb_queue_purge (&tp->out_of_order_queue); +__skb_queue_purge (&tp->async_wait_queue); inet->dport =0 ;
@@ -1855,7 +1856,7 @@ int tcp_setsockopt(struct sock *sk, int (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && inet_csk_ack_scheduled(sk)) { icsk->icsk_ack.pending |=ICSK_ACK_PUSHED ; -cleanup_rbuf (sk,1 ); +tcp_cleanup_rbuf (sk,1 );if (!(val &1 )) icsk->icsk_ack.pingpong =1 ; }
net/ipv4/tcp_ipv4.c +4 -0
@@ -1414,6 +1414,7 @@ static int tcp_v4_init_sock(struct sockstruct tcp_sock *tp =tcp_sk (sk);skb_queue_head_init (&tp->out_of_order_queue); +skb_queue_head_init (&tp->async_wait_queue);tcp_init_xmit_timers (sk);tcp_prequeue_init (tp);
@@ -1466,6 +1467,9 @@ int tcp_v4_destroy_sock(struct sock *sk)/* Cleans up our, hopefully empty, out_of_order_queue. */ __skb_queue_purge (&tp->out_of_order_queue); +/* Cleans up our async_wait_queue */ +__skb_queue_purge (&tp->async_wait_queue); +/* Clean prequeue, it must be empty really */ __skb_queue_purge (&tp->ucopy.prequeue);
net/ipv4/tcp_minisocks.c +1 -0
@@ -389,6 +389,7 @@ struct sock *tcp_create_openreq_child(sttcp_set_ca_state (newsk, TCP_CA_Open);tcp_init_xmit_timers (newsk);skb_queue_head_init (&newtp->out_of_order_queue); +skb_queue_head_init (&newtp->async_wait_queue); newtp->rcv_wup = treq->rcv_isn +1 ; newtp->write_seq = treq->snt_isn +1 ; newtp->pushed_seq = newtp->write_seq;
net/ipv6/tcp_ipv6.c +1 -0
@@ -1863,6 +1863,7 @@ static int tcp_v6_init_sock(struct sockstruct tcp_sock *tp =tcp_sk (sk);skb_queue_head_init (&tp->out_of_order_queue); +skb_queue_head_init (&tp->async_wait_queue);tcp_init_xmit_timers (sk);tcp_prequeue_init (tp);
Quoted 22 lines · Chris Leech
Structure changes for TCP recv offload to I/OAT
Adds an
async_wait_queueand some additional fields totcp_sock, acopied_earlyflag tosb_buffand adma_cookie_ttotcp_skb_cbRenames
cleanup_rbuftotcp_cleanup_rbufand makes it non-static so we can call it fromtcp_input.c---
include/linux/skbuff.h | 5 +++-- include/linux/tcp.h | 9 +++++++++ include/net/tcp.h | 10 ++++++++++ net/core/skbuff.c | 1 + net/ipv4/tcp.c | 11 ++++++----- net/ipv4/tcp_ipv4.c | 4 ++++ net/ipv4/tcp_minisocks.c | 1 + net/ipv6/tcp_ipv6.c | 1 + 8 files changed, 35 insertions(+), 7 deletions(-)diff -urp
a/include/linux/skbuff.hb/include/linux/skbuff.h
include/linux/skbuff.h struct sk_buff { · line 251
Quoted 5 lines
include/linux/skbuff.h +1
-1@@ -248,7 +248,7 @@ struct sk_buff {* want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. */ -char cb[40 ]; +char cb[44 ];
Hi Chris
Please consider not enlarging cb[] if not CONFIG_NET_DMA ?
I mean, most machines wont have a compatable NIC, so why should they pay the price (memory, cpu) in a critical structure named sk_buff ?
#ifdef CONFIG_NET_DMA
typedef dma_cookie_t net_dma_cookie_t;
#else
typedef struct {} net_dma_cookie_t;
#endif
...
char cb[40+sizeof(net_dma_cookie_t)];
Same remark apply for the rest of your patch : Please consider to make added fields and code conditional to CONFIG_NET_DMA
Eric
A message that is not in the archive (sent off-list or not yet received): [email protected]
RFC PATCH 4/5 I/OAT DMA support and TCP acceleration
Sorry, bounced from vger the first time due to formatting
---------- Forwarded message ----------
From: Chris Leech <[email protected]>
Date: Dec 20, 2005 11:05 PM
Subject: Re: [RFC][PATCH 4/5] I/OAT DMA support and TCP acceleration
To: Eric Dumazet <[email protected]>
Cc: lkml <[email protected]>, netdev <[email protected]>, "Grover, Andrew" <[email protected]>, "Ronciak, John" <[email protected]>
Quoted 11 lines · Eric Dumazet
Please consider not enlarging cb[] if not
CONFIG_NET_DMA?I mean, most machines wont have a compatable NIC, so why should they pay the price (memory, cpu) in a critical structure named
sk_buff?#ifdef
CONFIG_NET_DMA
typedefdma_cookie_tnet_dma_cookie_t;
#else
typedef struct {}net_dma_cookie_t;
#endif
Quoted 4 lines
...
char cb[40+sizeof(net_dma_cookie_t)];
That could be a good way to deal with it. Actually, I should double
check the length of tcp_skb_cb. I took a quick look and thought that there might be some room left there anyway, even though the comment in tcp.h says otherwise.
-Chris
David S. Miller
maintainerFrom: Chris Leech <[email protected]>
Date: Tue, 20 Dec 2005 23:10:07 -0800
Quoted 4 lines
That could be a good way to deal with it. Actually, I should double
check the length oftcp_skb_cb. I took a quick look and thought that there might be some room left there anyway, even though the comment intcp.hsays otherwise.
There isn't, it's basically full on 64-bit systems with ipv6 enabled.
Just put the DMA cookie object explicitly into struct sk_buff, protected by CONFIG_NET_DMA.
David S. Miller
maintainerFrom: Eric Dumazet <[email protected]>
Date: Wed, 21 Dec 2005 07:20:43 +0100
Quoted 1 line
Please consider not enlarging cb[] if not
CONFIG_NET_DMA?
I also disagree with putting this thing in the cb[] at all.
Just put the dma_cookie_t explicitly into struct sk_buff, protected by CONFIG_NET_DMA.