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

Merge branch 'so_incoming_cpu'

Eric Dumazet says:

====================
net: SO_INCOMING_CPU support

SO_INCOMING_CPU socket option (read by getsockopt()) provides
an alternative to RPS/RFS for high performance servers using
multi queues NIC.

TCP should use sk_mark_napi_id() for established sockets only.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+56 -4
+2
arch/alpha/include/uapi/asm/socket.h
··· 87 87 88 88 #define SO_BPF_EXTENSIONS 48 89 89 90 + #define SO_INCOMING_CPU 49 91 + 90 92 #endif /* _UAPI_ASM_SOCKET_H */
+2
arch/avr32/include/uapi/asm/socket.h
··· 80 80 81 81 #define SO_BPF_EXTENSIONS 48 82 82 83 + #define SO_INCOMING_CPU 49 84 + 83 85 #endif /* _UAPI__ASM_AVR32_SOCKET_H */
+2
arch/cris/include/uapi/asm/socket.h
··· 82 82 83 83 #define SO_BPF_EXTENSIONS 48 84 84 85 + #define SO_INCOMING_CPU 49 86 + 85 87 #endif /* _ASM_SOCKET_H */ 86 88 87 89
+2
arch/frv/include/uapi/asm/socket.h
··· 80 80 81 81 #define SO_BPF_EXTENSIONS 48 82 82 83 + #define SO_INCOMING_CPU 49 84 + 83 85 #endif /* _ASM_SOCKET_H */ 84 86
+2
arch/ia64/include/uapi/asm/socket.h
··· 89 89 90 90 #define SO_BPF_EXTENSIONS 48 91 91 92 + #define SO_INCOMING_CPU 49 93 + 92 94 #endif /* _ASM_IA64_SOCKET_H */
+2
arch/m32r/include/uapi/asm/socket.h
··· 80 80 81 81 #define SO_BPF_EXTENSIONS 48 82 82 83 + #define SO_INCOMING_CPU 49 84 + 83 85 #endif /* _ASM_M32R_SOCKET_H */
+2
arch/mips/include/uapi/asm/socket.h
··· 98 98 99 99 #define SO_BPF_EXTENSIONS 48 100 100 101 + #define SO_INCOMING_CPU 49 102 + 101 103 #endif /* _UAPI_ASM_SOCKET_H */
+2
arch/mn10300/include/uapi/asm/socket.h
··· 80 80 81 81 #define SO_BPF_EXTENSIONS 48 82 82 83 + #define SO_INCOMING_CPU 49 84 + 83 85 #endif /* _ASM_SOCKET_H */
+2
arch/parisc/include/uapi/asm/socket.h
··· 79 79 80 80 #define SO_BPF_EXTENSIONS 0x4029 81 81 82 + #define SO_INCOMING_CPU 0x402A 83 + 82 84 #endif /* _UAPI_ASM_SOCKET_H */
+2
arch/powerpc/include/uapi/asm/socket.h
··· 87 87 88 88 #define SO_BPF_EXTENSIONS 48 89 89 90 + #define SO_INCOMING_CPU 49 91 + 90 92 #endif /* _ASM_POWERPC_SOCKET_H */
+2
arch/s390/include/uapi/asm/socket.h
··· 86 86 87 87 #define SO_BPF_EXTENSIONS 48 88 88 89 + #define SO_INCOMING_CPU 49 90 + 89 91 #endif /* _ASM_SOCKET_H */
+2
arch/sparc/include/uapi/asm/socket.h
··· 76 76 77 77 #define SO_BPF_EXTENSIONS 0x0032 78 78 79 + #define SO_INCOMING_CPU 0x0033 80 + 79 81 /* Security levels - as per NRL IPv6 - don't actually do anything */ 80 82 #define SO_SECURITY_AUTHENTICATION 0x5001 81 83 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
+2
arch/xtensa/include/uapi/asm/socket.h
··· 91 91 92 92 #define SO_BPF_EXTENSIONS 48 93 93 94 + #define SO_INCOMING_CPU 49 95 + 94 96 #endif /* _XTENSA_SOCKET_H */
+12
include/net/sock.h
··· 273 273 * @sk_rcvtimeo: %SO_RCVTIMEO setting 274 274 * @sk_sndtimeo: %SO_SNDTIMEO setting 275 275 * @sk_rxhash: flow hash received from netif layer 276 + * @sk_incoming_cpu: record cpu processing incoming packets 276 277 * @sk_txhash: computed flow hash for use on transmit 277 278 * @sk_filter: socket filtering instructions 278 279 * @sk_protinfo: private area, net family specific, when not using slab ··· 351 350 #ifdef CONFIG_RPS 352 351 __u32 sk_rxhash; 353 352 #endif 353 + u16 sk_incoming_cpu; 354 + /* 16bit hole 355 + * Warned : sk_incoming_cpu can be set from softirq, 356 + * Do not use this hole without fully understanding possible issues. 357 + */ 358 + 354 359 __u32 sk_txhash; 355 360 #ifdef CONFIG_NET_RX_BUSY_POLL 356 361 unsigned int sk_napi_id; ··· 838 831 return __sk_backlog_rcv(sk, skb); 839 832 840 833 return sk->sk_backlog_rcv(sk, skb); 834 + } 835 + 836 + static inline void sk_incoming_cpu_update(struct sock *sk) 837 + { 838 + sk->sk_incoming_cpu = raw_smp_processor_id(); 841 839 } 842 840 843 841 static inline void sock_rps_record_flow_hash(__u32 hash)
+2
include/uapi/asm-generic/socket.h
··· 82 82 83 83 #define SO_BPF_EXTENSIONS 48 84 84 85 + #define SO_INCOMING_CPU 49 86 + 85 87 #endif /* __ASM_GENERIC_SOCKET_H */
+5
net/core/sock.c
··· 1213 1213 v.val = sk->sk_max_pacing_rate; 1214 1214 break; 1215 1215 1216 + case SO_INCOMING_CPU: 1217 + v.val = sk->sk_incoming_cpu; 1218 + break; 1219 + 1216 1220 default: 1217 1221 return -ENOPROTOOPT; 1218 1222 } ··· 1521 1517 1522 1518 newsk->sk_err = 0; 1523 1519 newsk->sk_priority = 0; 1520 + newsk->sk_incoming_cpu = raw_smp_processor_id(); 1524 1521 /* 1525 1522 * Before updating sk_refcnt, we must commit prior changes to memory 1526 1523 * (Documentation/RCU/rculist_nulls.txt for details)
+3 -1
net/ipv4/tcp_ipv4.c
··· 1429 1429 struct dst_entry *dst = sk->sk_rx_dst; 1430 1430 1431 1431 sock_rps_save_rxhash(sk, skb); 1432 + sk_mark_napi_id(sk, skb); 1432 1433 if (dst) { 1433 1434 if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || 1434 1435 dst->ops->check(dst, 0) == NULL) { ··· 1451 1450 1452 1451 if (nsk != sk) { 1453 1452 sock_rps_save_rxhash(nsk, skb); 1453 + sk_mark_napi_id(sk, skb); 1454 1454 if (tcp_child_process(sk, nsk, skb)) { 1455 1455 rsk = nsk; 1456 1456 goto reset; ··· 1663 1661 if (sk_filter(sk, skb)) 1664 1662 goto discard_and_relse; 1665 1663 1666 - sk_mark_napi_id(sk, skb); 1664 + sk_incoming_cpu_update(sk); 1667 1665 skb->dev = NULL; 1668 1666 1669 1667 bh_lock_sock_nested(sk);
+1
net/ipv4/udp.c
··· 1445 1445 if (inet_sk(sk)->inet_daddr) { 1446 1446 sock_rps_save_rxhash(sk, skb); 1447 1447 sk_mark_napi_id(sk, skb); 1448 + sk_incoming_cpu_update(sk); 1448 1449 } 1449 1450 1450 1451 rc = sock_queue_rcv_skb(sk, skb);
+3 -1
net/ipv6/tcp_ipv6.c
··· 1293 1293 struct dst_entry *dst = sk->sk_rx_dst; 1294 1294 1295 1295 sock_rps_save_rxhash(sk, skb); 1296 + sk_mark_napi_id(sk, skb); 1296 1297 if (dst) { 1297 1298 if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || 1298 1299 dst->ops->check(dst, np->rx_dst_cookie) == NULL) { ··· 1323 1322 */ 1324 1323 if (nsk != sk) { 1325 1324 sock_rps_save_rxhash(nsk, skb); 1325 + sk_mark_napi_id(sk, skb); 1326 1326 if (tcp_child_process(sk, nsk, skb)) 1327 1327 goto reset; 1328 1328 if (opt_skb) ··· 1456 1454 if (sk_filter(sk, skb)) 1457 1455 goto discard_and_relse; 1458 1456 1459 - sk_mark_napi_id(sk, skb); 1457 + sk_incoming_cpu_update(sk); 1460 1458 skb->dev = NULL; 1461 1459 1462 1460 bh_lock_sock_nested(sk);
+1
net/ipv6/udp.c
··· 577 577 if (!ipv6_addr_any(&sk->sk_v6_daddr)) { 578 578 sock_rps_save_rxhash(sk, skb); 579 579 sk_mark_napi_id(sk, skb); 580 + sk_incoming_cpu_update(sk); 580 581 } 581 582 582 583 rc = sock_queue_rcv_skb(sk, skb);
+3 -2
net/sctp/ulpqueue.c
··· 205 205 if (sock_flag(sk, SOCK_DEAD) || (sk->sk_shutdown & RCV_SHUTDOWN)) 206 206 goto out_free; 207 207 208 - if (!sctp_ulpevent_is_notification(event)) 208 + if (!sctp_ulpevent_is_notification(event)) { 209 209 sk_mark_napi_id(sk, skb); 210 - 210 + sk_incoming_cpu_update(sk); 211 + } 211 212 /* Check if the user wishes to receive this event. */ 212 213 if (!sctp_ulpevent_is_enabled(event, &sctp_sk(sk)->subscribe)) 213 214 goto out_free;