On Wed, Feb 28, 2024 at 10:41:37PM +0200, Andy Shevchenko wrote: > We have two new helpers struct_size_with_data() and struct_data_pointer() > that we can utilize in alloc_netdev_mqs() and netdev_priv(). Do it so. > > Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > --- > include/linux/netdevice.h | 3 ++- > net/core/dev.c | 10 +++++----- > 2 files changed, 7 insertions(+), 6 deletions(-) > > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > index c41019f34179..d046dca18854 100644 > --- a/include/linux/netdevice.h > +++ b/include/linux/netdevice.h > @@ -25,6 +25,7 @@ > #include <linux/bug.h> > #include <linux/delay.h> > #include <linux/atomic.h> > +#include <linux/overflow.h> > #include <linux/prefetch.h> > #include <asm/cache.h> > #include <asm/byteorder.h> > @@ -2668,7 +2669,7 @@ void dev_net_set(struct net_device *dev, struct net *net) > */ > static inline void *netdev_priv(const struct net_device *dev) > { > - return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN); > + return struct_data_pointer(dev, NETDEV_ALIGN); > } I really don't like hiding these trailing allocations from the compiler. Why can't something like this be done (totally untested): diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 118c40258d07..dae6df4fb177 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2475,6 +2475,8 @@ struct net_device { /** @page_pools: page pools created for this netdevice */ struct hlist_head page_pools; #endif + u32 priv_size; + u8 priv_data[] __counted_by(priv_size) __aligned(NETDEV_ALIGN); }; #define to_net_dev(d) container_of(d, struct net_device, dev) @@ -2665,7 +2667,7 @@ void dev_net_set(struct net_device *dev, struct net *net) */ static inline void *netdev_priv(const struct net_device *dev) { - return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN); + return dev->priv_data; } /* Set the sysfs physical device reference for the network logical device diff --git a/net/core/dev.c b/net/core/dev.c index cb2dab0feee0..afaaa3224656 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10814,18 +10814,14 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, return NULL; } - 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; - } + alloc_size = struct_size(p, priv_data, sizeof_priv); /* ensure 32-byte alignment of whole construct */ alloc_size += NETDEV_ALIGN - 1; p = kvzalloc(alloc_size, GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); if (!p) return NULL; + p->priv_size = sizeof_priv; dev = PTR_ALIGN(p, NETDEV_ALIGN); dev->padded = (char *)dev - (char *)p; -- Kees Cook