mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-10 15:58:47 +00:00
tcp: simplify tcp_current_mss
There's very little need for most of the callsites to get tp->xmit_goal_size updated. That will cost us divide as is, so slice the function in two. Also, the only users of the tp->xmit_goal_size are directly behind tcp_current_mss(), so there's no need to store that variable into tcp_sock at all! The drop of xmit_goal_size currently leaves 16-bit hole and some reorganization would again be necessary to change that (but I'm aiming to fill that hole with u16 xmit_goal_size_segs to cache the results of the remaining divide to get that tso on regression). Bring xmit_goal_size parts into tcp.c Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Cc: Evgeniy Polyakov <zbr@ioremap.net> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
72211e9050
commit
0c54b85f28
@ -248,7 +248,6 @@ struct tcp_sock {
|
|||||||
/* inet_connection_sock has to be the first member of tcp_sock */
|
/* inet_connection_sock has to be the first member of tcp_sock */
|
||||||
struct inet_connection_sock inet_conn;
|
struct inet_connection_sock inet_conn;
|
||||||
u16 tcp_header_len; /* Bytes of tcp header to send */
|
u16 tcp_header_len; /* Bytes of tcp header to send */
|
||||||
u16 xmit_size_goal; /* Goal for segmenting output packets */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Header prediction flags
|
* Header prediction flags
|
||||||
|
@ -481,7 +481,16 @@ static inline void tcp_clear_xmit_timers(struct sock *sk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu);
|
extern unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu);
|
||||||
extern unsigned int tcp_current_mss(struct sock *sk, int large);
|
extern unsigned int tcp_current_mss(struct sock *sk);
|
||||||
|
|
||||||
|
/* Bound MSS / TSO packet size with the half of the window */
|
||||||
|
static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
|
||||||
|
{
|
||||||
|
if (tp->max_window && pktsize > (tp->max_window >> 1))
|
||||||
|
return max(tp->max_window >> 1, 68U - tp->tcp_header_len);
|
||||||
|
else
|
||||||
|
return pktsize;
|
||||||
|
}
|
||||||
|
|
||||||
/* tcp.c */
|
/* tcp.c */
|
||||||
extern void tcp_get_info(struct sock *, struct tcp_info *);
|
extern void tcp_get_info(struct sock *, struct tcp_info *);
|
||||||
@ -822,7 +831,7 @@ static inline void tcp_push_pending_frames(struct sock *sk)
|
|||||||
{
|
{
|
||||||
struct tcp_sock *tp = tcp_sk(sk);
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
|
|
||||||
__tcp_push_pending_frames(sk, tcp_current_mss(sk, 1), tp->nonagle);
|
__tcp_push_pending_frames(sk, tcp_current_mss(sk), tp->nonagle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tcp_init_wl(struct tcp_sock *tp, u32 seq)
|
static inline void tcp_init_wl(struct tcp_sock *tp, u32 seq)
|
||||||
|
@ -661,6 +661,37 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
|
||||||
|
int large_allowed)
|
||||||
|
{
|
||||||
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
|
u32 xmit_size_goal;
|
||||||
|
|
||||||
|
xmit_size_goal = mss_now;
|
||||||
|
|
||||||
|
if (large_allowed && sk_can_gso(sk)) {
|
||||||
|
xmit_size_goal = ((sk->sk_gso_max_size - 1) -
|
||||||
|
inet_csk(sk)->icsk_af_ops->net_header_len -
|
||||||
|
inet_csk(sk)->icsk_ext_hdr_len -
|
||||||
|
tp->tcp_header_len);
|
||||||
|
|
||||||
|
xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
|
||||||
|
xmit_size_goal -= (xmit_size_goal % mss_now);
|
||||||
|
}
|
||||||
|
|
||||||
|
return xmit_size_goal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tcp_send_mss(struct sock *sk, int *size_goal, int flags)
|
||||||
|
{
|
||||||
|
int mss_now;
|
||||||
|
|
||||||
|
mss_now = tcp_current_mss(sk);
|
||||||
|
*size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB));
|
||||||
|
|
||||||
|
return mss_now;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset,
|
static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset,
|
||||||
size_t psize, int flags)
|
size_t psize, int flags)
|
||||||
{
|
{
|
||||||
@ -677,8 +708,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
|
|||||||
|
|
||||||
clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
|
clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
|
||||||
|
|
||||||
mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
|
mss_now = tcp_send_mss(sk, &size_goal, flags);
|
||||||
size_goal = tp->xmit_size_goal;
|
|
||||||
copied = 0;
|
copied = 0;
|
||||||
|
|
||||||
err = -EPIPE;
|
err = -EPIPE;
|
||||||
@ -761,8 +791,7 @@ wait_for_memory:
|
|||||||
if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
|
if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
|
||||||
goto do_error;
|
goto do_error;
|
||||||
|
|
||||||
mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
|
mss_now = tcp_send_mss(sk, &size_goal, flags);
|
||||||
size_goal = tp->xmit_size_goal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -844,8 +873,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
|
|||||||
/* This should be in poll */
|
/* This should be in poll */
|
||||||
clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
|
clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
|
||||||
|
|
||||||
mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
|
mss_now = tcp_send_mss(sk, &size_goal, flags);
|
||||||
size_goal = tp->xmit_size_goal;
|
|
||||||
|
|
||||||
/* Ok commence sending. */
|
/* Ok commence sending. */
|
||||||
iovlen = msg->msg_iovlen;
|
iovlen = msg->msg_iovlen;
|
||||||
@ -1007,8 +1035,7 @@ wait_for_memory:
|
|||||||
if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
|
if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
|
||||||
goto do_error;
|
goto do_error;
|
||||||
|
|
||||||
mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
|
mss_now = tcp_send_mss(sk, &size_goal, flags);
|
||||||
size_goal = tp->xmit_size_goal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2864,7 +2864,7 @@ void tcp_simple_retransmit(struct sock *sk)
|
|||||||
const struct inet_connection_sock *icsk = inet_csk(sk);
|
const struct inet_connection_sock *icsk = inet_csk(sk);
|
||||||
struct tcp_sock *tp = tcp_sk(sk);
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
unsigned int mss = tcp_current_mss(sk, 0);
|
unsigned int mss = tcp_current_mss(sk);
|
||||||
u32 prior_lost = tp->lost_out;
|
u32 prior_lost = tp->lost_out;
|
||||||
|
|
||||||
tcp_for_write_queue(skb, sk) {
|
tcp_for_write_queue(skb, sk) {
|
||||||
|
@ -921,7 +921,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
|
|||||||
* factor and mss.
|
* factor and mss.
|
||||||
*/
|
*/
|
||||||
if (tcp_skb_pcount(skb) > 1)
|
if (tcp_skb_pcount(skb) > 1)
|
||||||
tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk, 1));
|
tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -982,15 +982,6 @@ void tcp_mtup_init(struct sock *sk)
|
|||||||
icsk->icsk_mtup.probe_size = 0;
|
icsk->icsk_mtup.probe_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bound MSS / TSO packet size with the half of the window */
|
|
||||||
static int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
|
|
||||||
{
|
|
||||||
if (tp->max_window && pktsize > (tp->max_window >> 1))
|
|
||||||
return max(tp->max_window >> 1, 68U - tp->tcp_header_len);
|
|
||||||
else
|
|
||||||
return pktsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function synchronize snd mss to current pmtu/exthdr set.
|
/* This function synchronize snd mss to current pmtu/exthdr set.
|
||||||
|
|
||||||
tp->rx_opt.user_mss is mss set by user by TCP_MAXSEG. It does NOT counts
|
tp->rx_opt.user_mss is mss set by user by TCP_MAXSEG. It does NOT counts
|
||||||
@ -1037,22 +1028,17 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
|
|||||||
/* Compute the current effective MSS, taking SACKs and IP options,
|
/* Compute the current effective MSS, taking SACKs and IP options,
|
||||||
* and even PMTU discovery events into account.
|
* and even PMTU discovery events into account.
|
||||||
*/
|
*/
|
||||||
unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
|
unsigned int tcp_current_mss(struct sock *sk)
|
||||||
{
|
{
|
||||||
struct tcp_sock *tp = tcp_sk(sk);
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
struct dst_entry *dst = __sk_dst_get(sk);
|
struct dst_entry *dst = __sk_dst_get(sk);
|
||||||
u32 mss_now;
|
u32 mss_now;
|
||||||
u16 xmit_size_goal;
|
|
||||||
int doing_tso = 0;
|
|
||||||
unsigned header_len;
|
unsigned header_len;
|
||||||
struct tcp_out_options opts;
|
struct tcp_out_options opts;
|
||||||
struct tcp_md5sig_key *md5;
|
struct tcp_md5sig_key *md5;
|
||||||
|
|
||||||
mss_now = tp->mss_cache;
|
mss_now = tp->mss_cache;
|
||||||
|
|
||||||
if (large_allowed && sk_can_gso(sk))
|
|
||||||
doing_tso = 1;
|
|
||||||
|
|
||||||
if (dst) {
|
if (dst) {
|
||||||
u32 mtu = dst_mtu(dst);
|
u32 mtu = dst_mtu(dst);
|
||||||
if (mtu != inet_csk(sk)->icsk_pmtu_cookie)
|
if (mtu != inet_csk(sk)->icsk_pmtu_cookie)
|
||||||
@ -1070,19 +1056,6 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
|
|||||||
mss_now -= delta;
|
mss_now -= delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmit_size_goal = mss_now;
|
|
||||||
|
|
||||||
if (doing_tso) {
|
|
||||||
xmit_size_goal = ((sk->sk_gso_max_size - 1) -
|
|
||||||
inet_csk(sk)->icsk_af_ops->net_header_len -
|
|
||||||
inet_csk(sk)->icsk_ext_hdr_len -
|
|
||||||
tp->tcp_header_len);
|
|
||||||
|
|
||||||
xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
|
|
||||||
xmit_size_goal -= (xmit_size_goal % mss_now);
|
|
||||||
}
|
|
||||||
tp->xmit_size_goal = xmit_size_goal;
|
|
||||||
|
|
||||||
return mss_now;
|
return mss_now;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1264,7 +1237,7 @@ int tcp_may_send_now(struct sock *sk)
|
|||||||
struct sk_buff *skb = tcp_send_head(sk);
|
struct sk_buff *skb = tcp_send_head(sk);
|
||||||
|
|
||||||
return (skb &&
|
return (skb &&
|
||||||
tcp_snd_test(sk, skb, tcp_current_mss(sk, 1),
|
tcp_snd_test(sk, skb, tcp_current_mss(sk),
|
||||||
(tcp_skb_is_last(sk, skb) ?
|
(tcp_skb_is_last(sk, skb) ?
|
||||||
tp->nonagle : TCP_NAGLE_PUSH)));
|
tp->nonagle : TCP_NAGLE_PUSH)));
|
||||||
}
|
}
|
||||||
@ -1421,7 +1394,7 @@ static int tcp_mtu_probe(struct sock *sk)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Very simple search strategy: just double the MSS. */
|
/* Very simple search strategy: just double the MSS. */
|
||||||
mss_now = tcp_current_mss(sk, 0);
|
mss_now = tcp_current_mss(sk);
|
||||||
probe_size = 2 * tp->mss_cache;
|
probe_size = 2 * tp->mss_cache;
|
||||||
size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache;
|
size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache;
|
||||||
if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) {
|
if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) {
|
||||||
@ -1903,7 +1876,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
|
|||||||
if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
|
if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
|
||||||
return -EHOSTUNREACH; /* Routing failure or similar. */
|
return -EHOSTUNREACH; /* Routing failure or similar. */
|
||||||
|
|
||||||
cur_mss = tcp_current_mss(sk, 0);
|
cur_mss = tcp_current_mss(sk);
|
||||||
|
|
||||||
/* If receiver has shrunk his window, and skb is out of
|
/* If receiver has shrunk his window, and skb is out of
|
||||||
* new window, do not retransmit it. The exception is the
|
* new window, do not retransmit it. The exception is the
|
||||||
@ -2111,7 +2084,7 @@ void tcp_send_fin(struct sock *sk)
|
|||||||
* unsent frames. But be careful about outgoing SACKS
|
* unsent frames. But be careful about outgoing SACKS
|
||||||
* and IP options.
|
* and IP options.
|
||||||
*/
|
*/
|
||||||
mss_now = tcp_current_mss(sk, 1);
|
mss_now = tcp_current_mss(sk);
|
||||||
|
|
||||||
if (tcp_send_head(sk) != NULL) {
|
if (tcp_send_head(sk) != NULL) {
|
||||||
TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN;
|
TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN;
|
||||||
@ -2523,7 +2496,7 @@ int tcp_write_wakeup(struct sock *sk)
|
|||||||
if ((skb = tcp_send_head(sk)) != NULL &&
|
if ((skb = tcp_send_head(sk)) != NULL &&
|
||||||
before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp))) {
|
before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp))) {
|
||||||
int err;
|
int err;
|
||||||
unsigned int mss = tcp_current_mss(sk, 0);
|
unsigned int mss = tcp_current_mss(sk);
|
||||||
unsigned int seg_size = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
|
unsigned int seg_size = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
|
||||||
|
|
||||||
if (before(tp->pushed_seq, TCP_SKB_CB(skb)->end_seq))
|
if (before(tp->pushed_seq, TCP_SKB_CB(skb)->end_seq))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user