Commit f346af6a authored by Alexander Viro's avatar Alexander Viro Committed by Stephen Hemminger

net_device and netdev private struct allocation improvements.

1) Ensure alignment of both net_device and private area.
2) Introduce netdev_priv(), an inline which allows the dynamic private
   area (dev->priv) to be calculated as a constant offset from the
   base struct net_device at compile time.
parent 373ed85e
......@@ -73,23 +73,28 @@
struct net_device *alloc_netdev(int sizeof_priv, const char *mask,
void (*setup)(struct net_device *))
{
void *p;
struct net_device *dev;
int alloc_size;
/* ensure 32-byte alignment of the private area */
alloc_size = sizeof (*dev) + sizeof_priv + 31;
/* ensure 32-byte alignment of both the device and private area */
dev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL);
if (dev == NULL)
{
printk(KERN_ERR "alloc_dev: Unable to allocate device memory.\n");
alloc_size = (sizeof(struct net_device) + 31) & ~31;
alloc_size += sizeof_priv + 31;
p = kmalloc (alloc_size, GFP_KERNEL);
if (!p) {
printk(KERN_ERR "alloc_dev: Unable to allocate device.\n");
return NULL;
}
memset(dev, 0, alloc_size);
memset(p, 0, alloc_size);
dev = (struct net_device *)(((long)p + 31) & ~31);
dev->padded = (char *)dev - (char *)p;
if (sizeof_priv)
dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
dev->priv = netdev_priv(dev);
setup(dev);
strcpy(dev->name, mask);
......
......@@ -470,8 +470,15 @@ struct net_device
/* class/net/name entry */
struct class_device class_dev;
struct net_device_stats* (*last_stats)(struct net_device *);
/* how much padding had been added by alloc_netdev() */
int padded;
};
static inline void *netdev_priv(struct net_device *dev)
{
return (char *)dev + ((sizeof(struct net_device) + 31) & ~31);
}
#define SET_MODULE_OWNER(dev) do { } while (0)
/* Set the sysfs physical device reference for the network logical device
* if set prior to registration will cause a symlink during initialization.
......
......@@ -2899,7 +2899,7 @@ void free_netdev(struct net_device *dev)
{
/* Compatiablity with error handling in drivers */
if (dev->reg_state == NETREG_UNINITIALIZED) {
kfree(dev);
kfree((char *)dev - dev->padded);
return;
}
......
......@@ -372,7 +372,7 @@ static void netdev_release(struct class_device *cd)
BUG_ON(dev->reg_state != NETREG_RELEASED);
kfree(dev);
kfree((char *)dev - dev->padded);
}
static struct class net_class = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment