Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9fe516ba authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

inet: move ipv6only in sock_common



When an UDP application switches from AF_INET to AF_INET6 sockets, we
have a small performance degradation for IPv4 communications because of
extra cache line misses to access ipv6only information.

This can also be noticed for TCP listeners, as ipv6_only_sock() is also
used from __inet_lookup_listener()->compute_score()

This is magnified when SO_REUSEPORT is used.

Move ipv6only into struct sock_common so that it is available at
no extra cost in lookups.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 090cce42
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -194,7 +194,7 @@ struct ipv6_pinfo {
	                        sndflow:1,
				repflow:1,
				pmtudisc:3,
				ipv6only:1,
				padding:1,	/* 1 bit hole */
				srcprefs:3,	/* 001: prefer temporary address
						 * 010: prefer public address
						 * 100: prefer care-of address
@@ -273,8 +273,8 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to,
	__inet_sk_copy_descendant(sk_to, sk_from, ancestor_size);
}

#define __ipv6_only_sock(sk)	(inet6_sk(sk)->ipv6only)
#define ipv6_only_sock(sk)	((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk))
#define __ipv6_only_sock(sk)	(sk->sk_ipv6only)
#define ipv6_only_sock(sk)	(__ipv6_only_sock(sk))
#define ipv6_sk_rxinfo(sk)	((sk)->sk_family == PF_INET6 && \
				 inet6_sk(sk)->rxopt.bits.rxinfo)

@@ -287,8 +287,8 @@ static inline const struct in6_addr *inet6_rcv_saddr(const struct sock *sk)

static inline int inet_v6_ipv6only(const struct sock *sk)
{
	return likely(sk->sk_state != TCP_TIME_WAIT) ?
		ipv6_only_sock(sk) : inet_twsk(sk)->tw_ipv6only;
	/* ipv6only field is at same position for timewait and other sockets */
	return ipv6_only_sock(sk);
}
#else
#define __ipv6_only_sock(sk)	0
+2 −1
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ struct inet_timewait_sock {
#define tw_family		__tw_common.skc_family
#define tw_state		__tw_common.skc_state
#define tw_reuse		__tw_common.skc_reuse
#define tw_ipv6only		__tw_common.skc_ipv6only
#define tw_bound_dev_if		__tw_common.skc_bound_dev_if
#define tw_node			__tw_common.skc_nulls_node
#define tw_bind_node		__tw_common.skc_bind_node
@@ -131,7 +132,7 @@ struct inet_timewait_sock {
	__be16			tw_sport;
	kmemcheck_bitfield_begin(flags);
	/* And these are ours. */
	unsigned int		tw_ipv6only     : 1,
	unsigned int		tw_pad0		: 1,	/* 1 bit hole */
				tw_transparent  : 1,
				tw_flowlabel	: 20,
				tw_pad		: 2,	/* 2 bits hole */
+3 −1
Original line number Diff line number Diff line
@@ -181,7 +181,8 @@ struct sock_common {
	unsigned short		skc_family;
	volatile unsigned char	skc_state;
	unsigned char		skc_reuse:4;
	unsigned char		skc_reuseport:4;
	unsigned char		skc_reuseport:1;
	unsigned char		skc_ipv6only:1;
	int			skc_bound_dev_if;
	union {
		struct hlist_node	skc_bind_node;
@@ -317,6 +318,7 @@ struct sock {
#define sk_state		__sk_common.skc_state
#define sk_reuse		__sk_common.skc_reuse
#define sk_reuseport		__sk_common.skc_reuseport
#define sk_ipv6only		__sk_common.skc_ipv6only
#define sk_bound_dev_if		__sk_common.skc_bound_dev_if
#define sk_bind_node		__sk_common.skc_bind_node
#define sk_prot			__sk_common.skc_prot
+1 −3
Original line number Diff line number Diff line
@@ -55,11 +55,9 @@ void dccp_time_wait(struct sock *sk, int state, int timeo)
		const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
#if IS_ENABLED(CONFIG_IPV6)
		if (tw->tw_family == PF_INET6) {
			const struct ipv6_pinfo *np = inet6_sk(sk);

			tw->tw_v6_daddr = sk->sk_v6_daddr;
			tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr;
			tw->tw_ipv6only = np->ipv6only;
			tw->tw_ipv6only = sk->sk_ipv6only;
		}
#endif
		/* Linkage updates. */
+1 −1
Original line number Diff line number Diff line
@@ -298,7 +298,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
			tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr;
			tw->tw_tclass = np->tclass;
			tw->tw_flowlabel = np->flow_label >> 12;
			tw->tw_ipv6only = np->ipv6only;
			tw->tw_ipv6only = sk->sk_ipv6only;
		}
#endif

Loading