* [PATCH net-next 0/2] tcp: tcp_get_info() locking changes
@ 2016-11-04 18:54 Eric Dumazet
2016-11-04 18:54 ` [PATCH net-next 1/2] tcp: shortcut listeners in tcp_get_info() Eric Dumazet
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Eric Dumazet @ 2016-11-04 18:54 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Neal Cardwell, Yuchung Cheng, Soheil Hassas Yeganeh,
Eric Dumazet, Eric Dumazet
This short series prepares tcp_get_info() for more detailed infos.
In order to not slow down fast path, our goal is to use the normal
socket spinlock instead of custom synchronization.
All we need to ensure is that tcp_get_info() is not called with
ehash lock, which might dead lock, since packet processing would acquire
the spinlocks in reverse way.
Eric Dumazet (2):
tcp: shortcut listeners in get_tcp_info()
tcp: no longer hold ehash lock while calling tcp_get_info()
include/linux/tcp.h | 2 --
net/ipv4/inet_diag.c | 48 +++++++++++++++++++++++++++++--------------
net/ipv4/tcp.c | 57 ++++++++++++++++++++++++++++------------------------
net/ipv4/tcp_input.c | 4 ----
4 files changed, 64 insertions(+), 47 deletions(-)
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH net-next 1/2] tcp: shortcut listeners in tcp_get_info() 2016-11-04 18:54 [PATCH net-next 0/2] tcp: tcp_get_info() locking changes Eric Dumazet @ 2016-11-04 18:54 ` Eric Dumazet 2016-11-04 18:54 ` [PATCH net-next 2/2] tcp: no longer hold ehash lock while calling tcp_get_info() Eric Dumazet 2016-11-09 18:03 ` [PATCH net-next 0/2] tcp: tcp_get_info() locking changes David Miller 2 siblings, 0 replies; 9+ messages in thread From: Eric Dumazet @ 2016-11-04 18:54 UTC (permalink / raw) To: David S . Miller Cc: netdev, Neal Cardwell, Yuchung Cheng, Soheil Hassas Yeganeh, Eric Dumazet, Eric Dumazet Being lockless in tcp_get_info() is hard, because we need to add specific synchronization in TCP fast path, like seqcount. Following patch will change inet_diag_dump_icsk() to no longer hold any lock for non listeners, so that we can properly acquire socket lock in get_tcp_info() and let it return more consistent counters. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Yuchung Cheng <ycheng@google.com> Acked-by: Soheil Hassas Yeganeh <soheil@google.com> Acked-by: Neal Cardwell <ncardwell@google.com> --- net/ipv4/tcp.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 3251fe71f39f..117982be0cab 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2721,6 +2721,27 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) info->tcpi_state = sk_state_load(sk); + /* Report meaningful fields for all TCP states, including listeners */ + rate = READ_ONCE(sk->sk_pacing_rate); + rate64 = rate != ~0U ? rate : ~0ULL; + put_unaligned(rate64, &info->tcpi_pacing_rate); + + rate = READ_ONCE(sk->sk_max_pacing_rate); + rate64 = rate != ~0U ? rate : ~0ULL; + put_unaligned(rate64, &info->tcpi_max_pacing_rate); + + info->tcpi_reordering = tp->reordering; + info->tcpi_snd_cwnd = tp->snd_cwnd; + + if (info->tcpi_state == TCP_LISTEN) { + /* listeners aliased fields : + * tcpi_unacked -> Number of children ready for accept() + * tcpi_sacked -> max backlog + */ + info->tcpi_unacked = sk->sk_ack_backlog; + info->tcpi_sacked = sk->sk_max_ack_backlog; + return; + } info->tcpi_ca_state = icsk->icsk_ca_state; info->tcpi_retransmits = icsk->icsk_retransmits; info->tcpi_probes = icsk->icsk_probes_out; @@ -2748,13 +2769,9 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) info->tcpi_snd_mss = tp->mss_cache; info->tcpi_rcv_mss = icsk->icsk_ack.rcv_mss; - if (info->tcpi_state == TCP_LISTEN) { - info->tcpi_unacked = sk->sk_ack_backlog; - info->tcpi_sacked = sk->sk_max_ack_backlog; - } else { - info->tcpi_unacked = tp->packets_out; - info->tcpi_sacked = tp->sacked_out; - } + info->tcpi_unacked = tp->packets_out; + info->tcpi_sacked = tp->sacked_out; + info->tcpi_lost = tp->lost_out; info->tcpi_retrans = tp->retrans_out; info->tcpi_fackets = tp->fackets_out; @@ -2768,23 +2785,13 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) info->tcpi_rtt = tp->srtt_us >> 3; info->tcpi_rttvar = tp->mdev_us >> 2; info->tcpi_snd_ssthresh = tp->snd_ssthresh; - info->tcpi_snd_cwnd = tp->snd_cwnd; info->tcpi_advmss = tp->advmss; - info->tcpi_reordering = tp->reordering; info->tcpi_rcv_rtt = jiffies_to_usecs(tp->rcv_rtt_est.rtt)>>3; info->tcpi_rcv_space = tp->rcvq_space.space; info->tcpi_total_retrans = tp->total_retrans; - rate = READ_ONCE(sk->sk_pacing_rate); - rate64 = rate != ~0U ? rate : ~0ULL; - put_unaligned(rate64, &info->tcpi_pacing_rate); - - rate = READ_ONCE(sk->sk_max_pacing_rate); - rate64 = rate != ~0U ? rate : ~0ULL; - put_unaligned(rate64, &info->tcpi_max_pacing_rate); - do { start = u64_stats_fetch_begin_irq(&tp->syncp); put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked); -- 2.8.0.rc3.226.g39d4020 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH net-next 2/2] tcp: no longer hold ehash lock while calling tcp_get_info() 2016-11-04 18:54 [PATCH net-next 0/2] tcp: tcp_get_info() locking changes Eric Dumazet 2016-11-04 18:54 ` [PATCH net-next 1/2] tcp: shortcut listeners in tcp_get_info() Eric Dumazet @ 2016-11-04 18:54 ` Eric Dumazet 2016-11-09 18:03 ` [PATCH net-next 0/2] tcp: tcp_get_info() locking changes David Miller 2 siblings, 0 replies; 9+ messages in thread From: Eric Dumazet @ 2016-11-04 18:54 UTC (permalink / raw) To: David S . Miller Cc: netdev, Neal Cardwell, Yuchung Cheng, Soheil Hassas Yeganeh, Eric Dumazet, Eric Dumazet We had various problems in the past in tcp_get_info() and used specific synchronization to avoid deadlocks. We would like to add more instrumentation points for TCP, and avoiding grabing socket lock in tcp_getinfo() was too costly. Being able to lock the socket allows to provide consistent set of fields. inet_diag_dump_icsk() can make sure ehash locks are not held any more when tcp_get_info() is called. We can remove syncp added in commit d654976cbf85 ("tcp: fix a potential deadlock in tcp_get_info()"), but we need to use lock_sock_fast() instead of spin_lock_bh() since TCP input path can now be run from process context. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Yuchung Cheng <ycheng@google.com> Acked-by: Soheil Hassas Yeganeh <soheil@google.com> Acked-by: Neal Cardwell <ncardwell@google.com> --- include/linux/tcp.h | 2 -- net/ipv4/inet_diag.c | 48 +++++++++++++++++++++++++++++++++--------------- net/ipv4/tcp.c | 20 +++++++++----------- net/ipv4/tcp_input.c | 4 ---- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index a17ae7b85218..32a7c7e35b71 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -176,8 +176,6 @@ struct tcp_sock { * sum(delta(snd_una)), or how many bytes * were acked. */ - struct u64_stats_sync syncp; /* protects 64bit vars (cf tcp_get_info()) */ - u32 snd_una; /* First byte we want an ack for */ u32 snd_sml; /* Last byte of the most recently transmitted small packet */ u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */ diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 3b34024202d8..4dea33e5f295 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -861,10 +861,11 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, struct netlink_callback *cb, const struct inet_diag_req_v2 *r, struct nlattr *bc) { + bool net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN); struct net *net = sock_net(skb->sk); - int i, num, s_i, s_num; u32 idiag_states = r->idiag_states; - bool net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN); + int i, num, s_i, s_num; + struct sock *sk; if (idiag_states & TCPF_SYN_RECV) idiag_states |= TCPF_NEW_SYN_RECV; @@ -877,7 +878,6 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, for (i = s_i; i < INET_LHTABLE_SIZE; i++) { struct inet_listen_hashbucket *ilb; - struct sock *sk; num = 0; ilb = &hashinfo->listening_hash[i]; @@ -922,13 +922,14 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, if (!(idiag_states & ~TCPF_LISTEN)) goto out; +#define SKARR_SZ 16 for (i = s_i; i <= hashinfo->ehash_mask; i++) { struct inet_ehash_bucket *head = &hashinfo->ehash[i]; spinlock_t *lock = inet_ehash_lockp(hashinfo, i); struct hlist_nulls_node *node; - struct sock *sk; - - num = 0; + struct sock *sk_arr[SKARR_SZ]; + int num_arr[SKARR_SZ]; + int idx, accum, res; if (hlist_nulls_empty(&head->chain)) continue; @@ -936,9 +937,12 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, if (i > s_i) s_num = 0; +next_chunk: + num = 0; + accum = 0; spin_lock_bh(lock); sk_nulls_for_each(sk, node, &head->chain) { - int state, res; + int state; if (!net_eq(sock_net(sk), net)) continue; @@ -962,21 +966,35 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, if (!inet_diag_bc_sk(bc, sk)) goto next_normal; - res = sk_diag_fill(sk, skb, r, + sock_hold(sk); + num_arr[accum] = num; + sk_arr[accum] = sk; + if (++accum == SKARR_SZ) + break; +next_normal: + ++num; + } + spin_unlock_bh(lock); + res = 0; + for (idx = 0; idx < accum; idx++) { + if (res >= 0) { + res = sk_diag_fill(sk_arr[idx], skb, r, sk_user_ns(NETLINK_CB(cb->skb).sk), NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh, net_admin); - if (res < 0) { - spin_unlock_bh(lock); - goto done; + if (res < 0) + num = num_arr[idx]; } -next_normal: - ++num; + sock_gen_put(sk_arr[idx]); } - - spin_unlock_bh(lock); + if (res < 0) + break; cond_resched(); + if (accum == SKARR_SZ) { + s_num = num + 1; + goto next_chunk; + } } done: diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 117982be0cab..a7d54cbcdabb 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -405,7 +405,6 @@ void tcp_init_sock(struct sock *sk) tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; tp->snd_cwnd_clamp = ~0; tp->mss_cache = TCP_MSS_DEFAULT; - u64_stats_init(&tp->syncp); tp->reordering = sock_net(sk)->ipv4.sysctl_tcp_reordering; tcp_enable_early_retrans(tp); @@ -2710,9 +2709,8 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ const struct inet_connection_sock *icsk = inet_csk(sk); u32 now = tcp_time_stamp, intv; - unsigned int start; - int notsent_bytes; u64 rate64; + bool slow; u32 rate; memset(info, 0, sizeof(*info)); @@ -2792,17 +2790,17 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) info->tcpi_total_retrans = tp->total_retrans; - do { - start = u64_stats_fetch_begin_irq(&tp->syncp); - put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked); - put_unaligned(tp->bytes_received, &info->tcpi_bytes_received); - } while (u64_stats_fetch_retry_irq(&tp->syncp, start)); + slow = lock_sock_fast(sk); + + put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked); + put_unaligned(tp->bytes_received, &info->tcpi_bytes_received); + info->tcpi_notsent_bytes = max_t(int, 0, tp->write_seq - tp->snd_nxt); + + unlock_sock_fast(sk, slow); + info->tcpi_segs_out = tp->segs_out; info->tcpi_segs_in = tp->segs_in; - notsent_bytes = READ_ONCE(tp->write_seq) - READ_ONCE(tp->snd_nxt); - info->tcpi_notsent_bytes = max(0, notsent_bytes); - info->tcpi_min_rtt = tcp_min_rtt(tp); info->tcpi_data_segs_in = tp->data_segs_in; info->tcpi_data_segs_out = tp->data_segs_out; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index f2c59c8e57ff..a70046fea0e8 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3351,9 +3351,7 @@ static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack) u32 delta = ack - tp->snd_una; sock_owned_by_me((struct sock *)tp); - u64_stats_update_begin_raw(&tp->syncp); tp->bytes_acked += delta; - u64_stats_update_end_raw(&tp->syncp); tp->snd_una = ack; } @@ -3363,9 +3361,7 @@ static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq) u32 delta = seq - tp->rcv_nxt; sock_owned_by_me((struct sock *)tp); - u64_stats_update_begin_raw(&tp->syncp); tp->bytes_received += delta; - u64_stats_update_end_raw(&tp->syncp); tp->rcv_nxt = seq; } -- 2.8.0.rc3.226.g39d4020 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 0/2] tcp: tcp_get_info() locking changes 2016-11-04 18:54 [PATCH net-next 0/2] tcp: tcp_get_info() locking changes Eric Dumazet 2016-11-04 18:54 ` [PATCH net-next 1/2] tcp: shortcut listeners in tcp_get_info() Eric Dumazet 2016-11-04 18:54 ` [PATCH net-next 2/2] tcp: no longer hold ehash lock while calling tcp_get_info() Eric Dumazet @ 2016-11-09 18:03 ` David Miller 2016-11-09 18:58 ` Eric Dumazet 2 siblings, 1 reply; 9+ messages in thread From: David Miller @ 2016-11-09 18:03 UTC (permalink / raw) To: edumazet; +Cc: netdev, ncardwell, ycheng, soheil, eric.dumazet From: Eric Dumazet <edumazet@google.com> Date: Fri, 4 Nov 2016 11:54:30 -0700 > This short series prepares tcp_get_info() for more detailed infos. > > In order to not slow down fast path, our goal is to use the normal > socket spinlock instead of custom synchronization. > > All we need to ensure is that tcp_get_info() is not called with > ehash lock, which might dead lock, since packet processing would acquire > the spinlocks in reverse way. Looks really nice, series applied, thanks Eric. BTW, can we possibly use the netlink NOP trick to align the netlink attribute data here and avoid these unaligned accesses? Thanks again. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 0/2] tcp: tcp_get_info() locking changes 2016-11-09 18:03 ` [PATCH net-next 0/2] tcp: tcp_get_info() locking changes David Miller @ 2016-11-09 18:58 ` Eric Dumazet 2016-11-09 19:24 ` [PATCH net-next] tcp: remove unaligned accesses from tcp_get_info() Eric Dumazet 0 siblings, 1 reply; 9+ messages in thread From: Eric Dumazet @ 2016-11-09 18:58 UTC (permalink / raw) To: David Miller; +Cc: edumazet, netdev, ncardwell, ycheng, soheil On Wed, 2016-11-09 at 13:03 -0500, David Miller wrote: > Looks really nice, series applied, thanks Eric. > > BTW, can we possibly use the netlink NOP trick to align the netlink > attribute data here and avoid these unaligned accesses? > Good idea, I will do this, thanks for the suggestion. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH net-next] tcp: remove unaligned accesses from tcp_get_info() 2016-11-09 18:58 ` Eric Dumazet @ 2016-11-09 19:24 ` Eric Dumazet 2016-11-09 19:30 ` Soheil Hassas Yeganeh ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Eric Dumazet @ 2016-11-09 19:24 UTC (permalink / raw) To: David Miller; +Cc: edumazet, netdev, ncardwell, ycheng, soheil From: Eric Dumazet <edumazet@google.com> After commit 6ed46d1247a5 ("sock_diag: align nlattr properly when needed"), tcp_get_info() gets 64bit aligned memory, so we can avoid the unaligned helpers. Suggested-by: David Miller <davem@davemloft.net> Signed-off-by: Eric Dumazet <edumazet@google.com> --- net/ipv4/tcp.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index a7d54cbcdabbbc0838c00e05074ef15560665f2d..f8f924ca662d5c84e438a6eacbe8f734ff0674ae 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -279,7 +279,6 @@ #include <asm/uaccess.h> #include <asm/ioctls.h> -#include <asm/unaligned.h> #include <net/busy_poll.h> int sysctl_tcp_min_tso_segs __read_mostly = 2; @@ -2722,11 +2721,11 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) /* Report meaningful fields for all TCP states, including listeners */ rate = READ_ONCE(sk->sk_pacing_rate); rate64 = rate != ~0U ? rate : ~0ULL; - put_unaligned(rate64, &info->tcpi_pacing_rate); + info->tcpi_pacing_rate = rate64; rate = READ_ONCE(sk->sk_max_pacing_rate); rate64 = rate != ~0U ? rate : ~0ULL; - put_unaligned(rate64, &info->tcpi_max_pacing_rate); + info->tcpi_max_pacing_rate = rate64; info->tcpi_reordering = tp->reordering; info->tcpi_snd_cwnd = tp->snd_cwnd; @@ -2792,8 +2791,8 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) slow = lock_sock_fast(sk); - put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked); - put_unaligned(tp->bytes_received, &info->tcpi_bytes_received); + info->tcpi_bytes_acked = tp->bytes_acked; + info->tcpi_bytes_received = tp->bytes_received; info->tcpi_notsent_bytes = max_t(int, 0, tp->write_seq - tp->snd_nxt); unlock_sock_fast(sk, slow); @@ -2811,7 +2810,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) if (rate && intv) { rate64 = (u64)rate * tp->mss_cache * USEC_PER_SEC; do_div(rate64, intv); - put_unaligned(rate64, &info->tcpi_delivery_rate); + info->tcpi_delivery_rate = rate64; } } EXPORT_SYMBOL_GPL(tcp_get_info); ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH net-next] tcp: remove unaligned accesses from tcp_get_info() 2016-11-09 19:24 ` [PATCH net-next] tcp: remove unaligned accesses from tcp_get_info() Eric Dumazet @ 2016-11-09 19:30 ` Soheil Hassas Yeganeh 2016-11-09 20:46 ` Yuchung Cheng 2016-11-10 3:51 ` David Miller 2 siblings, 0 replies; 9+ messages in thread From: Soheil Hassas Yeganeh @ 2016-11-09 19:30 UTC (permalink / raw) To: Eric Dumazet Cc: David Miller, Eric Dumazet, netdev, Neal Cardwell, Yuchung Cheng On Wed, Nov 9, 2016 at 2:24 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote: > > From: Eric Dumazet <edumazet@google.com> > > After commit 6ed46d1247a5 ("sock_diag: align nlattr properly when > needed"), tcp_get_info() gets 64bit aligned memory, so we can avoid > the unaligned helpers. > > Suggested-by: David Miller <davem@davemloft.net> > Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Soheil Hassas Yeganeh <soheil@google.com> > --- > net/ipv4/tcp.c | 11 +++++------ > 1 file changed, 5 insertions(+), 6 deletions(-) > > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c > index a7d54cbcdabbbc0838c00e05074ef15560665f2d..f8f924ca662d5c84e438a6eacbe8f734ff0674ae 100644 > --- a/net/ipv4/tcp.c > +++ b/net/ipv4/tcp.c > @@ -279,7 +279,6 @@ > > #include <asm/uaccess.h> > #include <asm/ioctls.h> > -#include <asm/unaligned.h> > #include <net/busy_poll.h> > > int sysctl_tcp_min_tso_segs __read_mostly = 2; > @@ -2722,11 +2721,11 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) > /* Report meaningful fields for all TCP states, including listeners */ > rate = READ_ONCE(sk->sk_pacing_rate); > rate64 = rate != ~0U ? rate : ~0ULL; > - put_unaligned(rate64, &info->tcpi_pacing_rate); > + info->tcpi_pacing_rate = rate64; > > rate = READ_ONCE(sk->sk_max_pacing_rate); > rate64 = rate != ~0U ? rate : ~0ULL; > - put_unaligned(rate64, &info->tcpi_max_pacing_rate); > + info->tcpi_max_pacing_rate = rate64; > > info->tcpi_reordering = tp->reordering; > info->tcpi_snd_cwnd = tp->snd_cwnd; > @@ -2792,8 +2791,8 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) > > slow = lock_sock_fast(sk); > > - put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked); > - put_unaligned(tp->bytes_received, &info->tcpi_bytes_received); > + info->tcpi_bytes_acked = tp->bytes_acked; > + info->tcpi_bytes_received = tp->bytes_received; > info->tcpi_notsent_bytes = max_t(int, 0, tp->write_seq - tp->snd_nxt); > > unlock_sock_fast(sk, slow); > @@ -2811,7 +2810,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) > if (rate && intv) { > rate64 = (u64)rate * tp->mss_cache * USEC_PER_SEC; > do_div(rate64, intv); > - put_unaligned(rate64, &info->tcpi_delivery_rate); > + info->tcpi_delivery_rate = rate64; > } > } > EXPORT_SYMBOL_GPL(tcp_get_info); > > Very nice! Thanks. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next] tcp: remove unaligned accesses from tcp_get_info() 2016-11-09 19:24 ` [PATCH net-next] tcp: remove unaligned accesses from tcp_get_info() Eric Dumazet 2016-11-09 19:30 ` Soheil Hassas Yeganeh @ 2016-11-09 20:46 ` Yuchung Cheng 2016-11-10 3:51 ` David Miller 2 siblings, 0 replies; 9+ messages in thread From: Yuchung Cheng @ 2016-11-09 20:46 UTC (permalink / raw) To: Eric Dumazet Cc: David Miller, Eric Dumazet, netdev, Neal Cardwell, Soheil Hassas Yeganeh On Wed, Nov 9, 2016 at 11:24 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote: > > From: Eric Dumazet <edumazet@google.com> > > After commit 6ed46d1247a5 ("sock_diag: align nlattr properly when > needed"), tcp_get_info() gets 64bit aligned memory, so we can avoid > the unaligned helpers. > > Suggested-by: David Miller <davem@davemloft.net> > Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Yuchung Cheng <ycheng@google.com> > --- > net/ipv4/tcp.c | 11 +++++------ > 1 file changed, 5 insertions(+), 6 deletions(-) > > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c > index a7d54cbcdabbbc0838c00e05074ef15560665f2d..f8f924ca662d5c84e438a6eacbe8f734ff0674ae 100644 > --- a/net/ipv4/tcp.c > +++ b/net/ipv4/tcp.c > @@ -279,7 +279,6 @@ > > #include <asm/uaccess.h> > #include <asm/ioctls.h> > -#include <asm/unaligned.h> > #include <net/busy_poll.h> > > int sysctl_tcp_min_tso_segs __read_mostly = 2; > @@ -2722,11 +2721,11 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) > /* Report meaningful fields for all TCP states, including listeners */ > rate = READ_ONCE(sk->sk_pacing_rate); > rate64 = rate != ~0U ? rate : ~0ULL; > - put_unaligned(rate64, &info->tcpi_pacing_rate); > + info->tcpi_pacing_rate = rate64; > > rate = READ_ONCE(sk->sk_max_pacing_rate); > rate64 = rate != ~0U ? rate : ~0ULL; > - put_unaligned(rate64, &info->tcpi_max_pacing_rate); > + info->tcpi_max_pacing_rate = rate64; > > info->tcpi_reordering = tp->reordering; > info->tcpi_snd_cwnd = tp->snd_cwnd; > @@ -2792,8 +2791,8 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) > > slow = lock_sock_fast(sk); > > - put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked); > - put_unaligned(tp->bytes_received, &info->tcpi_bytes_received); > + info->tcpi_bytes_acked = tp->bytes_acked; > + info->tcpi_bytes_received = tp->bytes_received; > info->tcpi_notsent_bytes = max_t(int, 0, tp->write_seq - tp->snd_nxt); > > unlock_sock_fast(sk, slow); > @@ -2811,7 +2810,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) > if (rate && intv) { > rate64 = (u64)rate * tp->mss_cache * USEC_PER_SEC; > do_div(rate64, intv); > - put_unaligned(rate64, &info->tcpi_delivery_rate); > + info->tcpi_delivery_rate = rate64; > } > } > EXPORT_SYMBOL_GPL(tcp_get_info); > > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next] tcp: remove unaligned accesses from tcp_get_info() 2016-11-09 19:24 ` [PATCH net-next] tcp: remove unaligned accesses from tcp_get_info() Eric Dumazet 2016-11-09 19:30 ` Soheil Hassas Yeganeh 2016-11-09 20:46 ` Yuchung Cheng @ 2016-11-10 3:51 ` David Miller 2 siblings, 0 replies; 9+ messages in thread From: David Miller @ 2016-11-10 3:51 UTC (permalink / raw) To: eric.dumazet; +Cc: edumazet, netdev, ncardwell, ycheng, soheil From: Eric Dumazet <eric.dumazet@gmail.com> Date: Wed, 09 Nov 2016 11:24:22 -0800 > From: Eric Dumazet <edumazet@google.com> > > After commit 6ed46d1247a5 ("sock_diag: align nlattr properly when > needed"), tcp_get_info() gets 64bit aligned memory, so we can avoid > the unaligned helpers. > > Suggested-by: David Miller <davem@davemloft.net> > Signed-off-by: Eric Dumazet <edumazet@google.com> Nice, applied. Thanks! ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-11-10 3:52 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-11-04 18:54 [PATCH net-next 0/2] tcp: tcp_get_info() locking changes Eric Dumazet 2016-11-04 18:54 ` [PATCH net-next 1/2] tcp: shortcut listeners in tcp_get_info() Eric Dumazet 2016-11-04 18:54 ` [PATCH net-next 2/2] tcp: no longer hold ehash lock while calling tcp_get_info() Eric Dumazet 2016-11-09 18:03 ` [PATCH net-next 0/2] tcp: tcp_get_info() locking changes David Miller 2016-11-09 18:58 ` Eric Dumazet 2016-11-09 19:24 ` [PATCH net-next] tcp: remove unaligned accesses from tcp_get_info() Eric Dumazet 2016-11-09 19:30 ` Soheil Hassas Yeganeh 2016-11-09 20:46 ` Yuchung Cheng 2016-11-10 3:51 ` David Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox