Subject: Re: netdev->priv and netdev_priv(dev)

From: Stephen Hemminger <[email-masked]>
Date: Tue, 29 Jan 2008 12:42:59 -0800

On Tue, 29 Jan 2008 21:10:00 +0100
Krzysztof Halasa <[email-masked]> wrote:

> A commit few months ago introduced a change:
> 
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
>  
>  static inline void *netdev_priv(const struct net_device *dev)
>  {
> -       return (char *)dev + ((sizeof(struct net_device)
> -                                       + NETDEV_ALIGN_CONST)
> -                               & ~NETDEV_ALIGN_CONST);
> +       return dev->priv;
>  }
>  
> This change caused some problems for drivers which used
> netdev_priv(dev) and dev->priv for different purposes.
> 

Those drivers were making a incorrect assumption and should be fixed.
The in-tree drivers were fixed when this was done. If you have an out
of tree driver, then too bad for you.

> 
> The following patch restores previous behaviour.
> 
> Signed-off-by: Krzysztof Halasa <[email-masked]>
> 
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -584,7 +584,10 @@ struct net_device
>  
>  static inline void *netdev_priv(const struct net_device *dev)
>  {
> -	return dev->priv;
> +	return (char *)dev + ((sizeof(struct net_device) +
> +			       sizeof(struct net_device_subqueue) *
> +			       (dev->egress_subqueue_count - 1) +
> +			       NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
>  }
>  
>  #define SET_MODULE_OWNER(dev) do { } while (0)
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -3693,13 +3693,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
>  		(((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
>  	dev->padded = (char *)dev - (char *)p;
>  
> -	if (sizeof_priv) {
> -		dev->priv = ((char *)dev +
> -			     ((sizeof(struct net_device) +
> -			       (sizeof(struct net_device_subqueue) *
> -				(queue_count - 1)) + NETDEV_ALIGN_CONST)
> -			      & ~NETDEV_ALIGN_CONST));
> -	}
> +	if (sizeof_priv)
> +		dev->priv = netdev_priv(dev);
>  
>  	dev->egress_subqueue_count = queue_count;
>  

The additional overhead of the address calculation would slow down the
well behaved drivers.  There was discussion of alternative layouts of
the network device allocation or limiting the number of subqueue's so
that netdev_priv could be a simple addition again, but nothing came of
it.

-- 
Stephen Hemminger <[email-masked]>