diff options
author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-06-19 01:46:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-06-19 01:46:52 -0400 |
commit | 2e6599cb899ba4b133f42cbf9d2b1883d2dc583a (patch) | |
tree | b5d4fcca4d2a515fc3d3d20cefaaeebd8dbf661f /net/ipv4/tcp_output.c | |
parent | 1944972d3bb651474a5021c9da8d0166ae19f1eb (diff) |
[NET] Generalise TCP's struct open_request minisock infrastructure
Kept this first changeset minimal, without changing existing names to
ease peer review.
Basicaly tcp_openreq_alloc now receives the or_calltable, that in turn
has two new members:
->slab, that replaces tcp_openreq_cachep
->obj_size, to inform the size of the openreq descendant for
a specific protocol
The protocol specific fields in struct open_request were moved to a
class hierarchy, with the things that are common to all connection
oriented PF_INET protocols in struct inet_request_sock, the TCP ones
in tcp_request_sock, that is an inet_request_sock, that is an
open_request.
I.e. this uses the same approach used for the struct sock class
hierarchy, with sk_prot indicating if the protocol wants to use the
open_request infrastructure by filling in sk_prot->rsk_prot with an
or_calltable.
Results? Performance is improved and TCP v4 now uses only 64 bytes per
open request minisock, down from 96 without this patch :-)
Next changeset will rename some of the structs, fields and functions
mentioned above, struct or_calltable is way unclear, better name it
struct request_sock_ops, s/struct open_request/struct request_sock/g,
etc.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index fa24e7ae1f40..f3c8747caf91 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -1358,6 +1358,7 @@ int tcp_send_synack(struct sock *sk) | |||
1358 | struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, | 1358 | struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, |
1359 | struct open_request *req) | 1359 | struct open_request *req) |
1360 | { | 1360 | { |
1361 | struct inet_request_sock *ireq = inet_rsk(req); | ||
1361 | struct tcp_sock *tp = tcp_sk(sk); | 1362 | struct tcp_sock *tp = tcp_sk(sk); |
1362 | struct tcphdr *th; | 1363 | struct tcphdr *th; |
1363 | int tcp_header_size; | 1364 | int tcp_header_size; |
@@ -1373,47 +1374,47 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
1373 | skb->dst = dst_clone(dst); | 1374 | skb->dst = dst_clone(dst); |
1374 | 1375 | ||
1375 | tcp_header_size = (sizeof(struct tcphdr) + TCPOLEN_MSS + | 1376 | tcp_header_size = (sizeof(struct tcphdr) + TCPOLEN_MSS + |
1376 | (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) + | 1377 | (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) + |
1377 | (req->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) + | 1378 | (ireq->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) + |
1378 | /* SACK_PERM is in the place of NOP NOP of TS */ | 1379 | /* SACK_PERM is in the place of NOP NOP of TS */ |
1379 | ((req->sack_ok && !req->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0)); | 1380 | ((ireq->sack_ok && !ireq->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0)); |
1380 | skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size); | 1381 | skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size); |
1381 | 1382 | ||
1382 | memset(th, 0, sizeof(struct tcphdr)); | 1383 | memset(th, 0, sizeof(struct tcphdr)); |
1383 | th->syn = 1; | 1384 | th->syn = 1; |
1384 | th->ack = 1; | 1385 | th->ack = 1; |
1385 | if (dst->dev->features&NETIF_F_TSO) | 1386 | if (dst->dev->features&NETIF_F_TSO) |
1386 | req->ecn_ok = 0; | 1387 | ireq->ecn_ok = 0; |
1387 | TCP_ECN_make_synack(req, th); | 1388 | TCP_ECN_make_synack(req, th); |
1388 | th->source = inet_sk(sk)->sport; | 1389 | th->source = inet_sk(sk)->sport; |
1389 | th->dest = req->rmt_port; | 1390 | th->dest = ireq->rmt_port; |
1390 | TCP_SKB_CB(skb)->seq = req->snt_isn; | 1391 | TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn; |
1391 | TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; | 1392 | TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; |
1392 | TCP_SKB_CB(skb)->sacked = 0; | 1393 | TCP_SKB_CB(skb)->sacked = 0; |
1393 | skb_shinfo(skb)->tso_segs = 1; | 1394 | skb_shinfo(skb)->tso_segs = 1; |
1394 | skb_shinfo(skb)->tso_size = 0; | 1395 | skb_shinfo(skb)->tso_size = 0; |
1395 | th->seq = htonl(TCP_SKB_CB(skb)->seq); | 1396 | th->seq = htonl(TCP_SKB_CB(skb)->seq); |
1396 | th->ack_seq = htonl(req->rcv_isn + 1); | 1397 | th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); |
1397 | if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ | 1398 | if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ |
1398 | __u8 rcv_wscale; | 1399 | __u8 rcv_wscale; |
1399 | /* Set this up on the first call only */ | 1400 | /* Set this up on the first call only */ |
1400 | req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); | 1401 | req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); |
1401 | /* tcp_full_space because it is guaranteed to be the first packet */ | 1402 | /* tcp_full_space because it is guaranteed to be the first packet */ |
1402 | tcp_select_initial_window(tcp_full_space(sk), | 1403 | tcp_select_initial_window(tcp_full_space(sk), |
1403 | dst_metric(dst, RTAX_ADVMSS) - (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), | 1404 | dst_metric(dst, RTAX_ADVMSS) - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), |
1404 | &req->rcv_wnd, | 1405 | &req->rcv_wnd, |
1405 | &req->window_clamp, | 1406 | &req->window_clamp, |
1406 | req->wscale_ok, | 1407 | ireq->wscale_ok, |
1407 | &rcv_wscale); | 1408 | &rcv_wscale); |
1408 | req->rcv_wscale = rcv_wscale; | 1409 | ireq->rcv_wscale = rcv_wscale; |
1409 | } | 1410 | } |
1410 | 1411 | ||
1411 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ | 1412 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ |
1412 | th->window = htons(req->rcv_wnd); | 1413 | th->window = htons(req->rcv_wnd); |
1413 | 1414 | ||
1414 | TCP_SKB_CB(skb)->when = tcp_time_stamp; | 1415 | TCP_SKB_CB(skb)->when = tcp_time_stamp; |
1415 | tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), req->tstamp_ok, | 1416 | tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok, |
1416 | req->sack_ok, req->wscale_ok, req->rcv_wscale, | 1417 | ireq->sack_ok, ireq->wscale_ok, ireq->rcv_wscale, |
1417 | TCP_SKB_CB(skb)->when, | 1418 | TCP_SKB_CB(skb)->when, |
1418 | req->ts_recent); | 1419 | req->ts_recent); |
1419 | 1420 | ||