RFC: A reduced Linux network stack for small systems
Subsystems (61)
There has been a lot of interest recently to run Linux on very small systems, like Quark systems. These may have only 2-4MB memory. They are also limited by flash space.
One problem on these small system is the size of the network stack. Currently enabling IPv4 costs about 400k in text, which is prohibitive on a 2MB system, and very expensive with 4MB.
There were proposals to instead use LWIP in user space. LWIP with its socket interface comes in at a bit over 100k overhead per application.
I maintain that the Linux network stack is actually not that bloated, it just has a lot of features :-) The goal of this project was to subset it in a sensible way so that the native kernel stack becomes competitive with LWIP.
It turns out that the standard stack has a couple of features that are not really needed on client systems. Luckily it is also relatively well modularized, so it becomes possible to stub out these features at the edge.
With removing these features we still have a powerful TCP/IP stack, but one that fits better into small systems.
It would have been prohibitive to ifdef every optional feature. This patchkit relies heavily on LTO to effectively remove unused code. This allows to disable features only at the module boundaries, and rely on the compiler to drop unreferenced code and data.
A few features have been also reimplemented in a simpler way. And I shrank a number of data structures based on CONFIG_BASE_SMALL.
With these changes I can get a fully featured network stack down to about 170k with LTO. Without LTO there are also benefits, but somewhat less.
There are essentially three sensible configurations:
- Full featured like today.
- Client only subset, but still works with standard distribution userland. Remove some obscure features like fastopen, make all tables smaller, packet socket mmap code, use a simpler routing table, remove high speed networking features like RPX, XPS, GRO offload. Disable SNMP, TCP metrics
- Minimal subset for deeply embedded systems that can use special userland. Remove rtnetlink (ioctl only), remove ethtool, raw sockets.
Right now I'm using own Kconfigs for every removed features. I realize this somewhat increases the compile test matrix. It would be possible to hide some of the options and select them using higher level configurations like the ones listed above. I haven't done this in this version.
At this point I'm mainly interested in review and comments.
Git trees:
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-misc net/debloat Main tree
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-misc net/debloat-3.14 3.14 based tree.
Thanks to Tom Zanussi for contributions and testing.
Andi Kleen
PATCH 1/24 net, diet: Reduce netdev name hash table for CONFIG_BASE_SMALL
From: Andi Kleen <[email protected]>
Small systems typically only have two network devices, so use hash shift 2.
--- include/net/net_namespace.h | 4 ++++ 1 file changed, 4 insertions(+)
include/net/net_namespace.h +4 -0
@@ -37,7 +37,11 @@ struct sock;struct netns_ipvs ; +#ifdef CONFIG_BASE_SMALL +#define NETDEV_HASHBITS 2 +#else #define NETDEV_HASHBITS 8 +#endif #define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS)struct net {
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 01/24] net, diet: Reduce netdev name hash table for CONFIG_BASE_SMALL
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:50 -0700
Quoted 2 lines
Small systems typically only have two network devices, so use hash shift 2.
Maybe in terms of physical interfaces, but they may also have lots of software interfaces.
Sorry, this doesn't make any sense, I'm not applying this.
PATCH 2/24 net, diet: Reduce NAPI hash table for CONFIG_BASE_SMALL
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
For really small kernels, use only 3 bits for the hash table.
--- net/core/dev.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/core/dev.c +8 -1
@@ -175,7 +175,14 @@ EXPORT_SYMBOL(dev_base_lock);static DEFINE_SPINLOCK (napi_hash_lock);static unsigned int napi_gen_id; -static DEFINE_HASHTABLE(napi_hash, 8); + +#ifdef CONFIG_BASE_SMALL +#define NAPI_HASH_BITS 3 +#else +#define NAPI_HASH_BITS 8 +#endif + +static DEFINE_HASHTABLE(napi_hash, NAPI_HASH_BITS);static seqcount_t devnet_rename_seq;
Signature · 1 line
1.9.0
PATCH 3/24 net, diet: Decrease ip defrag hash tables and max length with BASE_SMALL
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
When CONFIG_BASE_SMALL is set only use 16 entries in the IP defrag hash table. Also limit the max length of chains to 32 packets.
The sizes are somewhat arbitary and could be changed.
--- include/net/inet_frag.h | 6 ++++++ 1 file changed, 6 insertions(+)
include/net/inet_frag.h +6 -0
@@ -41,6 +41,10 @@ struct inet_frag_queue {struct netns_frags *net; }; +#ifdef CONFIG_BASE_SMALL +#define INETFRAGS_HASHSZ 16 +#define INETFRAGS_MAXDEPTH 32 +#else #define INETFRAGS_HASHSZ 1024/* averaged:
@@ -50,6 +54,8 @@ struct inet_frag_queue {*/ #define INETFRAGS_MAXDEPTH 128 +#endif +struct inet_frag_bucket {struct hlist_head chain;spinlock_t chain_lock;
Signature · 1 line
1.9.0
PATCH 4/24 net, diet: Make FIB hash tables smaller with CONFIG_BASE_SMALL
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Just make the FIB hash tables much smaller for small kernel.
--- include/net/ip_fib.h | 5 +++++ net/ipv4/fib_semantics.c | 4 ++++ 2 files changed, 9 insertions(+)
include/net/ip_fib.h +5 -0
@@ -65,7 +65,11 @@ struct fnhe_hash_bucket {struct fib_nh_exception __rcu *chain; }; +#ifdef CONFIG_BASE_SMALL +#define FNHE_HASH_SIZE 16 +#else #define FNHE_HASH_SIZE 2048 +#endif #define FNHE_RECLAIM_DEPTH 5struct fib_nh {
@@ -162,6 +166,7 @@ struct fib_result_nl {#ifdef CONFIG_IP_MULTIPLE_TABLES #define FIB_TABLE_HASHSZ 256#else +/* Can we use 1 for BASE_SMALL? */ #define FIB_TABLE_HASHSZ 2#endif
net/ipv4/fib_semantics.c +4 -0
@@ -51,7 +51,11 @@ static struct hlist_head *fib_info_laddrhash;static unsigned int fib_info_hash_size;static unsigned int fib_info_cnt; +#ifdef CONFIG_BASE_SMALL +#define DEVINDEX_HASHBITS 2 +#else #define DEVINDEX_HASHBITS 8 +#endif #define DEVINDEX_HASHSIZE (1U << DEVINDEX_HASHBITS)static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE ];
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 04/24] net, diet: Make FIB hash tables smaller with CONFIG_BASE_SMALL
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:53 -0700
Quoted 6 lines
From: Andi Kleen <[email protected]>
Just make the FIB hash tables much smaller for small kernel.
Signed-off-by Andi Kleen <[email protected]>
Sounds like an exploit waiting to happen.
PATCH 5/24 net, diet: Default to small TCP hash tables on small kernels
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
--- net/ipv4/tcp.c | 4 ++++ 1 file changed, 4 insertions(+)
net/ipv4/tcp.c +4 -0
@@ -3127,7 +3127,11 @@ EXPORT_SYMBOL_GPL(tcp_done);extern struct tcp_congestion_ops tcp_reno; +#ifdef CONFIG_BASE_SMALL +static __initdata unsigned long thash_entries =16 ; +#else static __initdata unsigned long thash_entries; +#endif static int __init set_thash_entries (char *str) {ssize_t ret;
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 05/24] net, diet: Default to small TCP hash tables on small kernels
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:54 -0700
Quoted 3 lines
From: Andi Kleen <[email protected]>
Signed-off-by Andi Kleen <[email protected]>
Same comment as per other hash table reductions, this doesn't make any sense even for the claimed goal.
PATCH 6/24 net, diet: Use small UDP hash tables on small kernels
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
UDP has two hash tables, for UDP and UDP lite. Default them to 16 entries each on small kernels. This can be still overriden on the command line.
--- net/ipv4/udp.c | 5 +++++ 1 file changed, 5 insertions(+)
net/ipv4/udp.c +5 -0
@@ -2415,7 +2415,12 @@ void udp4_proc_exit(void) }#endif /* CONFIG_PROC_FS */ +#ifdef CONFIG_BASE_SMALL +static __initdata unsigned long uhash_entries =16 ; +#else static __initdata unsigned long uhash_entries; +#endif +static int __init set_uhash_entries (char *str) {ssize_t ret;
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 06/24] net, diet: Use small UDP hash tables on small kernels
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:55 -0700
Quoted 7 lines
From: Andi Kleen <[email protected]>
UDP has two hash tables, for UDP and UDP lite. Default them to 16 entries each on small kernels. This can be still overriden on the command line.
Signed-off-by Andi Kleen <[email protected]>
Likewise, if you make it too small, overrunning the machine is way too easy. Maybe it's even more important in a lower powered machine than a high powered one.
Re: [PATCH 06/24] net, diet: Use small UDP hash tables on small kernels
In reply to Andi KleenQuoted 18 lines · Andi Kleen
From: Andi Kleen <[email protected]>
UDP has two hash tables, for UDP and UDP lite. Default them to 16 entries each on small kernels. This can be still overriden on the command line.
Signed-off-by Andi Kleen <[email protected]>--- net/ipv4/udp.c | 5 +++++ 1 file changed, 5 insertions(+)net/ipv4/udp.c +0
-0@@ -2415,7 +2415,12 @@ void udp4_proc_exit(void) }#endif /* CONFIG_PROC_FS */
net/ipv4/udp.c void udp4_proc_exit(void) · line 2426
Quoted 10 lines
net/ipv4/udp.c +5
-0+#ifdef CONFIG_BASE_SMALL +static __initdata unsigned long uhash_entries =16 ; +#else static __initdata unsigned long uhash_entries; +#endif +static int __init set_uhash_entries (char *str) {ssize_t ret;
Its changed to UDP_HTABLE_SIZE_MIN later in alloc_large_system_hash()
The reason there is a minimum UDP hash size is PORTS_PER_CHAIN, or DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN) on stack.
This patch has no effect on a small machine, because we already dynamically size this hash table.
(The factor is one slot per 2MB of low memory)
Re: [PATCH 06/24] net, diet: Use small UDP hash tables on small kernels
Quoted 2 lines
This patch has no effect on a small machine, because we already dynamically size this hash table.
Good point.
Quoted 2 lines
(The factor is one slot per 2MB of low memory)
Ok I need to fix that, because a single slot on a 2MB system is likely not enough.
-Andi
Re: [PATCH 06/24] net, diet: Use small UDP hash tables on small kernels
Quoted 2 lines · Andi Kleen
Ok I need to fix that, because a single slot on a 2MB system is likely not enough.
You have nothing to do.
It will use a 128 slots hash table with current code.
PATCH 7/24 net, diet: Make ping sockets optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
This saves about 6k text/data. ping still works fine using raw sockets like it always did.
text data bss dec hex filename
268128 11555 7872 287555 46343 net/ipv4/built-in.o-noping 273610 11843 8176 293629 47afd net/ipv4/built-in.o-ping
--- include/net/ping.h | 15 +++++++++++---- include/net/transp_v6.h | 2 -- net/ipv4/Kconfig | 5 +++++ net/ipv4/Makefile | 3 ++- net/ipv4/af_inet.c | 9 ++++----- net/ipv4/icmp.c | 1 + net/ipv4/ping.c | 3 +++ net/ipv6/Makefile | 3 ++- net/ipv6/af_inet6.c | 8 ++++++-- 9 files changed, 34 insertions(+), 15 deletions(-)
include/net/ping.h +11 -4
@@ -71,7 +71,6 @@ void ping_unhash(struct sock *sk);int ping_init_sock (struct sock *sk);void ping_close (struct sock *sk,long timeout);int ping_bind (struct sock *sk,struct sockaddr *uaddr,int addr_len); -void ping_err (struct sk_buff *skb,int offset,u32 info);int ping_getfrag (void *from,char *to,int offset,int fraglen,int odd,struct sk_buff *);
@@ -82,7 +81,6 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,int ping_v6_sendmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t len);int ping_queue_rcv_skb (struct sock *sk,struct sk_buff *skb); -void ping_rcv (struct sk_buff *skb);#ifdef CONFIG_PROC_FS struct ping_seq_afinfo {
@@ -100,12 +98,21 @@ void ping_seq_stop(struct seq_file *seq, void *v);int ping_proc_register (struct net *net,struct ping_seq_afinfo *afinfo);void ping_proc_unregister (struct net *net,struct ping_seq_afinfo *afinfo); -int __init ping_proc_init (void ); -void ping_proc_exit (void );#endif +#ifdef CONFIG_IP_PING +void ping_rcv (struct sk_buff *skb); +void ping_err (struct sk_buff *skb,int offset,u32 info);void __init ping_init (void );int __init pingv6_init (void );void pingv6_exit (void ); +#else +static inline void ping_init (void ) {} +static inline int pingv6_init (void ) {return 0 ; } +static inline void pingv6_exit (void ) { } +static inline void ping_err (struct sk_buff *skb,int offset,u32 info) {} +static inline void ping_rcv (struct sk_buff *skb) {} +#endif +#endif /* _PING_H */
include/net/transp_v6.h +0 -2
@@ -19,8 +19,6 @@ int ipv6_frag_init(void);void ipv6_frag_exit (void );/* transport protocols */ -int pingv6_init (void ); -void pingv6_exit (void );int rawv6_init (void );void rawv6_exit (void );int udpv6_init (void );
net/ipv4/Kconfig +5 -0
@@ -52,6 +52,11 @@ config IP_ADVANCED_ROUTER If unsure, say N here. +config IP_PING + bool "IP: ping sockets" + ---help--- + Enable ping sockets to enable suid-less ping. + config IP_FIB_TRIE_STATS bool "FIB TRIE statistics" depends on IP_ADVANCED_ROUTER
net/ipv4/Makefile +2 -1
@@ -11,9 +11,10 @@ obj-y := route.o inetpeer.o protocol.o \ tcp_offload.o datagram.o raw.o udp.o udplite.o \ udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \ fib_frontend.o fib_semantics.o fib_trie.o \ - inet_fragment.o ping.o ip_tunnel_core.o gre_offload.o + inet_fragment.o ip_tunnel_core.o gre_offload.o obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o +obj-$(CONFIG_IP_PING) += ping.o obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
net/ipv4/af_inet.c +4 -5
@@ -1015,7 +1015,7 @@ static struct inet_protosw inetsw_array[] = .no_check = UDP_CSUM_DEFAULT, .flags = INET_PROTOSW_PERMANENT, }, - +#ifdef CONFIG_IP_PING { .type = SOCK_DGRAM, .protocol = IPPROTO_ICMP,
@@ -1024,6 +1024,7 @@ static struct inet_protosw inetsw_array[] = .no_check = UDP_CSUM_DEFAULT, .flags = INET_PROTOSW_REUSE, }, +#endif { .type = SOCK_RAW,
@@ -1719,7 +1720,9 @@ static int __init inet_init(void)if (rc) goto out_unregister_udp_proto; +#ifdef CONFIG_IP_PING rc =proto_register (&ping_prot,1 ); +#endif if (rc) goto out_unregister_raw_proto;
@@ -1836,15 +1839,11 @@ static int __init ipv4_proc_init(void) goto out_tcp;if (udp4_proc_init ()) goto out_udp; -if (ping_proc_init ()) - goto out_ping;if (ip_misc_proc_init ()) goto out_misc; out:return rc; out_misc: -ping_proc_exit (); -out_ping:udp4_proc_exit (); out_udp:tcp4_proc_exit ();
net/ipv4/icmp.c +1 -0
@@ -989,6 +989,7 @@ void icmp_err(struct sk_buff *skb, u32 info)return ; } +/* RED-PEN dead code? the if above will eat all. */ if (type ==ICMP_DEST_UNREACH && code ==ICMP_FRAG_NEEDED )ipv4_update_pmtu (skb, net, info,0 ,0 ,IPPROTO_ICMP ,0 );else if (type ==ICMP_REDIRECT )
net/ipv4/ping.c +3 -0
@@ -1206,6 +1206,9 @@ void ping_proc_exit(void) unregister_pernet_subsys(&ping_v4_net_ops); } +module_init (ping_proc_init); +module_exit (ping_proc_init); +#endif void __init ping_init (void )
net/ipv6/Makefile +2 -1
@@ -7,13 +7,14 @@ obj-$(CONFIG_IPV6) += ipv6.o ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ addrlabel.o \ route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \ - raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o ping.o \ + raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o ipv6-offload := ip6_offload.o tcpv6_offload.o udp_offload.o exthdrs_offload.o ipv6-$(CONFIG_SYSCTL) = sysctl_net_ipv6.o ipv6-$(CONFIG_IPV6_MROUTE) += ip6mr.o +ipv6-$(CONFIG_IP_PING) += ping.o ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \ xfrm6_output.o xfrm6_protocol.o
net/ipv6/af_inet6.c +6 -2
@@ -861,16 +861,18 @@ static int __init inet6_init(void)if (err) goto out_unregister_udplite_proto; +#ifdef CONFIG_IP_PING err =proto_register (&pingv6_prot,1 );if (err) - goto out_unregister_ping_proto; + goto out_unregister_raw_proto; +#endif /* We MUST register RAW sockets before we create the ICMP6, * IGMP6, or NDISC control sockets. */ err =rawv6_init ();if (err) - goto out_unregister_raw_proto; + goto out_unregister_ping_proto;/* Register the family here so that the init calls below will * be able to create sockets. (?? is this dangerous ??)
@@ -1022,8 +1024,10 @@ register_pernet_fail: out_sock_register_fail:rawv6_exit (); out_unregister_ping_proto: +#ifdef CONFIG_IP_PING proto_unregister (&pingv6_prot); out_unregister_raw_proto: +#endif proto_unregister (&rawv6_prot); out_unregister_udplite_proto:proto_unregister (&udplitev6_prot);
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 07/24] net, diet: Make ping sockets optional
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:56 -0700
Quoted 10 lines
From: Andi Kleen <[email protected]>
This saves about 6k text/data. ping still works fine using raw sockets like it always did.
text data bss dec hex filename
268128 11555 7872 287555 46343 net/ipv4/built-in.o-noping 273610 11843 8176 293629 47afd net/ipv4/built-in.o-pingSigned-off-by Andi Kleen <[email protected]>
Sorry, not applying this, it's been discussed already, and it's exactly small'ish systems that want this facility.
We want to move away from raw sockets, and making this optional is not going to help us move forward down that path.
PATCH 8/24 net, diet: Make TCP metrics optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
This is all the code that saves connection information between different sockets. Not really essential for small systems.
Saves about 5.5k text
text data bss dec hex filename
492952 19571 13480 526003 806b3 net/built-in.o-with-metrics 487675 19275 13480 520430 7f0ee net/built-in.o-without-metrics
--- include/net/tcp.h | 25 +++++++++++++++++++++++++ net/ipv4/Kconfig | 6 ++++++ net/ipv4/Makefile | 3 ++- net/ipv4/sysctl_net_ipv4.c | 2 ++ 4 files changed, 35 insertions(+), 1 deletion(-)
include/net/tcp.h +25 -0
@@ -419,14 +419,29 @@ int tcp_child_process(struct sock *parent, struct sock *child, struct sk_buff *skb);void tcp_enter_loss (struct sock *sk,int how);void tcp_clear_retrans (struct tcp_sock *tp); +#ifdef CONFIG_TCP_METRICS void tcp_update_metrics (struct sock *sk);void tcp_init_metrics (struct sock *sk);void tcp_metrics_init (void ); +bool tcp_peer_is_proven (struct request_sock *req,struct dst_entry *dst,bool paws_check);bool tcp_remember_stamp (struct sock *sk);bool tcp_tw_remember_stamp (struct inet_timewait_sock *tw);void tcp_fetch_timewait_stamp (struct sock *sk,struct dst_entry *dst); +#else +static inline void tcp_update_metrics (struct sock *sk) {} +static inline void tcp_init_metrics (struct sock *sk) {} +static inline void tcp_metrics_init (void ) {} +static inline bool tcp_peer_is_proven (struct request_sock *req, +struct dst_entry *dst, +bool paws_check) {return false; } +static inline bool tcp_remember_stamp (struct sock *sk) {return false; } +static inline bool +tcp_tw_remember_stamp (struct inet_timewait_sock *tw) {return false; } +static inline void +tcp_fetch_timewait_stamp (struct sock *sk,struct dst_entry *dst) {} +#endif void tcp_disable_fack (struct tcp_sock *tp);void tcp_close (struct sock *sk,long timeout);void tcp_init_sock (struct sock *sk);
@@ -1296,11 +1311,21 @@ int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, const struct tcp_md5sig_key *key);/* From tcp_fastopen.c */ +#ifdef CONFIG_TCP_METRICS void tcp_fastopen_cache_get (struct sock *sk,u16 *mss,struct tcp_fastopen_cookie *cookie,int *syn_loss,unsigned long *last_syn_loss);void tcp_fastopen_cache_set (struct sock *sk,u16 mss,struct tcp_fastopen_cookie *cookie,bool syn_lost); +#else +static inline void +tcp_fastopen_cache_get (struct sock *sk,u16 *mss, +struct tcp_fastopen_cookie *cookie,int *syn_loss, +unsigned long *last_syn_loss) {} +static inline void +tcp_fastopen_cache_set (struct sock *sk,u16 mss, +struct tcp_fastopen_cookie *cookie,bool syn_lost) {} +#endif struct tcp_fastopen_request {/* Fast Open cookie. Size 0 means a cookie request */ struct tcp_fastopen_cookie cookie;
net/ipv4/Kconfig +6 -0
@@ -264,6 +264,12 @@ config IP_PIMSM_V2 gated-5). This routing protocol is not used widely, so say N unless you want to play with it. +config TCP_METRICS + bool "Report TCP metrics over netlink" + ---help--- + Enable support in TCP to save host information between different + connections. + config SYN_COOKIES bool "IP: TCP syncookie support" ---help---
net/ipv4/Makefile +2 -1
@@ -7,7 +7,7 @@ obj-y := route.o inetpeer.o protocol.o \ ip_output.o ip_sockglue.o inet_hashtables.o \ inet_timewait_sock.o inet_connection_sock.o \ tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ - tcp_minisocks.o tcp_cong.o tcp_metrics.o tcp_fastopen.o \ + tcp_minisocks.o tcp_cong.o tcp_fastopen.o \ tcp_offload.o datagram.o raw.o udp.o udplite.o \ udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \ fib_frontend.o fib_semantics.o fib_trie.o \
@@ -17,6 +17,7 @@ obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o obj-$(CONFIG_IP_PING) += ping.o obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o obj-$(CONFIG_PROC_FS) += proc.o +obj-$(CONFIG_TCP_METRICS) += tcp_metrics.o obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o obj-$(CONFIG_IP_MROUTE) += ipmr.o obj-$(CONFIG_NET_IPIP) += ipip.o
net/ipv4/sysctl_net_ipv4.c +2 -0
@@ -573,6 +573,7 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, +#ifdef CONFIG_TCP_METRICS { .procname = "tcp_no_metrics_save", .data = &sysctl_tcp_nometrics_save,
@@ -580,6 +581,7 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, +#endif { .procname = "tcp_moderate_rcvbuf", .data = &sysctl_tcp_moderate_rcvbuf,
Signature · 1 line
1.9.0
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 81 lines · Andi Kleen
From: Andi Kleen <[email protected]>
This is all the code that saves connection information between different sockets. Not really essential for small systems.
Saves about 5.5k text
text data bss dec hex filename
492952 19571 13480 526003 806b3 net/built-in.o-with-metrics 487675 19275 13480 520430 7f0ee net/built-in.o-without-metricsSigned-off-by Andi Kleen <[email protected]>--- include/net/tcp.h | 25 +++++++++++++++++++++++++ net/ipv4/Kconfig | 6 ++++++ net/ipv4/Makefile | 3 ++- net/ipv4/sysctl_net_ipv4.c | 2 ++ 4 files changed, 35 insertions(+), 1 deletion(-)include/net/tcp.h +25
-0@@ -419,14 +419,29 @@ int tcp_child_process(struct sock *parent, struct sock *child, struct sk_buff *skb);void tcp_enter_loss (struct sock *sk,int how);void tcp_clear_retrans (struct tcp_sock *tp); +#ifdef CONFIG_TCP_METRICS void tcp_update_metrics (struct sock *sk);void tcp_init_metrics (struct sock *sk);void tcp_metrics_init (void ); +bool tcp_peer_is_proven (struct request_sock *req,struct dst_entry *dst,bool paws_check);bool tcp_remember_stamp (struct sock *sk);bool tcp_tw_remember_stamp (struct inet_timewait_sock *tw);void tcp_fetch_timewait_stamp (struct sock *sk,struct dst_entry *dst); +#else +static inline void tcp_update_metrics (struct sock *sk) {} +static inline void tcp_init_metrics (struct sock *sk) {} +static inline void tcp_metrics_init (void ) {} +static inline bool tcp_peer_is_proven (struct request_sock *req, +struct dst_entry *dst, +bool paws_check) {return false; } +static inline bool tcp_remember_stamp (struct sock *sk) {return false; } +static inline bool +tcp_tw_remember_stamp (struct inet_timewait_sock *tw) {return false; } +static inline void +tcp_fetch_timewait_stamp (struct sock *sk,struct dst_entry *dst) {} +#endif void tcp_disable_fack (struct tcp_sock *tp);void tcp_close (struct sock *sk,long timeout);void tcp_init_sock (struct sock *sk);@@ -1296,11 +1311,21 @@ int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, const struct tcp_md5sig_key *key);/* From tcp_fastopen.c */ +#ifdef CONFIG_TCP_METRICS void tcp_fastopen_cache_get (struct sock *sk,u16 *mss,struct tcp_fastopen_cookie *cookie,int *syn_loss,unsigned long *last_syn_loss);void tcp_fastopen_cache_set (struct sock *sk,u16 mss,struct tcp_fastopen_cookie *cookie,bool syn_lost); +#else +static inline void +tcp_fastopen_cache_get (struct sock *sk,u16 *mss, +struct tcp_fastopen_cookie *cookie,int *syn_loss, +unsigned long *last_syn_loss) {} +static inline void +tcp_fastopen_cache_set (struct sock *sk,u16 mss, +struct tcp_fastopen_cookie *cookie,bool syn_lost) {} +#endif struct tcp_fastopen_request {/* Fast Open cookie. Size 0 means a cookie request */ struct tcp_fastopen_cookie cookie;net/ipv4/Kconfig +0
-0
net/ipv4/Kconfig config IP_PIMSM_V2 · line 271
Quoted 8 lines
net/ipv4/Kconfig +5
-0@@ -264,6 +264,12 @@ config IP_PIMSM_V2 gated-5). This routing protocol is not used widely, so say N unless you want to play with it. +config TCP_METRICS + bool "Report TCP metrics over netlink" + ---help--- + Enable support in TCP to save host information between different + connections.
Please add that "Certain TCP features such as active TCP Fast Open depends on this."
Quoted 52 lines
net/ipv4/Kconfig +1
-0+ config SYN_COOKIES bool "IP: TCP syncookie support" ---help---net/ipv4/Makefile +2
-1@@ -7,7 +7,7 @@ obj-y := route.o inetpeer.o protocol.o \ ip_output.o ip_sockglue.o inet_hashtables.o \ inet_timewait_sock.o inet_connection_sock.o \ tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ - tcp_minisocks.o tcp_cong.o tcp_metrics.o tcp_fastopen.o \ + tcp_minisocks.o tcp_cong.o tcp_fastopen.o \ tcp_offload.o datagram.o raw.o udp.o udplite.o \ udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \ fib_frontend.o fib_semantics.o fib_trie.o \@@ -17,6 +17,7 @@ obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o obj-$(CONFIG_IP_PING) += ping.o obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o obj-$(CONFIG_PROC_FS) += proc.o +obj-$(CONFIG_TCP_METRICS) += tcp_metrics.o obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o obj-$(CONFIG_IP_MROUTE) += ipmr.o obj-$(CONFIG_NET_IPIP) += ipip.onet/ipv4/sysctl_net_ipv4.c +2
-1@@ -573,6 +573,7 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, +#ifdef CONFIG_TCP_METRICS { .procname = "tcp_no_metrics_save", .data = &sysctl_tcp_nometrics_save,@@ -580,6 +581,7 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, +#endif { .procname = "tcp_moderate_rcvbuf", .data = &sysctl_tcp_moderate_rcvbuf, --1.9.0
--
To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 7 lines
net/ipv4/Kconfig config IP_PIMSM_V2 · line 271
Quoted 5 lines
net/ipv4/Kconfig +5
-0+config TCP_METRICS + bool "Report TCP metrics over netlink" + ---help--- + Enable support in TCP to save host information between different + connections.Please add that "Certain TCP features such as active TCP Fast Open depends on this."
I added a select.
Also will fix the inaccurate help line.
-Andi
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:57 -0700
Quoted 3 lines
This is all the code that saves connection information between different sockets. Not really essential for small systems.
It is absolutely essential unless you want poor performance of TCP connections.
I'm not applying this.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 9 lines · David Miller
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:57 -0700Quoted 3 lines
This is all the code that saves connection information between different sockets. Not really essential for small systems.
It is absolutely essential unless you want poor performance of TCP connections.
Ok so every code in the network stack is essential?
What parts would you remove to get the foot print down for a 2MB single purpose machine?
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only.
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
From: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 05:21:14 +0200
Quoted 2 lines
What parts would you remove to get the foot print down for a 2MB single purpose machine?
I wouldn't use Linux, end of story.
Maybe two decades ago, but not now, those days are over.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 9 lines · David Miller
From: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 05:21:14 +0200Quoted 2 lines
What parts would you remove to get the foot print down for a 2MB single purpose machine?
I wouldn't use Linux, end of story.
Maybe two decades ago, but not now, those days are over.
These 'new' systems we're talking about pretty much are the same as systems from 20 years ago e.g. Quark, which is essentially a 486, with tiny amounts of RAM, say less than 2 MB, so I hope those days aren't over forever for Linux...
Anyway, Andi's net-diet and LTO patches allowed me to go from a kernel text size of above 1100k down to about 750k with the kernel network stack running an unmodified small web server (nostromo) and the ability to drop in a dedicated single-purpose application that this type of system would typically run e.g. something based on for example UDP.
I was able to get that down to about 620k removing INET completely and replacing it with LWIP, but LWIP either bloated the application back up to similar memory usage numbers as with INET configured in, or alternatively required extensive changes to the application in order to use the not-bloating low-level interface.
But why go to all that trouble when there's a perfectly good networking stack in the kernel? Even if most of these options aren't things that would be useful to most systems, being able to turn them off and save 1/3 of the kernel text size for tiny systems like this does makes a big difference...
Tom
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 5 lines
But why go to all that trouble when there's a perfectly good networking stack in the kernel? Even if most of these options aren't things that would be useful to most systems, being able to turn them off and save 1/3 of the kernel text size for tiny systems like this does makes a big difference...
There are a vast number of low memory devices for various platforms and FPGA devices. I've also been looking at this for some other projects and there is a reason I went back and started playing with 2.11BSD.
Quoted 2 lines
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
Simple answer. 2.11BSD is vastly superior on a small system to 2.4.x Linux. Also 2.4 is old and lightly maintained. Even forking 3.15 into bloatix and embedded Linux (ELKS2 ;-)) would make more sense.
2/11BSD has the advantage that you don't need virtual memory and you don't have the cost of page tables which are mostly useless on a device that small these days because I/O speeds are so much higher. It has a bloatfree userspace, although it does need chunks of the openbsd security work backporting.
Forking a current Linux would give you all the modern stuff wanted like USB, SPI, eMMC etc but comes with all the debloating work and some annoying assumptions about memory. Do the fork off GregKH's next long term kernel and it wouldn't be that horrific to maintain until there is a clear picture about uses and whether it justifies merging ?
Quoted 3 lines
Another poster commented that 16MB of DRAM would be cheaper than the 2MB of ram you have on these boards, probably one that fits your size profile is available as well.
16MB of DRAM means adding a chip to your system. You've just exceeded the space, power and cost budget on the very low end. In many cases like FPGA systems you can't even add DRAM without major hoop jumping.
On the Linux side there's also a ton of other stuff with vm handling that could be done far better for a small x86 device if the kernel was split (for now anyway). If it gets a lot of users then DaveM's arguments about unjustified maintenance hassle go away and it an then get re-merged.
Quoted 1 line
2MB is just a rediculous restriction.
Linux used to run fine in 2MB ;-)
Quoted 2 lines
And last time I checked Linux wasn't a special purpose operating system, but lucky for you I hear there are lots of those around.
Server, desktop, tablet and even phone main OS devices are "special purpose" in the big picture of processor use. Even today 2MB is "big computer" to an awful lot of people!
Alan
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
From: One Thousand Gnomes <[email protected]>
Date: Wed, 7 May 2014 14:59:38 +0100
Quoted 3 lines
16MB of DRAM means adding a chip to your system. You've just exceeded the space, power and cost budget on the very low end. In many cases like FPGA systems you can't even add DRAM without major hoop jumping.
A year or so for now this may not be true, which makes these kinds of changes very nearly in the "point in time solution" category.
My main point in all of this is that whilst Linux should work on a braod range of system types, there has to be a limit somewhere and I think 2MB is off the deep end.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 10 lines · David Miller
From: One Thousand Gnomes <[email protected]>
Date: Wed, 7 May 2014 14:59:38 +0100Quoted 3 lines
16MB of DRAM means adding a chip to your system. You've just exceeded the space, power and cost budget on the very low end. In many cases like FPGA systems you can't even add DRAM without major hoop jumping.
A year or so for now this may not be true, which makes these kinds of changes very nearly in the "point in time solution" category.
Quoted 8 lines
My main point in all of this is that whilst Linux should work on a braod range of system types, there has to be a limit somewhere and I think 2MB is off the deep end.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Linux 2.6.33 is currently running on a microcontroller with 2MB of flash and 256K of RAM. See Vitaly Wool's presentation from ELC about this here:
http://elinux.org/images/c/ca/Spreading.pdf.
It might be off the deep end, but I think that's pretty exciting.
That's not a super-recent kernel, but I think current kernels could get to 512K RAM and 2MB flash with some elbow grease. That hits the sweet spot for where the deep embedded processors (everything on-die, at really aggressive price per unit) are heading in the next few years.
I sympathize with the arguments about increasing configuration complexity, and the possibility of introducing bugs. "big switches" and LTO should both help with the config complexity problem. With regard to bugs, I think some of the patches may be a problem, and that's where the help of the networking experts would be great in helping to avoid problems. Dropping optional features is going to happen on these devices whether it's Linux running there or some RTOS. Linux will certainly be talking to these devices, if not running in them. So your life on the host side might be improved if you have some say what the stack looks like on the device side.
If you don't want to help avoid problems, I understand. All the kernel maintainers are extremely busy. But the use cases are pretty interesting, and it would be nice to have you on board.
-- Tim Bird
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
From: Tim Bird <[email protected]>
Date: Wed, 7 May 2014 15:19:03 -0700
Quoted 3 lines
If you don't want to help avoid problems, I understand. All the kernel maintainers are extremely busy. But the use cases are pretty interesting, and it would be nice to have you on board.
Or running with improper privileges.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to David MillerQuoted 9 lines · David Miller
From: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 05:21:14 +0200Quoted 2 lines
What parts would you remove to get the foot print down for a 2MB single purpose machine?
I wouldn't use Linux, end of story.
Maybe two decades ago, but not now, those days are over.
That's a self-fulfilling prophecy: if you and others assume that Linux should not run on such machines, then size regressions will continue to happen, and patches to make Linux continue running on such systems will not make it into the kernel.
There are real people and products intending to use Linux on incredibly tiny embedded systems; Tom already posted about one in this thread. Personally, I'd much rather see Linux on such systems rather than some crazy embedded (often proprietary) OS, and so would many other people. A NAK isn't going to cut it, here; tiny Linux systems are going to exist, and they shouldn't have to maintain a long-term out-of-tree fork or use crazy things like LWIP.
I understand that you want to reduce maintenance effort and Kconfig option proliferation; that's a very real concern. It's likely possible to address those concerns while still producing a usable minimal version of the networking stack, if you'd be willing to provide feedback and support iteration of patches like these.
Would you be interested in discussing this at Kernel Summit, perhaps? Would that help to hammer out a plan for this?
- Josh Triplett
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
From: [email protected]
Date: Tue, 6 May 2014 08:57:03 -0700
Quoted 12 lines · David Miller
Quoted 9 lines
From: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 05:21:14 +0200Quoted 2 lines
What parts would you remove to get the foot print down for a 2MB single purpose machine?
I wouldn't use Linux, end of story.
Maybe two decades ago, but not now, those days are over.
That's a self-fulfilling prophecy:
Making 2MB RAM machines today makes no sense at all.
The lowest end dirt cheap smartphone, something which fits on someone's pocket, has gigabytes of ram.
The only entity looking backwards are the people making these improperly provisioned systems.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 12 lines · David Miller
From: [email protected]
Date: Tue, 6 May 2014 08:57:03 -0700Quoted 9 lines · David Miller
Quoted 8 lines
From: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 05:21:14 +0200Quoted 2 lines
What parts would you remove to get the foot print down for a 2MB single purpose machine?
I wouldn't use Linux, end of story.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Maybe two decades ago, but not now, those days are over.
That's a self-fulfilling prophecy:
Making 2MB RAM machines today makes no sense at all.
The lowest end dirt cheap smartphone, something which fits on someone's pocket, has gigabytes of ram.
The lowest-end smartphone isn't anywhere close to "dirt cheap", and hardly counts as "embedded" at all anymore. Smartphones cost $100+; we're talking about systems in the low tens of dollars or less. These systems will have no graphics, no peripherals, and only one or two specific functions. The entirety of their functionality will likely consist of a single userspace program; they might not even have a PID 2. *That's* the kind of "embedded" we're talking about, not the supercomputers we carry around in our pockets.
Every KB of RAM costs real money and SoC die area (for eDRAM/eSRAM). Look at how much cache low-end processors have, and imagine running entirely out of *that*. Let's not surrender that entire class of devices to VxWorks, FreeRTOS, and other painfully non-Linux systems, when we already know it's possible to run Linux on them successfully.
- Josh Triplett
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 6 lines · On 05/06/2014 09:41 AM, [email protected] wrote:
Quoted 4 lines · David Miller
Making 2MB RAM machines today makes no sense at all.
The lowest end dirt cheap smartphone, something which fits on someone's pocket, has gigabytes of ram.
Quoted 8 lines
The lowest-end smartphone isn't anywhere close to "dirt cheap", and hardly counts as "embedded" at all anymore. Smartphones cost $100+; we're talking about systems in the low tens of dollars or less. These systems will have no graphics, no peripherals, and only one or two specific functions. The entirety of their functionality will likely consist of a single userspace program; they might not even have a PID 2. *That's* the kind of "embedded" we're talking about, not the supercomputers we carry around in our pockets.
Would this be some sort of "Internet of Things" system?
rick jones
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 16 lines · Rick Jones
Quoted 6 lines · On 05/06/2014 09:41 AM, [email protected] wrote:
Quoted 4 lines · David Miller
Making 2MB RAM machines today makes no sense at all.
The lowest end dirt cheap smartphone, something which fits on someone's pocket, has gigabytes of ram.
Quoted 8 lines
The lowest-end smartphone isn't anywhere close to "dirt cheap", and hardly counts as "embedded" at all anymore. Smartphones cost $100+; we're talking about systems in the low tens of dollars or less. These systems will have no graphics, no peripherals, and only one or two specific functions. The entirety of their functionality will likely consist of a single userspace program; they might not even have a PID 2. *That's* the kind of "embedded" we're talking about, not the supercomputers we carry around in our pockets.
Quoted 1 line
Would this be some sort of "Internet of Things" system?
That's one of many buzzwords being used for this kind of system, sure. The "Internet of" part makes networking particularly important.
- Josh Triplett
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to [email protected]From: [email protected]
Date: Tue, 6 May 2014 09:41:08 -0700
Quoted 1 line
Every KB of RAM costs real money and SoC die area (for eDRAM/eSRAM).
Another poster commented that 16MB of DRAM would be cheaper than the 2MB of ram you have on these boards, probably one that fits your size profile is available as well.
2MB is just a rediculous restriction.
And last time I checked Linux wasn't a special purpose operating system, but lucky for you I hear there are lots of those around.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 10 lines · David Miller
From: [email protected]
Date: Tue, 6 May 2014 09:41:08 -0700Quoted 1 line
Every KB of RAM costs real money and SoC die area (for eDRAM/eSRAM).
Another poster commented that 16MB of DRAM would be cheaper than the 2MB of ram you have on these boards, probably one that fits your size profile is available as well.
2MB is just a rediculous restriction.
Embedded systems experts disagree with you there; there *are* systems where the most cost-efficient approach is a few MB (or a few hundred KB) of non-discrete memory. We're not talking about socketed memory or even soldered-down memory; we're talking about entire systems that fit on a small SoC die. The space not used by that extra RAM may well be better spent on CPU optimizations, or some other integrated component.
Such boards will be built, and many of them will run Linux, despite your incredulity. When you're building millions of a board, it's well worth optimizing software to eliminate components from the bill of materials.
And even on a system with 4MB or 8MB or 16MB of memory, a few hundred extra KB used by the kernel and unavailable to userspace *matters*; that could be the difference between fitting in 8MB or 16MB.
Quoted 2 lines
And last time I checked Linux wasn't a special purpose operating system
No, it's an extremely general-purpose operating system, supporting enough customization to run on everything from supercomputers to some embedded systems. And that's partly because people who care about those systems submit patches to make Linux scale. You take patches to scale *up* to absurdly huge systems; what makes it so painful to take patches to scale *down*?
Quoted 1 line
, but lucky for you I hear there are lots of those around.
Why would I want to run one of those when I can run Linux?
- Josh Triplett
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 19 lines · On Tue, May 6, 2014 at 10:55 AM, <[email protected]> wrote:
Quoted 10 lines · David Miller
From: [email protected]
Date: Tue, 6 May 2014 09:41:08 -0700Quoted 1 line
Every KB of RAM costs real money and SoC die area (for eDRAM/eSRAM).
Another poster commented that 16MB of DRAM would be cheaper than the 2MB of ram you have on these boards, probably one that fits your size profile is available as well.
2MB is just a rediculous restriction.
Embedded systems experts disagree with you there; there *are* systems where the most cost-efficient approach is a few MB (or a few hundred KB) of non-discrete memory. We're not talking about socketed memory or even soldered-down memory; we're talking about entire systems that fit on a small SoC die. The space not used by that extra RAM may well be better spent on CPU optimizations, or some other integrated component.
Quoted 3 lines
Such boards will be built, and many of them will run Linux, despite your incredulity. When you're building millions of a board, it's well worth optimizing software to eliminate components from the bill of materials.
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 2 lines
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
Nobody wants to be stuck on an ancient kernel forever.
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Cong WangQuoted 3 lines · Cong Wang
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
If you compare a 3.x and a 2.4.x kernel with the same minimal feature set, you might see that the 3.x is bigger.
Thanks,
Richard
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Cong WangFrom: Cong Wang <[email protected]>
Date: Tue, 6 May 2014 11:33:11 -0700
Quoted 2 lines
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
+1
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 7 lines · David Miller
From: Cong Wang <[email protected]>
Date: Tue, 6 May 2014 11:33:11 -0700Quoted 2 lines
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
+1
You've got to be kidding. Using 2.4 for a new network-connected device, today? With all of its potential security holes that nobody is paying attention to? Easier to fork 3.15 and trim it down than to do *that*. And there *are* a huge number of useful features in 3.15+, not least of which drivers for current hardware.
- Josh Triplett
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
From: [email protected]
Date: Tue, 6 May 2014 14:08:15 -0700
Quoted 7 lines · David Miller
Quoted 6 lines
From: Cong Wang <[email protected]>
Date: Tue, 6 May 2014 11:33:11 -0700Quoted 2 lines
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
Quoted 7 lines
Quoted 1 line
+1
You've got to be kidding. Using 2.4 for a new network-connected device, today? With all of its potential security holes that nobody is paying attention to? Easier to fork 3.15 and trim it down than to do *that*. And there *are* a huge number of useful features in 3.15+, not least of which drivers for current hardware.
So you're saying that the 2.4.x -stable maintainer did a shitty job and his work is worthless?
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 12 lines · David Miller
From: [email protected]
Date: Tue, 6 May 2014 14:08:15 -0700Quoted 9 lines · David Miller
Quoted 7 lines
From: Cong Wang <[email protected]>
Date: Tue, 6 May 2014 11:33:11 -0700Quoted 2 lines
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
+1
Quoted 8 lines
Quoted 5 lines
You've got to be kidding. Using 2.4 for a new network-connected device, today? With all of its potential security holes that nobody is paying attention to? Easier to fork 3.15 and trim it down than to do *that*. And there *are* a huge number of useful features in 3.15+, not least of which drivers for current hardware.
So you're saying that the 2.4.x -stable maintainer did a shitty job and his work is worthless?
There's a difference between maintaining 2.4.x for all the existing users who can't or won't upgrade, and introducing a *new* product shipping with 2.4.x. There's something very wrong if 2.4.x works for cases that 3.x doesn't; that would be a serious regression.
- Josh Triplett
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 2 lines · On Tue, 2014-05-06 at 15:50 -0700, [email protected] wrote:
There's something very wrong if 2.4.x works for cases that 3.x doesn't; that would be a serious regression.
You'll have to ask Linus to bring back i386 support then, I believe it was removed in 3.8
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Cong WangQuoted 20 lines · Cong Wang
Quoted 19 lines · On Tue, May 6, 2014 at 10:55 AM, <[email protected]> wrote:
Quoted 10 lines · David Miller
From: [email protected]
Date: Tue, 6 May 2014 09:41:08 -0700Quoted 1 line
Every KB of RAM costs real money and SoC die area (for eDRAM/eSRAM).
Another poster commented that 16MB of DRAM would be cheaper than the 2MB of ram you have on these boards, probably one that fits your size profile is available as well.
2MB is just a rediculous restriction.
Embedded systems experts disagree with you there; there *are* systems where the most cost-efficient approach is a few MB (or a few hundred KB) of non-discrete memory. We're not talking about socketed memory or even soldered-down memory; we're talking about entire systems that fit on a small SoC die. The space not used by that extra RAM may well be better spent on CPU optimizations, or some other integrated component.
Quoted 6 lines
Quoted 3 lines
Such boards will be built, and many of them will run Linux, despite your incredulity. When you're building millions of a board, it's well worth optimizing software to eliminate components from the bill of materials.
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
So.. what is kernel composed of? Ton of drivers and a bit of generic code.
And when doing this, you probably need the drivers from 3.x for your hardware.
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Cong WangQuoted 18 lines · Cong Wang
Quoted 17 lines · On Tue, May 6, 2014 at 10:55 AM, <[email protected]> wrote:
Quoted 9 lines · David Miller
From: [email protected]
Date: Tue, 6 May 2014 09:41:08 -0700Quoted 1 line
Every KB of RAM costs real money and SoC die area (for eDRAM/eSRAM).
Another poster commented that 16MB of DRAM would be cheaper than the 2MB of ram you have on these boards, probably one that fits your size profile is available as well.
2MB is just a rediculous restriction.
Embedded systems experts disagree with you there; there *are* systems where the most cost-efficient approach is a few MB (or a few hundred KB) of non-discrete memory. We're not talking about socketed memory or even soldered-down memory; we're talking about entire systems that fit on a small SoC die. The space not used by that extra RAM may well be better spent on CPU optimizations, or some other integrated component.
Quoted 5 lines
Quoted 3 lines
Such boards will be built, and many of them will run Linux, despite your incredulity. When you're building millions of a board, it's well worth optimizing software to eliminate components from the bill of materials.
So why bothers 3.15+ Linux kernel? Why not use an old kernel e.g. 2.4.x? 2.4.x kernel doesn't have so many new features you want to get rid of here.
Maybe 2.4.x kernel doesn't have so many new features that we want to use here.
Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to [email protected]Quoted 2 lines · On Tue, May 06, 2014 at 09:41:08AM -0700, [email protected] wrote:
Quoted 1 line · David Miller
Making 2MB RAM machines today makes no sense at all.
Besides cost, one of the main reasons for designing tiny systems today is battery life. Some devices cannot be recharged every week, like your smart phone must.
Quoted 2 lines
Quoted 2 lines
The lowest end dirt cheap smartphone, something which fits on someone's pocket, has gigabytes of ram.
Right, these low end smart phones are nicer than the DEC Alpha work stations we had at university. I would not call them "small" embedded systems.
Quoted 5 lines
Every KB of RAM costs real money and SoC die area (for eDRAM/eSRAM). Look at how much cache low-end processors have, and imagine running entirely out of *that*. Let's not surrender that entire class of devices to VxWorks, FreeRTOS, and other painfully non-Linux systems, when we already know it's possible to run Linux on them successfully.
I have also been working on tiny system recently (and hope to get out of it soon ;). This whole IoT trend might just go away, I sure hope it does, but in general there is a growing need for tiny systems with excellent networking.
Davem's attitude is understandable, and Linux should not be expected to fit into every last micro controller, but still I observe the kernel getting ever bigger, even in the most basic configurations. I don't think there is valid technical reason for bloat, but rather it is an issue that doesn't affect too many people.
In any case I would really like to see the possibility of leaving pieces out for these tiny systems, but it would be a balancing act. On the one hand, we want the stable/powerful/wonderful Linux stack in our tiny systems. On the other hand, if we rip everything out to make it fit, then it is no longer the same thing. So I think Dave is right in rejecting anything that compromises the _quality_ of the stack.
Off on a tangent:
Regarding the multiplicity of RTOSs out there, all I can say is, they all suck, especially the ones you pay money for. It would be great to have a small Linux like OS for micro controllers and tiny micro processors. I have looked and looked for an open source, posix like alternative, but all I found was Nuttx, ActionOS, and RTEMS. I looked closely at the first two, and putting aside technical issues, neither seems to have any steam in terms of active development. RTEMS says it has a BSD stack, and it seems to have a respectable development effort, but I did not look too closely at it.
There is a huge area out there (think of all the Cortex M3) that needs a real networking stack, but I don't see much hope. Minimizing Linux is a big PITA (tons of work), and building a suitably small OS from scratch is hopeless. As was said, it is easier just to buy a bigger memory. The people who can't or won't (who are also building the IoT) will just throw in some lwIP or uIP. You can imagine how secure these systems will be.
Thanks,
Richard
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 3 lines
So I think Dave is right
in rejecting anything that compromises the _quality_ of the stack.
I don't think anything I removed compromised quality (modulo bugs) It's still a more-features-than-your-typical-BSD TCP/IP stack
-Andi
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 6 lines · Andi Kleen
Quoted 3 lines
So I think Dave is right
in rejecting anything that compromises the _quality_ of the stack.I don't think anything I removed compromised quality (modulo bugs) It's still a more-features-than-your-typical-BSD TCP/IP stack
But Dave seems to think so.
My (obvious?) point is, if you make the stack different, and not just smaller by omitting optional features, then that defeats the point of wanting the Linux stack in the first place.
Thanks,
Richard
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 9 lines · Richard Cochran
Quoted 6 lines · Andi Kleen
Quoted 3 lines
So I think Dave is right
in rejecting anything that compromises the _quality_ of the stack.I don't think anything I removed compromised quality (modulo bugs) It's still a more-features-than-your-typical-BSD TCP/IP stack
But Dave seems to think so.
Appeal to authority?
The vast majority of the patches only remove optional user interfaces. If the single program running on the embedded system does not use these interfaces it's simply dead code.
The patches that change non interface parts:
- Make FASTOPEN optional. FASTOPEN is a very expensive feature because it pulls in the complete crypto subsystem. It's also a feature that needs to be explicitely enabled by the user program, and I doubt is widely deployed
(my work station did exactly zero fast opens ever)
- Make TCP_METRICS optional, so connections don't share state.
- Simplify the routing table for the client < 10 routes case. Works exactly the same as before with a small number of routes.
- Make GRO optional.
This is purely a performance feature for high bandwidth.
-Andi
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 2 lines · Andi Kleen
- Make GRO optional.
This is purely a performance feature for high bandwidth.
Make this properly then, instead of relying on LTO.
We did preliminary work to put this stuff in separate files, but its not complete yet.
tcpv4_offload has pointers to tcp4_gro_receive() and tcp4_gro_complete()
Is LTO smart enough to understand this will never be called, and do proper code elimination of whole _gro_ helpers ?
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 9 lines · Eric Dumazet
Quoted 2 lines · Andi Kleen
- Make GRO optional.
This is purely a performance feature for high bandwidth.Make this properly then, instead of relying on LTO.
We did preliminary work to put this stuff in separate files, but its not complete yet.
FWIW doesn't matter for LTO.
Quoted 5 lines
tcpv4_offloadhas pointers totcp4_gro_receive()andtcp4_gro_complete()Is LTO smart enough to understand this will never be called, and do proper code elimination of whole _gro_ helpers ?
When there are pointers in static objects it cannot eliminate it for C (it may work for C++)
However if you just remove the pointer it'll remove the rest.
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only.
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 12:50:49 -0700
Quoted 1 line
It's still a more-features-than-your-typical-BSD TCP/IP stack
Said the guy posting patches to remove TCP metrics.
RE: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to [email protected]From: [email protected]
...
Quoted 5 lines
Every KB of RAM costs real money and SoC die area (for eDRAM/eSRAM). Look at how much cache low-end processors have, and imagine running entirely out of *that*. Let's not surrender that entire class of devices to VxWorks, FreeRTOS, and other painfully non-Linux systems, when we already know it's possible to run Linux on them successfully.
Have you considered running (say) NetBSD instead of Linux? You'll get more support there for running on 'small memory' systems. You can also make your own changes with having issues with the GPL.
David
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to David MillerQuoted 12 lines · David Miller
From: [email protected]
Date: Tue, 6 May 2014 08:57:03 -0700Quoted 9 lines · David Miller
Quoted 8 lines
From: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 05:21:14 +0200Quoted 2 lines
What parts would you remove to get the foot print down for a 2MB single purpose machine?
I wouldn't use Linux, end of story.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Maybe two decades ago, but not now, those days are over.
That's a self-fulfilling prophecy:
Making 2MB RAM machines today makes no sense at all.
The lowest end dirt cheap smartphone, something which fits on someone's pocket, has gigabytes of ram.
Low end smartphone is quite high-end device :-). It only has to run for few days on big battery.
I have programmable watch with <64K RAM. Yes, that one runs for months on battery.
Quoted 2 lines
The only entity looking backwards are the people making these improperly provisioned systems.
There's nothing improper about small ammount of RAM to save power.
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to [email protected]Quoted 3 lines · On Tue, 2014-05-06 at 08:57 -0700, [email protected] wrote:
A NAK isn't going to cut it, here; tiny Linux systems are going to exist, and they shouldn't have to maintain a long-term out-of-tree fork or use crazy things like LWIP.
What's wrong with user space implementations of networking stacks ?
For many usages, it can bring 10 times the performance of having user application and kernel sockets.
In any cases, we do not model kernel implementations to 'compete' with user space.
We simply can not compete with user space, as a programmer is free to keep what he really wants/needs.
I have started using linux on 386/486 pcs which had more than 2MB of memory, it makes me sad we want linux-3.16 to run on this kind of hardware, and consuming time to save few KB here and here.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 7 lines · Eric Dumazet
Quoted 3 lines · On Tue, 2014-05-06 at 08:57 -0700, [email protected] wrote:
A NAK isn't going to cut it, here; tiny Linux systems are going to exist, and they shouldn't have to maintain a long-term out-of-tree fork or use crazy things like LWIP.
What's wrong with user space implementations of networking stacks ?
What's wrong with the kernel implementation?
Quoted 2 lines
For many usages, it can bring 10 times the performance of having user application and kernel sockets.
Sounds like we have some optimization to do, then; there's no fundamental unfixable reason for that delta.
Quoted 5 lines
In any cases, we do not model kernel implementations to 'compete' with user space.
We simply can not compete with user space, as a programmer is free to keep what he really wants/needs.
The kernel can do the same. Consider the idea of analyzing a set of userspace programs, determining what kernel functionality they do and don't need, feeding that information into the kernel build process, and automatically dropping unused bits of the kernel.
Ideally, that kind of process would support eliminating kernel config options that just select userspace-visible interfaces, leaving only the kernel config options that change how those interfaces behave (size/performance/feature tradeoffs).
- Josh Triplett
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 2 lines · On Tue, 2014-05-06 at 09:45 -0700, [email protected] wrote:
Sounds like we have some optimization to do, then; there's no fundamental unfixable reason for that delta.
I think you have little idea of the reasons for this delta.
Some servers handle 10 millions of TCP flows, using as little as 1KB per connection in user space, all included.
Do you have an idea of how much memory is needed for 10 millions TCP sockets in the kernel ?
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 6 lines · Eric Dumazet
Quoted 2 lines · On Tue, 2014-05-06 at 09:45 -0700, [email protected] wrote:
Sounds like we have some optimization to do, then; there's no fundamental unfixable reason for that delta.
I think you have little idea of the reasons for this delta.
I have a rather good idea, actually.
Quoted 5 lines
Some servers handle 10 millions of TCP flows, using as little as 1KB per connection in user space, all included.
Do you have an idea of how much memory is needed for 10 millions TCP sockets in the kernel ?
Too much. That's potentially fixable, but not if we start with the premise that it's impossible.
- Josh Triplett
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to [email protected]From: [email protected]
Date: Tue, 6 May 2014 09:45:46 -0700
Quoted 4 lines
The kernel can do the same. Consider the idea of analyzing a set of userspace programs, determining what kernel functionality they do and don't need, feeding that information into the kernel build process, and automatically dropping unused bits of the kernel.
Please make sure I'm not on the list of people who see reports for bugs reported in that setup.
Thanks :-)
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 8 lines · David Miller
From: [email protected]
Date: Tue, 6 May 2014 09:45:46 -0700Quoted 4 lines
The kernel can do the same. Consider the idea of analyzing a set of userspace programs, determining what kernel functionality they do and don't need, feeding that information into the kernel build process, and automatically dropping unused bits of the kernel.
Quoted 4 lines
Please make sure I'm not on the list of people who see reports for bugs reported in that setup.
Thanks :-)
Fine by me. Just please allow such a setup to exist. :)
- Josh Triplett
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
From: [email protected]
Date: Tue, 6 May 2014 10:21:06 -0700
Quoted 9 lines · David Miller
Quoted 8 lines
From: [email protected]
Date: Tue, 6 May 2014 09:45:46 -0700Quoted 4 lines
The kernel can do the same. Consider the idea of analyzing a set of userspace programs, determining what kernel functionality they do and don't need, feeding that information into the kernel build process, and automatically dropping unused bits of the kernel.
Quoted 6 lines
Quoted 4 lines
Please make sure I'm not on the list of people who see reports for bugs reported in that setup.
Thanks :-)
Fine by me. Just please allow such a setup to exist. :)
You see, that's the point I'm trying to make, once it's upstream then it's my problem.
You absolutely must consider the burdon you put upon upstream maintainers when you ask for things to be included.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 2 lines
You see, that's the point I'm trying to make, once it's upstream then it's my problem.
FWIW I don't think any of the changes I proposed would be likely to add lots of new bugs. Nothing was really adding any significant new logic, just doing less (modulo perhaps fib_list) Was that your main concern?
I realize the many config options are something that could be consolidated to ease compile time testing.
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only.
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
From: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 22:06:44 +0200
Quoted 5 lines
Quoted 2 lines
You see, that's the point I'm trying to make, once it's upstream then it's my problem.
FWIW I don't think any of the changes I proposed would be likely to add lots of new bugs.
Then you're living in a dream world, one in which the rest of us do not live in.
Every new configuration combination is a new situation that competes testing wise with the others.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to David MillerQuoted 17 lines · David Miller
From: [email protected]
Date: Tue, 6 May 2014 10:21:06 -0700Quoted 14 lines · David Miller
Quoted 12 lines
From: [email protected]
Date: Tue, 6 May 2014 09:45:46 -0700Quoted 4 lines
The kernel can do the same. Consider the idea of analyzing a set of userspace programs, determining what kernel functionality they do and don't need, feeding that information into the kernel build process, and automatically dropping unused bits of the kernel.
Please make sure I'm not on the list of people who see reports for bugs reported in that setup.
Thanks :-)
Quoted 7 lines
Quoted 1 line
Fine by me. Just please allow such a setup to exist. :)
You see, that's the point I'm trying to make, once it's upstream then it's my problem.
You absolutely must consider the burdon you put upon upstream maintainers when you ask for things to be included.
Absolutely. And Andi and I are both interested in working *with* you to find a way to run on tiny embedded systems *without* necessarily introducing excessive proliferation of configuration options or unnecessarily increasing your support burden.
For instance, it's easy enough to key some options off of CONFIG_NR_CPUS (such as data structure sizes), or introduce a big config switch (CONFIG_NETWORK_FULL=n or similar) that controls all of these cases rather than having option for each. That would not be hard to supply in a v2 of this patch series.
And if you're asking for someone to help pay attention to bug reports so you don't have to, that's reasonable as well; just like you probably have a stock response for "that's a crazy distro kernel, ask them about it and not me", you could have a stock response for "that kernel has the crazy embedded option turned on, ask the embedded people about it and not me". It doesn't just have to be *your* problem alone.
There's a stigma rightfully attached to out-of-tree patches, which roughly amounts to "people ought to submit patches upstream, we shouldn't have to support or care about out-of-tree patches". But that only works if the responses to patch submissions are either "No, because you need to fix X, Y, and Z", or "No, because your use case is better served by this existing mechanism already in the kernel", rather than "No, your use case is not valid".
- Josh Triplett
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 6 lines
And if you're asking for someone to help pay attention to bug reports so you don't have to, that's reasonable as well; just like you probably have a stock response for "that's a crazy distro kernel, ask them about it and not me", you could have a stock response for "that kernel has the crazy embedded option turned on, ask the embedded people about it and not me". It doesn't just have to be *your* problem alone.
We could add a tainted flag for these configurations and a message at bootup to make it obvious in bug reports. Would that help?
-Andi
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Eric DumazetFrom: Eric Dumazet <[email protected]>
Date: Tue, 06 May 2014 09:39:19 -0700
Quoted 3 lines
I have started using linux on 386/486 pcs which had more than 2MB of memory, it makes me sad we want linux-3.16 to run on this kind of hardware, and consuming time to save few KB here and here.
+1
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Eric DumazetQuoted 2 lines
We simply can not compete with user space, as a programmer is free to keep what he really wants/needs.
Not true.
With my patches and LTO Linux can be competive with LWIP+socket layer. (about 60K more text). And it's easier to use because it's just the standard interface.
Quoted 3 lines
I have started using linux on 386/486 pcs which had more than 2MB of memory, it makes me sad we want linux-3.16 to run on this kind of hardware, and consuming time to save few KB here and here.
Linux has always been a system from very small to big. That's been one of its strengths. It is very adaptable.
Many subsystems are very configurable for this. For example that is why we have both SLOB and SLUB. That is why we have NOMMU MM and lots of other tuning knobs for small systems.
So if the other subsystems can do this, why should it be impossible for networking?
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 16 lines · Andi Kleen
Quoted 2 lines
We simply can not compete with user space, as a programmer is free to keep what he really wants/needs.
Not true.
With my patches and LTO Linux can be competive with LWIP+socket layer. (about 60K more text). And it's easier to use because it's just the standard interface.
Quoted 3 lines
I have started using linux on 386/486 pcs which had more than 2MB of memory, it makes me sad we want linux-3.16 to run on this kind of hardware, and consuming time to save few KB here and here.
Linux has always been a system from very small to big. That's been one of its strengths. It is very adaptable.
Quoted 8 lines
Many subsystems are very configurable for this. For example that is why we have both SLOB and SLUB. That is why we have NOMMU MM and lots of other tuning knobs for small systems.
So if the other subsystems can do this, why should it be impossible for networking?
Can this at least be done without the combinatorial explosion in number of configurations? As Yuchung pointed out these patches introduce at least one unresolved configuration dependency. CONFIG_SMP works quite well since with a single parameter we can enable/disable a whole bunch of functionality in bulk, and it's quite clear that new development cannot break smp or non-smp configurations. Maybe you want something similar like CONFIG_NETWORK_SMALL?
Tom
Quoted 8 lines
-Andi
--
[email protected] -- Speaking for myself only
--
To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 25 lines · Tom Herbert
Quoted 16 lines · Andi Kleen
Quoted 2 lines
We simply can not compete with user space, as a programmer is free to keep what he really wants/needs.
Not true.
With my patches and LTO Linux can be competive with LWIP+socket layer. (about 60K more text). And it's easier to use because it's just the standard interface.
Quoted 3 lines
I have started using linux on 386/486 pcs which had more than 2MB of memory, it makes me sad we want linux-3.16 to run on this kind of hardware, and consuming time to save few KB here and here.
Linux has always been a system from very small to big. That's been one of its strengths. It is very adaptable.
Quoted 8 lines
Many subsystems are very configurable for this. For example that is why we have both SLOB and SLUB. That is why we have NOMMU MM and lots of other tuning knobs for small systems.
So if the other subsystems can do this, why should it be impossible for networking?
Quoted 7 lines
Can this at least be done without the combinatorial explosion in number of configurations? As Yuchung pointed out these patches introduce at least one unresolved configuration dependency.
CONFIG_SMPworks quite well since with a single parameter we can enable/disable a whole bunch of functionality in bulk, and it's quite clear that new development cannot break smp or non-smp configurations. Maybe you want something similar likeCONFIG_NETWORK_SMALL?
That seems completely reasonable. Likewise, for infrastructure that scales by CPU, keying off of CONFIG_NR_CPUS might make sense.
I'd suggest inverting it, so that 'n' means "small" and 'y' means fully featured. Here's a rough description for a CONFIG_NETWORK_FULL:
config NETWORK_FULL
default y
bool "Full-featured networking stack" if EMBEDDED --help--
Leave this option enabled for a full-featured networking stack, including features used by the vast majority of systems. Saying N here results in a minimal embedded networking stack, suitable only for the most memory-constrained and storage-constrained systems; the minimal stack removes many features, and optimizes for code and data size rather than performance.
If in doubt, say Y here.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Tom HerbertQuoted 7 lines
Can this at least be done without the combinatorial explosion in number of configurations? As Yuchung pointed out these patches introduce at least one unresolved configuration dependency.
CONFIG_SMPworks quite well since with a single parameter we can enable/disable a whole bunch of functionality in bulk, and it's quite clear that new development cannot break smp or non-smp configurations. Maybe you want something similar likeCONFIG_NETWORK_SMALL?
Yes I've considered this. I'm not sure SMP is good enough though, at some point we'll get tiny dual core systems.
Quoted 3 lines
From the 0/0:
Quoted 1 line
Quoted 1 line
Right now I'm using own Kconfigs for every removed features. I realize this somewhat increases the compile test matrix. It would be possible to hide some of the options and select them using higher level configurations like the ones listed above. I haven't done this in this version.
<<<
-Andi
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Andi KleenQuoted 4 lines · Andi Kleen
Quoted 2 lines
We simply can not compete with user space, as a programmer is free to keep what he really wants/needs.
Not true.
You can shake the kernel as much as you want, you wont make :
- a TCP socket
- a dentry
- an inode
- a file structure
- eventpoll structures (assuming epoll use)
- 2 dst per flow.
In 1024 bytes of memory, and keep an efficient kernel to handle arbitrary number of sockets using the venerable and slow BSD socket api.
I was objecting to the "crazy things like LWIP" comment from Josh, not to your patches in general.
I actually took a look at them but stopped at patch 22
Adding ~1000 lines of code to save few KB was the point I gave up.
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 14 lines · Eric Dumazet
Quoted 4 lines · Andi Kleen
Quoted 2 lines
We simply can not compete with user space, as a programmer is free to keep what he really wants/needs.
Not true.
You can shake the kernel as much as you want, you wont make :
- a TCP socket
- a dentry
- an inode
- a file structure
- eventpoll structures (assuming epoll use)
- 2 dst per flow.
Quoted 5 lines
In 1024 bytes of memory, and keep an efficient kernel to handle arbitrary number of sockets using the venerable and slow BSD socket api.
I was objecting to the "crazy things like LWIP" comment from Josh, not to your patches in general.
My primary statement was that it's crazy to use something like LWIP just because you want a *tiny* system. We could argue about using LWIP because you want a massively scalable system, or one that more closely couples userspace and the kernel, but that's not the current goal in any case. So let's drop that branch of the thread. :)
Quoted 3 lines
I actually took a look at them but stopped at patch 22
Adding ~1000 lines of code to save few KB was the point I gave up.
Please consider ignoring that one and reading the rest; we could always handle the routing table issue separately.
- Josh Triplett
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Eric DumazetQuoted 2 lines
In 1024 bytes of memory, and keep an efficient kernel to handle arbitrary number of sockets using the venerable and slow BSD socket api.
I agree running in 1024 bytes would be challenging.
Quoted 1 line
Adding ~1000 lines of code to save few KB was the point I gave up.
You're refering to fib_list? It currently has some duplicated code (this could/should be fixed). Or we could drop it, I suppose, if really everyone hates it.
(I thought it was a cute idea, but I'm biased :-)
Total it is saving 350k, about 30% of the total text size of the mini kernel (plus some dynamic savings) with networking.
I would be happy to fix any reasonable objection. But fundamental "I don't care about anything smaller than my smart phone" type arguments are not particularly constructive.
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only
David Miller
maintainerRe: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Eric DumazetFrom: Eric Dumazet <[email protected]>
Date: Tue, 06 May 2014 13:17:58 -0700
Quoted 1 line
Adding ~1000 lines of code to save few KB was the point I gave up.
+1
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to Eric DumazetQuoted 14 lines · On Tue, 06 May 2014 13:17:58 -0700 Eric Dumazet <[email protected]> wrote:
Quoted 4 lines · Andi Kleen
Quoted 2 lines
We simply can not compete with user space, as a programmer is free to keep what he really wants/needs.
Not true.
You can shake the kernel as much as you want, you wont make :
- a TCP socket
- a dentry
- an inode
- a file structure
- eventpoll structures (assuming epoll use)
- 2 dst per flow.
Quoted 2 lines
In 1024 bytes of memory, and keep an efficient kernel to handle arbitrary number of sockets using the venerable and slow BSD socket api.
IoT devices don't care. Most embedded devices don't care. A lot of the current generation of proprietary non Linux very low end RTOS systems support *one socket*, some even use a wireless controller which has a proprietary mini tcp/ip and wifi stack that provices *one socket*
If you want Linux to run on the kind of low end 'single chip' systems or FPGA systems then you want to be able to run in very little memory. Network performance is usually near irrelevant. If its controlling a smart plug it doesn't need to do megabit encrypted streams or fast connect.
Alan
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
Quoted 11 lines · One Thousand Gnomes
IoT devices don't care. Most embedded devices don't care. A lot of the current generation of proprietary non Linux very low end RTOS systems support *one socket*, some even use a wireless controller which has a proprietary mini tcp/ip and wifi stack that provices *one socket*
If you want Linux to run on the kind of low end 'single chip' systems or FPGA systems then you want to be able to run in very little memory. Network performance is usually near irrelevant. If its controlling a smart plug it doesn't need to do megabit encrypted streams or fast connect.
This describes an industrial control system I've been working on for the last ten years or so. It runs one application, this application makes one single TCP connection to a server which then stays up forever. The server can send modified configuration to the application and the application sends periodic reports about what it is doing. We've replaced 9600 bps current loop with TCP, not for performance reasons but for convenience. We have no use for ethtool, no use for packet filters, no use for firewalling and don't care if a socket uses 100 bytes or 10kBytes of kernel memory since we only have one. There are probably lots of embedded systems that need those features, but there are also lots of systems that don't.
The first version of the hardware used a 2.4.26 kernel on an Axis ETRAX LX processor, now were using a 2.6.33 kernel on an Atmel ARM9 processor. We have a problem with the flash getting corrupted every now and then, and this seems to be fixed in the latest stable kernel
(3.10). There are about 2000 changes to drivers/mtd and so far we have
not been able to bisect this to find out where and why things started working.
So we'd like to upgrade but we are also starting to run short on flash and the 3.10 kernel is noticeably bigger with the same configuration. Switching from gzip to xz compression did give us back enough flash space to fit everything in, but it's still tight. So if we can save a couple of 100k of text size and get a slightly less performant or featureful TCP stack, that would be a very good tradeoff for us.
/Christer
Re: [PATCH 08/24] net, diet: Make TCP metrics optional
In reply to David MillerQuoted 9 lines · David Miller
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:57 -0700Quoted 3 lines
This is all the code that saves connection information between different sockets. Not really essential for small systems.
It is absolutely essential unless you want poor performance of TCP connections.
Sounds like "poor" performance of TCP and 400KB memory free is tradeoff that makes for small machines.
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
PATCH 9/24 net, diet: Make ethtool optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Small embedded systems don't need ethtool, so make it optional.
Right now the driver code is not removed, unless the driver uses SET_ETHTOOL_OPS and LTO (which can eliminate unused code)
Saves about 10k text(without driver code):
text data bss dec hex filename
489877 19371 13480 522728 7f9e8 net/built-in.o 478967 19369 13480 511816 7cf48 net/built-in.o-wo-ethtool
--- include/linux/ethtool.h | 14 ++++++++++++++ include/linux/netdevice.h | 21 ++++++++++++++++++--- net/Kconfig | 6 ++++++ net/core/Makefile | 3 ++- net/core/dev.c | 2 ++ 5 files changed, 42 insertions(+), 4 deletions(-)
include/linux/ethtool.h +14 -0
@@ -40,8 +40,14 @@ struct compat_ethtool_rxnfc {#include <linux/rculist.h> +#ifdef CONFIG_NET_ETHTOOL extern int __ethtool_get_settings (struct net_device *dev,struct ethtool_cmd *cmd); +#else +static inline int __ethtool_get_settings (struct net_device *dev, +struct ethtool_cmd *cmd) +{return -EINVAL ; } +#endif /** * enum ethtool_phys_id_state - indicator state for physical identification
@@ -61,9 +67,17 @@ enum ethtool_phys_id_state {struct net_device ; +#ifdef CONFIG_NET_ETHTOOL /* Some generic methods drivers may use in their ethtool_ops */ u32 ethtool_op_get_link (struct net_device *dev);int ethtool_op_get_ts_info (struct net_device *dev,struct ethtool_ts_info *eti); +#else +/* Some generic methods drivers may use in their ethtool_ops */ +static inline u32 ethtool_op_get_link (struct net_device *dev) {return 0 ; } +static inline int +ethtool_op_get_ts_info (struct net_device *dev,struct ethtool_ts_info *eti) +{return -EINVAL ; } +#endif /** * ethtool_rxfh_indir_default - get default value for RX flow hash indirection
include/linux/netdevice.h +18 -3
@@ -56,12 +56,28 @@ struct device;struct phy_device ;/* 802.11 specific */ struct wireless_dev ; -/* source back-compat hooks */ + +#ifdef CONFIG_NET_ETHTOOL + +/* When the driver uses this macro ethtool code can be optimized out +* when not needed. We still reference it to avoid unused static +* warnings. +*/ #define SET_ETHTOOL_OPS (netdev,ops) \ - ( (netdev)->ethtool_ops = (ops) ) + ( (void)(ops), (netdev)->ethtool_ops = (ops) )void netdev_set_default_ethtool_ops (struct net_device *dev,const struct ethtool_ops *ops); +int dev_ethtool (struct net *net,struct ifreq *); + +#else +#define SET_ETHTOOL_OPS (netdev,ops) do {} while(0) +static inline void +netdev_set_default_ethtool_ops (struct net_device *dev, +const struct ethtool_ops *ops) {} +static inline int +dev_ethtool (struct net *net,struct ifreq *ifr) {return -EINVAL ; } +#endif /* Backlog congestion levels */ #define NET_RX_SUCCESS 0/* keep 'em coming, baby */
@@ -2616,7 +2632,6 @@ void netdev_rx_handler_unregister(struct net_device *dev);bool dev_valid_name (const char *name);int dev_ioctl (struct net *net,unsigned int cmd,void __user *); -int dev_ethtool (struct net *net,struct ifreq *);unsigned int dev_get_flags (const struct net_device *);int __dev_change_flags (struct net_device *,unsigned int flags);int dev_change_flags (struct net_device *,unsigned int );
net/Kconfig +6 -0
@@ -82,6 +82,12 @@ source "net/netlabel/Kconfig" endif # if INET +config NET_ETHTOOL + bool "Ethtool support" + default y + help + Support changing ethernet driver parameters from user tools. + config NETWORK_SECMARK bool "Security Marking" help
net/core/Makefile +2 -1
@@ -7,12 +7,13 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o -obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \ +obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ sock_diag.o dev_ioctl.o obj-$(CONFIG_XFRM) += flow.o obj-y += net-sysfs.o +obj-$(CONFIG_NET_ETHTOOL) += ethtool.o obj-$(CONFIG_PROC_FS) += net-procfs.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o obj-$(CONFIG_NETPOLL) += netpoll.o
net/core/dev.c +2 -0
@@ -6310,6 +6310,7 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev)static const struct ethtool_ops default_ethtool_ops; +#ifdef CONFIG_NET_ETHTOOL void netdev_set_default_ethtool_ops (struct net_device *dev,const struct ethtool_ops *ops) {
@@ -6317,6 +6318,7 @@ void netdev_set_default_ethtool_ops(struct net_device *dev, dev->ethtool_ops = ops; }EXPORT_SYMBOL_GPL (netdev_set_default_ethtool_ops); +#endif void netdev_freemem (struct net_device *dev) {
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 09/24] net, diet: Make ethtool optional
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:58 -0700
Quoted 1 line
Small embedded systems don't need ethtool, so make it optional.
You can't do anything non-trivial with an ethernet device without ethtool.
I am not applying this.
Re: [PATCH 09/24] net, diet: Make ethtool optional
Quoted 7 lines · David Miller
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:58 -0700Quoted 1 line
Small embedded systems don't need ethtool, so make it optional.
You can't do anything non-trivial with an ethernet device without ethtool.
You can configure the IP address and transmit and receive packets, and that is all a small embedded system is ever interested in.
Remember these systems don't have a shell, they just run a single application that only does one thing.
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only.
David Miller
maintainerRe: [PATCH 09/24] net, diet: Make ethtool optional
From: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 05:14:12 +0200
Quoted 2 lines
You can configure the IP address and transmit and receive packets, and that is all a small embedded system is ever interested in.
Then let's agree to disagree, I am absolutely certain that small systems are interested in much more than just these simple configuration operations.
PATCH 10/24 net, diet: Make LPF filter optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Small systems don't need the LPF filter, so make it all optional
Saves about 4K text
text data bss dec hex filename
483545 19371 13480 516396 7e12c net/built-in.o-wo-filter 487675 19275 13480 520430 7f0ee net/built-in.o-with-filter
--- drivers/net/team/Kconfig | 1 + include/linux/filter.h | 28 +++++++++++++++++++++++++++- init/Kconfig | 7 +++++++ net/Kconfig | 8 ++++++++ net/core/Makefile | 3 ++- net/netfilter/Kconfig | 1 + net/sched/Kconfig | 1 + 7 files changed, 47 insertions(+), 2 deletions(-)
drivers/net/team/Kconfig +1 -0
@@ -64,6 +64,7 @@ config NET_TEAM_MODE_ACTIVEBACKUP config NET_TEAM_MODE_LOADBALANCE tristate "Load-balance mode support" + select LPF_FILTER depends on NET_TEAM ---help--- This mode provides load balancing functionality. Tx port selection
include/linux/filter.h +27 -1
@@ -97,9 +97,9 @@ static inline unsigned int sk_filter_size(unsigned int proglen)#define sk_filter_proglen (fprog) \ (fprog->len * sizeof(fprog->filter[0])) +#ifdef CONFIG_LPF_FILTER #define SK_RUN_FILTER (filter, ctx) \ (*filter->bpf_func)(ctx, filter->insnsi) -int sk_filter (struct sock *sk,struct sk_buff *skb); u32 sk_run_filter_int_seccomp(const struct seccomp_data *ctx,
@@ -124,6 +124,32 @@ void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to);void sk_filter_charge (struct sock *sk,struct sk_filter *fp);void sk_filter_uncharge (struct sock *sk,struct sk_filter *fp); +#else +#define SK_RUN_FILTER (filter, ctx) 0 +static inline int +sk_filter (struct sock *sk,struct sk_buff *skb) {return 0 ; } +static inline u32 sk_run_filter_int_seccomp (const struct seccomp_data *ctx, +const struct sock_filter_int *insni) +{return 0 ; } +static inline u32 sk_run_filter_int_skb (const struct sk_buff *ctx, +const struct sock_filter_int *insni) +{return 0 ; } +static inline int sk_unattached_filter_create (struct sk_filter **pfp, +struct sock_fprog *fprog) +{return -EINVAL ; } +static inline void sk_unattached_filter_destroy (struct sk_filter *fp) {} +static inline int sk_attach_filter (struct sock_fprog *fprog,struct sock *sk) +{return -EINVAL ; } +static inline int sk_detach_filter (struct sock *sk) {return -EINVAL ; } +static inline int sk_chk_filter (struct sock_filter *filter,unsigned int flen) +{return 0 ; } +static inline int sk_get_filter (struct sock *sk,struct sock_filter __user *filter,unsigned len) +{return -EINVAL ; } +static inline void +sk_decode_filter (struct sock_filter *filt,struct sock_filter *to) {} +static inline void sk_filter_charge (struct sock *sk,struct sk_filter *fp) {} +static inline void sk_filter_uncharge (struct sock *sk,struct sk_filter *fp) {} +#endif #ifdef CONFIG_BPF_JIT #include <stdarg.h>
init/Kconfig +7 -0
@@ -1885,4 +1885,11 @@ config ASN1 inform it as to what tags are to be expected in a stream and what functions to call on what tags. +# Automatically enable LPF_FILTER when any architecture sets SECCOMP +config SECCOMP_ENABLE_LPF + bool + depends on SECCOMP + default y + select LPF_FILTER + source "kernel/Kconfig.locks"
net/Kconfig +8 -0
@@ -88,6 +88,13 @@ config NET_ETHTOOL help Support changing ethernet driver parameters from user tools. +# XXX seccomp and other users should auto enable? +config LPF_FILTER + bool "LPF filter" + default y + help + Enable BPF/LPF (Linux Packet Filter) filtering on sockets. + config NETWORK_SECMARK bool "Security Marking" help
@@ -275,6 +282,7 @@ config BQL config BPF_JIT bool "enable BPF Just In Time compiler" depends on HAVE_BPF_JIT + depends on LPF_FILTER depends on MODULES ---help--- Berkeley Packet Filter filtering capabilities are normally handled
net/core/Makefile +2 -1
@@ -8,7 +8,7 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ - neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ + neighbour.o rtnetlink.o utils.o link_watch.o \ sock_diag.o dev_ioctl.o obj-$(CONFIG_XFRM) += flow.o
@@ -16,6 +16,7 @@ obj-y += net-sysfs.o obj-$(CONFIG_NET_ETHTOOL) += ethtool.o obj-$(CONFIG_PROC_FS) += net-procfs.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o +obj-$(CONFIG_LPF_FILTER) += filter.o obj-$(CONFIG_NETPOLL) += netpoll.o obj-$(CONFIG_NET_DMA) += user_dma.o obj-$(CONFIG_FIB_RULES) += fib_rules.o
net/netfilter/Kconfig +1 -0
@@ -921,6 +921,7 @@ config NETFILTER_XT_MATCH_ADDRTYPE config NETFILTER_XT_MATCH_BPF tristate '"bpf" match support' depends on NETFILTER_ADVANCED + select LPF_FILTER help BPF matching applies a linux socket filter to each packet and accepts those for which the filter returns non-zero.
net/sched/Kconfig +1 -0
@@ -469,6 +469,7 @@ config NET_CLS_CGROUP config NET_CLS_BPF tristate "BPF-based classifier" select NET_CLS + select LPF_FILTER ---help--- If you say Y here, you will be able to classify packets based on programmable BPF (JIT'ed) filters as an alternative to ematches.
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 10/24] net, diet: Make LPF filter optional
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:25:59 -0700
Quoted 5 lines
From: Andi Kleen <[email protected]>
Small systems don't need the LPF filter, so make it all optional
Quoted 7 lines
Saves about 4K text
text data bss dec hex filename
483545 19371 13480 516396 7e12c net/built-in.o-wo-filter 487675 19275 13480 520430 7f0ee net/built-in.o-with-filterSigned-off-by Andi Kleen <[email protected]>
I think you highly underestimate how much "small systems" use packet capturing and thus BPF.
PATCH 11/24 net, diet: Move rtnl_lock to separate file
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
rtnl_lock is used in a lot of places independently from rtnetlink. Move it to an own file.
Only ugly part is that the rtnetlink init still needs to access the mutex. do this through a private backdoor, to avoid putting it into the headers for everyone.
--- net/core/Makefile | 3 ++- net/core/rtnetlink.c | 42 ++---------------------------------------- net/core/rtnl_lock.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 41 deletions(-) create mode 100644 net/core/rtnl_lock.c
net/core/Makefile +2 -1
@@ -3,7 +3,8 @@ # obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ - gen_stats.o gen_estimator.o net_namespace.o secure_seq.o flow_dissector.o + gen_stats.o gen_estimator.o net_namespace.o secure_seq.o flow_dissector.o \ + rtnl_lock.o obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
net/core/rtnetlink.c +2 -40
54 lines not on this page · raw message
net/core/rtnl_lock.c new file +44 -0
44 lines not on this page · raw message
Signature · 1 line
1.9.0
PATCH 12/24 net, diet: Make rtnetlink optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Small systems can use ioctl/ifconfig for routing and interface configuration. Make rtnetlink optional This saves ~29k without LTO, more with LTO.
text data bss dec hex filename
483545 19371 13480 516396 7e12c net/built-in.o-with-rtnetlink 454365 19275 12936 486576 76cb0 net/built-in.o-wo-rtnetlink
--- include/linux/rtnetlink.h | 56 +++++++++++++++++++++++++++++++++++++++++------ include/net/rtnetlink.h | 35 +++++++++++++++++++++++++++++ net/Kconfig | 8 +++++++ net/core/Makefile | 3 ++- net/ipv4/fib_frontend.c | 7 ++++++ net/ipv4/fib_lookup.h | 12 ++++++++++ net/ipv4/fib_semantics.c | 4 ++++ 7 files changed, 117 insertions(+), 8 deletions(-)
include/linux/rtnetlink.h +49 -7
@@ -7,15 +7,32 @@#include <uapi/linux/rtnetlink.h> extern int rtnetlink_send (struct sk_buff *skb,struct net *net,u32 pid,u32 group,int echo); -extern int rtnl_unicast (struct sk_buff *skb,struct net *net,u32 pid); -extern void rtnl_notify (struct sk_buff *skb,struct net *net,u32 pid, -u32 group,struct nlmsghdr *nlh,gfp_t flags); -extern void rtnl_set_sk_err (struct net *net,u32 group,int error); -extern int rtnetlink_put_metrics (struct sk_buff *skb,u32 *metrics);extern int rtnl_put_cacheinfo (struct sk_buff *skb,struct dst_entry *dst,u32 id,long expires,u32 error); +#ifdef CONFIG_RTNETLINK +void rtnl_set_sk_err (struct net *net,u32 group,int error); +int rtnetlink_put_metrics (struct sk_buff *skb,u32 *metrics); +void rtnl_notify (struct sk_buff *skb,struct net *net,u32 pid, +u32 group,struct nlmsghdr *nlh,gfp_t flags);void rtmsg_ifinfo (int type,struct net_device *dev,unsigned change,gfp_t flags); +int rtnl_unicast (struct sk_buff *skb,struct net *net,u32 pid); +#else +static inline int rtnl_unicast (struct sk_buff *skb,struct net *net,u32 pid) +{return -EIO ; } + +static inline void +rtmsg_ifinfo (int type,struct net_device *dev,unsigned change,gfp_t flags) {} + +static inline void +rtnl_notify (struct sk_buff *skb,struct net *net,u32 pid, +u32 group,struct nlmsghdr *nlh,gfp_t flags) {} + +static inline int +rtnetlink_put_metrics (struct sk_buff *skb,u32 *metrics) {return -EINVAL ; } + +static inline void rtnl_set_sk_err (struct net *net,u32 group,int error) {} +#endif /* RTNL is used as a global lock for all changes to network configuration */ extern void rtnl_lock (void );
@@ -59,7 +76,12 @@ static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev)extern struct netdev_queue *dev_ingress_queue_create (struct net_device *dev); +#ifdef CONFIG_RTNETLINK extern void rtnetlink_init (void ); +#else +static inline void rtnetlink_init (void ) {} +#endif +extern void __rtnl_unlock (void );#define ASSERT_RTNL () do { \
@@ -70,6 +92,7 @@ extern void __rtnl_unlock(void); } \ } while(0) +#ifdef CONFIG_RTNETLINK extern int ndo_dflt_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *dev,
@@ -79,11 +102,30 @@ extern int ndo_dflt_fdb_add(struct ndmsg *ndm,struct net_device *dev, const unsigned char *addr, u16 flags); +extern int ndo_dflt_bridge_getlink (struct sk_buff *skb,u32 pid,u32 seq, +struct net_device *dev,u16 mode);extern int ndo_dflt_fdb_del (struct ndmsg *ndm,struct nlattr *tb[],struct net_device *dev,const unsigned char *addr); -extern int ndo_dflt_bridge_getlink (struct sk_buff *skb,u32 pid,u32 seq, -struct net_device *dev,u16 mode); +#else +static inline int ndo_dflt_fdb_dump (struct sk_buff *skb, +struct netlink_callback *cb, +struct net_device *dev, +int idx) {return -EINVAL ; } +static inline int ndo_dflt_fdb_add (struct ndmsg *ndm, +struct nlattr *tb[], +struct net_device *dev, +const unsigned char *addr, +u16 flags) {return -EINVAL ; } +static inline int ndo_dflt_bridge_getlink (struct sk_buff *skb,u32 pid,u32 seq, +struct net_device *dev,u16 mode) +{return -EINVAL ; } +static inline int ndo_dflt_fdb_del (struct ndmsg *ndm, +struct nlattr *tb[], +struct net_device *dev, +const unsigned char *addr) +{return -EINVAL ; } +#endif /* !CONFIG_RTNETLINK */ #endif /* __LINUX_RTNETLINK_H */
include/net/rtnetlink.h +35 -0
@@ -8,12 +8,23 @@ typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *);typedef int (*rtnl_dumpit_func )(struct sk_buff *,struct netlink_callback *);typedef u16 (*rtnl_calcit_func )(struct sk_buff *,struct nlmsghdr *); +#ifdef CONFIG_RTNETLINK int __rtnl_register (int protocol,int msgtype,rtnl_doit_func ,rtnl_dumpit_func ,rtnl_calcit_func );void rtnl_register (int protocol,int msgtype,rtnl_doit_func ,rtnl_dumpit_func ,rtnl_calcit_func );int rtnl_unregister (int protocol,int msgtype);void rtnl_unregister_all (int protocol); +#else +static inline int __rtnl_register (int protocol,int msgtype, +rtnl_doit_func d,rtnl_dumpit_func du,rtnl_calcit_func c) +{return -EINVAL ; } +static inline void rtnl_register (int protocol,int msgtype, +rtnl_doit_func d,rtnl_dumpit_func du,rtnl_calcit_func c) +{ } +static inline int rtnl_unregister (int protocol,int msgtype) {return 0 ; } +static inline void rtnl_unregister_all (int protocol) {} +#endif static inline int rtnl_msg_family (const struct nlmsghdr *nlh) {
@@ -95,11 +106,25 @@ struct rtnl_link_ops { const struct net_device *slave_dev); }; +#ifdef CONFIG_RTNETLINK int __rtnl_link_register (struct rtnl_link_ops *ops);void __rtnl_link_unregister (struct rtnl_link_ops *ops);int rtnl_link_register (struct rtnl_link_ops *ops);void rtnl_link_unregister (struct rtnl_link_ops *ops); +#else +/* Return 0 to make the respective init functions not error out. +* We assume the subsystems are still somewhat useful even without +* rtnetlink. +*/ +static inline int __rtnl_link_register (struct rtnl_link_ops *ops) +{return 0 ; } +static inline void __rtnl_link_unregister (struct rtnl_link_ops *ops) {} + +static inline int rtnl_link_register (struct rtnl_link_ops *ops) +{return 0 ; } +static inline void rtnl_link_unregister (struct rtnl_link_ops *ops) {} +#endif /** * struct rtnl_af_ops - rtnetlink address family operations
@@ -129,10 +154,20 @@ struct rtnl_af_ops { const struct nlattr *attr); }; +#ifdef CONFIG_RTNETLINK +int __rtnl_af_register (struct rtnl_af_ops *ops);void __rtnl_af_unregister (struct rtnl_af_ops *ops);void rtnl_af_register (struct rtnl_af_ops *ops);void rtnl_af_unregister (struct rtnl_af_ops *ops); +#else +static inline int __rtnl_af_register (struct rtnl_af_ops *ops) +{return -EINVAL ; } +static inline void __rtnl_af_unregister (struct rtnl_af_ops *ops) {} + +static inline int rtnl_af_register (struct rtnl_af_ops *ops) {return -EINVAL ; } +static inline void rtnl_af_unregister (struct rtnl_af_ops *ops) {} +#endif struct net *rtnl_link_get_net (struct net *src_net,struct nlattr *tb[]); struct net_device *rtnl_create_link(struct net *net, char *ifname,
net/Kconfig +8 -0
@@ -24,6 +24,14 @@ menuconfig NET if NET +config RTNETLINK + bool "rtnetlink" + default y + help + Enable rtnetlink to configure routing and related setups. + This is needed for most modern configuration + tools, but old ifconfig can do without it. + config WANT_COMPAT_NETLINK_MESSAGES bool help
net/core/Makefile +2 -1
@@ -9,11 +9,12 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ - neighbour.o rtnetlink.o utils.o link_watch.o \ + neighbour.o utils.o link_watch.o \ sock_diag.o dev_ioctl.o obj-$(CONFIG_XFRM) += flow.o obj-y += net-sysfs.o +obj-$(CONFIG_RTNETLINK) += rtnetlink.o obj-$(CONFIG_NET_ETHTOOL) += ethtool.o obj-$(CONFIG_PROC_FS) += net-procfs.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o
net/ipv4/fib_frontend.c +7 -0
@@ -917,6 +917,9 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)#undef BRD1_OK } +#ifdef CONFIG_RTNETLINK +/* Isn't really rtnetlink, but close enough for this CONFIG. */ +static void nl_fib_lookup (struct fib_result_nl *frn,struct fib_table *tb) {
@@ -994,6 +997,10 @@ static void nl_fib_lookup_exit(struct net *net)netlink_kernel_release (net->ipv4.fibnl); net->ipv4.fibnl = NULL; } +#else +static inline void nl_fib_lookup_exit (struct net *net) {} +static inline int nl_fib_lookup_init (struct net *net) {return 0 ; } +#endif static void fib_disable_ip (struct net_device *dev,int force) {
net/ipv4/fib_lookup.h +12 -0
@@ -27,11 +27,23 @@ static inline void fib_alias_accessed(struct fib_alias *fa)void fib_release_info (struct fib_info *);struct fib_info *fib_create_info (struct fib_config *cfg);int fib_nh_match (struct fib_config *cfg,struct fib_info *fi); +#ifdef CONFIG_RTNETLINK int fib_dump_info (struct sk_buff *skb,u32 pid,u32 seq,int event,u32 tb_id,u8 type,__be32 dst,int dst_len,u8 tos,struct fib_info *fi,unsigned int );void rtmsg_fib (int event,__be32 key,struct fib_alias *fa,int dst_len,u32 tb_id,const struct nl_info *info,unsigned int nlm_flags); +#else +static inline int fib_dump_info (struct sk_buff *skb,u32 pid,u32 seq, +int event,u32 tb_id, +u8 type,__be32 dst,int dst_len,u8 tos, +struct fib_info *fi, +unsigned int f) {return -EINVAL ; } +static inline void +rtmsg_fib (int event,__be32 key,struct fib_alias *fa,int dst_len, +u32 tb_id,const struct nl_info *info,unsigned int nlm_flags) +{} +#endif struct fib_alias *fib_find_alias (struct list_head *fah,u8 tos,u32 prio); static inline void fib_result_assign(struct fib_result *res,
net/ipv4/fib_semantics.c +4 -0
@@ -356,6 +356,7 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev)return -1 ; } +#ifdef CONFIG_RTNETLINK static inline size_t fib_nlmsg_size (struct fib_info *fi) {size_t payload =NLMSG_ALIGN (sizeof (struct rtmsg ))
@@ -411,6 +412,7 @@ errout:if (err <0 ) rtnl_set_sk_err(info->nl_net, RTNLGRP_IPV4_ROUTE, err); } +#endif /* Return the first fib alias matching TOS with * priority less than or equal to PRIO.
@@ -998,6 +1000,7 @@ failure:return ERR_PTR (err); } +#ifdef CONFIG_RTNETLINK int fib_dump_info (struct sk_buff *skb,u32 portid,u32 seq,int event,u32 tb_id,u8 type,__be32 dst,int dst_len,u8 tos,struct fib_info *fi,unsigned int flags)
@@ -1089,6 +1092,7 @@ nla_put_failure:nlmsg_cancel (skb, nlh); return -EMSGSIZE; } +#endif /* * Update FIB if:
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 12/24] net, diet: Make rtnetlink optional
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:01 -0700
Quoted 11 lines
From: Andi Kleen <[email protected]>
Small systems can use ioctl/ifconfig for routing and interface configuration. Make rtnetlink optional This saves ~29k without LTO, more with LTO.
text data bss dec hex filename
483545 19371 13480 516396 7e12c net/built-in.o-with-rtnetlink 454365 19275 12936 486576 76cb0 net/built-in.o-wo-rtnetlinkSigned-off-by Andi Kleen <[email protected]>
Andi, I've had about enough with this patch series.
We have moved several tools to only use netlink because it's the only extensible facility, and we are not looking back.
The moment one of these "small" systems, or whatever you want to call it, tries to use any feature added to device configuration in the last 20 years ioctl doesn't cut it.
Re: [PATCH 12/24] net, diet: Make rtnetlink optional
Quoted 3 lines
The moment one of these "small" systems, or whatever you want to call it, tries to use any feature added to device configuration in the last 20 years ioctl doesn't cut it.
They will simply not use all that complexity ever, 400k is simply prohibitive with 2MB.
If you want to keep netlink what would you remove instead?
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only.
PATCH 13/24 net, diet: Make GRO offload optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Make the GRO offload code optional. It's not needed on small systems. Since it's not a single file there are a couple of ifdefs.
Some code is still there (not ifdef'ed) but can be removed now with LTO.
Without LTO it gives about 3K.
text data bss dec hex filename
432712 18689 12616 464017 71491 net/built-in.o-with-offload 429737 17665 12616 460018 704f2 net/built-in.o-wo-offload
--- include/net/protocol.h | 10 ++++++++++ include/net/tcp.h | 5 +++++ net/ipv4/Kconfig | 4 ++++ net/ipv4/Makefile | 5 +++-- net/ipv4/af_inet.c | 9 +++++++++ net/ipv4/protocol.c | 8 +++++++- net/ipv6/Makefile | 5 +++-- net/ipv6/protocol.c | 2 ++ 8 files changed, 43 insertions(+), 5 deletions(-)
include/net/protocol.h +10 -0
@@ -103,8 +103,18 @@ extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS];int inet_add_protocol (const struct net_protocol *prot,unsigned char num);int inet_del_protocol (const struct net_protocol *prot,unsigned char num); +#ifdef CONFIG_IP_OFFLOAD int inet_add_offload (const struct net_offload *prot,unsigned char num);int inet_del_offload (const struct net_offload *prot,unsigned char num); +#else +static inline int +inet_add_offload (const struct net_offload *prot,unsigned char num) +{return 0 ; } +static inline int +inet_del_offload (const struct net_offload *prot,unsigned char num) +{return 0 ; } +#endif +void inet_register_protosw (struct inet_protosw *p);void inet_unregister_protosw (struct inet_protosw *p);
include/net/tcp.h +5 -0
@@ -1567,7 +1567,12 @@ void tcp_v4_destroy_sock(struct sock *sk);struct sk_buff *tcp_gso_segment (struct sk_buff *skb,netdev_features_t features);struct sk_buff **tcp_gro_receive (struct sk_buff **head,struct sk_buff *skb); +#ifdef CONFIG_IP_OFFLOAD int tcp_gro_complete (struct sk_buff *skb); +#else +/* For the benefit of one driver who really shouldn't be using this. */ +static inline int tcp_gro_complete (struct sk_buff *skb) {return -EIO ; } +#endif void __tcp_v4_send_check (struct sk_buff *skb,__be32 saddr,__be32 daddr);
net/ipv4/Kconfig +4 -0
@@ -306,6 +306,10 @@ config SYN_COOKIES If unsure, say N. +config IP_OFFLOAD + bool "Support for IP GRO/offload" + default y + config NET_IPVTI tristate "Virtual (secure) IP: tunneling" select INET_TUNNEL
net/ipv4/Makefile +3 -2
@@ -8,8 +8,8 @@ obj-y := route.o inetpeer.o protocol.o \ inet_timewait_sock.o inet_connection_sock.o \ tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ tcp_minisocks.o tcp_cong.o tcp_fastopen.o \ - tcp_offload.o datagram.o raw.o udp.o udplite.o \ - udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \ + datagram.o raw.o udp.o udplite.o \ + arp.o icmp.o devinet.o af_inet.o igmp.o \ fib_frontend.o fib_semantics.o fib_trie.o \ inet_fragment.o ip_tunnel_core.o gre_offload.o
@@ -26,6 +26,7 @@ obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o obj-$(CONFIG_NET_IPGRE) += ip_gre.o obj-$(CONFIG_NET_IPVTI) += ip_vti.o obj-$(CONFIG_SYN_COOKIES) += syncookies.o +obj-$(CONFIG_IP_OFFLOAD) += tcp_offload.o udp_offload.o obj-$(CONFIG_INET_AH) += ah4.o obj-$(CONFIG_INET_ESP) += esp4.o obj-$(CONFIG_INET_IPCOMP) += ipcomp.o
net/ipv4/af_inet.c +9 -0
@@ -1209,6 +1209,9 @@ int inet_sk_rebuild_header(struct sock *sk) }EXPORT_SYMBOL (inet_sk_rebuild_header); +#ifdef CONFIG_IP_OFFLOAD +/* Should move to a new file */ +static int inet_gso_send_check (struct sk_buff *skb) {const struct net_offload *ops;
@@ -1455,6 +1458,8 @@ out_unlock: return err; } +#endif +int inet_ctl_sock_create (struct sock **sk,unsigned short family,unsigned short type,unsigned char protocol,struct net *net)
@@ -1653,6 +1658,9 @@ static int __init init_ipv4_mibs(void)static int ipv4_proc_init (void ); +#ifdef CONFIG_IP_OFFLOAD +/* Move elsewhere? */ +/* * IP protocol layer initialiser */
@@ -1690,6 +1698,7 @@ static int __init ipv4_offload_init(void) }fs_initcall (ipv4_offload_init); +#endif static struct packet_type ip_packet_type__read_mostly = { .type =cpu_to_be16 (ETH_P_IP ),
net/ipv4/protocol.c +7 -1
@@ -29,7 +29,6 @@#include <net/protocol.h> const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS ]__read_mostly ; -const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS ]__read_mostly ;int inet_add_protocol (const struct net_protocol *prot,unsigned char protocol) {
@@ -44,6 +43,9 @@ int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) }EXPORT_SYMBOL (inet_add_protocol); +#ifdef CONFIG_IP_OFFLOAD +const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS ]__read_mostly ; +int inet_add_offload (const struct net_offload *prot,unsigned char protocol) { return !cmpxchg((const struct net_offload **)&inet_offloads[protocol],
@@ -51,6 +53,8 @@ int inet_add_offload(const struct net_offload *prot, unsigned char protocol) }EXPORT_SYMBOL (inet_add_offload); +#endif +int inet_del_protocol (const struct net_protocol *prot,unsigned char protocol) {int ret;
@@ -64,6 +68,7 @@ int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) }EXPORT_SYMBOL (inet_del_protocol); +#ifdef CONFIG_IP_OFFLOAD int inet_del_offload (const struct net_offload *prot,unsigned char protocol) {int ret;
@@ -76,3 +81,4 @@ int inet_del_offload(const struct net_offload *prot, unsigned char protocol) return ret; }EXPORT_SYMBOL (inet_del_offload); +#endif
net/ipv6/Makefile +3 -2
@@ -10,7 +10,8 @@ ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o -ipv6-offload := ip6_offload.o tcpv6_offload.o udp_offload.o exthdrs_offload.o +ipv6-offload-$(CONFIG_IP_OFFLOAD) := ip6_offload.o tcpv6_offload.o \ + udp_offload.o exthdrs_offload.o ipv6-$(CONFIG_SYSCTL) = sysctl_net_ipv6.o ipv6-$(CONFIG_IPV6_MROUTE) += ip6mr.o
@@ -43,6 +44,6 @@ obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o obj-$(CONFIG_IPV6_GRE) += ip6_gre.o obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o ip6_icmp.o -obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload) +obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload-y) obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
net/ipv6/protocol.c +2 -0
@@ -50,6 +50,7 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocolEXPORT_SYMBOL (inet6_del_protocol);#endif +#ifdef CONFIG_IP_OFFLOAD const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS ]__read_mostly ;int inet6_add_offload (const struct net_offload *prot,unsigned char protocol)
@@ -71,3 +72,4 @@ int inet6_del_offload(const struct net_offload *prot, unsigned char protocol) return ret; }EXPORT_SYMBOL (inet6_del_offload); +#endif
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 13/24] net, diet: Make GRO offload optional
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:02 -0700
Quoted 1 line
It's not needed on small systems.
On the contrary, I would expect the performance gains from batching the packet receive path to be even larger on slow small computers.
Re: [PATCH 13/24] net, diet: Make GRO offload optional
Quoted 8 lines · David Miller
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:02 -0700Quoted 1 line
It's not needed on small systems.
On the contrary, I would expect the performance gains from batching the packet receive path to be even larger on slow small computers.
Ok I will rephrase it. The issue is really only the text size.
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only.
PATCH 14/24 net, diet: Make MIB statistics collections depend on PROC_FS
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
When PROC_FS is not compiled in we don't need the statistics gathering code, as the only way to see the output is through /proc. Saves about 5k text, likely more in dynamic memory.
text data bss dec hex filename 386302 8993 12564 407859 63933 net/built-in.o-with-mib 381542 8933 12564 403039 6265f net/built-in.o-wo-mib
--- include/net/ip.h | 9 ++++++++ include/net/ipv6.h | 8 ++++++- include/net/snmp.h | 60 ++++++++++++++++++++++++++++++++++++++++-------- net/ipv4/af_inet.c | 12 ++++++++++ net/ipv6/addrconf.c | 9 ++++++++ net/ipv6/addrconf_core.c | 2 ++ net/ipv6/af_inet6.c | 5 ++++ 7 files changed, 95 insertions(+), 10 deletions(-)
include/net/ip.h +9 -0
@@ -196,6 +196,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,#define NET_ADD_STATS_BH (net, field, adnd) SNMP_ADD_STATS_BH((net)->mib.net_statistics, field, adnd)#define NET_ADD_STATS_USER (net, field, adnd) SNMP_ADD_STATS_USER((net)->mib.net_statistics, field, adnd) +#ifdef CONFIG_PROC_FS unsigned long snmp_fold_field (void __percpu *mib[],int offt);#if BITS_PER_LONG ==32 u64 snmp_fold_field64 (void __percpu *mib[],int offt,size_t sync_off);
@@ -217,6 +218,12 @@ static inline void snmp_mib_free(void __percpu *ptr[SNMP_ARRAY_SZ]) ptr[i] = NULL; } } +#else +#define snmp_mib_init (a,b,c) ({ 0; }) +#define snmp_mib_free (x) do {} while (0) +#define snmp_fold_field (a, b) ({ 0; }) +#define snmp_fold_field64 (a, b, c) ({ 0; }) +#endif void inet_get_local_port_range (struct net *net,int *low,int *high);
@@ -523,6 +530,8 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,#ifdef CONFIG_PROC_FS int ip_misc_proc_init (void ); +#else +static inline int ip_misc_proc_init (void ) {return 0 ; }#endif #endif /* _IP_H */
include/net/ipv6.h +7 -1
@@ -830,11 +830,17 @@ int udp6_proc_init(struct net *net);void udp6_proc_exit (struct net *net);int udplite6_proc_init (void );void udplite6_proc_exit (void ); +#ifdef CONFIG_PROC_FS int ipv6_misc_proc_init (void );void ipv6_misc_proc_exit (void );int snmp6_register_dev (struct inet6_dev *idev);int snmp6_unregister_dev (struct inet6_dev *idev); - +#else +static inline int ipv6_misc_proc_init (void ) {return 0 ; } +static inline void ipv6_misc_proc_exit (void ) {} +static inline int snmp6_register_dev (struct inet6_dev *idev) {return 0 ; } +static inline int snmp6_unregister_dev (struct inet6_dev *idev) {return 0 ; } +#endif #else static inline int ac6_proc_init (struct net *net) {return 0 ; }static inline void ac6_proc_exit (struct net *net) { }
include/net/snmp.h +51 -9
134 lines not on this page · raw message
net/ipv4/af_inet.c +12 -0
@@ -1482,6 +1482,8 @@ int inet_ctl_sock_create(struct sock **sk, unsigned short family, }EXPORT_SYMBOL_GPL (inet_ctl_sock_create); +#ifdef CONFIG_PROC_FS +unsigned long snmp_fold_field (void __percpu *mib[],int offt) {unsigned long res =0 ;
@@ -1541,6 +1543,8 @@ int snmp_mib_init(void __percpu *ptr[2], size_t mibsize, size_t align) }EXPORT_SYMBOL_GPL (snmp_mib_init); +#endif +#ifdef CONFIG_IP_MULTICAST static const struct net_protocol igmp_protocol = { .handler = igmp_rcv,
@@ -1572,6 +1576,7 @@ static const struct net_protocol icmp_protocol = { .netns_ok = 1, }; +#ifdef CONFIG_PROC_FS static __net_init int ipv4_mib_init_net (struct net *net) {int i;
@@ -1656,6 +1661,13 @@ static int __init init_ipv4_mibs(void) return register_pernet_subsys(&ipv4_mib_ops); } +#else +static int __init init_ipv4_mibs (void ) +{ +return 0 ; +} +#endif +static int ipv4_proc_init (void );#ifdef CONFIG_IP_OFFLOAD
net/ipv6/addrconf.c +9 -0
@@ -271,6 +271,7 @@ static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,mod_delayed_work (addrconf_wq, &ifp->dad_work, delay); } +#ifdef CONFIG_PROC_FS static int snmp6_alloc_dev (struct inet6_dev *idev) {int i;
@@ -309,6 +310,9 @@ err_icmp: err_ip: return -ENOMEM; } +#else +static int snmp6_alloc_dev (struct inet6_dev *idev) {return 0 ; } +#endif static struct inet6_dev *ipv6_add_dev (struct net_device *dev) {
@@ -4348,6 +4352,7 @@ static inline size_t inet6_if_nlmsg_size(void) +nla_total_size (inet6_ifla6_size ());/* IFLA_PROTINFO */ } +#ifdef CONFIG_PROC_FS static inline void __snmp6_fill_statsdev (u64 *stats,atomic_long_t *mib,int items,int bytes) {
@@ -4391,6 +4396,10 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, break; } } +#else +static void snmp6_fill_stats (u64 *stats,struct inet6_dev *idev,int attrtype, +int bytes) {} +#endif static int inet6_fill_ifla6_attrs (struct sk_buff *skb,struct inet6_dev *idev) {
net/ipv6/addrconf_core.c +2 -0
@@ -121,9 +121,11 @@ EXPORT_SYMBOL(in6addr_sitelocal_allrouters);static void snmp6_free_dev (struct inet6_dev *idev) { +#ifdef CONFIG_PROC_FS kfree (idev->stats.icmpv6msgdev);kfree (idev->stats.icmpv6dev);snmp_mib_free ((void __percpu **)idev->stats.ipv6); +#endif }/* Nobody refers to this device, we may destroy it. */
net/ipv6/af_inet6.c +5 -0
@@ -711,6 +711,7 @@ static void ipv6_packet_cleanup(void)dev_remove_pack (&ipv6_packet_type); } +#ifdef CONFIG_PROC_FS static int __net_init ipv6_init_mibs (struct net *net) {int i;
@@ -768,6 +769,10 @@ static void ipv6_cleanup_mibs(struct net *net)snmp_mib_free ((void __percpu **)net->mib.icmpv6_statistics); kfree(net->mib.icmpv6msg_statistics); } +#else +static inline int __net_init ipv6_init_mibs (struct net *net) {return 0 ; } +static inline void ipv6_cleanup_mibs (struct net *net) {} +#endif static int __net_init inet6_net_init (struct net *net) {
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 14/24] net, diet: Make MIB statistics collections depend on PROC_FS
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:03 -0700
Quoted 11 lines
From: Andi Kleen <[email protected]>
When
PROC_FSis not compiled in we don't need the statistics gathering code, as the only way to see the output is through /proc. Saves about 5k text, likely more in dynamic memory.text data bss dec hex filename 386302 8993 12564 407859 63933 net/built-in.o-with-mib 381542 8933 12564 403039 6265f net/built-in.o-wo-mibSigned-off-by Andi Kleen <[email protected]>
Congratulations, you just broke ipv6 device address netlink dumps amongst other things.
PATCH 15/24 net, diet: Make igmp and mcast ioctls depend on IP_MULTICAST
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
There was already a CONFIG_IP_MULTICAST, but it didn't control the multicasting code (like igmp) in the IP stack, only some driver code. Change this.
This disables some multi cast filters in TCP/UDP too, but that should be ok because we never joing multicast groups without this options, so the packets should never arrive up-stack.
Worth ~20k when disabled
text data bss dec hex filename
420363 17509 11624 449496 6dbd8 net/built-in.o-with-mcast 399649 17381 11624 428654 68a6e net/built-in.o-wo-mcast
--- include/linux/igmp.h | 31 +++++++++++++++++++++++-------- net/ipv4/Kconfig | 8 +++----- net/ipv4/Makefile | 3 ++- net/ipv4/devinet.c | 2 ++ net/ipv4/ip_sockglue.c | 4 ++++ net/ipv4/sysctl_net_ipv4.c | 2 ++ 6 files changed, 36 insertions(+), 14 deletions(-)
include/linux/igmp.h +23 -8
@@ -108,11 +108,7 @@ struct ip_mc_list {#define IGMPV3_QQIC (value) IGMPV3_EXP(0x80, 4, 3, value)#define IGMPV3_MRC (value) IGMPV3_EXP(0x80, 4, 3, value) -extern int ip_check_mc_rcu (struct in_device *dev,__be32 mc_addr,__be32 src_addr,u16 proto);extern int igmp_rcv (struct sk_buff *); -extern int ip_mc_join_group (struct sock *sk,struct ip_mreqn *imr); -extern int ip_mc_leave_group (struct sock *sk,struct ip_mreqn *imr); -extern void ip_mc_drop_socket (struct sock *sk);extern int ip_mc_source (int add,int omode,struct sock *sk,struct ip_mreq_source *mreqs,int ifindex);extern int ip_mc_msfilter (struct sock *sk,struct ip_msfilter *msf,int ifindex);
@@ -120,14 +116,33 @@ extern int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf, struct ip_msfilter __user *optval, int __user *optlen);extern int ip_mc_gsfget (struct sock *sk,struct group_filter *gsf,struct group_filter __user *optval,int __user *optlen); -extern int ip_mc_sf_allow (struct sock *sk,__be32 local,__be32 rmt,int dif); -extern void ip_mc_init_dev (struct in_device *); -extern void ip_mc_destroy_dev (struct in_device *); -extern void ip_mc_up (struct in_device *);extern void ip_mc_down (struct in_device *);extern void ip_mc_unmap (struct in_device *);extern void ip_mc_remap (struct in_device *);extern void ip_mc_dec_group (struct in_device *in_dev,__be32 addr);extern void ip_mc_inc_group (struct in_device *in_dev,__be32 addr); +#ifdef CONFIG_IP_MULTICAST +extern int ip_mc_sf_allow (struct sock *sk,__be32 local,__be32 rmt,int dif); +extern int ip_check_mc_rcu (struct in_device *dev,__be32 mc_addr,__be32 src_addr,u16 proto); +extern void ip_mc_up (struct in_device *); +extern void ip_mc_destroy_dev (struct in_device *); +extern void ip_mc_init_dev (struct in_device *); +extern void ip_mc_drop_socket (struct sock *sk); +extern int ip_mc_join_group (struct sock *sk,struct ip_mreqn *imr); +extern int ip_mc_leave_group (struct sock *sk,struct ip_mreqn *imr); +#else +static inline int ip_mc_sf_allow (struct sock *sk,__be32 local,__be32 rmt,int dif) +{return 0 ; } +static inline int ip_check_mc_rcu (struct in_device *dev,__be32 mc_addr,__be32 src_addr,u16 proto) +{return 0 ; } +static inline void ip_mc_up (struct in_device *d) {} +static inline void ip_mc_destroy_dev (struct in_device *d) {} +static inline void ip_mc_init_dev (struct in_device *d) {} +static inline void ip_mc_drop_socket (struct sock *sk) {} +static inline int ip_mc_join_group (struct sock *sk,struct ip_mreqn *imr) +{return -EINVAL ; } +static inline int ip_mc_leave_group (struct sock *sk,struct ip_mreqn *imr) +{return -EINVAL ; } +#endif #endif
net/ipv4/Kconfig +3 -5
@@ -5,11 +5,9 @@ config IP_MULTICAST bool "IP: multicasting" help This is code for addressing several networked computers at once, - enlarging your kernel by about 2 KB. You need multicasting if you - intend to participate in the MBONE, a high bandwidth network on top - of the Internet which carries audio and video broadcasts. More - information about the MBONE is on the WWW at - <http://www.savetz.com/mbone/>. For most people, it's safe to say N. + enlarging your kernel by about 20 KB. This is needed for many + modern networking services on the local network, so you should + probably say Y. config IP_ADVANCED_ROUTER bool "IP: advanced router"
net/ipv4/Makefile +2 -1
@@ -9,7 +9,7 @@ obj-y := route.o inetpeer.o protocol.o \ tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ tcp_minisocks.o tcp_cong.o tcp_fastopen.o \ datagram.o raw.o udp.o udplite.o \ - arp.o icmp.o devinet.o af_inet.o igmp.o \ + arp.o icmp.o devinet.o af_inet.o \ fib_frontend.o fib_semantics.o fib_trie.o \ inet_fragment.o ip_tunnel_core.o gre_offload.o
@@ -37,6 +37,7 @@ obj-$(CONFIG_INET_TUNNEL) += tunnel4.o obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o obj-$(CONFIG_IP_PNP) += ipconfig.o +obj-$(CONFIG_IP_MULTICAST) += igmp.o obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/ obj-$(CONFIG_INET_DIAG) += inet_diag.o obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
net/ipv4/devinet.c +2 -0
@@ -1402,6 +1402,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,/* Send gratuitous ARP to notify of link change */ inetdev_send_gratuitous_arp (dev, in_dev);break ; +#ifdef CONFIG_IP_MULTICAST case NETDEV_DOWN :ip_mc_down (in_dev);break ;
@@ -1411,6 +1412,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,case NETDEV_POST_TYPE_CHANGE :ip_mc_remap (in_dev);break ; +#endif case NETDEV_CHANGEMTU :if (inetdev_valid_mtu (dev->mtu))break ;
net/ipv4/ip_sockglue.c +4 -0
@@ -652,6 +652,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,if (!val)skb_queue_purge (&sk->sk_error_queue);break ; +#ifdef CONFIG_IP_MULTICAST case IP_MULTICAST_TTL :if (sk->sk_type ==SOCK_STREAM ) goto e_inval;
@@ -1010,6 +1011,7 @@ mc_msf_out: goto e_inval; inet->mc_all = val;break ; +#endif case IP_ROUTER_ALERT : err =ip_ra_control (sk, val ?1 :0 ,NULL );break ;
@@ -1248,6 +1250,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,case IP_RECVERR : val = inet->recverr;break ; +#ifdef CONFIG_IP_MULTICAST case IP_MULTICAST_TTL : val = inet->mc_ttl;break ;
@@ -1310,6 +1313,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,case IP_MULTICAST_ALL : val = inet->mc_all;break ; +#endif case IP_PKTOPTIONS : {struct msghdr msg;
net/ipv4/sysctl_net_ipv4.c +2 -0
@@ -443,6 +443,7 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_do_large_bitmap, }, +#ifdef CONFIG_IP_MULTICAST { .procname = "igmp_max_memberships", .data = &sysctl_igmp_max_memberships,
@@ -457,6 +458,7 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, +#endif { .procname = "inet_peer_threshold", .data = &inet_peer_threshold,
Signature · 1 line
1.9.0
PATCH 16/24 net, diet: Make TCP fastopen optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Make TCP fast open a config option. It's not really needed on small systems. By itself it saves about 3k text, but the main advantage is that CONFIG_INET doesn't pull in AES and the crypto subsystem anymore, which is worth far more savings.
text data bss dec hex filename
6954762 1404960 765952 9125674 8b3f2a vmlinux-with-fastopen
6951618 1400608 765952 9118178 8b21e2 vmlinux-wo-fastopen
--- include/linux/tcp.h | 14 ++++++++++++-- include/net/request_sock.h | 5 +++++ include/net/tcp.h | 9 +++++++++ net/Kconfig | 4 ++-- net/core/request_sock.c | 2 ++ net/ipv4/Kconfig | 4 ++++ net/ipv4/Makefile | 3 ++- net/ipv4/sysctl_net_ipv4.c | 4 ++++ net/ipv4/tcp.c | 4 ++++ net/ipv4/tcp_ipv4.c | 18 ++++++++++++++++++ 10 files changed, 62 insertions(+), 5 deletions(-)
include/linux/tcp.h +12 -2
@@ -359,6 +359,9 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk)return (struct tcp_timewait_sock *)sk; } +extern void tcp_sock_destruct (struct sock *sk); + +#ifdef CONFIG_TCP_FASTOPEN static inline bool tcp_passive_fastopen (const struct sock *sk) { return (sk->sk_state == TCP_SYN_RECV &&
@@ -370,8 +373,6 @@ static inline bool fastopen_cookie_present(struct tcp_fastopen_cookie *foc)return foc->len !=-1 ; } -extern void tcp_sock_destruct (struct sock *sk); -static inline int fastopen_init_queue (struct sock *sk,int backlog) { struct request_sock_queue *queue =
@@ -391,4 +392,13 @@ static inline int fastopen_init_queue(struct sock *sk, int backlog)return 0 ; } +#else +static inline bool tcp_passive_fastopen (const struct sock *sk) +{return false; } +static inline bool fastopen_cookie_present (struct tcp_fastopen_cookie *foc) +{return false; } +static inline int fastopen_init_queue (struct sock *sk,int backlog) +{return 0 ; } +#endif +#endif /* _LINUX_TCP_H */
include/net/request_sock.h +5 -0
@@ -168,8 +168,13 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,void __reqsk_queue_destroy (struct request_sock_queue *queue);void reqsk_queue_destroy (struct request_sock_queue *queue); +#ifdef CONFIG_TCP_FASTOPEN void reqsk_fastopen_remove (struct sock *sk,struct request_sock *req,bool reset); +#else +static inline void reqsk_fastopen_remove (struct sock *sk,struct request_sock *req, +bool reset) {} +#endif static inline struct request_sock *reqsk_queue_yank_acceptq (struct request_sock_queue *queue)
include/net/tcp.h +9 -0
@@ -251,7 +251,11 @@ extern int sysctl_tcp_retries1;extern int sysctl_tcp_retries2;extern int sysctl_tcp_orphan_retries;extern int sysctl_tcp_syncookies; +#ifdef CONFIG_TCP_FASTOPEN extern int sysctl_tcp_fastopen; +#else +#define sysctl_tcp_fastopen 0 +#endif extern int sysctl_tcp_retrans_collapse;extern int sysctl_tcp_stdurg;extern int sysctl_tcp_rfc1337;
@@ -1333,7 +1337,12 @@ struct tcp_fastopen_request {size_t size;int copied;/* queued in tcp_connect() */ }; + +#ifdef CONFIG_TCP_FASTOPEN void tcp_free_fastopen_req (struct tcp_sock *tp); +#else +static inline void tcp_free_fastopen_req (struct tcp_sock *tp) {} +#endif extern struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;int tcp_fastopen_reset_cipher (void *key,unsigned int len);
net/Kconfig +2 -2
@@ -61,8 +61,8 @@ source "net/iucv/Kconfig" config INET bool "TCP/IP networking" - select CRYPTO - select CRYPTO_AES + select CRYPTO if TCP_FASTOPEN + select CRYPTO_AES if TCP_FASTOPEN ---help--- These are the protocols used on the Internet and on most local Ethernets. It is highly recommended to say Y here (this will enlarge
net/core/request_sock.c +2 -0
@@ -131,6 +131,7 @@ void reqsk_queue_destroy(struct request_sock_queue *queue)kfree (lopt); } +#ifdef CONFIG_TCP_FASTOPEN /* * This function is called to set a Fast Open socket's "fastopen_rsk" field * to NULL when a TFO socket no longer needs to access the request_sock.
@@ -222,3 +223,4 @@ out:spin_unlock_bh (&fastopenq->lock); sock_put(lsk); } +#endif
net/ipv4/Kconfig +4 -0
@@ -320,6 +320,10 @@ config NET_IPVTI the notion of a secure tunnel for IPSEC and then use routing protocol on top. +config TCP_FASTOPEN + bool "Enable TCP fastopen" + default y + config INET_AH tristate "IP: AH transformation" select XFRM_ALGO
net/ipv4/Makefile +2 -1
@@ -7,7 +7,7 @@ obj-y := route.o inetpeer.o protocol.o \ ip_output.o ip_sockglue.o inet_hashtables.o \ inet_timewait_sock.o inet_connection_sock.o \ tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ - tcp_minisocks.o tcp_cong.o tcp_fastopen.o \ + tcp_minisocks.o tcp_cong.o \ datagram.o raw.o udp.o udplite.o \ arp.o icmp.o devinet.o af_inet.o \ fib_frontend.o fib_semantics.o fib_trie.o \
@@ -55,6 +55,7 @@ obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o +obj-$(CONFIG_TCP_FASTOPEN) += tcp_fastopen.o obj-$(CONFIG_MEMCG_KMEM) += tcp_memcontrol.o obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
net/ipv4/sysctl_net_ipv4.c +4 -0
@@ -200,6 +200,7 @@ static int proc_allowed_congestion_control(struct ctl_table *ctl,return ret; } +#ifdef CONFIG_TCP_FASTOPEN static int proc_tcp_fastopen_key (struct ctl_table *ctl,int write,void __user *buffer,size_t *lenp,loff_t *ppos)
@@ -246,6 +247,7 @@ bad_key:kfree (tbl.data);return ret; } +#endif static struct ctl_table ipv4_table[] = { {
@@ -388,6 +390,7 @@ static struct ctl_table ipv4_table[] = { .proc_handler = proc_dointvec },#endif +#ifdef CONFIG_TCP_FASTOPEN { .procname = "tcp_fastopen", .data = &sysctl_tcp_fastopen,
@@ -401,6 +404,7 @@ static struct ctl_table ipv4_table[] = { .maxlen = ((TCP_FASTOPEN_KEY_LENGTH * 2) + 10), .proc_handler = proc_tcp_fastopen_key, }, +#endif { .procname = "tcp_tw_recycle", .data = &tcp_death_row.sysctl_tw_recycle,
net/ipv4/tcp.c +4 -0
@@ -1036,6 +1036,7 @@ static inline int select_size(const struct sock *sk, bool sg)return tmp; } +#ifdef CONFIG_TCP_FASTOPEN void tcp_free_fastopen_req (struct tcp_sock *tp) {if (tp->fastopen_req !=NULL ) {
@@ -1069,6 +1070,7 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,tcp_free_fastopen_req (tp); return err; } +#endif int tcp_sendmsg (struct kiocb *iocb,struct sock *sk,struct msghdr *msg,size_t size)
@@ -1084,6 +1086,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,lock_sock (sk); flags = msg->msg_flags; +#ifdef CONFIG_TCP_FASTOPEN if (flags &MSG_FASTOPEN ) { err =tcp_sendmsg_fastopen (sk, msg, &copied_syn, size);if (err == -EINPROGRESS && copied_syn >0 )
@@ -1092,6 +1095,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out_err; offset = copied_syn; } +#endif timeo =sock_sndtimeo (sk, flags &MSG_DONTWAIT );
net/ipv4/tcp_ipv4.c +18 -0
@@ -1260,6 +1260,7 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { };#endif +#ifdef CONFIG_TCP_FASTOPEN static bool tcp_fastopen_check(struct sock *sk, struct sk_buff *skb, struct request_sock *req, struct tcp_fastopen_cookie *foc,
@@ -1440,6 +1441,23 @@ static int tcp_v4_conn_req_fastopen(struct sock *sk,WARN_ON (req->sk ==NULL ); return 0; } +#else +static bool tcp_fastopen_check (struct sock *sk,struct sk_buff *skb, +struct request_sock *req, +struct tcp_fastopen_cookie *foc, +struct tcp_fastopen_cookie *valid_foc) +{ +return false; +} + +static int tcp_v4_conn_req_fastopen (struct sock *sk, +struct sk_buff *skb, +struct sk_buff *skb_synack, +struct request_sock *req) +{ +return 0 ; +} +#endif int tcp_v4_conn_request (struct sock *sk,struct sk_buff *skb) {
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 16/24] net, diet: Make TCP fastopen optional
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:05 -0700
Quoted 2 lines
Make TCP fast open a config option. It's not really needed on small systems. By itself it saves about 3k text,
It's for the sake of the remote service not the local client, sorry I'm not applying this, it's a facility we want to be ubiquitous and in widespread use on as many systems as possible.
I'm not applying this, sorry.
PATCH 17/24 net, diet: Make internal control sockets use UDP
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Make the internal stack socket use UDP. This avoids a dependency to the soon optional RAW sockets.
Generally the users only use rudimential socket services, mostly for managing the socket buffer. This is the same for UDP and RAW.
Could in fact remove the arguments.
--- net/ipv4/icmp.c | 9 ++++++++- net/ipv6/af_inet6.c | 3 +++ net/ipv6/icmp.c | 2 +- net/ipv6/mcast.c | 2 +- net/ipv6/ndisc.c | 2 +- net/ipv6/tcp_ipv6.c | 2 +- 6 files changed, 15 insertions(+), 5 deletions(-)
net/ipv4/icmp.c +8 -1
@@ -1092,8 +1092,15 @@ static int __net_init icmp_sk_init(struct net *net)for_each_possible_cpu (i) {struct sock *sk; +/* +* Use UDP here. We only use rudimentary +* functionality of the socket, and UDP +* provides it for us. +* This avoids a dependency on the optional +* RAW sockets +*/ err =inet_ctl_sock_create (&sk,PF_INET , -SOCK_RAW ,IPPROTO_ICMP , net); +SOCK_DGRAM ,0 , net);if (err <0 ) goto fail;
net/ipv6/af_inet6.c +3 -0
@@ -854,6 +854,9 @@ static int __init inet6_init(void)if (err) goto out; +/* We MUST register UDP sockets before we create the ICMP6, +* IGMP6, or NDISC control sockets. +*/ err =proto_register (&udpv6_prot,1 );if (err) goto out_unregister_tcp_proto;
net/ipv6/icmp.c +1 -1
@@ -844,7 +844,7 @@ static int __net_init icmpv6_sk_init(struct net *net)for_each_possible_cpu (i) { err =inet_ctl_sock_create (&sk,PF_INET6 , -SOCK_RAW ,IPPROTO_ICMPV6 , net); +SOCK_DGRAM ,0 , net);if (err <0 ) {pr_err ("Failed to initialize the ICMP6 control socket (err %d)\n" , err);
net/ipv6/mcast.c +1 -1
@@ -2870,7 +2870,7 @@ static int __net_init igmp6_net_init(struct net *net)int err; err =inet_ctl_sock_create (&net->ipv6.igmp_sk,PF_INET6 , -SOCK_RAW ,IPPROTO_ICMPV6 , net); +SOCK_DGRAM ,0 , net);if (err <0 ) {pr_err ("Failed to initialize the IGMP6 control socket (err %d)\n" , err);
net/ipv6/ndisc.c +1 -1
@@ -1689,7 +1689,7 @@ static int __net_init ndisc_net_init(struct net *net)int err; err =inet_ctl_sock_create (&sk,PF_INET6 , -SOCK_RAW ,IPPROTO_ICMPV6 , net); +SOCK_DGRAM ,0 , net);if (err <0 ) { ND_PRINTK(0, err, "NDISC: Failed to initialize the control socket (err %d)\n",
net/ipv6/tcp_ipv6.c +1 -1
@@ -1989,7 +1989,7 @@ static struct inet_protosw tcpv6_protosw = {static int __net_init tcpv6_net_init (struct net *net) {return inet_ctl_sock_create (&net->ipv6.tcp_sk,PF_INET6 , -SOCK_RAW ,IPPROTO_TCP , net); +SOCK_DGRAM ,0 , net); } static void __net_exit tcpv6_net_exit(struct net *net)
Signature · 1 line
1.9.0
PATCH 18/24 net, diet: Make raw sockets optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Not really needed on small embedded systems. Saves about 5k text, more with IPv6.
--- include/net/ip.h | 5 +++++ include/net/ipv6.h | 5 +++++ include/net/raw.h | 15 +++++++++------ include/net/rawv6.h | 8 ++++++++ include/net/transp_v6.h | 5 +++++ net/ipv4/Kconfig | 5 +++++ net/ipv4/Makefile | 3 ++- net/ipv4/af_inet.c | 8 ++++++++ net/ipv4/ip_input.c | 2 ++ net/ipv4/proc.c | 2 ++ net/ipv6/Kconfig | 1 + net/ipv6/Makefile | 3 ++- net/ipv6/af_inet6.c | 4 ++++ net/ipv6/ip6_output.c | 4 ++++ net/ipv6/proc.c | 2 ++ 15 files changed, 64 insertions(+), 8 deletions(-)
include/net/ip.h +5 -0
@@ -445,7 +445,12 @@ static inline int sk_mc_loop(struct sock *sk)return 1 ; } +#ifdef CONFIG_INET_RAW bool ip_call_ra_chain (struct sk_buff *skb); +#else +static inline bool ip_call_ra_chain (struct sk_buff *skb) +{return false; } +#endif /* * Functions provided by ip_fragment.c
include/net/ipv6.h +5 -0
@@ -822,8 +822,13 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,#ifdef CONFIG_PROC_FS int ac6_proc_init (struct net *net);void ac6_proc_exit (struct net *net); +#ifdef CONFIG_INET_RAW int raw6_proc_init (void );void raw6_proc_exit (void ); +#else +static inline int raw6_proc_init (void ) {return 0 ; } +static inline void raw6_proc_exit (void ) {} +#endif int tcp6_proc_init (struct net *net);void tcp6_proc_exit (struct net *net);int udp6_proc_init (struct net *net);
include/net/raw.h +9 -6
@@ -23,8 +23,17 @@extern struct proto raw_prot; +#ifdef CONFIG_INET_RAW void raw_icmp_error (struct sk_buff *,int ,u32 );int raw_local_deliver (struct sk_buff *,int ); +int raw_proc_init (void ); +void raw_proc_exit (void ); +#else +static inline void raw_icmp_error (struct sk_buff *skb,int a,u32 b) {} +static inline int raw_local_deliver (struct sk_buff *skb,int s) {return 0 ; } +static inline int raw_proc_init (void ) {return 0 ; } +static inline void raw_proc_exit (void ) {} +#endif int raw_rcv (struct sock *,struct sk_buff *);
@@ -35,10 +44,6 @@ struct raw_hashinfo {struct hlist_head ht[RAW_HTABLE_SIZE ]; }; -#ifdef CONFIG_PROC_FS -int raw_proc_init(void); -void raw_proc_exit(void); -struct raw_iter_state {struct seq_net_private p;int bucket;
@@ -55,8 +60,6 @@ void raw_seq_stop(struct seq_file *seq, void *v);int raw_seq_open (struct inode *ino,struct file *file,struct raw_hashinfo *h,const struct seq_operations *ops); -#endif -void raw_hash_sk (struct sock *sk);void raw_unhash_sk (struct sock *sk);
include/net/rawv6.h +8 -0
@@ -3,9 +3,17 @@#include <net/protocol.h> + +#ifdef CONFIG_INET_RAW void raw6_icmp_error (struct sk_buff *,int nexthdr,u8 type,u8 code,int inner_offset,__be32 );bool raw6_local_deliver (struct sk_buff *,int ); +#else +static inline void raw6_icmp_error (struct sk_buff *skb,int nexthdr, +u8 type,u8 code,int inner_offset,__be32 x) {} +static inline bool raw6_local_deliver (struct sk_buff *skb,int x) +{return false; } +#endif int rawv6_rcv (struct sock *sk,struct sk_buff *skb);
include/net/transp_v6.h +5 -0
@@ -19,8 +19,13 @@ int ipv6_frag_init(void);void ipv6_frag_exit (void );/* transport protocols */ +#ifdef CONFIG_INET_RAW int rawv6_init (void );void rawv6_exit (void ); +#else +static inline int rawv6_init (void ) {return 0 ; } +static inline void rawv6_exit (void ) {} +#endif int udpv6_init (void );void udpv6_exit (void );int udplitev6_init (void );
net/ipv4/Kconfig +5 -0
@@ -62,6 +62,10 @@ config IP_FIB_TRIE_STATS Keep track of statistics on structure of FIB TRIE table. Useful for testing and measuring TRIE performance. +config INET_RAW + bool "IP: Support raw sockets" + default y + config IP_MULTIPLE_TABLES bool "IP: policy routing" depends on IP_ADVANCED_ROUTER
@@ -218,6 +222,7 @@ config NET_IPGRE_BROADCAST config IP_MROUTE bool "IP: multicast routing" depends on IP_MULTICAST + select INET_RAW help This is used if you want your machine to act as a router for IP packets that have several destination addresses. It is needed on the
net/ipv4/Makefile +2 -1
@@ -8,7 +8,7 @@ obj-y := route.o inetpeer.o protocol.o \ inet_timewait_sock.o inet_connection_sock.o \ tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ tcp_minisocks.o tcp_cong.o \ - datagram.o raw.o udp.o udplite.o \ + datagram.o udp.o udplite.o \ arp.o icmp.o devinet.o af_inet.o \ fib_frontend.o fib_semantics.o fib_trie.o \ inet_fragment.o ip_tunnel_core.o gre_offload.o
@@ -58,6 +58,7 @@ obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o obj-$(CONFIG_TCP_FASTOPEN) += tcp_fastopen.o obj-$(CONFIG_MEMCG_KMEM) += tcp_memcontrol.o obj-$(CONFIG_NETLABEL) += cipso_ipv4.o +obj-$(CONFIG_INET_RAW) += raw.o obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \ xfrm4_output.o xfrm4_protocol.o
net/ipv4/af_inet.c +8 -0
@@ -956,6 +956,7 @@ const struct proto_ops inet_dgram_ops = { };EXPORT_SYMBOL (inet_dgram_ops); +#ifdef CONFIG_INET_RAW /* * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without * udp_poll
@@ -985,6 +986,7 @@ static const struct proto_ops inet_sockraw_ops = { .compat_ioctl = inet_compat_ioctl, #endif }; +#endif static const struct net_proto_family inet_family_ops = { .family = PF_INET,
@@ -1026,6 +1028,7 @@ static struct inet_protosw inetsw_array[] = },#endif +#ifdef CONFIG_INET_RAW { .type = SOCK_RAW, .protocol = IPPROTO_IP, /* wild card */
@@ -1034,6 +1037,7 @@ static struct inet_protosw inetsw_array[] = .no_check = UDP_CSUM_DEFAULT, .flags = INET_PROTOSW_REUSE, } +#endif };#define INETSW_ARRAY_LEN ARRAY_SIZE(inetsw_array)
@@ -1737,9 +1741,11 @@ static int __init inet_init(void)if (rc) goto out_unregister_tcp_proto; +#ifdef CONFIG_INET_RAW rc =proto_register (&raw_prot,1 );if (rc) goto out_unregister_udp_proto; +#endif #ifdef CONFIG_IP_PING rc =proto_register (&ping_prot,1 );
@@ -1835,8 +1841,10 @@ static int __init inet_init(void) out:return rc; out_unregister_raw_proto: +#ifdef CONFIG_INET_RAW proto_unregister (&raw_prot); out_unregister_udp_proto: +#endif proto_unregister (&udp_prot); out_unregister_tcp_proto:proto_unregister (&tcp_prot);
net/ipv4/ip_input.c +2 -0
@@ -147,6 +147,7 @@#include <linux/mroute.h> #include <linux/netlink.h> +#ifdef CONFIG_INET_RAW /* * Process Router Attention IP option (RFC 2113) */
@@ -186,6 +187,7 @@ bool ip_call_ra_chain(struct sk_buff *skb) }return false; } +#endif static int ip_local_deliver_finish (struct sk_buff *skb) {
net/ipv4/proc.c +2 -0
@@ -69,8 +69,10 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) proto_memory_allocated(&udp_prot));seq_printf (seq,"UDPLITE: inuse %d\n" ,sock_prot_inuse_get (net, &udplite_prot)); +#ifdef CONFIG_INET_RAW seq_printf (seq,"RAW: inuse %d\n" ,sock_prot_inuse_get (net, &raw_prot)); +#endif seq_printf (seq,"FRAG: inuse %d memory %d\n" ,ip_frag_nqueues (net),ip_frag_mem (net));return 0 ;
net/ipv6/Kconfig +1 -0
@@ -88,6 +88,7 @@ config INET6_IPCOMP config IPV6_MIP6 tristate "IPv6: Mobility" select XFRM + select INET_RAW ---help--- Support for IPv6 Mobility described in RFC 3775.
net/ipv6/Makefile +2 -1
@@ -7,13 +7,14 @@ obj-$(CONFIG_IPV6) += ipv6.o ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ addrlabel.o \ route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \ - raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ + icmp.o mcast.o reassembly.o tcp_ipv6.o \ exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o ipv6-offload-$(CONFIG_IP_OFFLOAD) := ip6_offload.o tcpv6_offload.o \ udp_offload.o exthdrs_offload.o ipv6-$(CONFIG_SYSCTL) = sysctl_net_ipv6.o +ipv6-$(CONFIG_INET_RAW) += raw.o ipv6-$(CONFIG_IPV6_MROUTE) += ip6mr.o ipv6-$(CONFIG_IP_PING) += ping.o
net/ipv6/af_inet6.c +4 -0
@@ -865,9 +865,11 @@ static int __init inet6_init(void)if (err) goto out_unregister_udp_proto; +#ifdef CONFIG_INET_RAW err =proto_register (&rawv6_prot,1 );if (err) goto out_unregister_udplite_proto; +#endif #ifdef CONFIG_IP_PING err =proto_register (&pingv6_prot,1 );
@@ -1036,8 +1038,10 @@ out_unregister_ping_proto:proto_unregister (&pingv6_prot); out_unregister_raw_proto:#endif +#ifdef CONFIG_INET_RAW proto_unregister (&rawv6_prot); out_unregister_udplite_proto: +#endif proto_unregister (&udplitev6_prot); out_unregister_udp_proto:proto_unregister (&udpv6_prot);
net/ipv6/ip6_output.c +4 -0
@@ -235,6 +235,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,EXPORT_SYMBOL (ip6_xmit); +#ifdef CONFIG_INET_RAW static int ip6_call_ra_chain (struct sk_buff *skb,int sel) {struct ip6_ra_chain *ra;
@@ -263,6 +264,7 @@ static int ip6_call_ra_chain(struct sk_buff *skb, int sel)read_unlock (&ip6_ra_lock); return 0; } +#endif static int ip6_forward_proxy_check (struct sk_buff *skb) {
@@ -394,10 +396,12 @@ int ip6_forward(struct sk_buff *skb)* cannot be fragmented, because there is no warranty * that different fragments will go along one path. --ANK */ +#ifdef CONFIG_INET_RAW if (unlikely (opt->flags &IP6SKB_ROUTERALERT )) {if (ip6_call_ra_chain (skb,ntohs (opt->ra)))return 0 ; } +#endif /* * check and decrement ttl
net/ipv6/proc.c +2 -0
@@ -40,8 +40,10 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v) sock_prot_inuse_get(net, &udpv6_prot));seq_printf (seq,"UDPLITE6: inuse %d\n" ,sock_prot_inuse_get (net, &udplitev6_prot)); +#ifdef CONFIG_INET_RAW seq_printf (seq,"RAW6: inuse %d\n" ,sock_prot_inuse_get (net, &rawv6_prot)); +#endif seq_printf (seq,"FRAG6: inuse %d memory %d\n" ,ip6_frag_nqueues (net),ip6_frag_mem (net));return 0 ;
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 18/24] net, diet: Make raw sockets optional
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:07 -0700
Quoted 2 lines
Not really needed on small embedded systems. Saves about 5k text, more with IPv6.
Sorry, you can't have half a functioning ipv4 stack.
I'm not applying this.
PATCH 19/24 net, diet: Make RPS configurable
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Multiple receive queues are not needed on small systems, so allow disabling them.
This is already disabled with !SMP, but it also makes sense to disable on very small SMP systems (like dual core SOC)
Can be worth ~30k code and 6k data
text data bss dec hex filename
6923914 1398176 634880 8956970 88ac2a vmlinux-with-rps
6893698 1392544 634880 8921122 882022 vmlinux-wo-rps
--- net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/Kconfig +1 -1
@@ -248,7 +248,7 @@ source "net/mpls/Kconfig" source "net/hsr/Kconfig" config RPS - boolean + bool "Support multiqueue input queues (RPS)" depends on SMP && SYSFS default y
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 19/24] net, diet: Make RPS configurable
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:08 -0700
Quoted 2 lines
Multiple receive queues are not needed on small systems, so allow disabling them.
It's only enabled with SMP...
I'm really totally, and completely, convinced that you wrote this entire patch series with your brain turned off.
I'm not applying any patch in this series Andi, come back when you have something specific and small and reasonable to discuss, rather than this huge patch bomb of total and complete crap.
Re: [PATCH 19/24] net, diet: Make RPS configurable
Quoted 7 lines · David Miller
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:08 -0700Quoted 2 lines
Multiple receive queues are not needed on small systems, so allow disabling them.
It's only enabled with SMP...
You didn't read the whole description, did you?
-Andi
Re: [PATCH 19/24] net, diet: Make RPS configurable
In reply to Andi KleenQuoted 8 lines · Andi Kleen
From: Andi Kleen <[email protected]>
Multiple receive queues are not needed on small systems, so allow disabling them.
This is already disabled with !SMP, but it also makes sense to disable on very small SMP systems (like dual core SOC)
Such a pointless design still doesn't mean that you *have* to enable SMP, does it? How much would you save all over the kernel by simply disabling SMP?
As for the system design: It seems to me that it would be more useful to replace one of the CPU cores with some RAM...
Bjørn
PATCH 20/24 net, diet: Make XPS configurable
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Not needed on small systems. Already disabled with !SMP, but also makes sense to explicitely disabled on very small multi-core SOCKs.
Saves ~6k text, but increases the data segment by a mysterious ~4k (some padding?)
text data bss dec hex filename
6893698 1392544 634880 8921122 882022 vmlinux-with-xps
6887542 1396544 634880 8918966 8817b6 vmlinux-wo-xps
--- net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/Kconfig +1 -1
@@ -259,7 +259,7 @@ config RFS_ACCEL default y config XPS - boolean + bool "Support multiqueue transmit queues (XPS)" depends on SMP default y
Signature · 1 line
1.9.0
PATCH 21/24 net, diet: Make packet tpacket/mmap/fanout/rings optional
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Many DHCP clients need basic packet sockets, but they don't need the fancy zero copy packet capture code, like tpacket, mmap, rings, fanouts. This is quite substantial code, so it's worthwhile to make it optional
Worth nearly 10k code.
text data bss dec hex filename
952827 71874 25352 1050053 1005c5 net/built-in.o-with-packet-mmap 943211 71810 25352 1040373 fdff5 net/built-in.o-wo-packet-mmap
--- net/packet/Kconfig | 8 +++++ net/packet/af_packet.c | 82 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 15 deletions(-)
net/packet/Kconfig +8 -0
@@ -22,3 +22,11 @@ config PACKET_DIAG ---help--- Support for PF_PACKET sockets monitoring interface used by the ss tool. If unsure, say Y. + +config PACKET_MMAP + bool "Enable packet mmap/ring support" + depends on PACKET + default y + ---help--- + Enable support to mmap the packet data zero copy. This is useful for + highspeed packet interceptors.
net/packet/af_packet.c +67 -15
214 lines not on this page · raw message
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 21/24] net, diet: Make packet tpacket/mmap/fanout/rings optional
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:10 -0700
Quoted 7 lines
From: Andi Kleen <[email protected]>
Many DHCP clients need basic packet sockets, but they don't need the fancy zero copy packet capture code, like tpacket, mmap, rings, fanouts. This is quite substantial code, so it's worthwhile to make it optional
Quoted 7 lines
Worth nearly 10k code.
text data bss dec hex filename
952827 71874 25352 1050053 1005c5 net/built-in.o-with-packet-mmap 943211 71810 25352 1040373 fdff5 net/built-in.o-wo-packet-mmapSigned-off-by Andi Kleen <[email protected]>
Sorry, I'm not applying this either.
Small systems use packet generation and reception tools commonly, and the only sane way to do so is with tpacket.
PATCH 22/24 net, diet: Support simpler routing table
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Add an optional fib_list that uses a simple list to store routes. This is suitable for single homed client system which typically have only a handful of routes.
The new file is a complete 1:1 replacement for fib_trie and implements the same API for other files.
The code still uses RCU, so should have similar multi-core scalability, as long as the number of routes is small. It also has
all the functionality of the fib_trie, so can be used
with advanced routing (except for a few missing proc files)
The code started as a copy of fib_trie, with all the trie code replaced with a simple list. There's some very similar code with trie that could be factored out in a common file.
Worth about 8.5k of code. In addition it uses kmalloc instead of explicit slabs, which gives better memory efficiency for very small routing table (all data <4K, so sharing with other kmalloc users is possible)
text data bss dec hex filename
943211 71810 25352 1040373 fdff5 net/built-in.o-fib-list 951716 72066 25352 1049134 10022e net/built-in.o-fib-trie
XXX experimential, needs more testing, review
--- net/ipv4/Kconfig | 18 +- net/ipv4/Makefile | 4 +- net/ipv4/fib_list.c | 985 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1005 insertions(+), 2 deletions(-) create mode 100644 net/ipv4/fib_list.c
net/ipv4/Kconfig +17 -1
@@ -55,9 +55,25 @@ config IP_PING ---help--- Enable ping sockets to enable suid-less ping. +config FIB_TRIE + bool "Use trie based routing table" + default y + ---help--- + This is an advanced routing table implementation that scales to a larger + number of routes. When in doubt say y. + +config FIB_LIST + bool + default y + depends on !FIB_TRIE + ---help--- + This is a very simple linear routing table implementation that is only + suitable for clients with a very small number of routes (<10). The only + advantage over FIB_TRIE is smaller code size. + config IP_FIB_TRIE_STATS bool "FIB TRIE statistics" - depends on IP_ADVANCED_ROUTER + depends on IP_ADVANCED_ROUTER && FIB_TRIE ---help--- Keep track of statistics on structure of FIB TRIE table. Useful for testing and measuring TRIE performance.
net/ipv4/Makefile +3 -1
@@ -10,9 +10,11 @@ obj-y := route.o inetpeer.o protocol.o \ tcp_minisocks.o tcp_cong.o \ datagram.o udp.o udplite.o \ arp.o icmp.o devinet.o af_inet.o \ - fib_frontend.o fib_semantics.o fib_trie.o \ + fib_frontend.o fib_semantics.o \ inet_fragment.o ip_tunnel_core.o gre_offload.o +obj-$(CONFIG_FIB_TRIE) += fib_trie.o +obj-$(CONFIG_FIB_LIST) += fib_list.o obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o obj-$(CONFIG_IP_PING) += ping.o obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
net/ipv4/fib_list.c new file +985 -0
985 lines not on this page · raw message
Signature · 1 line
1.9.0
David Miller
maintainerRe: [PATCH 22/24] net, diet: Support simpler routing table
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:11 -0700
Quoted 3 lines
Add an optional
fib_listthat uses a simple list to store routes. This is suitable for single homed client system which typically have only a handful of routes.
Sorry I'm not applying this.
We had two routing table implementations for some time and it sucked, it meant two code paths and two places for bugs to hide.
I want only one data structure which does the job well, and we have that now.
Re: [PATCH 22/24] net, diet: Support simpler routing table
Quoted 11 lines · David Miller
From: Andi Kleen <[email protected]>
Date: Mon, 5 May 2014 15:26:11 -0700Quoted 3 lines
Add an optional
fib_listthat uses a simple list to store routes. This is suitable for single homed client system which typically have only a handful of routes.Sorry I'm not applying this.
We had two routing table implementations for some time and it sucked, it meant two code paths and two places for bugs to hide.
FWIW it seems to me the trie code is very stable, there doesn't seem to be any big changes in a long time.
Quoted 3 lines
I want only one data structure which does the job well, and we have that now.
I don't see any good way to slim the trie code down. Do you?
It's just inherently complex. Yes on many systems it's a good thing, and the complexity is justified,
but on the tiny systems the bloat and code size just hurts.
If we can't get the bloat down these users will just desert us to lwip ...
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only.
David Miller
maintainerRe: [PATCH 22/24] net, diet: Support simpler routing table
From: Andi Kleen <[email protected]>
Date: Tue, 6 May 2014 05:08:33 +0200
Quoted 2 lines
FWIW it seems to me the trie code is very stable, there doesn't seem to be any big changes in a long time.
But it was BUGGY AS HELL in the corner cases because it wasn't the default while it sat next to fib_hash.
It only got totally fixed when it was the ONLY option.
That's exactly my point, parts of it never got tested and were never verified because debugging resources for it was split with another implementation.
PATCH 23/24 net, diet: Add coccinelle script to convert drivers to ETHTOOL_OPS
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Useful to remove unneeded driver code when ethtool is disabled.
The patches doing this are submitted too, but let's add the script too so people can re-use it.
--- scripts/coccinelle/api/ethtool_ops.cocci | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 scripts/coccinelle/api/ethtool_ops.cocci
scripts/coccinelle/api/ethtool_ops.cocci new file +9 -0
@@ -0,0 +1,9 @@ +// Convert network drivers to use the SET_ETHTOOL_OPS macro +// This allows to compile out the ethtool code when not needed. +// +@@ +struct ethtool_ops *ops; +struct net_device *dev; +@@ +- dev->ethtool_ops = ops; ++ SET_ETHTOOL_OPS(dev, ops);
Signature · 1 line
1.9.0
Nicolas Palix
maintainerRe: [PATCH 23/24] net, diet: Add coccinelle script to convert drivers to ETHTOOL_OPS
Hi David,
I saw you rejected almost the entire patch series.
However, is there any interest to enforce the use of SET_ETHTOOL_OPS ? Are you likely to merge the patch 24/24 [1] ?
Regards,
[1] https://lkml.org/lkml/2014/5/5/679
Quoted 34 lines · Andi Kleen
From: Andi Kleen <[email protected]>
Useful to remove unneeded driver code when ethtool is disabled.
The patches doing this are submitted too, but let's add the script too so people can re-use it.
Cc Julia Lawall <[email protected]>Cc Gilles Muller <[email protected]>Cc Nicolas Palix <[email protected]>Signed-off-by Andi Kleen <[email protected]>--- scripts/coccinelle/api/ethtool_ops.cocci | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 scripts/coccinelle/api/ethtool_ops.cocciscripts/coccinelle/api/ethtool_ops.cocci new file +9
-1@@ -0,0 +1,9 @@ +// Convert network drivers to use the SET_ETHTOOL_OPS macro +// This allows to compile out the ethtool code when not needed. +// +@@ +struct ethtool_ops *ops; +struct net_device *dev; +@@ +- dev->ethtool_ops = ops; ++ SET_ETHTOOL_OPS(dev, ops); --1.9.0
Signature · 3 lines
Nicolas Palix Tel: +33 4 76 51 46 27 http://lig-membres.imag.fr/palix/
David Miller
maintainerRe: [PATCH 23/24] net, diet: Add coccinelle script to convert drivers to ETHTOOL_OPS
From: Nicolas Palix <[email protected]>
Date: Tue, 6 May 2014 11:27:27 +0200
Quoted 4 lines
I saw you rejected almost the entire patch series.
However, is there any interest to enforce the use of
SET_ETHTOOL_OPS? Are you likely to merge the patch 24/24 [1] ?
SET_ETHTOOL_OPS only exists so that drivers could be compiled on "older" kernels.
But the usefulness of that is long gone, we've had netdev->ethtool_ops since way before we started using GIT.
I'd rather see a patch which removes it, to be honest.
Re: [PATCH 23/24] net, diet: Add coccinelle script to convert drivers to ETHTOOL_OPS
Am Tue, May 06, 2014 at 11:05:04AM -0400 schrieb David Miller:
Quoted 7 lines
SET_ETHTOOL_OPSonly exists so that drivers could be compiled on "older" kernels.But the usefulness of that is long gone, we've had
netdev->ethtool_opssince way before we started using GIT.I'd rather see a patch which removes it, to be honest.
Something like this?
https://www.lebenslange-mailadresse.de/lkml/remove-SET_ETHTOOL_OPS.patch
PATCH 24/24 net, diet: Convert all drivers to use SET_ETHTOOL_OPS
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Convert all drivers to use SET_ETHTOOL_OPS. This allows the compiler to throw the code away when CONFIG_ETHTOOL is disabled, saving text size
This is a purely mechanic patch, done with the following coccinelle script (also available in scripts/coccinelle/api/ethtool_ops.cocci)
// Convert network drivers to use the SET_ETHTOOL_OPS macro // This allows to compile out the ethtool code when not needed. //
@@
struct ethtool_ops *ops;
struct net_device *dev;
@@
- dev->ethtool_ops = ops;
+ SET_ETHTOOL_OPS(dev, ops);
--- arch/um/drivers/net_kern.c | 2 +- drivers/firewire/net.c | 2 +- drivers/infiniband/hw/nes/nes_nic.c | 2 +- drivers/net/bonding/bond_main.c | 2 +- drivers/net/cris/eth_v10.c | 2 +- drivers/net/ethernet/3com/3c515.c | 2 +- drivers/net/ethernet/3com/3c59x.c | 2 +- drivers/net/ethernet/8390/ax88796.c | 2 +- drivers/net/ethernet/8390/etherh.c | 2 +- drivers/net/ethernet/8390/ne2k-pci.c | 2 +- drivers/net/ethernet/adi/bfin_mac.c | 2 +- drivers/net/ethernet/aeroflex/greth.c | 2 +- drivers/net/ethernet/allwinner/sun4i-emac.c | 2 +- drivers/net/ethernet/amd/pcnet32.c | 2 +- drivers/net/ethernet/amd/sunlance.c | 2 +- drivers/net/ethernet/apple/bmac.c | 2 +- drivers/net/ethernet/arc/emac_main.c | 2 +- drivers/net/ethernet/atheros/atlx/atl1.c | 2 +- drivers/net/ethernet/broadcom/bnx2.c | 2 +- drivers/net/ethernet/broadcom/tg3.c | 2 +- drivers/net/ethernet/cadence/at91_ether.c | 2 +- drivers/net/ethernet/cirrus/ep93xx_eth.c | 2 +- drivers/net/ethernet/davicom/dm9000.c | 2 +- drivers/net/ethernet/dec/tulip/de2104x.c | 2 +- drivers/net/ethernet/dec/tulip/dmfe.c | 2 +- drivers/net/ethernet/dec/tulip/uli526x.c | 2 +- drivers/net/ethernet/dec/tulip/winbond-840.c | 2 +- drivers/net/ethernet/dnet.c | 2 +- drivers/net/ethernet/ethoc.c | 2 +- drivers/net/ethernet/fealnx.c | 2 +- drivers/net/ethernet/freescale/fec_main.c | 2 +- drivers/net/ethernet/freescale/fec_mpc52xx.c | 2 +- drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c | 2 +- drivers/net/ethernet/freescale/gianfar.c | 2 +- drivers/net/ethernet/ibm/ibmveth.c | 2 +- drivers/net/ethernet/jme.c | 2 +- drivers/net/ethernet/korina.c | 2 +- drivers/net/ethernet/lantiq_etop.c | 2 +- drivers/net/ethernet/marvell/skge.c | 2 +- drivers/net/ethernet/micrel/ks8842.c | 2 +- drivers/net/ethernet/micrel/ks8851_mll.c | 2 +- drivers/net/ethernet/nuvoton/w90p910_ether.c | 2 +- drivers/net/ethernet/nxp/lpc_eth.c | 2 +- drivers/net/ethernet/octeon/octeon_mgmt.c | 2 +- drivers/net/ethernet/pasemi/pasemi_mac.c | 2 +- drivers/net/ethernet/rdc/r6040.c | 2 +- drivers/net/ethernet/realtek/8139cp.c | 2 +- drivers/net/ethernet/realtek/8139too.c | 2 +- drivers/net/ethernet/sfc/efx.c | 2 ++ drivers/net/ethernet/sgi/ioc3-eth.c | 2 +- drivers/net/ethernet/silan/sc92031.c | 2 +- drivers/net/ethernet/sis/sis900.c | 2 +- drivers/net/ethernet/smsc/epic100.c | 2 +- drivers/net/ethernet/smsc/smc911x.c | 2 +- drivers/net/ethernet/smsc/smc91x.c | 2 +- drivers/net/ethernet/smsc/smsc911x.c | 2 +- drivers/net/ethernet/smsc/smsc9420.c | 2 +- drivers/net/ethernet/sun/cassini.c | 2 +- drivers/net/ethernet/sun/niu.c | 2 +- drivers/net/ethernet/sun/sunbmac.c | 2 +- drivers/net/ethernet/sun/sungem.c | 2 +- drivers/net/ethernet/sun/sunhme.c | 4 ++-- drivers/net/ethernet/sun/sunqe.c | 2 +- drivers/net/ethernet/sun/sunvnet.c | 2 +- drivers/net/ethernet/ti/cpmac.c | 2 +- drivers/net/ethernet/toshiba/ps3_gelic_net.c | 2 +- drivers/net/ethernet/toshiba/ps3_gelic_wireless.c | 2 +- drivers/net/ethernet/toshiba/spider_net.c | 2 +- drivers/net/ethernet/toshiba/tc35815.c | 2 +- drivers/net/ethernet/tundra/tsi108_eth.c | 2 +- drivers/net/ethernet/via/via-rhine.c | 2 +- drivers/net/ethernet/via/via-velocity.c | 2 +- drivers/net/ethernet/wiznet/w5100.c | 2 +- drivers/net/ethernet/wiznet/w5300.c | 2 +- drivers/net/ethernet/xilinx/ll_temac_main.c | 2 +- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 2 +- drivers/net/ethernet/xircom/xirc2ps_cs.c | 2 +- drivers/net/ethernet/xscale/ixp4xx_eth.c | 2 +- drivers/net/loopback.c | 2 +- drivers/net/macvlan.c | 2 +- drivers/net/nlmon.c | 2 +- drivers/net/team/team.c | 2 +- drivers/net/tun.c | 2 +- drivers/net/usb/mcs7830.c | 2 +- drivers/net/usb/sr9700.c | 2 +- drivers/net/usb/usbnet.c | 2 +- drivers/net/veth.c | 2 +- drivers/net/wimax/i2400m/netdev.c | 2 +- drivers/net/wimax/i2400m/usb.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/net/wireless/ipw2x00/ipw2100.c | 2 +- drivers/net/wireless/ipw2x00/ipw2200.c | 2 +- drivers/net/wireless/libertas/main.c | 2 +- drivers/net/wireless/libertas/mesh.c | 2 +- drivers/net/wireless/mwifiex/cfg80211.c | 2 +- drivers/net/wireless/prism54/islpci_dev.c | 2 +- drivers/staging/bcm/Bcmnet.c | 2 +- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 2 +- drivers/staging/wlags49_h2/wl_netdev.c | 3 +-- net/8021q/vlan_dev.c | 2 +- 100 files changed, 102 insertions(+), 101 deletions(-)
arch/um/drivers/net_kern.c +1 -1
@@ -477,7 +477,7 @@ static void eth_configure(int n, void *init, char *mac, dev->mtu = transport->user->mtu; dev->netdev_ops = ¨_netdev_ops; - dev->ethtool_ops = ¨_net_ethtool_ops; +SET_ETHTOOL_OPS (dev, ¨_net_ethtool_ops); dev->watchdog_timeo = (HZ >>1 ); dev->irq =UM_ETH_IRQ ;
drivers/firewire/net.c +1 -1
@@ -1393,7 +1393,7 @@ static void fwnet_init_dev(struct net_device *net) net->hard_header_len =FWNET_HLEN ; net->type =ARPHRD_IEEE1394 ; net->tx_queue_len =FWNET_TX_QUEUE_LEN ; - net->ethtool_ops = &fwnet_ethtool_ops; +SET_ETHTOOL_OPS (net, &fwnet_ethtool_ops); }/* caller must hold fwnet_device_mutex */
drivers/infiniband/hw/nes/nes_nic.c +1 -1
@@ -1678,7 +1678,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, netdev->addr_len =ETH_ALEN ; netdev->type =ARPHRD_ETHER ; netdev->netdev_ops = &nes_netdev_ops; - netdev->ethtool_ops = &nes_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &nes_ethtool_ops);netif_napi_add (netdev, &nesvnic->napi, nes_netdev_poll,128 );nes_debug (NES_DBG_INIT ,"Enabling VLAN Insert/Delete.\n" );
drivers/net/bonding/bond_main.c +1 -1
@@ -3910,7 +3910,7 @@ void bond_setup(struct net_device *bond_dev)/* Initialize the device entry points */ ether_setup (bond_dev); bond_dev->netdev_ops = &bond_netdev_ops; - bond_dev->ethtool_ops = &bond_ethtool_ops; +SET_ETHTOOL_OPS (bond_dev, &bond_ethtool_ops); bond_dev->destructor = bond_destructor;
drivers/net/cris/eth_v10.c +1 -1
@@ -314,7 +314,7 @@ etrax_ethernet_init(void)/* fill in our handlers so the network layer can talk to us in the future */ - dev->ethtool_ops = &e100_ethtool_ops; +SET_ETHTOOL_OPS (dev, &e100_ethtool_ops); dev->netdev_ops = &e100_netdev_ops;spin_lock_init (&np->lock);
drivers/net/ethernet/3com/3c515.c +1 -1
@@ -698,7 +698,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,/* The 3c51x-specific entries in the device structure. */ dev->netdev_ops = &netdev_ops; dev->watchdog_timeo = (400 *HZ ) /1000 ; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops);return register_netdev (dev); }
drivers/net/ethernet/3com/3c59x.c +1 -1
@@ -1467,7 +1467,7 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, (dev->features & NETIF_F_IP_CSUM) ? "en":"dis"); } - dev->ethtool_ops = &vortex_ethtool_ops; +SET_ETHTOOL_OPS (dev, &vortex_ethtool_ops); dev->watchdog_timeo = (watchdog *HZ ) /1000 ;if (pdev) {
drivers/net/ethernet/8390/ax88796.c +1 -1
@@ -782,7 +782,7 @@ static int ax_init_dev(struct net_device *dev) ei_local->msg_enable = ax_msg_enable; dev->netdev_ops = &ax_netdev_ops; - dev->ethtool_ops = &ax_ethtool_ops; +SET_ETHTOOL_OPS (dev, &ax_ethtool_ops); ret =ax_mii_init (dev);if (ret)
drivers/net/ethernet/8390/etherh.c +1 -1
@@ -688,7 +688,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) dev->netdev_ops = ðerh_netdev_ops; dev->irq = ec->irq; - dev->ethtool_ops = ðerh_ethtool_ops; +SET_ETHTOOL_OPS (dev, ðerh_ethtool_ops);if (data->supported & SUPPORTED_Autoneg) dev->flags |=IFF_AUTOMEDIA ;
drivers/net/ethernet/8390/ne2k-pci.c +1 -1
@@ -373,7 +373,7 @@ static int ne2k_pci_init_one(struct pci_dev *pdev, ei_status.get_8390_hdr = &ne2k_pci_get_8390_hdr; ei_status.priv = (unsigned long ) pdev; - dev->ethtool_ops = &ne2k_pci_ethtool_ops; +SET_ETHTOOL_OPS (dev, &ne2k_pci_ethtool_ops);NS8390_init (dev,0 );memcpy (dev->dev_addr, SA_prom, dev->addr_len);
drivers/net/ethernet/adi/bfin_mac.c +1 -1
@@ -1683,7 +1683,7 @@ static int bfin_mac_probe(struct platform_device *pdev)ether_setup (ndev); ndev->netdev_ops = &bfin_mac_netdev_ops; - ndev->ethtool_ops = &bfin_mac_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &bfin_mac_ethtool_ops);init_timer (&lp->tx_reclaim_timer); lp->tx_reclaim_timer.data = (unsigned long )lp;
drivers/net/ethernet/aeroflex/greth.c +1 -1
@@ -1529,7 +1529,7 @@ static int greth_of_probe(struct platform_device *ofdev) } dev->netdev_ops = &greth_netdev_ops; - dev->ethtool_ops = &greth_ethtool_ops; +SET_ETHTOOL_OPS (dev, &greth_ethtool_ops); err =register_netdev (dev);if (err) {
drivers/net/ethernet/allwinner/sun4i-emac.c +1 -1
@@ -879,7 +879,7 @@ static int emac_probe(struct platform_device *pdev) ndev->netdev_ops = &emac_netdev_ops; ndev->watchdog_timeo =msecs_to_jiffies (watchdog); - ndev->ethtool_ops = &emac_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &emac_ethtool_ops);platform_set_drvdata (pdev, ndev);
drivers/net/ethernet/amd/pcnet32.c +1 -1
@@ -1900,7 +1900,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)/* The PCNET32-specific entries in the device structure. */ dev->netdev_ops = &pcnet32_netdev_ops; - dev->ethtool_ops = &pcnet32_ethtool_ops; +SET_ETHTOOL_OPS (dev, &pcnet32_ethtool_ops); dev->watchdog_timeo = (5 *HZ );/* Fill in the generic fields of the device structure. */
drivers/net/ethernet/amd/sunlance.c +1 -1
@@ -1450,7 +1450,7 @@ no_link_test: lp->dev = dev;SET_NETDEV_DEV (dev, &op->dev); dev->watchdog_timeo =5 *HZ ; - dev->ethtool_ops = &sparc_lance_ethtool_ops; +SET_ETHTOOL_OPS (dev, &sparc_lance_ethtool_ops); dev->netdev_ops = &sparc_lance_ops; dev->irq = op->archdata.irqs[0 ];
drivers/net/ethernet/apple/bmac.c +1 -1
@@ -1301,7 +1301,7 @@ static int bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)bmwrite (dev,INTDISABLE , DisableAll); dev->netdev_ops = &bmac_netdev_ops; - dev->ethtool_ops = &bmac_ethtool_ops; +SET_ETHTOOL_OPS (dev, &bmac_ethtool_ops);bmac_get_station_address (dev, addr);if (bmac_verify_checksum (dev) !=0 )
drivers/net/ethernet/arc/emac_main.c +1 -1
@@ -665,7 +665,7 @@ static int arc_emac_probe(struct platform_device *pdev)SET_NETDEV_DEV (ndev, &pdev->dev); ndev->netdev_ops = &arc_emac_netdev_ops; - ndev->ethtool_ops = &arc_emac_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &arc_emac_ethtool_ops); ndev->watchdog_timeo =TX_TIMEOUT ;/* FIXME :: no multicast support yet */ ndev->flags &= ~IFF_MULTICAST ;
drivers/net/ethernet/atheros/atlx/atl1.c +1 -1
@@ -3014,7 +3014,7 @@ static int atl1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->watchdog_timeo =5 *HZ ;netif_napi_add (netdev, &adapter->napi, atl1_rings_clean,64 ); - netdev->ethtool_ops = &atl1_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &atl1_ethtool_ops); adapter->bd_number = cards_found;/* setup the private structure */
drivers/net/ethernet/broadcom/bnx2.c +1 -1
@@ -8556,7 +8556,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->netdev_ops = &bnx2_netdev_ops; dev->watchdog_timeo =TX_TIMEOUT ; - dev->ethtool_ops = &bnx2_ethtool_ops; +SET_ETHTOOL_OPS (dev, &bnx2_ethtool_ops); bp =netdev_priv (dev);
drivers/net/ethernet/broadcom/tg3.c +1 -1
@@ -17590,7 +17590,7 @@ static int tg3_init_one(struct pci_dev *pdev, tp->rx_pending =TG3_DEF_RX_RING_PENDING ; tp->rx_jumbo_pending =TG3_DEF_RX_JUMBO_RING_PENDING ; - dev->ethtool_ops = &tg3_ethtool_ops; +SET_ETHTOOL_OPS (dev, &tg3_ethtool_ops); dev->watchdog_timeo =TG3_TX_TIMEOUT ; dev->netdev_ops = &tg3_netdev_ops; dev->irq = pdev->irq;
drivers/net/ethernet/cadence/at91_ether.c +1 -1
@@ -353,7 +353,7 @@ static int __init at91ether_probe(struct platform_device *pdev)ether_setup (dev); dev->netdev_ops = &at91ether_netdev_ops; - dev->ethtool_ops = &macb_ethtool_ops; +SET_ETHTOOL_OPS (dev, &macb_ethtool_ops);platform_set_drvdata (pdev, dev);SET_NETDEV_DEV (dev, &pdev->dev);
drivers/net/ethernet/cirrus/ep93xx_eth.c +1 -1
@@ -765,7 +765,7 @@ static struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data)memcpy (dev->dev_addr, data->dev_addr,ETH_ALEN ); - dev->ethtool_ops = &ep93xx_ethtool_ops; +SET_ETHTOOL_OPS (dev, &ep93xx_ethtool_ops); dev->netdev_ops = &ep93xx_netdev_ops; dev->features |=NETIF_F_SG |NETIF_F_HW_CSUM ;
drivers/net/ethernet/davicom/dm9000.c +1 -1
@@ -1602,7 +1602,7 @@ dm9000_probe(struct platform_device *pdev) ndev->netdev_ops = &dm9000_netdev_ops; ndev->watchdog_timeo =msecs_to_jiffies (watchdog); - ndev->ethtool_ops = &dm9000_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &dm9000_ethtool_ops); db->msg_enable =NETIF_MSG_LINK ; db->mii.phy_id_mask =0x1f ;
drivers/net/ethernet/dec/tulip/de2104x.c +1 -1
@@ -1985,7 +1985,7 @@ static int de_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->netdev_ops = &de_netdev_ops;SET_NETDEV_DEV (dev, &pdev->dev); - dev->ethtool_ops = &de_ethtool_ops; +SET_ETHTOOL_OPS (dev, &de_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ; de =netdev_priv (dev);
drivers/net/ethernet/dec/tulip/dmfe.c +1 -1
@@ -477,7 +477,7 @@ static int dmfe_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)pci_set_drvdata (pdev, dev); dev->netdev_ops = &netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops);netif_carrier_off (dev);spin_lock_init (&db->lock);
drivers/net/ethernet/dec/tulip/uli526x.c +1 -1
@@ -372,7 +372,7 @@ static int uli526x_init_one(struct pci_dev *pdev,/* Register some necessary functions */ dev->netdev_ops = &netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops);spin_lock_init (&db->lock);
drivers/net/ethernet/dec/tulip/winbond-840.c +1 -1
@@ -431,7 +431,7 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)/* The chip-specific entries in the device structure. */ dev->netdev_ops = &netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ; i =register_netdev (dev);
drivers/net/ethernet/dnet.c +1 -1
@@ -876,7 +876,7 @@ static int dnet_probe(struct platform_device *pdev) dev->netdev_ops = &dnet_netdev_ops;netif_napi_add (dev, &bp->napi, dnet_poll,64 ); - dev->ethtool_ops = &dnet_ethtool_ops; +SET_ETHTOOL_OPS (dev, &dnet_ethtool_ops); dev->base_addr = (unsigned long )bp->regs;
drivers/net/ethernet/ethoc.c +1 -1
@@ -1234,7 +1234,7 @@ static int ethoc_probe(struct platform_device *pdev) netdev->netdev_ops = ðoc_netdev_ops; netdev->watchdog_timeo =ETHOC_TIMEOUT ; netdev->features |=0 ; - netdev->ethtool_ops = ðoc_ethtool_ops; +SET_ETHTOOL_OPS (netdev, ðoc_ethtool_ops);/* setup NAPI */ netif_napi_add (netdev, &priv->napi, ethoc_poll,64 );
drivers/net/ethernet/fealnx.c +1 -1
@@ -657,7 +657,7 @@ static int fealnx_init_one(struct pci_dev *pdev, } dev->netdev_ops = &netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ; err =register_netdev (dev);
drivers/net/ethernet/freescale/fec_main.c +1 -1
@@ -2019,7 +2019,7 @@ static int fec_enet_init(struct net_device *ndev)/* The FEC Ethernet specific entries in the device structure */ ndev->watchdog_timeo =TX_TIMEOUT ; ndev->netdev_ops = &fec_netdev_ops; - ndev->ethtool_ops = &fec_enet_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &fec_enet_ethtool_ops);writel (FEC_RX_DISABLED_IMASK , fep->hwp +FEC_IMASK );netif_napi_add (ndev, &fep->napi, fec_enet_rx_napi,NAPI_POLL_WEIGHT );
drivers/net/ethernet/freescale/fec_mpc52xx.c +1 -1
@@ -879,7 +879,7 @@ static int mpc52xx_fec_probe(struct platform_device *op)/* Init ether ndev with what we have */ ndev->netdev_ops = &mpc52xx_fec_netdev_ops; - ndev->ethtool_ops = &mpc52xx_fec_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &mpc52xx_fec_ethtool_ops); ndev->watchdog_timeo =FEC_WATCHDOG_TIMEOUT ; ndev->base_addr = mem.start;SET_NETDEV_DEV (ndev, &op->dev);
drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +1 -1
@@ -1103,7 +1103,7 @@ static int fs_enet_probe(struct platform_device *ofdev)netif_napi_add (ndev, &fep->napi, fs_enet_rx_napi, fpi->napi_weight); - ndev->ethtool_ops = &fs_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &fs_ethtool_ops);init_timer (&fep->phy_timer_list);
drivers/net/ethernet/freescale/gianfar.c +1 -1
@@ -1304,7 +1304,7 @@ static int gfar_probe(struct platform_device *ofdev) dev->watchdog_timeo =TX_TIMEOUT ; dev->mtu =1500 ; dev->netdev_ops = &gfar_netdev_ops; - dev->ethtool_ops = &gfar_ethtool_ops; +SET_ETHTOOL_OPS (dev, &gfar_ethtool_ops);/* Register for napi ...We are registering NAPI for each grp */ for (i =0 ; i < priv->num_grps; i++) {
drivers/net/ethernet/ibm/ibmveth.c +1 -1
@@ -1384,7 +1384,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) netdev->irq = dev->irq; netdev->netdev_ops = &ibmveth_netdev_ops; - netdev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &netdev_ethtool_ops);SET_NETDEV_DEV (netdev, &dev->dev); netdev->hw_features =NETIF_F_SG |NETIF_F_RXCSUM |NETIF_F_IP_CSUM |NETIF_F_IPV6_CSUM ;
drivers/net/ethernet/jme.c +1 -1
@@ -3005,7 +3005,7 @@ jme_init_one(struct pci_dev *pdev, goto err_out_release_regions; } netdev->netdev_ops = &jme_netdev_ops; - netdev->ethtool_ops = &jme_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &jme_ethtool_ops); netdev->watchdog_timeo =TX_TIMEOUT ; netdev->hw_features =NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
drivers/net/ethernet/korina.c +1 -1
@@ -1160,7 +1160,7 @@ static int korina_probe(struct platform_device *pdev) lp->dev = dev; dev->netdev_ops = &korina_netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ;netif_napi_add (dev, &lp->napi, korina_poll,64 );
drivers/net/ethernet/lantiq_etop.c +1 -1
@@ -741,7 +741,7 @@ ltq_etop_probe(struct platform_device *pdev) }strcpy (dev->name,"eth%d" ); dev->netdev_ops = <q_eth_netdev_ops; - dev->ethtool_ops = <q_etop_ethtool_ops; +SET_ETHTOOL_OPS (dev, <q_etop_ethtool_ops); priv =netdev_priv (dev); priv->res = res; priv->pdev = pdev;
drivers/net/ethernet/marvell/skge.c +1 -1
@@ -3854,7 +3854,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,SET_NETDEV_DEV (dev, &hw->pdev->dev); dev->netdev_ops = &skge_netdev_ops; - dev->ethtool_ops = &skge_ethtool_ops; +SET_ETHTOOL_OPS (dev, &skge_ethtool_ops); dev->watchdog_timeo =TX_WATCHDOG ; dev->irq = hw->pdev->irq;
drivers/net/ethernet/micrel/ks8842.c +1 -1
@@ -1192,7 +1192,7 @@ static int ks8842_probe(struct platform_device *pdev)spin_lock_init (&adapter->lock); netdev->netdev_ops = &ks8842_netdev_ops; - netdev->ethtool_ops = &ks8842_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &ks8842_ethtool_ops);/* Check if a mac address was given */ i = netdev->addr_len;
drivers/net/ethernet/micrel/ks8851_mll.c +1 -1
@@ -1583,7 +1583,7 @@ static int ks8851_probe(struct platform_device *pdev)spin_lock_init (&ks->statelock); netdev->netdev_ops = &ks_netdev_ops; - netdev->ethtool_ops = &ks_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &ks_ethtool_ops);/* setup mii state */ ks->mii.dev = netdev;
drivers/net/ethernet/nuvoton/w90p910_ether.c +1 -1
@@ -945,7 +945,7 @@ static int w90p910_ether_setup(struct net_device *dev)ether_setup (dev); dev->netdev_ops = &w90p910_ether_netdev_ops; - dev->ethtool_ops = &w90p910_ether_ethtool_ops; +SET_ETHTOOL_OPS (dev, &w90p910_ether_ethtool_ops); dev->tx_queue_len =16 ; dev->dma =0x0 ;
drivers/net/ethernet/nxp/lpc_eth.c +1 -1
@@ -1379,7 +1379,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)/* Setup driver functions */ ndev->netdev_ops = &lpc_netdev_ops; - ndev->ethtool_ops = &lpc_eth_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &lpc_eth_ethtool_ops); ndev->watchdog_timeo =msecs_to_jiffies (2500 );/* Get size of DMA buffers/descriptors region */
drivers/net/ethernet/octeon/octeon_mgmt.c +1 -1
@@ -1541,7 +1541,7 @@ static int octeon_mgmt_probe(struct platform_device *pdev) netdev->priv_flags |=IFF_UNICAST_FLT ; netdev->netdev_ops = &octeon_mgmt_ops; - netdev->ethtool_ops = &octeon_mgmt_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &octeon_mgmt_ethtool_ops); mac =of_get_mac_address (pdev->dev.of_node);
drivers/net/ethernet/pasemi/pasemi_mac.c +1 -1
@@ -1812,7 +1812,7 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)/* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */ mac->bufsz = dev->mtu +ETH_HLEN +ETH_FCS_LEN +LOCAL_SKB_ALIGN +128 ; - dev->ethtool_ops = &pasemi_mac_ethtool_ops; +SET_ETHTOOL_OPS (dev, &pasemi_mac_ethtool_ops);if (err) goto out;
drivers/net/ethernet/rdc/r6040.c +1 -1
@@ -1171,7 +1171,7 @@ static int r6040_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)/* The RDC-specific entries in the device structure. */ dev->netdev_ops = &r6040_netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ;netif_napi_add (dev, &lp->napi, r6040_poll,64 );
drivers/net/ethernet/realtek/8139cp.c +1 -1
@@ -1992,7 +1992,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev->netdev_ops = &cp_netdev_ops;netif_napi_add (dev, &cp->napi, cp_rx_poll,16 ); - dev->ethtool_ops = &cp_ethtool_ops; +SET_ETHTOOL_OPS (dev, &cp_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ; dev->features |=NETIF_F_HW_VLAN_CTAG_TX |NETIF_F_HW_VLAN_CTAG_RX ;
drivers/net/ethernet/realtek/8139too.c +1 -1
@@ -996,7 +996,7 @@ static int rtl8139_init_one(struct pci_dev *pdev,/* The Rtl8139-specific entries in the device structure. */ dev->netdev_ops = &rtl8139_netdev_ops; - dev->ethtool_ops = &rtl8139_ethtool_ops; +SET_ETHTOOL_OPS (dev, &rtl8139_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ;netif_napi_add (dev, &tp->napi, rtl8139_poll,64 );
drivers/net/ethernet/sfc/efx.c +2 -0
@@ -2214,6 +2214,8 @@ static int efx_netdev_event(struct notifier_block *this, {struct net_device *net_dev =netdev_notifier_info_to_dev (ptr); +/* FIXME: this is broken now with !NETDEV_OPS */ +if ((net_dev->netdev_ops == &efx_farch_netdev_ops || net_dev->netdev_ops == &efx_ef10_netdev_ops) && event ==NETDEV_CHANGENAME )
drivers/net/ethernet/sgi/ioc3-eth.c +1 -1
@@ -1325,7 +1325,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)/* The IOC3-specific entries in the device structure. */ dev->watchdog_timeo =5 *HZ ; dev->netdev_ops = &ioc3_netdev_ops; - dev->ethtool_ops = &ioc3_ethtool_ops; +SET_ETHTOOL_OPS (dev, &ioc3_ethtool_ops); dev->hw_features =NETIF_F_IP_CSUM |NETIF_F_RXCSUM ; dev->features =NETIF_F_IP_CSUM ;
drivers/net/ethernet/silan/sc92031.c +1 -1
@@ -1442,7 +1442,7 @@ static int sc92031_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev->netdev_ops = &sc92031_netdev_ops; dev->watchdog_timeo =TX_TIMEOUT ; - dev->ethtool_ops = &sc92031_ethtool_ops; +SET_ETHTOOL_OPS (dev, &sc92031_ethtool_ops); priv =netdev_priv (dev);spin_lock_init (&priv->lock);
drivers/net/ethernet/sis/sis900.c +1 -1
@@ -496,7 +496,7 @@ static int sis900_probe(struct pci_dev *pci_dev,/* The SiS900-specific entries in the device structure. */ net_dev->netdev_ops = &sis900_netdev_ops; net_dev->watchdog_timeo =TX_TIMEOUT ; - net_dev->ethtool_ops = &sis900_ethtool_ops; +SET_ETHTOOL_OPS (net_dev, &sis900_ethtool_ops);if (sis900_debug >0 ) sis_priv->msg_enable = sis900_debug;
drivers/net/ethernet/smsc/epic100.c +1 -1
@@ -480,7 +480,7 @@ static int epic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)/* The Epic-specific entries in the device structure. */ dev->netdev_ops = &epic_netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ;netif_napi_add (dev, &ep->napi, epic_poll,64 );
drivers/net/ethernet/smsc/smc911x.c +1 -1
@@ -1932,7 +1932,7 @@ static int smc911x_probe(struct net_device *dev) dev->netdev_ops = &smc911x_netdev_ops; dev->watchdog_timeo =msecs_to_jiffies (watchdog); - dev->ethtool_ops = &smc911x_ethtool_ops; +SET_ETHTOOL_OPS (dev, &smc911x_ethtool_ops);INIT_WORK (&lp->phy_configure, smc911x_phy_configure); lp->mii.phy_id_mask =0x1f ;
drivers/net/ethernet/smsc/smc91x.c +1 -1
@@ -1971,7 +1971,7 @@ static int smc_probe(struct net_device *dev, void __iomem *ioaddr, dev->watchdog_timeo =msecs_to_jiffies (watchdog); dev->netdev_ops = &smc_netdev_ops; - dev->ethtool_ops = &smc_ethtool_ops; +SET_ETHTOOL_OPS (dev, &smc_ethtool_ops);tasklet_init (&lp->tx_task, smc_hardware_send_pkt, (unsigned long )dev);INIT_WORK (&lp->phy_configure, smc_phy_configure);
drivers/net/ethernet/smsc/smsc911x.c +1 -1
@@ -2259,7 +2259,7 @@ static int smsc911x_init(struct net_device *dev) dev->flags |=IFF_MULTICAST ;netif_napi_add (dev, &pdata->napi, smsc911x_poll,SMSC_NAPI_WEIGHT ); dev->netdev_ops = &smsc911x_netdev_ops; - dev->ethtool_ops = &smsc911x_ethtool_ops; +SET_ETHTOOL_OPS (dev, &smsc911x_ethtool_ops);return 0 ; }
drivers/net/ethernet/smsc/smsc9420.c +1 -1
@@ -1661,7 +1661,7 @@ smsc9420_probe(struct pci_dev *pdev, const struct pci_device_id *id)smsc9420_check_mac_address (dev); dev->netdev_ops = &smsc9420_netdev_ops; - dev->ethtool_ops = &smsc9420_ethtool_ops; +SET_ETHTOOL_OPS (dev, &smsc9420_ethtool_ops);netif_napi_add (dev, &pd->napi, smsc9420_rx_poll,NAPI_WEIGHT );
drivers/net/ethernet/sun/cassini.c +1 -1
@@ -5103,7 +5103,7 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)skb_queue_head_init (&cp->rx_flows[i]); dev->netdev_ops = &cas_netdev_ops; - dev->ethtool_ops = &cas_ethtool_ops; +SET_ETHTOOL_OPS (dev, &cas_ethtool_ops); dev->watchdog_timeo =CAS_TX_TIMEOUT ;#ifdef USE_NAPI
drivers/net/ethernet/sun/niu.c +1 -1
@@ -9699,7 +9699,7 @@ static const struct net_device_ops niu_netdev_ops = {static void niu_assign_netdev_ops (struct net_device *dev) { dev->netdev_ops = &niu_netdev_ops; - dev->ethtool_ops = &niu_ethtool_ops; +SET_ETHTOOL_OPS (dev, &niu_ethtool_ops); dev->watchdog_timeo =NIU_TX_TIMEOUT ; }
drivers/net/ethernet/sun/sunbmac.c +1 -1
@@ -1180,7 +1180,7 @@ static int bigmac_ether_init(struct platform_device *op, bp->dev = dev;/* Set links to our BigMAC open and close routines. */ - dev->ethtool_ops = &bigmac_ethtool_ops; +SET_ETHTOOL_OPS (dev, &bigmac_ethtool_ops); dev->netdev_ops = &bigmac_ops; dev->watchdog_timeo =5 *HZ ;
drivers/net/ethernet/sun/sungem.c +1 -1
@@ -2965,7 +2965,7 @@ static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->netdev_ops = &gem_netdev_ops;netif_napi_add (dev, &gp->napi, gem_poll,64 ); - dev->ethtool_ops = &gem_ethtool_ops; +SET_ETHTOOL_OPS (dev, &gem_ethtool_ops); dev->watchdog_timeo =5 *HZ ; dev->dma =0 ;
drivers/net/ethernet/sun/sunhme.c +2 -2
@@ -2767,7 +2767,7 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe) hp->dev = dev; dev->netdev_ops = &hme_netdev_ops; dev->watchdog_timeo =5 *HZ ; - dev->ethtool_ops = &hme_ethtool_ops; +SET_ETHTOOL_OPS (dev, &hme_ethtool_ops);/* Happy Meal can do it all... */ dev->hw_features =NETIF_F_SG |NETIF_F_HW_CSUM ;
@@ -3082,7 +3082,7 @@ static int happy_meal_pci_probe(struct pci_dev *pdev, hp->dev = dev; dev->netdev_ops = &hme_netdev_ops; dev->watchdog_timeo =5 *HZ ; - dev->ethtool_ops = &hme_ethtool_ops; +SET_ETHTOOL_OPS (dev, &hme_ethtool_ops);/* Happy Meal can do it all... */ dev->hw_features =NETIF_F_SG |NETIF_F_HW_CSUM ;
drivers/net/ethernet/sun/sunqe.c +1 -1
@@ -895,7 +895,7 @@ static int qec_ether_init(struct platform_device *op) dev->watchdog_timeo =5 *HZ ; dev->irq = op->archdata.irqs[0 ]; dev->dma =0 ; - dev->ethtool_ops = &qe_ethtool_ops; +SET_ETHTOOL_OPS (dev, &qe_ethtool_ops); dev->netdev_ops = &qec_ops; res =register_netdev (dev);
drivers/net/ethernet/sun/sunvnet.c +1 -1
@@ -1043,7 +1043,7 @@ static struct vnet *vnet_new(const u64 *local_mac) vp->local_mac = *local_mac; dev->netdev_ops = &vnet_ops; - dev->ethtool_ops = &vnet_ethtool_ops; +SET_ETHTOOL_OPS (dev, &vnet_ethtool_ops); dev->watchdog_timeo =VNET_TX_TIMEOUT ; err =register_netdev (dev);
drivers/net/ethernet/ti/cpmac.c +1 -1
@@ -1157,7 +1157,7 @@ static int cpmac_probe(struct platform_device *pdev) dev->irq =platform_get_irq_byname (pdev,"irq" ); dev->netdev_ops = &cpmac_netdev_ops; - dev->ethtool_ops = &cpmac_ethtool_ops; +SET_ETHTOOL_OPS (dev, &cpmac_ethtool_ops);netif_napi_add (dev, &priv->napi, cpmac_poll,64 );
drivers/net/ethernet/toshiba/ps3_gelic_net.c +1 -1
@@ -1467,7 +1467,7 @@ static void gelic_ether_setup_netdev_ops(struct net_device *netdev, netdev->watchdog_timeo =GELIC_NET_WATCHDOG_TIMEOUT ;/* NAPI */ netif_napi_add (netdev, napi, gelic_net_poll,NAPI_POLL_WEIGHT ); - netdev->ethtool_ops = &gelic_ether_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &gelic_ether_ethtool_ops); netdev->netdev_ops = &gelic_netdevice_ops; }
drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +1 -1
@@ -2589,7 +2589,7 @@ static void gelic_wl_setup_netdev_ops(struct net_device *netdev)BUG_ON (!wl); netdev->watchdog_timeo =GELIC_NET_WATCHDOG_TIMEOUT ; - netdev->ethtool_ops = &gelic_wl_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &gelic_wl_ethtool_ops); netdev->netdev_ops = &gelic_wl_netdevice_ops; netdev->wireless_data = &wl->wireless_data; netdev->wireless_handlers = &gelic_wl_wext_handler_def;
drivers/net/ethernet/toshiba/spider_net.c +1 -1
@@ -2286,7 +2286,7 @@ spider_net_setup_netdev_ops(struct net_device *netdev) netdev->netdev_ops = &spider_net_ops; netdev->watchdog_timeo =SPIDER_NET_WATCHDOG_TIMEOUT ;/* ethtool ops */ - netdev->ethtool_ops = &spider_net_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &spider_net_ethtool_ops); }/**
drivers/net/ethernet/toshiba/tc35815.c +1 -1
@@ -825,7 +825,7 @@ static int tc35815_init_one(struct pci_dev *pdev,/* Initialize the device structure. */ dev->netdev_ops = &tc35815_netdev_ops; - dev->ethtool_ops = &tc35815_ethtool_ops; +SET_ETHTOOL_OPS (dev, &tc35815_ethtool_ops); dev->watchdog_timeo =TC35815_TX_TIMEOUT ;netif_napi_add (dev, &lp->napi, tc35815_poll,NAPI_WEIGHT );
drivers/net/ethernet/tundra/tsi108_eth.c +1 -1
@@ -1604,7 +1604,7 @@ tsi108_init_one(struct platform_device *pdev) data->id = pdev->id;netif_napi_add (dev, &data->napi, tsi108_poll,64 ); dev->netdev_ops = &tsi108_netdev_ops; - dev->ethtool_ops = &tsi108_ethtool_ops; +SET_ETHTOOL_OPS (dev, &tsi108_ethtool_ops);/* Apparently, the Linux networking code won't use scatter-gather * if the hardware doesn't do checksums. However, it's faster
drivers/net/ethernet/via/via-rhine.c +1 -1
@@ -1022,7 +1022,7 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)/* The chip-specific entries in the device structure. */ dev->netdev_ops = &rhine_netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ;netif_napi_add (dev, &rp->napi, rhine_napipoll,64 );
drivers/net/ethernet/via/via-velocity.c +1 -1
@@ -2875,7 +2875,7 @@ static int velocity_probe(struct device *dev, int irq, vptr->phy_id =MII_GET_PHY_ID (vptr->mac_regs); netdev->netdev_ops = &velocity_netdev_ops; - netdev->ethtool_ops = &velocity_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &velocity_ethtool_ops);netif_napi_add (netdev, &vptr->napi, velocity_poll,VELOCITY_NAPI_WEIGHT );
drivers/net/ethernet/wiznet/w5100.c +1 -1
@@ -710,7 +710,7 @@ static int w5100_probe(struct platform_device *pdev)ether_setup (ndev); ndev->netdev_ops = &w5100_netdev_ops; - ndev->ethtool_ops = &w5100_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &w5100_ethtool_ops); ndev->watchdog_timeo =HZ ;netif_napi_add (ndev, &priv->napi, w5100_napi_poll,16 );
drivers/net/ethernet/wiznet/w5300.c +1 -1
@@ -622,7 +622,7 @@ static int w5300_probe(struct platform_device *pdev)ether_setup (ndev); ndev->netdev_ops = &w5300_netdev_ops; - ndev->ethtool_ops = &w5300_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &w5300_ethtool_ops); ndev->watchdog_timeo =HZ ;netif_napi_add (ndev, &priv->napi, w5300_napi_poll,16 );
drivers/net/ethernet/xilinx/ll_temac_main.c +1 -1
@@ -1018,7 +1018,7 @@ static int temac_of_probe(struct platform_device *op) ndev->flags &= ~IFF_MULTICAST ;/* clear multicast */ ndev->features =NETIF_F_SG ; ndev->netdev_ops = &temac_netdev_ops; - ndev->ethtool_ops = &temac_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &temac_ethtool_ops);#if 0 ndev->features |=NETIF_F_IP_CSUM ;/* Can checksum TCP/UDP over IPv4. */ ndev->features |=NETIF_F_HW_CSUM ;/* Can checksum all the packets. */
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +1 -1
@@ -1492,7 +1492,7 @@ static int axienet_of_probe(struct platform_device *op) ndev->flags &= ~IFF_MULTICAST ;/* clear multicast */ ndev->features =NETIF_F_SG ; ndev->netdev_ops = &axienet_netdev_ops; - ndev->ethtool_ops = &axienet_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &axienet_ethtool_ops); lp =netdev_priv (ndev); lp->ndev = ndev;
drivers/net/ethernet/xircom/xirc2ps_cs.c +1 -1
@@ -493,7 +493,7 @@ xirc2ps_probe(struct pcmcia_device *link)/* Fill in card specific entries */ dev->netdev_ops = &netdev_ops; - dev->ethtool_ops = &netdev_ethtool_ops; +SET_ETHTOOL_OPS (dev, &netdev_ethtool_ops); dev->watchdog_timeo =TX_TIMEOUT ;INIT_WORK (&local->tx_timeout_task, xirc2ps_tx_timeout_task);
drivers/net/ethernet/xscale/ixp4xx_eth.c +1 -1
@@ -1436,7 +1436,7 @@ static int eth_init_one(struct platform_device *pdev) } dev->netdev_ops = &ixp4xx_netdev_ops; - dev->ethtool_ops = &ixp4xx_ethtool_ops; +SET_ETHTOOL_OPS (dev, &ixp4xx_ethtool_ops); dev->tx_queue_len =100 ;netif_napi_add (dev, &port->napi, eth_poll,NAPI_WEIGHT );
drivers/net/loopback.c +1 -1
@@ -182,7 +182,7 @@ static void loopback_setup(struct net_device *dev) | NETIF_F_NETNS_LOCAL |NETIF_F_VLAN_CHALLENGED |NETIF_F_LOOPBACK ; - dev->ethtool_ops = &loopback_ethtool_ops; +SET_ETHTOOL_OPS (dev, &loopback_ethtool_ops); dev->header_ops = ð_header_ops; dev->netdev_ops = &loopback_ops; dev->destructor = loopback_dev_free;
drivers/net/macvlan.c +1 -1
@@ -735,7 +735,7 @@ void macvlan_common_setup(struct net_device *dev) dev->netdev_ops = &macvlan_netdev_ops; dev->destructor = free_netdev; dev->header_ops = &macvlan_hard_header_ops; - dev->ethtool_ops = &macvlan_ethtool_ops; +SET_ETHTOOL_OPS (dev, &macvlan_ethtool_ops); }EXPORT_SYMBOL_GPL (macvlan_common_setup);
drivers/net/nlmon.c +1 -1
@@ -133,7 +133,7 @@ static void nlmon_setup(struct net_device *dev) dev->tx_queue_len =0 ; dev->netdev_ops = &nlmon_ops; - dev->ethtool_ops = &nlmon_ethtool_ops; +SET_ETHTOOL_OPS (dev, &nlmon_ethtool_ops); dev->destructor = free_netdev; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
drivers/net/team/team.c +1 -1
@@ -2011,7 +2011,7 @@ static void team_setup(struct net_device *dev)ether_setup (dev); dev->netdev_ops = &team_netdev_ops; - dev->ethtool_ops = &team_ethtool_ops; +SET_ETHTOOL_OPS (dev, &team_ethtool_ops); dev->destructor = team_destructor; dev->tx_queue_len =0 ; dev->flags |=IFF_MULTICAST ;
drivers/net/tun.c +1 -1
@@ -1418,7 +1418,7 @@ static void tun_setup(struct net_device *dev) tun->owner =INVALID_UID ; tun->group =INVALID_GID ; - dev->ethtool_ops = &tun_ethtool_ops; +SET_ETHTOOL_OPS (dev, &tun_ethtool_ops); dev->destructor = tun_free_netdev; }
drivers/net/usb/mcs7830.c +1 -1
@@ -503,7 +503,7 @@ static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)if (ret) goto out; - net->ethtool_ops = &mcs7830_ethtool_ops; +SET_ETHTOOL_OPS (net, &mcs7830_ethtool_ops); net->netdev_ops = &mcs7830_netdev_ops;/* reserve space for the status byte on rx */
drivers/net/usb/sr9700.c +1 -1
@@ -327,7 +327,7 @@ static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf) netdev = dev->net; netdev->netdev_ops = &sr9700_netdev_ops; - netdev->ethtool_ops = &sr9700_ethtool_ops; +SET_ETHTOOL_OPS (netdev, &sr9700_ethtool_ops); netdev->hard_header_len +=SR_TX_OVERHEAD ; dev->hard_mtu = netdev->mtu + netdev->hard_header_len;/* bulkin buffer is preferably not less than 3K */
drivers/net/usb/usbnet.c +1 -1
@@ -1616,7 +1616,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) net->netdev_ops = &usbnet_netdev_ops; net->watchdog_timeo =TX_TIMEOUT_JIFFIES ; - net->ethtool_ops = &usbnet_ethtool_ops; +SET_ETHTOOL_OPS (net, &usbnet_ethtool_ops);// allow device-specific bind/init procedures // NOTE net->name still not usable ...
drivers/net/veth.c +1 -1
@@ -274,7 +274,7 @@ static void veth_setup(struct net_device *dev) dev->priv_flags |=IFF_LIVE_ADDR_CHANGE ; dev->netdev_ops = &veth_netdev_ops; - dev->ethtool_ops = &veth_ethtool_ops; +SET_ETHTOOL_OPS (dev, &veth_ethtool_ops); dev->features |=NETIF_F_LLTX ; dev->features |=VETH_FEATURES ; dev->vlan_features = dev->features &
drivers/net/wimax/i2400m/netdev.c +1 -1
@@ -631,7 +631,7 @@ void i2400m_netdev_setup(struct net_device *net_dev) & ~IFF_MULTICAST); net_dev->watchdog_timeo =I2400M_TX_TIMEOUT ; net_dev->netdev_ops = &i2400m_netdev_ops; - net_dev->ethtool_ops = &i2400m_ethtool_ops; +SET_ETHTOOL_OPS (net_dev, &i2400m_ethtool_ops);d_fnend (3 ,NULL ,"(net_dev %p) = void\n" , net_dev); }EXPORT_SYMBOL_GPL (i2400m_netdev_setup);
drivers/net/wimax/i2400m/usb.c +1 -1
@@ -364,7 +364,7 @@ void i2400mu_netdev_setup(struct net_device *net_dev) struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m);i2400mu_init (i2400mu);i2400m_netdev_setup (net_dev); - net_dev->ethtool_ops = &i2400mu_ethtool_ops; +SET_ETHTOOL_OPS (net_dev, &i2400mu_ethtool_ops); }
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +1 -1
@@ -680,7 +680,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked) ndev->netdev_ops = &brcmf_netdev_ops_pri; ndev->hard_header_len += drvr->hdrlen; - ndev->ethtool_ops = &brcmf_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &brcmf_ethtool_ops); drvr->rxsz = ndev->mtu + ndev->hard_header_len + drvr->hdrlen;
drivers/net/wireless/ipw2x00/ipw2100.c +1 -1
@@ -6069,7 +6069,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, priv->ieee->worst_rssi =-85 ; dev->netdev_ops = &ipw2100_netdev_ops; - dev->ethtool_ops = &ipw2100_ethtool_ops; +SET_ETHTOOL_OPS (dev, &ipw2100_ethtool_ops); dev->wireless_handlers = &ipw2100_wx_handler_def; priv->wireless_data.libipw = priv->ieee; dev->wireless_data = &priv->wireless_data;
drivers/net/wireless/ipw2x00/ipw2200.c +1 -1
@@ -11823,7 +11823,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, priv->wireless_data.spy_data = &priv->ieee->spy_data; net_dev->wireless_data = &priv->wireless_data; net_dev->wireless_handlers = &ipw_wx_handler_def; - net_dev->ethtool_ops = &ipw_ethtool_ops; +SET_ETHTOOL_OPS (net_dev, &ipw_ethtool_ops); err =sysfs_create_group (&pdev->dev.kobj, &ipw_attribute_group);if (err) {
drivers/net/wireless/libertas/main.c +1 -1
@@ -995,7 +995,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) dev->netdev_ops = &lbs_netdev_ops; dev->watchdog_timeo =5 *HZ ; - dev->ethtool_ops = &lbs_ethtool_ops; +SET_ETHTOOL_OPS (dev, &lbs_ethtool_ops); dev->flags |=IFF_BROADCAST |IFF_MULTICAST ; priv->card = card;
drivers/net/wireless/libertas/mesh.c +1 -1
@@ -1016,7 +1016,7 @@ static int lbs_add_mesh(struct lbs_private *priv) priv->mesh_dev = mesh_dev; mesh_dev->netdev_ops = &mesh_netdev_ops; - mesh_dev->ethtool_ops = &lbs_ethtool_ops; +SET_ETHTOOL_OPS (mesh_dev, &lbs_ethtool_ops);eth_hw_addr_inherit (mesh_dev, priv->dev);SET_NETDEV_DEV (priv->mesh_dev, priv->dev->dev.parent);
drivers/net/wireless/mwifiex/cfg80211.c +1 -1
@@ -2296,7 +2296,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, dev->flags |=IFF_BROADCAST |IFF_MULTICAST ; dev->watchdog_timeo =MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT ; dev->hard_header_len +=MWIFIEX_MIN_DATA_HEADER_LEN ; - dev->ethtool_ops = &mwifiex_ethtool_ops; +SET_ETHTOOL_OPS (dev, &mwifiex_ethtool_ops); mdev_priv =netdev_priv (dev); *((unsigned long *) mdev_priv) = (unsigned long ) priv;
drivers/net/wireless/prism54/islpci_dev.c +1 -1
@@ -834,7 +834,7 @@ islpci_setup(struct pci_dev *pdev)/* initialize the function pointers */ ndev->netdev_ops = &islpci_netdev_ops; ndev->wireless_handlers = &prism54_handler_def; - ndev->ethtool_ops = &islpci_ethtool_ops; +SET_ETHTOOL_OPS (ndev, &islpci_ethtool_ops);/* ndev->set_multicast_list = &islpci_set_multicast_list; */ ndev->addr_len =ETH_ALEN ;
drivers/staging/bcm/Bcmnet.c +1 -1
@@ -195,7 +195,7 @@ int register_networkdev(struct bcm_mini_adapter *Adapter)int result; net->netdev_ops = &bcmNetDevOps; - net->ethtool_ops = &bcm_ethtool_ops; +SET_ETHTOOL_OPS (net, &bcm_ethtool_ops); net->mtu =MTU_SIZE ;/* 1400 Bytes */ net->tx_queue_len =TX_QLEN ; net->flags |=IFF_NOARP ;
drivers/staging/rtl8192e/rtl8192e/rtl_core.c +1 -1
@@ -2928,7 +2928,7 @@ static int rtl8192_pci_probe(struct pci_dev *pdev, dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def; - dev->ethtool_ops = &rtl819x_ethtool_ops; +SET_ETHTOOL_OPS (dev, &rtl819x_ethtool_ops); dev->type =ARPHRD_ETHER ; dev->watchdog_timeo =HZ *3 ;
drivers/staging/wlags49_h2/wl_netdev.c +1 -2
@@ -1183,8 +1183,7 @@ struct net_device *wl_device_alloc(void) dev->watchdog_timeo =TX_TIMEOUT ; - dev->ethtool_ops = &wl_ethtool_ops; - +SET_ETHTOOL_OPS (dev, &wl_ethtool_ops);netif_stop_queue (dev);/* Allocate virtual devices for WDS support if needed */
net/8021q/vlan_dev.c +1 -1
@@ -831,7 +831,7 @@ void vlan_setup(struct net_device *dev) dev->netdev_ops = &vlan_netdev_ops; dev->destructor = free_netdev; - dev->ethtool_ops = &vlan_ethtool_ops; +SET_ETHTOOL_OPS (dev, &vlan_ethtool_ops);memset (dev->broadcast,0 ,ETH_ALEN ); }
Signature · 1 line
1.9.0
Quoted 56 lines · Andi Kleen
There has been a lot of interest recently to run Linux on very small systems, like Quark systems. These may have only 2-4MB memory. They are also limited by flash space.
One problem on these small system is the size of the network stack. Currently enabling IPv4 costs about 400k in text, which is prohibitive on a 2MB system, and very expensive with 4MB.
There were proposals to instead use LWIP in user space. LWIP with its socket interface comes in at a bit over 100k overhead per application.
I maintain that the Linux network stack is actually not that bloated, it just has a lot of features :-) The goal of this project was to subset it in a sensible way so that the native kernel stack becomes competitive with LWIP.
It turns out that the standard stack has a couple of features that are not really needed on client systems. Luckily it is also relatively well modularized, so it becomes possible to stub out these features at the edge.
With removing these features we still have a powerful TCP/IP stack, but one that fits better into small systems.
It would have been prohibitive to ifdef every optional feature. This patchkit relies heavily on LTO to effectively remove unused code. This allows to disable features only at the module boundaries, and rely on the compiler to drop unreferenced code and data.
A few features have been also reimplemented in a simpler way. And I shrank a number of data structures based on
CONFIG_BASE_SMALL.With these changes I can get a fully featured network stack down to about 170k with LTO. Without LTO there are also benefits, but somewhat less.
There are essentially three sensible configurations:
- Full featured like today.
- Client only subset, but still works with standard distribution userland. Remove some obscure features like fastopen, make all tables smaller, packet socket mmap code, use a simpler routing table, remove high speed networking features like RPX, XPS, GRO offload. Disable SNMP, TCP metrics
- Minimal subset for deeply embedded systems that can use special userland. Remove rtnetlink (ioctl only), remove ethtool, raw sockets.Right now I'm using own Kconfigs for every removed features. I realize this somewhat increases the compile test matrix. It would be possible to hide some of the options and select them using higher level configurations like the ones listed above. I haven't done this in this version.
At this point I'm mainly interested in review and comments.
Git trees:
Quoted 7 lines
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat Main tree
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat-3.143.14 based tree.Thanks to Tom Zanussi for contributions and testing.
What kind of userspace do you use on such a small system? It looks like you run kernels without procfs and netlink, so not even ps would work. :)
Signature · 2 lines
Thanks, //richard
Quoted 60 lines · Richard Weinberger
Quoted 59 lines · Andi Kleen
There has been a lot of interest recently to run Linux on very small systems, like Quark systems. These may have only 2-4MB memory. They are also limited by flash space.
One problem on these small system is the size of the network stack. Currently enabling IPv4 costs about 400k in text, which is prohibitive on a 2MB system, and very expensive with 4MB.
There were proposals to instead use LWIP in user space. LWIP with its socket interface comes in at a bit over 100k overhead per application.
I maintain that the Linux network stack is actually not that bloated, it just has a lot of features :-) The goal of this project was to subset it in a sensible way so that the native kernel stack becomes competitive with LWIP.
It turns out that the standard stack has a couple of features that are not really needed on client systems. Luckily it is also relatively well modularized, so it becomes possible to stub out these features at the edge.
With removing these features we still have a powerful TCP/IP stack, but one that fits better into small systems.
It would have been prohibitive to ifdef every optional feature. This patchkit relies heavily on LTO to effectively remove unused code. This allows to disable features only at the module boundaries, and rely on the compiler to drop unreferenced code and data.
A few features have been also reimplemented in a simpler way. And I shrank a number of data structures based on
CONFIG_BASE_SMALL.With these changes I can get a fully featured network stack down to about 170k with LTO. Without LTO there are also benefits, but somewhat less.
There are essentially three sensible configurations:
- Full featured like today.
- Client only subset, but still works with standard distribution userland. Remove some obscure features like fastopen, make all tables smaller, packet socket mmap code, use a simpler routing table, remove high speed networking features like RPX, XPS, GRO offload. Disable SNMP, TCP metrics
- Minimal subset for deeply embedded systems that can use special userland. Remove rtnetlink (ioctl only), remove ethtool, raw sockets.Right now I'm using own Kconfigs for every removed features. I realize this somewhat increases the compile test matrix. It would be possible to hide some of the options and select them using higher level configurations like the ones listed above. I haven't done this in this version.
At this point I'm mainly interested in review and comments.
Git trees:
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat Main tree
Quoted 9 lines
Quoted 4 lines
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat-3.143.14 based tree.Thanks to Tom Zanussi for contributions and testing.
What kind of userspace do you use on such a small system? It looks like you run kernels without procfs and netlink, so not even ps would work. :)
The microYocto 'distro' I have running with these net-diet patches doesn't use a full procfs, but a pared-down version (CONFIG_PROCFS_MIN). Keeping ps working is of course essential, and it does that (along with a couple other things like /proc/filesystems and /proc/mounts I needed to boot):
https://github.com/tzanussi/linux-yocto-micro-3.14/commit/68379432afcfa82ac695d9f02892fcf48ade5ae8
Anyway all the userspace and kernel bits are available for anyone who wants to build it and try it out:
https://github.com/tzanussi/meta-galileo/blob/daisy/meta-galileo/README
It's very much a work-in-progress with a lot of rough edges, but it is a fully functional system on real hardware (Galileo board/Quark processor) with a usable shell (ps too!) and web server running on a kernel with native networking and ~ 750k text size.
Tom
Quoted 82 lines · Tom Zanussi
Quoted 60 lines · Richard Weinberger
Quoted 59 lines · Andi Kleen
There has been a lot of interest recently to run Linux on very small systems, like Quark systems. These may have only 2-4MB memory. They are also limited by flash space.
One problem on these small system is the size of the network stack. Currently enabling IPv4 costs about 400k in text, which is prohibitive on a 2MB system, and very expensive with 4MB.
There were proposals to instead use LWIP in user space. LWIP with its socket interface comes in at a bit over 100k overhead per application.
I maintain that the Linux network stack is actually not that bloated, it just has a lot of features :-) The goal of this project was to subset it in a sensible way so that the native kernel stack becomes competitive with LWIP.
It turns out that the standard stack has a couple of features that are not really needed on client systems. Luckily it is also relatively well modularized, so it becomes possible to stub out these features at the edge.
With removing these features we still have a powerful TCP/IP stack, but one that fits better into small systems.
It would have been prohibitive to ifdef every optional feature. This patchkit relies heavily on LTO to effectively remove unused code. This allows to disable features only at the module boundaries, and rely on the compiler to drop unreferenced code and data.
A few features have been also reimplemented in a simpler way. And I shrank a number of data structures based on
CONFIG_BASE_SMALL.With these changes I can get a fully featured network stack down to about 170k with LTO. Without LTO there are also benefits, but somewhat less.
There are essentially three sensible configurations:
- Full featured like today.
- Client only subset, but still works with standard distribution userland. Remove some obscure features like fastopen, make all tables smaller, packet socket mmap code, use a simpler routing table, remove high speed networking features like RPX, XPS, GRO offload. Disable SNMP, TCP metrics
- Minimal subset for deeply embedded systems that can use special userland. Remove rtnetlink (ioctl only), remove ethtool, raw sockets.Right now I'm using own Kconfigs for every removed features. I realize this somewhat increases the compile test matrix. It would be possible to hide some of the options and select them using higher level configurations like the ones listed above. I haven't done this in this version.
At this point I'm mainly interested in review and comments.
Git trees:
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat Main treeQuoted 9 lines
Quoted 4 lines
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat-3.143.14 based tree.Thanks to Tom Zanussi for contributions and testing.
What kind of userspace do you use on such a small system? It looks like you run kernels without procfs and netlink, so not even ps would work. :)
The microYocto 'distro' I have running with these net-diet patches doesn't use a full procfs, but a pared-down version (
CONFIG_PROCFS_MIN). Keeping ps working is of course essential, and it does that (along with a couple other things like/proc/filesystemsand/proc/mountsI needed to boot):https://github.com/tzanussi/linux-yocto-micro-3.14/commit/68379432afcfa82ac695d9f02892fcf48ade5ae8
Anyway all the userspace and kernel bits are available for anyone who wants to build it and try it out:
Quoted 6 lines
https://github.com/tzanussi/meta-galileo/blob/daisy/meta-galileo/README
It's very much a work-in-progress with a lot of rough edges, but it is a fully functional system on real hardware (Galileo board/Quark processor) with a usable shell (ps too!) and web server running on a kernel with native networking and ~ 750k text size.
Intel Galileo datasheet says:
- 400MHz 32bit Intel
- 512 KBytes of on-die embedded SRAM
- 256 MByte DRAM, enabled by the firmware by default
where did 2-4Mbyte restriction come from?
Anyway, with all these hacks you get a half functional kernel with "a lot of rough edges"
that is likely working only for the given very limited set of applications. Kernel function profiling can potentially achieve the same thing. Profile the kernel with the set of apps and then prune all cold functions out of kernel.
config explosion and LTO is unnecessary. Just some linker hacks. Obviously such kernel will also be half functional,
but you'll get big reduction in .text that it seems is the goal of this project.
Quoted 90 lines · Alexei Starovoitov
Quoted 82 lines · Tom Zanussi
Quoted 60 lines · Richard Weinberger
Quoted 59 lines · Andi Kleen
There has been a lot of interest recently to run Linux on very small systems, like Quark systems. These may have only 2-4MB memory. They are also limited by flash space.
One problem on these small system is the size of the network stack. Currently enabling IPv4 costs about 400k in text, which is prohibitive on a 2MB system, and very expensive with 4MB.
There were proposals to instead use LWIP in user space. LWIP with its socket interface comes in at a bit over 100k overhead per application.
I maintain that the Linux network stack is actually not that bloated, it just has a lot of features :-) The goal of this project was to subset it in a sensible way so that the native kernel stack becomes competitive with LWIP.
It turns out that the standard stack has a couple of features that are not really needed on client systems. Luckily it is also relatively well modularized, so it becomes possible to stub out these features at the edge.
With removing these features we still have a powerful TCP/IP stack, but one that fits better into small systems.
It would have been prohibitive to ifdef every optional feature. This patchkit relies heavily on LTO to effectively remove unused code. This allows to disable features only at the module boundaries, and rely on the compiler to drop unreferenced code and data.
A few features have been also reimplemented in a simpler way. And I shrank a number of data structures based on
CONFIG_BASE_SMALL.With these changes I can get a fully featured network stack down to about 170k with LTO. Without LTO there are also benefits, but somewhat less.
There are essentially three sensible configurations:
- Full featured like today.
- Client only subset, but still works with standard distribution userland. Remove some obscure features like fastopen, make all tables smaller, packet socket mmap code, use a simpler routing table, remove high speed networking features like RPX, XPS, GRO offload. Disable SNMP, TCP metrics
- Minimal subset for deeply embedded systems that can use special userland. Remove rtnetlink (ioctl only), remove ethtool, raw sockets.Right now I'm using own Kconfigs for every removed features. I realize this somewhat increases the compile test matrix. It would be possible to hide some of the options and select them using higher level configurations like the ones listed above. I haven't done this in this version.
At this point I'm mainly interested in review and comments.
Git trees:
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat Main treeQuoted 9 lines
Quoted 4 lines
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat-3.143.14 based tree.Thanks to Tom Zanussi for contributions and testing.
What kind of userspace do you use on such a small system? It looks like you run kernels without procfs and netlink, so not even ps would work. :)
The microYocto 'distro' I have running with these net-diet patches doesn't use a full procfs, but a pared-down version (
CONFIG_PROCFS_MIN). Keeping ps working is of course essential, and it does that (along with a couple other things like/proc/filesystemsand/proc/mountsI needed to boot):https://github.com/tzanussi/linux-yocto-micro-3.14/commit/68379432afcfa82ac695d9f02892fcf48ade5ae8
Anyway all the userspace and kernel bits are available for anyone who wants to build it and try it out:
Quoted 6 lines
https://github.com/tzanussi/meta-galileo/blob/daisy/meta-galileo/README
It's very much a work-in-progress with a lot of rough edges, but it is a fully functional system on real hardware (Galileo board/Quark processor) with a usable shell (ps too!) and web server running on a kernel with native networking and ~ 750k text size.
Quoted 7 lines
Intel Galileo datasheet says:
- 400MHz 32bit Intel
- 512 KBytes of on-die embedded SRAM
- 256 MByte DRAM, enabled by the firmware by defaultwhere did 2-4Mbyte restriction come from?
General 'order-of-magnitude' difference from the typical 'tiny distro' which typically targets about 16MB, so sort of arbitrary, but it's a nice round goal for similar systems I'm sure are coming.
Actually, a better goal would be to run only on the 512k SRAM, but let's start with something more achievable for a first cut.
Quoted 2 lines
Anyway, with all these hacks you get a half functional kernel with "a lot of rough edges"
'work-in-progress' see above.
Quoted 4 lines
that is likely working only for the given very limited set of applications. Kernel function profiling can potentially achieve the same thing. Profile the kernel with the set of apps and then prune all cold functions out of kernel.
Right, and are Profile-Guided-Optimization results now reproduceable? Better change it to Trace-Guided-Optimization. But yeah, for a single-purpose system where it's known exactly what will run for the lifetime of the system, it makes sense to get rid of all the codepaths that will never be hit.
Quoted 3 lines
config explosion and LTO is unnecessary. Just some linker hacks. Obviously such kernel will also be half functional,
but you'll get big reduction in .text that it seems is the goal of this project.
Quoted 111 lines · Tom Zanussi
Quoted 90 lines · Alexei Starovoitov
Quoted 82 lines · Tom Zanussi
Quoted 60 lines · Richard Weinberger
Quoted 59 lines · Andi Kleen
There has been a lot of interest recently to run Linux on very small systems, like Quark systems. These may have only 2-4MB memory. They are also limited by flash space.
One problem on these small system is the size of the network stack. Currently enabling IPv4 costs about 400k in text, which is prohibitive on a 2MB system, and very expensive with 4MB.
There were proposals to instead use LWIP in user space. LWIP with its socket interface comes in at a bit over 100k overhead per application.
I maintain that the Linux network stack is actually not that bloated, it just has a lot of features :-) The goal of this project was to subset it in a sensible way so that the native kernel stack becomes competitive with LWIP.
It turns out that the standard stack has a couple of features that are not really needed on client systems. Luckily it is also relatively well modularized, so it becomes possible to stub out these features at the edge.
With removing these features we still have a powerful TCP/IP stack, but one that fits better into small systems.
It would have been prohibitive to ifdef every optional feature. This patchkit relies heavily on LTO to effectively remove unused code. This allows to disable features only at the module boundaries, and rely on the compiler to drop unreferenced code and data.
A few features have been also reimplemented in a simpler way. And I shrank a number of data structures based on
CONFIG_BASE_SMALL.With these changes I can get a fully featured network stack down to about 170k with LTO. Without LTO there are also benefits, but somewhat less.
There are essentially three sensible configurations:
- Full featured like today.
- Client only subset, but still works with standard distribution userland. Remove some obscure features like fastopen, make all tables smaller, packet socket mmap code, use a simpler routing table, remove high speed networking features like RPX, XPS, GRO offload. Disable SNMP, TCP metrics
- Minimal subset for deeply embedded systems that can use special userland. Remove rtnetlink (ioctl only), remove ethtool, raw sockets.Right now I'm using own Kconfigs for every removed features. I realize this somewhat increases the compile test matrix. It would be possible to hide some of the options and select them using higher level configurations like the ones listed above. I haven't done this in this version.
At this point I'm mainly interested in review and comments.
Git trees:
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat Main treeQuoted 9 lines
Quoted 4 lines
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-miscnet/debloat-3.143.14 based tree.Thanks to Tom Zanussi for contributions and testing.
What kind of userspace do you use on such a small system? It looks like you run kernels without procfs and netlink, so not even ps would work. :)
The microYocto 'distro' I have running with these net-diet patches doesn't use a full procfs, but a pared-down version (
CONFIG_PROCFS_MIN). Keeping ps working is of course essential, and it does that (along with a couple other things like/proc/filesystemsand/proc/mountsI needed to boot):https://github.com/tzanussi/linux-yocto-micro-3.14/commit/68379432afcfa82ac695d9f02892fcf48ade5ae8
Anyway all the userspace and kernel bits are available for anyone who wants to build it and try it out:
Quoted 6 lines
https://github.com/tzanussi/meta-galileo/blob/daisy/meta-galileo/README
It's very much a work-in-progress with a lot of rough edges, but it is a fully functional system on real hardware (Galileo board/Quark processor) with a usable shell (ps too!) and web server running on a kernel with native networking and ~ 750k text size.
Quoted 7 lines
Intel Galileo datasheet says:
- 400MHz 32bit Intel
- 512 KBytes of on-die embedded SRAM
- 256 MByte DRAM, enabled by the firmware by defaultwhere did 2-4Mbyte restriction come from?
General 'order-of-magnitude' difference from the typical 'tiny distro' which typically targets about 16MB, so sort of arbitrary, but it's a nice round goal for similar systems I'm sure are coming.
Actually, a better goal would be to run only on the 512k SRAM, but let's start with something more achievable for a first cut.
Quoted 2 lines
Anyway, with all these hacks you get a half functional kernel with "a lot of rough edges"
'work-in-progress' see above.
Quoted 7 lines
Quoted 4 lines
that is likely working only for the given very limited set of applications. Kernel function profiling can potentially achieve the same thing. Profile the kernel with the set of apps and then prune all cold functions out of kernel.
Right, and are Profile-Guided-Optimization results now reproduceable? Better change it to Trace-Guided-Optimization. But yeah, for a
not quite. I'm saying: no extra optimizations, no GCC changes. Compile kernel as-is. Most functions have a stub for mcount() already. Use it to track whether kernel function was called or not. Collect this data in userspace (as perf already does), add few more functions that had 'notrace' attribute on them, and feed this into special linker that unpacks existing vmlinux, throws away cold functions, relocates the rest and here you have tiny vmlinux without recompilation.
Quoted 9 lines
single-purpose system where it's known exactly what will run for the lifetime of the system, it makes sense to get rid of all the codepaths that will never be hit.
Quoted 3 lines
config explosion and LTO is unnecessary. Just some linker hacks. Obviously such kernel will also be half functional,
but you'll get big reduction in .text that it seems is the goal of this project.
Quoted 7 lines
not quite. I'm saying: no extra optimizations, no GCC changes. Compile kernel as-is. Most functions have a stub for
mcount()already. Use it to track whether kernel function was called or not. Collect this data in userspace (as perf already does), add few more functions that had 'notrace' attribute on them, and feed this into special linker that unpacks existing vmlinux, throws away cold functions, relocates the rest and here you have tiny vmlinux without recompilation.
That's very difficult for networking code. How would you know you exercised all the corner cases in the TCP stack? And you wouldn't want a remotely exploitable system because some important error handler is missing.
I agree it may work for some other subsystems.
-Andi
Quoted 8 lines · Andi Kleen
Quoted 7 lines
not quite. I'm saying: no extra optimizations, no GCC changes. Compile kernel as-is. Most functions have a stub for
mcount()already. Use it to track whether kernel function was called or not. Collect this data in userspace (as perf already does), add few more functions that had 'notrace' attribute on them, and feed this into special linker that unpacks existing vmlinux, throws away cold functions, relocates the rest and here you have tiny vmlinux without recompilation.
Quoted 4 lines
That's very difficult for networking code. How would you know you exercised all the corner cases in the TCP stack? And you wouldn't want a remotely exploitable system because some important error handler is missing.
I think removing functions by linker will get you the same level of bugs then stubbing functions out by kconfig.
One doesn't have to use profile feedback to remove them.
Either linker or config approach seems pretty much equivalent to me. In case of config, a lot of patches need to be reviewed and maintained. In case of linker the embedded setup can pick and choose without burdening mainline. If it crashes, it will be clear that it crashed due to call to removed function. Iteratively you'll get a setup that works for this particular application.
Both approaches are full of potential crashes, undoing removal is much easier with linker. Best solution is to add memory and don't mess with .text.
Quoted 3 lines
I agree it may work for some other subsystems.
-Andi
Quoted 8 lines
Quoted 7 lines
Quoted 4 lines
that is likely working only for the given very limited set of applications. Kernel function profiling can potentially achieve the same thing. Profile the kernel with the set of apps and then prune all cold functions out of kernel.
Right, and are Profile-Guided-Optimization results now reproduceable? Better change it to Trace-Guided-Optimization. But yeah, for a
Quoted 7 lines
not quite. I'm saying: no extra optimizations, no GCC changes. Compile kernel as-is. Most functions have a stub for
mcount()already. Use it to track whether kernel function was called or not. Collect this data in userspace (as perf already does), add few more functions that had 'notrace' attribute on them, and feed this into special linker that unpacks existing vmlinux, throws away cold functions, relocates the rest and here you have tiny vmlinux without recompilation.
It sounds like unstripped kernel will not even fit on the target machine. If it+application would fit there, you'd have no reason to strip it down...
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Hi!
Quoted 14 lines
Quoted 8 lines
wants to build it and try it out:
https://github.com/tzanussi/meta-galileo/blob/daisy/meta-galileo/README
It's very much a work-in-progress with a lot of rough edges, but it is a fully functional system on real hardware (Galileo board/Quark processor) with a usable shell (ps too!) and web server running on a kernel with native networking and ~ 750k text size.
Intel Galileo datasheet says:
- 400MHz 32bit Intel
- 512 KBytes of on-die embedded SRAM
- 256 MByte DRAM, enabled by the firmware by default
Quoted 8 lines
where did 2-4Mbyte restriction come from?
Anyway, with all these hacks you get a half functional kernel with "a lot of rough edges"
that is likely working only for the given very limited set of applications. Kernel function profiling can potentially achieve the same thing. Profile the kernel with the set of apps and then prune all cold functions out of kernel.
That does not really work, right? As soon attacker triggers some error path you did not trigger in testing, your machine dies.
That no longer qualifies as functional kernel.
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
RE: A reduced Linux network stack for small systems
In reply to Andi KleenFrom: Andi Kleen
Quoted 3 lines
There has been a lot of interest recently to run Linux on very small systems, like Quark systems. These may have only 2-4MB memory. They are also limited by flash space.
I'm intrigued about the 2-4MB memory.
That is more that would typically be available on-chip in a DSP or FPGA. It sounds like an expensive SRAM chip.
OTOH a single SDRAM gives 16MB and DDR a lot more - and are a lot cheaper and lower power.
Most modern silicon can easily have SDRAM/DDR interfaces.
You may want some size reduction to run in 16MB, but it is not as problematic as running in 2MB.
With that little memory I wouldn't want to run anything that relied on dynamic memory allocation (after startup) - except for fixed size data buffers.
David
Re: A reduced Linux network stack for small systems
Quoted 6 lines
You may want some size reduction to run in 16MB, but it is not as problematic as running in 2MB.
With that little memory I wouldn't want to run anything that relied on dynamic memory allocation (after startup) - except for fixed size data buffers.
You mean like µhttpd 8) Been there, done that and Tom in fact sent me the patches to port it to Linux from 2.11BSD PDP/11.
You can do a lot in a very small space. Heck you can run a full 2.11BSD on a PDP/11 in 1MB, including network stack. You used to be able to build a full self hosting Linux 1.x on a 4MB 386.
If you are using glibc and GNU tools it isn't going to work, but long ago tools were written which just did the job they were supposed to do at the time and were small and tidy. Programmers were expected to use shell scripts to combine them for harder jobs rather than be the one person a year who invoked gnu-wibble --format-sideways-while-singing --tune=waltzing-matilda
Alan