Where is the private data stored for each net_device in Linux kernel 2.6.32 or later?

c, linux, linux-kernel

Solution

This answer references version 3.14 of the Linux kernel.

The private data is stored at the end of the `net_device` structure.

You allocate a `net_device` by calling `alloc_netdev`, which is just a macro for `alloc_netdev_mqs`. The first parameter is `int sizeof_priv`, which specifies the amount of additional space you wish to be allocated at the end of the `net_device` for your private data.

You access this private data by calling the (inline) function `netdev_priv`. By looking at that function, you can see it just returns an aligned pointer after the end of the real `struct net_device`:

static inline void *netdev_priv(const struct net_device *dev)
{
    return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
}

I'm going to assume that the developers did this for cache reasons. This way, the private data will fall on the same cache line as the rest of the structure, instead of having to access memory very far away from the `net_device` via the `priv` pointer.

As an example, the Intel e100 driver defines a private `struct nic` in e100.c, and allocates its `net_device` in `e100_probe`. You see that it passes `sizeof(struct nic)` to `alloc_etherdev`, which is a convenience function for allocating Ethernet devices:

static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
     struct net_device *netdev;
     struct nic *nic;
     int err;

     if (!(netdev = alloc_etherdev(sizeof(struct nic))))
         return -ENOMEM;

Then to access this private data elsewhere, they call `netdev_priv`, as seen here in `mdio_write`:

static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
{
    struct nic *nic = netdev_priv(netdev);

    nic->mdio_ctrl(nic, addr, mdi_write, reg, data);
}

Problem

For Linux kernel 2.4 or 2.6 earlier than 2.6.31, the `net_device` struct for each registered network device has a private data block associated with it, which is pointed to by the `priv` pointer in the `net_device` struct. However, for kernel version 2.6.32 or later, the `priv` pointer has been deprecated. I am wondering where the network interface driver's private data can be stored now. Is anyone clear of the relatively new implementation of `net_device` struct? Thanks in advance.

Original source