Skip to contentSkip to conversation

net: shrink net_device by #ifdef-ing protocol-specific members

PATCH In review Lucian Adrian Grijincu 5 participants 11 messages Jul 27, 2009 – Jul 29, 2009

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 net: shrink net_device by #ifdef-ing protocol-specific members

Some members of net_device are used only by some protocols.

If those protocols are not compiled (as modules or linked in) they should not take up space in the structure.

These members are also used in inline functions defined in headers not protected by the protocol-specific CONFIG_ guards. Adding #ifdef CONFIG_* guards header wide is against the current style and more invasive than guarding only the definitions.

This patch includes a fix for an error spotted by Eric Dumazet <[email protected]> regarding mishandlement of modules in a previous version of the patch.

---
 include/linux/inetdevice.h |    2 ++
 include/linux/netdevice.h  |   14 ++++++++++++++
 include/net/ax25.h         |    2 ++
 net/core/dev.c             |    6 ++++++
 4 files changed, 24 insertions(+), 0 deletions(-)
include/linux/inetdevice.h +1 -0
index acef2a7..88132ff 100644
@@ -166,6 +166,7 @@ static __inline__ int bad_mask(__be32 mask, __be32 addr)
 
 #define endfor_ifa(in_dev) }
 
+#ifdef CONFIG_INET
 static inline struct in_device *__in_dev_get_rcu(const struct

net_device *dev)
{
struct in_device *in_dev = dev->ip_ptr;
@@ -192,6 +193,7 @@ __in_dev_get_rtnl(const struct net_device *dev)
{
return (struct in_device*)dev->ip_ptr;
}
+#endif /* CONFIG_INET */

extern void in_dev_finish_destroy(struct in_device *idev);

include/linux/netdevice.h +14 -0
index 8a17b6c..465c3de 100644
@@ -762,14 +762,28 @@ struct net_device
 #ifdef CONFIG_NET_DSA
 	void			*dsa_ptr;	/* dsa specific data */
 #endif
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
 	void 			*atalk_ptr;	/* AppleTalk link 	*/
+#endif
+#ifdef CONFIG_INET
 	void			*ip_ptr;	/* IPv4 specific data	*/
+#endif
+#if defined(CONFIG_DECNET) || defined(CONFIG_DECNET_MODULE)
 	void                    *dn_ptr;        /* DECnet specific data */
+#endif
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	void                    *ip6_ptr;       /* IPv6 specific data */
+#endif
+#if defined(CONFIG_ECONET) || defined(CONFIG_ECONET_MODULE)
 	void			*ec_ptr;	/* Econet specific data	*/
+#endif
+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 	void			*ax25_ptr;	/* AX.25 specific data */
+#endif
+#ifdef CONFIG_WIRELESS
 	struct wireless_dev	*ieee80211_ptr;	/* IEEE 802.11 specific data,
 						   assign before registering */
+#endif
 
 /*
  * Cache line mostly used on receive path (including eth_type_trans())
include/net/ax25.h +0 -0
index 717e219..37f86ac 100644
@@ -300,10 +300,12 @@ extern void ax25_digi_invert(const ax25_digi *,

ax25_digi *);
extern ax25_dev *ax25_dev_list;
extern spinlock_t ax25_dev_lock;

+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev) {
return dev->ax25_ptr;
}
+#endif

extern ax25_dev *ax25_addr_ax25dev(ax25_address *); extern void ax25_dev_device_up(struct net_device *);

net/core/dev.c +6 -0
index e2e9e4a..d8e85ba 100644
@@ -4686,9 +4686,15 @@ void netdev_run_todo(void)
 
 		/* paranoia */
 		BUG_ON(atomic_read(&dev->refcnt));
+#ifdef CONFIG_INET
 		WARN_ON(dev->ip_ptr);
+#endif
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		WARN_ON(dev->ip6_ptr);
+#endif
+#if defined(CONFIG_DECNET) || defined(CONFIG_DECNET_MODULE)
 		WARN_ON(dev->dn_ptr);
+#endif
 
 		if (dev->destructor)
 			dev->destructor(dev);
Signature · 1 line
1.6.3.3
maintainer
#1 lore raw

From: Lucian Adrian Grijincu <[email protected]>
Date: Mon, 27 Jul 2009 18:09:08 +0300

Quoted 4 lines

Some members of net_device are used only by some protocols.

If those protocols are not compiled (as modules or linked in) they should not take up space in the structure.

This benefits, at best, %0.000000001 of users of the Linux kernel, because every distribution is going to turn on every single option.

If you want to shrink structures, find ways to eliminate or shrink structure members in all cases.

I'm not applying this.

#2 lore raw
Quoted 7 lines · David Miller

From: Lucian Adrian Grijincu <[email protected]>
Date: Mon, 27 Jul 2009 18:09:08 +0300

Quoted 3 lines

Some members of net_device are used only by some protocols. If those protocols are not compiled (as modules or linked in) they should not take up space in the structure.

This benefits, at best, %0.000000001 of users of the Linux kernel, because every distribution is going to turn on every single option.

I think the cost of maintaining this is small and the percentage of users that benefit underestimated.

It does help handsets a trivial amount, which are unlikely to ever enable decnet or econet.

Quoted 2 lines

If you want to shrink structures, find ways to eliminate or shrink structure members in all cases.

Good advice.

maintainer
#3 lore raw

From: Joe Perches <[email protected]>
Date: Mon, 27 Jul 2009 09:23:01 -0700

Quoted 11 lines · David Miller
Quoted 7 lines

From: Lucian Adrian Grijincu <[email protected]>
Date: Mon, 27 Jul 2009 18:09:08 +0300

Quoted 3 lines

Some members of net_device are used only by some protocols. If those protocols are not compiled (as modules or linked in) they should not take up space in the structure.

This benefits, at best, %0.000000001 of users of the Linux kernel, because every distribution is going to turn on every single option.

I think the cost of maintaining this is small and the percentage of users that benefit underestimated.

Prove it.

Prove that it helps enough to maintain this ifdef abortion in our header files.

It only gives the false sense of satisfation that we're making our datastructures less bloated. We're not, and in fact they keep getting larger, and if we add these ifdefs the new excuse for bloat will be "but it gets compiled out on embedded et al. builds that don't use this or that feature."

Putting this crap in is just a big smoke screen which gives a disincentive for making real improvements in this area.

If I thought this was worthwhile I would have done it 10 years ago.

#4 lore raw
Quoted 5 lines · David Miller

From: Joe Perches <[email protected]>
Date: Mon, 27 Jul 2009 09:23:01 -0700

Quoted 2 lines

I think the cost of maintaining this is small and the percentage of users that benefit underestimated.

Prove it.

Cost/bit/knot valuations are arbitrary.

cheers, Joe

#10 lore raw
In reply to Lucian Adrian Grijincu

include/linux/netdevice.h struct net_device · line 786

Quoted 7 lines · On Monday 27 July 2009 18:09:08 ext Lucian Adrian Grijincu wrote:
include/linux/netdevice.h +4 -0
+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 	void			*ax25_ptr;	/* AX.25 specific data */
+#endif
+#ifdef CONFIG_WIRELESS
 	struct wireless_dev	*ieee80211_ptr;	/* IEEE 802.11 specific data,
 						   assign before registering */
+#endif

If I'm not mistaken, AX.25 can only be used with ARPHRD_AX25 devices, no? Should there be a single opaque pointer for all non-generic address families do, that would only be used by the one matching the header type?

Signature · 2 lines
Rémi Denis-Courmont
Nokia Devices R&D, Maemo Software, Helsinki
#5 lore raw
In reply to David Miller
Quoted 11 lines · On Monday 27 July 2009 18:26:44 David Miller wrote:

From: Lucian Adrian Grijincu <[email protected]>
Date: Mon, 27 Jul 2009 18:09:08 +0300

Quoted 4 lines

Some members of net_device are used only by some protocols.

If those protocols are not compiled (as modules or linked in) they should not take up space in the structure.

This benefits, at best, %0.000000001 of users of the Linux kernel, because every distribution is going to turn on every single option.

Not all Linux users are using regular (desktop/server) distributions. Linux is used in embedded systems as well and in these case it makes sense to turn off ax25/econet/decnet and in some cases even wireless/ipv6.

Quoted 2 lines

If you want to shrink structures, find ways to eliminate or shrink structure members in all cases.

We are looking into that as well since we have a pretty aggressive goal (get net_device to 450 bytes or so), but we thought of starting with the low hanging fruits.

Any suggestions in this area?

tavi

#6 lore raw
Quoted 10 lines · Octavian Purdila
Quoted 6 lines · On Monday 27 July 2009 18:26:44 David Miller wrote:

From: Lucian Adrian Grijincu <[email protected]>

Quoted 3 lines

Some members of net_device are used only by some protocols. If those protocols are not compiled (as modules or linked in) they should not take up space in the structure.

This benefits, at best, %0.000000001 of users of the Linux kernel, because every distribution is going to turn on every single option.

Not all Linux users are using regular (desktop/server) distributions. Linux is used in embedded systems as well and in these case it makes sense to turn off ax25/econet/decnet and in some cases even wireless/ipv6.

Quoted 6 lines
Quoted 2 lines

If you want to shrink structures, find ways to eliminate or shrink structure members in all cases.

We are looking into that as well since we have a pretty aggressive goal (get net_device to 450 bytes or so), but we thought of starting with the low hanging fruits.
Any suggestions in this area?

Some maybe not so good ones:

Perhaps:

	struct timer_list	watchdog_timer;
might become a
	struct timer_list	*watchdog_timer;

Maybe all the protocol/mac/bridge/vlan/garp/wireless specific pointers might become a pointer to a list or array of pointers allocated on demand.

Maybe combine perm_addr/broadcast/mc_list/uc addresses into a single list with type information. Maybe include dev_addrs, but it's iterated with an rcu lock held.

Gaining less than 0, except maybe for weird network testing devices, use a pointer to struct net_device_stats.

maintainer
#8 lore raw
In reply to Octavian Purdila

From: Octavian Purdila <[email protected]>
Date: Tue, 28 Jul 2009 17:43:27 +0300

Quoted 7 lines · On Monday 27 July 2009 18:26:44 David Miller wrote:
Quoted 4 lines

This benefits, at best, %0.000000001 of users of the Linux kernel, because every distribution is going to turn on every single option.

Not all Linux users are using regular (desktop/server) distributions.

I didn't say all, I said "nearly all" which for many considerations is roughly equivalent.

That %0.0000000001 was meant to represent non-distribution users.

#9 lore raw
Quoted 7 lines · On Tuesday 28 July 2009 20:28:08 David Miller wrote:

From: Octavian Purdila <[email protected]>
Date: Tue, 28 Jul 2009 17:43:27 +0300

Quoted 4 lines · On Monday 27 July 2009 18:26:44 David Miller wrote:
Quoted 2 lines

This benefits, at best, %0.000000001 of users of the Linux kernel, because every distribution is going to turn on every single option.

Quoted 6 lines
Quoted 1 line

Not all Linux users are using regular (desktop/server) distributions.

I didn't say all, I said "nearly all" which for many considerations is roughly equivalent.

That %0.0000000001 was meant to represent non-distribution users.

There are many embedded / dedicated devices out there which use a customized Linux kernel (wireless routers and other network appliances, set-top boxes, TVs, etc.).

I have no idea about what the actual percent of the Linux users these account for, but to dismiss it as %0.0000000001 seems like a rush statement to me.

tavi

#7 lore raw
In reply to Joe Perches
Quoted 16 lines · On Tuesday 28 July 2009 19:49:15 Joe Perches wrote:
Quoted 4 lines

We are looking into that as well since we have a pretty aggressive goal (get net_device to 450 bytes or so), but we thought of starting with the low hanging fruits.
Any suggestions in this area?

Some maybe not so good ones:

Perhaps:

	struct timer_list	watchdog_timer;
might become a
	struct timer_list	*watchdog_timer;

Maybe all the protocol/mac/bridge/vlan/garp/wireless specific pointers might become a pointer to a list or array of pointers allocated on demand.

Quoted 6 lines

Maybe combine perm_addr/broadcast/mc_list/uc addresses into a single list with type information. Maybe include dev_addrs, but it's iterated with an rcu lock held.

Gaining less than 0, except maybe for weird network testing devices, use a pointer to struct net_device_stats.

Thanks for the suggestions.

BTW, we've noticed that the biggest net_device consumer is struct device with 176 bytes consumed on our arch (powerpc) and the only things that are used from it seems to be the numa node id and the driver name. Some drivers also use it but most of the usage seems to be related to sysfs.

Do you think its worth trying to make dev dependent on CONFIG_SYSFS?

tavi