This patchs add the CONFIG_ETHTOOL option which allows to remove
support for ethtool, not necessarly used on embedded systems. As this
is a size-reduction option, it depends on CONFIG_EMBEDDED. It allows
to save ~6 kilobytes of kernel code:
text data bss dec hex filename
1258447 123592 212992 1595031 185697 vmlinux
1252147 123592 212992 1588731 183dfb vmlinux.new
-6300 0 0 -6300 -189C +/-
Bonding and bridging both depends on Ethtool functionnality, so
ETHTOOL is selected automatically when either bonding and bridging are
selected.
Question: should we also remove ethtool-related functions from all
network drivers ?
This patch has been originally written by Matt Mackall
<[email protected]>, and is part of the Linux Tiny project.
Signed-off-by: Thomas Petazzoni <[email protected]>
Signed-off-by: Matt Mackall <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/net/Kconfig | 1 +
include/linux/ethtool.h | 16 ++++++++++++++++
init/Kconfig | 8 ++++++++
net/bridge/Kconfig | 1 +
net/core/Makefile | 3 ++-
net/core/dev.c | 4 ++++
6 files changed, 32 insertions(+), 1 deletion(-)
Index: linuxdev/drivers/net/Kconfig
===================================================================
--- linuxdev.orig/drivers/net/Kconfig
+++ linuxdev/drivers/net/Kconfig
@@ -61,6 +61,7 @@
config BONDING
tristate "Bonding driver support"
depends on INET
+ select ETHTOOL
---help---
Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
Channels together. This is called 'Etherchannel' by Cisco,
Index: linuxdev/include/linux/ethtool.h
===================================================================
--- linuxdev.orig/include/linux/ethtool.h
+++ linuxdev/include/linux/ethtool.h
@@ -283,6 +283,7 @@
struct net_device;
/* Some generic methods drivers may use in their ethtool_ops */
+#ifdef CONFIG_ETHTOOL
u32 ethtool_op_get_link(struct net_device *dev);
u32 ethtool_op_get_tx_csum(struct net_device *dev);
int ethtool_op_set_tx_csum(struct net_device *dev, u32 data);
@@ -296,6 +297,21 @@
int ethtool_op_set_ufo(struct net_device *dev, u32 data);
u32 ethtool_op_get_flags(struct net_device *dev);
int ethtool_op_set_flags(struct net_device *dev, u32 data);
+#else
+static inline u32 ethtool_op_get_link(struct net_device *dev) { return 0; }
+static inline u32 ethtool_op_get_tx_csum(struct net_device *dev) { return 0; }
+static inline int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) { return 0; }
+static inline int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) { return 0; }
+static inline int ethtool_op_set_tx_ipv6_csum(struct net_device *dev, u32 data) { return 0; }
+static inline u32 ethtool_op_get_sg(struct net_device *dev) { return 0; }
+static inline int ethtool_op_set_sg(struct net_device *dev, u32 data) { return 0; }
+static inline u32 ethtool_op_get_tso(struct net_device *dev) { return 0; }
+static inline int ethtool_op_set_tso(struct net_device *dev, u32 data) { return 0; }
+static inline u32 ethtool_op_get_ufo(struct net_device *dev) { return 0; }
+static inline int ethtool_op_set_ufo(struct net_device *dev, u32 data) { return 0; }
+static inline u32 ethtool_op_get_flags(struct net_device *dev) { return 0; }
+static inline int ethtool_op_set_flags(struct net_device *dev, u32 data) { return 0; }
+#endif
/**
* ðtool_ops - Alter and report network device settings
Index: linuxdev/init/Kconfig
===================================================================
--- linuxdev.orig/init/Kconfig
+++ linuxdev/init/Kconfig
@@ -740,6 +740,14 @@
for filesystems like NFS and for the flock() system
call. Disabling this option saves about 11k.
+config ETHTOOL
+ bool "Enable ethtool support" if EMBEDDED
+ depends on NET
+ default y
+ help
+ Disabling this option removes support for configuring
+ ethernet device features via ethtool. Saves about 6k.
+
config VM_EVENT_COUNTERS
default y
bool "Enable VM event counters for /proc/vmstat" if EMBEDDED
Index: linuxdev/net/bridge/Kconfig
===================================================================
--- linuxdev.orig/net/bridge/Kconfig
+++ linuxdev/net/bridge/Kconfig
@@ -6,6 +6,7 @@
tristate "802.1d Ethernet Bridging"
select LLC
select STP
+ select ETHTOOL
---help---
If you say Y here, then your Linux box will be able to act as an
Ethernet bridge, which means that the different Ethernet segments it
Index: linuxdev/net/core/Makefile
===================================================================
--- linuxdev.orig/net/core/Makefile
+++ linuxdev/net/core/Makefile
@@ -7,10 +7,11 @@
obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
-obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \
+obj-y += dev.o dev_mcast.o dst.o netevent.o \
neighbour.o rtnetlink.o utils.o link_watch.o filter.o
obj-$(CONFIG_XFRM) += flow.o
+obj-$(CONFIG_ETHTOOL) += ethtool.o
obj-y += net-sysfs.o
obj-$(CONFIG_NET_PKTGEN) += pktgen.o
obj-$(CONFIG_NETPOLL) += netpoll.o
Index: linuxdev/net/core/dev.c
===================================================================
--- linuxdev.orig/net/core/dev.c
+++ linuxdev/net/core/dev.c
@@ -3669,6 +3669,7 @@
return ret;
case SIOCETHTOOL:
+#ifdef CONFIG_ETHTOOL
dev_load(net, ifr.ifr_name);
rtnl_lock();
ret = dev_ethtool(net, &ifr);
@@ -3681,6 +3682,9 @@
ret = -EFAULT;
}
return ret;
+#else
+ return -EINVAL;
+#endif
/*
* These ioctl calls:
--
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com
Thomas Petazzoni wrote:
[...]
> --- linuxdev.orig/include/linux/ethtool.h
> +++ linuxdev/include/linux/ethtool.h
> @@ -283,6 +283,7 @@
> struct net_device;
>
> /* Some generic methods drivers may use in their ethtool_ops */
> +#ifdef CONFIG_ETHTOOL
> u32 ethtool_op_get_link(struct net_device *dev);
> u32 ethtool_op_get_tx_csum(struct net_device *dev);
> int ethtool_op_set_tx_csum(struct net_device *dev, u32 data);
> @@ -296,6 +297,21 @@
> int ethtool_op_set_ufo(struct net_device *dev, u32 data);
> u32 ethtool_op_get_flags(struct net_device *dev);
> int ethtool_op_set_flags(struct net_device *dev, u32 data);
> +#else
> +static inline u32 ethtool_op_get_link(struct net_device *dev) { return 0; }
> +static inline u32 ethtool_op_get_tx_csum(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) { return 0; }
> +static inline int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) { return 0; }
> +static inline int ethtool_op_set_tx_ipv6_csum(struct net_device *dev, u32 data) { return 0; }
> +static inline u32 ethtool_op_get_sg(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_sg(struct net_device *dev, u32 data) { return 0; }
> +static inline u32 ethtool_op_get_tso(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_tso(struct net_device *dev, u32 data) { return 0; }
> +static inline u32 ethtool_op_get_ufo(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_ufo(struct net_device *dev, u32 data) { return 0; }
> +static inline u32 ethtool_op_get_flags(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_flags(struct net_device *dev, u32 data) { return 0; }
The dummy setter functions should return -EOPNOTSUPP. The getter functions
just read device feature flags and could be made inline. They have no way
of returning failure.
[...]
> ===================================================================
> --- linuxdev.orig/net/core/dev.c
> +++ linuxdev/net/core/dev.c
> @@ -3669,6 +3669,7 @@
> return ret;
>
> case SIOCETHTOOL:
> +#ifdef CONFIG_ETHTOOL
> dev_load(net, ifr.ifr_name);
> rtnl_lock();
> ret = dev_ethtool(net, &ifr);
> @@ -3681,6 +3682,9 @@
> ret = -EFAULT;
> }
> return ret;
> +#else
> + return -EINVAL;
> +#endif
>
> /*
> * These ioctl calls:
You also need to conditionalise dev_disable_lro().
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
On Thu, 2008-07-31 at 11:27 +0200, Thomas Petazzoni wrote:
>
> +#else
> +static inline u32 ethtool_op_get_link(struct net_device *dev) { return 0; }
> +static inline u32 ethtool_op_get_tx_csum(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) { return 0; }
> +static inline int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) { return 0; }
> +static inline int ethtool_op_set_tx_ipv6_csum(struct net_device *dev, u32 data) { return 0; }
> +static inline u32 ethtool_op_get_sg(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_sg(struct net_device *dev, u32 data) { return 0; }
> +static inline u32 ethtool_op_get_tso(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_tso(struct net_device *dev, u32 data) { return 0; }
> +static inline u32 ethtool_op_get_ufo(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_ufo(struct net_device *dev, u32 data) { return 0; }
> +static inline u32 ethtool_op_get_flags(struct net_device *dev) { return 0; }
> +static inline int ethtool_op_set_flags(struct net_device *dev, u32 data) { return 0; }
> +#endif
It's alleged that these functions are called from 'core' network code in
some places, although I can't actually see any evidence of that anywhere
in Linus' tree except for vlans and bridging.
If that's actually the case, perhaps it makes sense to add a
WARN_ON_ONCE() to these empty functions, so that a developer who
disables CONFIG_ETHTOOL when they shouldn't will see a nasty warning
about it rather than a silent failure?
Btw, I see you've made bridging 'select ETHTOOL'; did you do the same
for vlan support?
--
David Woodhouse Open Source Technology Centre
[email protected] Intel Corporation
From: Ben Hutchings <[email protected]>
Date: Thu, 31 Jul 2008 11:40:05 +0100
> You also need to conditionalise dev_disable_lro().
That can only be done once the CONFIG_ETHTOOL select statement
is added for CONFIG_INET.
Which basically makes this CONFIG_ETHTOOL thing completely pointless.
From: David Woodhouse <[email protected]>
Date: Thu, 31 Jul 2008 11:42:47 +0100
> It's alleged that these functions are called from 'core' network code in
> some places, although I can't actually see any evidence of that anywhere
> in Linus' tree except for vlans and bridging.
>
> If that's actually the case, perhaps it makes sense to add a
> WARN_ON_ONCE() to these empty functions, so that a developer who
> disables CONFIG_ETHTOOL when they shouldn't will see a nasty warning
> about it rather than a silent failure?
>
> Btw, I see you've made bridging 'select ETHTOOL'; did you do the same
> for vlan support?
CONFIG_INET needs it too.
dev_disable_lro() calls the ethtool ops directly.
But it still needs to be conditional, because as I said what I see
happening next is this CONFIG_ETHTOOL thing getting jammed into each
and every network driver. (in fact, ethtool support code in a single
driver probably drarfs the 6K savings this initial patch is giving
us).
And at which point you'll have a broken system for drivers that
enable LRO and the user enables forwarding.
On Thu, 2008-07-31 at 03:49 -0700, David Miller wrote:
> From: Ben Hutchings <[email protected]>
> Date: Thu, 31 Jul 2008 11:40:05 +0100
>
> > You also need to conditionalise dev_disable_lro().
>
> That can only be done once the CONFIG_ETHTOOL select statement
> is added for CONFIG_INET.
>
> Which basically makes this CONFIG_ETHTOOL thing completely pointless.
Other potential approaches include not enabling LRO by default if
!CONFIG_ETHTOOL. Or having the driver(s) which _do_ enable LRO by
default 'select ETHTOOL'.
--
dwmw2
From: David Woodhouse <[email protected]>
Date: Thu, 31 Jul 2008 11:54:24 +0100
> Other potential approaches include not enabling LRO by default if
> !CONFIG_ETHTOOL. Or having the driver(s) which _do_ enable LRO by
> default 'select ETHTOOL'.
It is possible for us to generically enable LRO for every device,
since it is a software algorithm. And likely we will do something
like this in the not too distant future.
On Thu, 2008-07-31 at 03:51 -0700, David Miller wrote:
> CONFIG_INET needs it too.
>
> dev_disable_lro() calls the ethtool ops directly.
Ah, right. That's why it didn't show up in my grep.
There are solutions to that, as I said. Either we could 'select ETHTOOL'
in those drivers which enable LRO by default, or we could just make sure
they _don't_ enable LRO by default when CONFIG_ETHTOOL isn't set.
And if we end up doing LRO generically in software where the hardware
doesn't handle it, presumably we can do that without having to use
ethtool to change the hardware behaviour?
> But it still needs to be conditional, because as I said what I see
> happening next is this CONFIG_ETHTOOL thing getting jammed into each
> and every network driver. (in fact, ethtool support code in a single
> driver probably drarfs the 6K savings this initial patch is giving
> us).
I think we can avoid that. If the actual functions and the struct
ethtool_ops are static, and if we have something like...
#ifdef CONFIG_ETHTOOL
#define dev_set_ethtool_ops(dev, ops) dev->ethtool_ops = ops
#else
#define dev_set_ethtool_ops(dev, ops) (void)ops
#endif
... then it should all fall out silently. (Yeah, those definitions would
need 'hardening' but they're a proof of concept).
> And at which point you'll have a broken system for drivers that
> enable LRO and the user enables forwarding.
Obviously that needs avoiding. Thanks for the technical feedback.
After an offline discussion, I understand that if we can sort out the
actual technical issues, you'll carry this in the net tree. Thanks.
--
David Woodhouse Open Source Technology Centre
[email protected] Intel Corporation
From: David Woodhouse <[email protected]>
Date: Thu, 31 Jul 2008 12:29:30 +0100
> After an offline discussion, I understand that if we can sort out the
> actual technical issues, you'll carry this in the net tree. Thanks.
I will, but only because you threatened to bypass me and send them
directly to Linus. And frankly fighting someone willing to do things
like that is simply not worth my time, so I'll just merge them blindly.
You just let me know when you think they are ready for inclusion.
On Thu, 2008-07-31 at 04:33 -0700, David Miller wrote:
> From: David Woodhouse <[email protected]>
> Date: Thu, 31 Jul 2008 12:29:30 +0100
>
> > After an offline discussion, I understand that if we can sort out the
> > actual technical issues, you'll carry this in the net tree. Thanks.
>
> I will, but only because you threatened to bypass me and send them
> directly to Linus. And frankly fighting someone willing to do things
> like that is simply not worth my time, so I'll just merge them
> blindly.
That doesn't make a lot of sense, Dave. Just because I _submit_ them to
Linus, that doesn't mean he automatically takes them.
I only said I'd submit them directly to Linus because I _think_ he'd
agree with Andrew and I, and take them despite your objections. And
because I think that's the right thing for him to do.
I wasn't going to hack hera and just put them into his tree by myself.
But don't let me talk you out of taking the patches... :)
> You just let me know when you think they are ready for inclusion.
I'll do that; thanks.
--
dwmw2
From: David Woodhouse <[email protected]>
Date: Thu, 31 Jul 2008 12:46:41 +0100
> I only said I'd submit them directly to Linus because I _think_ he'd
> agree with Andrew and I, and take them despite your objections. And
> because I think that's the right thing for him to do.
I guess Linus is unable to participate in the discussion, voice his
opinion, and sort this out with the rest of us unless you submit the
patches directly to him for inclusion, right?
Can you at least begin to see why your doing that might irritate me?
> > You just let me know when you think they are ready for inclusion.
>
> I'll do that; thanks.
No problem.
On Thu, Jul 31, 2008 at 12:46:41PM +0100, David Woodhouse wrote:
> On Thu, 2008-07-31 at 04:33 -0700, David Miller wrote:
> > From: David Woodhouse <[email protected]>
> > Date: Thu, 31 Jul 2008 12:29:30 +0100
> >
> > > After an offline discussion, I understand that if we can sort out the
> > > actual technical issues, you'll carry this in the net tree. Thanks.
> >
> > I will, but only because you threatened to bypass me and send them
> > directly to Linus. And frankly fighting someone willing to do things
> > like that is simply not worth my time, so I'll just merge them
> > blindly.
>
> That doesn't make a lot of sense, Dave. Just because I _submit_ them to
> Linus, that doesn't mean he automatically takes them.
>
> I only said I'd submit them directly to Linus because I _think_ he'd
> agree with Andrew and I, and take them despite your objections. And
> because I think that's the right thing for him to do.
>...
I'm sure we can find simpler and less controversial ways to save 6 kB in
the network stack. E.g. Ilpo's past work on making inline functions in
the network stack out-of-line had far bigger effects than the patch in
this discussion. And as a bonus, his work brings benefits to everyone.
It might have also made more sense to spend some of the energy used in
this discussion instead on checking where the global 24 kB size increase
Thomas reported for 2.6.27-rc1 compared to 2.6.26 comes from.
It's kinda silly to spend time on creating and arguing about non-trivial
patches that might save a few kB for very few people while noone seems
to work on reducing the continuous size increase of the kernel that
affects everyone...
> dwmw2
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
Le Thu, 31 Jul 2008 18:58:20 +0300,
Adrian Bunk <[email protected]> a écrit :
> It might have also made more sense to spend some of the energy used
> in this discussion instead on checking where the global 24 kB size
> increase Thomas reported for 2.6.27-rc1 compared to 2.6.26 comes from.
I agree. This is something I'm working on. I hope to have results soon.
But I *fear* that the results will be: the size growth is 10 bytes
here, 22 bytes there, 35 bytes here, spread over hundreds of patches.
Something we can do anything against.
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com