Anakin Tung
Anakin Tung

Reputation: 419

not understand the mechanism of free_netdev

I study network-device-driver recently. But somehow not understand free_netdev this function.

I have read the following link: Possible de-reference of private data using net_device

The answer says that when free the network device, the private data will also be free.

After checking this function, I found that it will call the following function:

 void netdev_freemem(struct net_device *dev)
 {
     char *addr = (char *)dev - dev->padded; 
     kvfree(addr);
 }

But I cannot understand why call this function will free all the net_device memory, and also the private data?

Or my understanding is wrong...

Just wondering if someone can guide me to understand the mechanism of free_netdev.

Thanks in advance.

Upvotes: 1

Views: 329

Answers (2)

Anakin Tung
Anakin Tung

Reputation: 419

Thanks @Nithin

After checking code of alloc_netdev_mqs, I think it will be clear to draw a diagram to answer my own question. So from the diagram, we can see (char *)dev - dev->padded is just want to find the p's location, And free this p variable will just free all the allocated memory.

------------------- [p = kzalloc(alloc_size, GFP_KERNEL)]

------------------- [dev = PTR_ALIGN(p, NETDEV_ALIGN)]
                     since p may not aligned to NETDEV_ALIGN * n 
                     and the final added NETDEV_ALIGN - 1 is for the space
                     of dev - p

------------------- [size of net_device struct]


------------------- [do the size alignment of net_device struct]




------------------- [private data] 



------------------- [add final NETDEV_ALIGN - 1 for padding]

Upvotes: 0

Nithin
Nithin

Reputation: 191

Check out alloc_netdev() function definition in net/core/dev.c

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

p = kzalloc(alloc_size, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
    if (!p) 
    p = vzalloc(alloc_size);
if (!p) 
    return NULL;

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

It does a Kzalloc of sizeof(struct net_device) + sizeof_priv + padding_bytes.

So net_device private is memory immediately following struct net_device and hence kfree() of netdev frees even net_device_private memory.

Upvotes: 3

Related Questions