0
votes

Recently I study the linux network driver, and I have some problem for the memory alignment in the structure.

here is the code fragment for in net/core/dev.c alloc_netdev_mqs:

alloc_size = sizeof(struct net_device)
if(sizeof_priv) 
{
    alloc_size = ALIGN(alloc_size, NETDEV_ALIGN) ---------(1)
    alloc_size += sizeof_priv;
}
/*ensure 32-byte alignment of whole construct*/
alloc_size += NETDEV_ALIGN - 1;                  ----------(2)

In the (1) place, I think it is reasonable to do ALIGN, since we want to align the struct net_device to the multiplier of NETDEV_ALIGN.

But in (2) place, in order to make alignment, why not use: ALIGN(alloc_size, NETDEV_ALIGN) again??

for example if we have : net_device 3 byte, NETDEV_ALIGN 4 byte, and private date 2 byte:

in (1) place we have ALIGN(3, 4) => 4byte then the (private data size) + (net device size) = 4+2 = 6 byte

in (2) why not use ALIGN(6, 4) => 8byte ??

I just cannot figure out why, and not find answer by googling. Any help will be appreciated!

1

1 Answers

0
votes

The thing is that NETDEV_ALIGN=32 is more than alignment provided by kmalloc (at most 16 bytes). Because of that alignment of the structure is forced using additional padding:

p = kzalloc(alloc_size,...);
....
dev = PTR_ALIGN(p, NETDEV_ALIGN);
dev->padded = (char *)dev - (char *)p;

Additional value NETDEV_ALIGN - 1 is used for provide bytes for padding (which can never exceed this value).