Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

txhash: Make rethinking txhash behavior configurable via sysctl

Add a per ns sysctl that controls the txhash rethink behavior:
net.core.txrehash. When enabled, the same behavior is retained,
when disabled, rethink is not performed. Sysctl is enabled by default.

Signed-off-by: Akhmat Karakotov <hmukos@yandex-team.ru>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Akhmat Karakotov and committed by
David S. Miller
e187013a 678dfd52

+39 -15
+1
include/net/netns/core.h
··· 10 10 struct ctl_table_header *sysctl_hdr; 11 11 12 12 int sysctl_somaxconn; 13 + u8 sysctl_txrehash; 13 14 14 15 #ifdef CONFIG_PROC_FS 15 16 struct prot_inuse __percpu *prot_inuse;
+21 -13
include/net/sock.h
··· 587 587 __tmp | SK_USER_DATA_NOCOPY); \ 588 588 }) 589 589 590 + static inline 591 + struct net *sock_net(const struct sock *sk) 592 + { 593 + return read_pnet(&sk->sk_net); 594 + } 595 + 596 + static inline 597 + void sock_net_set(struct sock *sk, struct net *net) 598 + { 599 + write_pnet(&sk->sk_net, net); 600 + } 601 + 590 602 /* 591 603 * SK_CAN_REUSE and SK_NO_REUSE on a socket mean that the socket is OK 592 604 * or not whether his port will be reused by someone else. SK_FORCE_REUSE ··· 2066 2054 2067 2055 static inline bool sk_rethink_txhash(struct sock *sk) 2068 2056 { 2069 - if (sk->sk_txhash) { 2057 + u8 rehash; 2058 + 2059 + if (!sk->sk_txhash) 2060 + return false; 2061 + 2062 + rehash = READ_ONCE(sock_net(sk)->core.sysctl_txrehash); 2063 + 2064 + if (rehash) { 2070 2065 sk_set_txhash(sk); 2071 2066 return true; 2072 2067 } 2068 + 2073 2069 return false; 2074 2070 } 2075 2071 ··· 2722 2702 { 2723 2703 __skb_unlink(skb, &sk->sk_receive_queue); 2724 2704 __kfree_skb(skb); 2725 - } 2726 - 2727 - static inline 2728 - struct net *sock_net(const struct sock *sk) 2729 - { 2730 - return read_pnet(&sk->sk_net); 2731 - } 2732 - 2733 - static inline 2734 - void sock_net_set(struct sock *sk, struct net *net) 2735 - { 2736 - write_pnet(&sk->sk_net, net); 2737 2705 } 2738 2706 2739 2707 static inline bool
+3
include/uapi/linux/socket.h
··· 31 31 32 32 #define SOCK_BUF_LOCK_MASK (SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK) 33 33 34 + #define SOCK_TXREHASH_DISABLED 0 35 + #define SOCK_TXREHASH_ENABLED 1 36 + 34 37 #endif /* _UAPI_LINUX_SOCKET_H */
+2
net/core/net_namespace.c
··· 364 364 static int __net_init net_defaults_init_net(struct net *net) 365 365 { 366 366 net->core.sysctl_somaxconn = SOMAXCONN; 367 + net->core.sysctl_txrehash = SOCK_TXREHASH_ENABLED; 368 + 367 369 return 0; 368 370 } 369 371
+12 -2
net/core/sysctl_net_core.c
··· 593 593 .extra1 = SYSCTL_ZERO, 594 594 .proc_handler = proc_dointvec_minmax 595 595 }, 596 + { 597 + .procname = "txrehash", 598 + .data = &init_net.core.sysctl_txrehash, 599 + .maxlen = sizeof(u8), 600 + .mode = 0644, 601 + .extra1 = SYSCTL_ZERO, 602 + .extra2 = SYSCTL_ONE, 603 + .proc_handler = proc_dou8vec_minmax, 604 + }, 596 605 { } 597 606 }; 598 607 ··· 620 611 621 612 static __net_init int sysctl_core_net_init(struct net *net) 622 613 { 623 - struct ctl_table *tbl; 614 + struct ctl_table *tbl, *tmp; 624 615 625 616 tbl = netns_core_table; 626 617 if (!net_eq(net, &init_net)) { ··· 628 619 if (tbl == NULL) 629 620 goto err_dup; 630 621 631 - tbl[0].data = &net->core.sysctl_somaxconn; 622 + for (tmp = tbl; tmp->procname; tmp++) 623 + tmp->data += (char *)net - (char *)&init_net; 632 624 633 625 /* Don't export any sysctls to unprivileged users */ 634 626 if (net->user_ns != &init_user_ns) {