net: Record receive queue number for a connection
authorAmritha Nambiar <amritha.nambiar@intel.com>
Sat, 30 Jun 2018 04:26:57 +0000 (21:26 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 2 Jul 2018 00:06:24 +0000 (09:06 +0900)
This patch adds a new field to sock_common 'skc_rx_queue_mapping'
which holds the receive queue number for the connection. The Rx queue
is marked in tcp_finish_connect() to allow a client app to do
SO_INCOMING_NAPI_ID after a connect() call to get the right queue
association for a socket. Rx queue is also marked in tcp_conn_request()
to allow syn-ack to go on the right tx-queue associated with
the queue on which syn is received.

Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Signed-off-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/busy_poll.h
include/net/sock.h
net/core/sock.c
net/ipv4/tcp_input.c

index c5187438af38fe4b4c309ea327757b316288c4c9..9e36fda652b7e277edb006d981a311ea1cfe6dba 100644 (file)
@@ -151,6 +151,7 @@ static inline void sk_mark_napi_id(struct sock *sk, const struct sk_buff *skb)
 #ifdef CONFIG_NET_RX_BUSY_POLL
        sk->sk_napi_id = skb->napi_id;
 #endif
+       sk_rx_queue_set(sk, skb);
 }
 
 /* variant used for unconnected sockets */
index 37b09c84504b129e050eb92636f666833af0cd4e..2b097cc8972768aa4a164f0a686318ffe494976f 100644 (file)
@@ -139,6 +139,7 @@ typedef __u64 __bitwise __addrpair;
  *     @skc_node: main hash linkage for various protocol lookup tables
  *     @skc_nulls_node: main hash linkage for TCP/UDP/UDP-Lite protocol
  *     @skc_tx_queue_mapping: tx queue number for this connection
+ *     @skc_rx_queue_mapping: rx queue number for this connection
  *     @skc_flags: place holder for sk_flags
  *             %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE,
  *             %SO_OOBINLINE settings, %SO_TIMESTAMPING settings
@@ -215,6 +216,9 @@ struct sock_common {
                struct hlist_nulls_node skc_nulls_node;
        };
        unsigned short          skc_tx_queue_mapping;
+#ifdef CONFIG_XPS
+       unsigned short          skc_rx_queue_mapping;
+#endif
        union {
                int             skc_incoming_cpu;
                u32             skc_rcv_wnd;
@@ -326,6 +330,9 @@ struct sock {
 #define sk_nulls_node          __sk_common.skc_nulls_node
 #define sk_refcnt              __sk_common.skc_refcnt
 #define sk_tx_queue_mapping    __sk_common.skc_tx_queue_mapping
+#ifdef CONFIG_XPS
+#define sk_rx_queue_mapping    __sk_common.skc_rx_queue_mapping
+#endif
 
 #define sk_dontcopy_begin      __sk_common.skc_dontcopy_begin
 #define sk_dontcopy_end                __sk_common.skc_dontcopy_end
@@ -1702,6 +1709,27 @@ static inline int sk_tx_queue_get(const struct sock *sk)
        return -1;
 }
 
+static inline void sk_rx_queue_set(struct sock *sk, const struct sk_buff *skb)
+{
+#ifdef CONFIG_XPS
+       if (skb_rx_queue_recorded(skb)) {
+               u16 rx_queue = skb_get_rx_queue(skb);
+
+               if (WARN_ON_ONCE(rx_queue == NO_QUEUE_MAPPING))
+                       return;
+
+               sk->sk_rx_queue_mapping = rx_queue;
+       }
+#endif
+}
+
+static inline void sk_rx_queue_clear(struct sock *sk)
+{
+#ifdef CONFIG_XPS
+       sk->sk_rx_queue_mapping = NO_QUEUE_MAPPING;
+#endif
+}
+
 static inline void sk_set_socket(struct sock *sk, struct socket *sock)
 {
        sk_tx_queue_clear(sk);
index bcc41829a16d50714bdd3c25c976c0b7296fab84..dac6d785186be24065f8ebfa17d1fe163f6da6d9 100644 (file)
@@ -2818,6 +2818,8 @@ void sock_init_data(struct socket *sock, struct sock *sk)
        sk->sk_pacing_rate = ~0U;
        sk->sk_pacing_shift = 10;
        sk->sk_incoming_cpu = -1;
+
+       sk_rx_queue_clear(sk);
        /*
         * Before updating sk_refcnt, we must commit prior changes to memory
         * (Documentation/RCU/rculist_nulls.txt for details)
index eecd359595fc17d98e331b9560a79e924ded8b25..a4731995e89933775ff863c68ee0119494b93190 100644 (file)
@@ -78,6 +78,7 @@
 #include <linux/errqueue.h>
 #include <trace/events/tcp.h>
 #include <linux/static_key.h>
+#include <net/busy_poll.h>
 
 int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
 
@@ -5592,6 +5593,7 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb)
        if (skb) {
                icsk->icsk_af_ops->sk_rx_dst_set(sk, skb);
                security_inet_conn_established(sk, skb);
+               sk_mark_napi_id(sk, skb);
        }
 
        tcp_init_transfer(sk, BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB);
@@ -6420,6 +6422,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
        tcp_rsk(req)->snt_isn = isn;
        tcp_rsk(req)->txhash = net_tx_rndhash();
        tcp_openreq_init_rwin(req, sk, dst);
+       sk_rx_queue_set(req_to_sk(req), skb);
        if (!want_cookie) {
                tcp_reqsk_record_syn(sk, req, skb);
                fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst);