Message ID | 20240614115317.657700-1-leitao@debian.org |
---|---|
State | Superseded |
Headers | show |
Series | wifi: mt76: un-embedd netdev from mt76_dev | expand |
On Fri, Jun 14, 2024 at 04:52:42AM -0700, Breno Leitao wrote: > Embedding net_device into structures prohibits the usage of flexible > arrays in the net_device structure. For more details, see the discussion > at [1]. > > Un-embed the net_devices from struct mt76_dev by converting them > into pointers, and allocating them dynamically. Use the leverage > alloc_netdev_dummy() to allocate the net_device object at > mt76_dma_init(). > > The free of the device occurs at mt76_dma_cleanup(). > > Link: https://lore.kernel.org/all/20240229225910.79e224cf@kernel.org/ [1] > Signed-off-by: Breno Leitao <leitao@debian.org> > --- > > PS: Due to the lack of hardware, this patch was not tested on a real > hardware, unfortunately. > > PS2: this is the last driver that is still using embedded netdevices. ... > diff --git a/drivers/net/wireless/mediatek/mt76/dma.h b/drivers/net/wireless/mediatek/mt76/dma.h > index 1de5a2b20f74..6454a5eca13e 100644 > --- a/drivers/net/wireless/mediatek/mt76/dma.h > +++ b/drivers/net/wireless/mediatek/mt76/dma.h > @@ -116,4 +116,9 @@ mt76_dma_should_drop_buf(bool *drop, u32 ctrl, u32 buf1, u32 info) > } > } > > +static inline struct mt76_dev *mt76_from_netdev(struct net_device *dev) > +{ > + return *(struct mt76_dev **)netdev_priv(dev); > +} > + > #endif Hi Breno, I agree that the above is correct, but I wonder if somehow it is nicer to avoid explicit casts and instead take advantage of implicit casting too and from void *. Maybe something like this: static inline struct mt76_dev *mt76_from_netdev(struct net_device *dev) { struct mt76_dev **priv; priv = netdev_priv(dev); return *priv; } Further, some of the callers of mt76_from_netdev() cast the return value to (struct mt7615_dev *). Which seems a bit awkward seeing as it was very recently a void * (i.e. netdev_priv() returns void *). I wonder if something like this makes sense, which I believe would avoid the need for any callers to cast. static inline void *mt76_priv(struct net_device *dev) { struct mt76_dev **priv; priv = netdev_priv(dev); return *priv; } Ideas above compile tested only. Other than the above, which is clearly more about style than substance, this patch looks good to me. Reviewed-by: Simon Horman <horms@kernel.org>
Breno Leitao <leitao@debian.org> writes: > Embedding net_device into structures prohibits the usage of flexible > arrays in the net_device structure. For more details, see the discussion > at [1]. > > Un-embed the net_devices from struct mt76_dev by converting them > into pointers, and allocating them dynamically. Use the leverage > alloc_netdev_dummy() to allocate the net_device object at > mt76_dma_init(). > > The free of the device occurs at mt76_dma_cleanup(). > > Link: https://lore.kernel.org/all/20240229225910.79e224cf@kernel.org/ [1] > Signed-off-by: Breno Leitao <leitao@debian.org> > --- > > PS: Due to the lack of hardware, this patch was not tested on a real > hardware, unfortunately. > > PS2: this is the last driver that is still using embedded netdevices. Is this patch a dependency to other patches? I'm asking because it will be _slow_ to get this patch to net-next via wireless trees. If there's urgency then it's much better to take it directly to net-next (of course with acks from Felix and Lorenzo).
Hello Kalle, On Mon, Jun 17, 2024 at 12:03:49PM +0300, Kalle Valo wrote: > Breno Leitao <leitao@debian.org> writes: > > > Embedding net_device into structures prohibits the usage of flexible > > arrays in the net_device structure. For more details, see the discussion > > at [1]. > > > > Un-embed the net_devices from struct mt76_dev by converting them > > into pointers, and allocating them dynamically. Use the leverage > > alloc_netdev_dummy() to allocate the net_device object at > > mt76_dma_init(). > > > > The free of the device occurs at mt76_dma_cleanup(). > > > > Link: https://lore.kernel.org/all/20240229225910.79e224cf@kernel.org/ [1] > > Signed-off-by: Breno Leitao <leitao@debian.org> > > --- > > > > PS: Due to the lack of hardware, this patch was not tested on a real > > hardware, unfortunately. > > > > PS2: this is the last driver that is still using embedded netdevices. > > Is this patch a dependency to other patches? I'm asking because it will > be _slow_ to get this patch to net-next via wireless trees. If there's > urgency then it's much better to take it directly to net-next (of course > with acks from Felix and Lorenzo). Since this is the last patch for the whole flexible netdev work, I would prefer to have it through net-next then, so, we finish the whole work sooner rather than later. I will prepare a v2 with Simon's suggestion, and I can target net-next. I am just waiting a bit more to hear from Felix and Lorenzo. Thanks!
Breno Leitao <leitao@debian.org> writes: > Hello Kalle, > > On Mon, Jun 17, 2024 at 12:03:49PM +0300, Kalle Valo wrote: >> Breno Leitao <leitao@debian.org> writes: >> >> > Embedding net_device into structures prohibits the usage of flexible >> > arrays in the net_device structure. For more details, see the discussion >> > at [1]. >> > >> > Un-embed the net_devices from struct mt76_dev by converting them >> > into pointers, and allocating them dynamically. Use the leverage >> > alloc_netdev_dummy() to allocate the net_device object at >> > mt76_dma_init(). >> > >> > The free of the device occurs at mt76_dma_cleanup(). >> > >> > Link: https://lore.kernel.org/all/20240229225910.79e224cf@kernel.org/ [1] >> > Signed-off-by: Breno Leitao <leitao@debian.org> >> > --- >> > >> > PS: Due to the lack of hardware, this patch was not tested on a real >> > hardware, unfortunately. >> > >> > PS2: this is the last driver that is still using embedded netdevices. >> >> Is this patch a dependency to other patches? I'm asking because it will >> be _slow_ to get this patch to net-next via wireless trees. If there's >> urgency then it's much better to take it directly to net-next (of course >> with acks from Felix and Lorenzo). > > Since this is the last patch for the whole flexible netdev work, I would > prefer to have it through net-next then, so, we finish the whole work > sooner rather than later. Ok, even though I hate dealing with conflicts between trees I still think it's better to get this directly to net-next. I hate "hurry up!" emails even more ;)
diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c index ae83be572b94..b6a2746c187d 100644 --- a/drivers/net/wireless/mediatek/mt76/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/debugfs.c @@ -33,8 +33,8 @@ mt76_napi_threaded_set(void *data, u64 val) if (!mt76_is_mmio(dev)) return -EOPNOTSUPP; - if (dev->napi_dev.threaded != val) - return dev_set_threaded(&dev->napi_dev, val); + if (dev->napi_dev->threaded != val) + return dev_set_threaded(dev->napi_dev, val); return 0; } @@ -44,7 +44,7 @@ mt76_napi_threaded_get(void *data, u64 *val) { struct mt76_dev *dev = data; - *val = dev->napi_dev.threaded; + *val = dev->napi_dev->threaded; return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index f4f88c444e21..bf67b1f2348a 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -916,7 +916,7 @@ int mt76_dma_rx_poll(struct napi_struct *napi, int budget) struct mt76_dev *dev; int qid, done = 0, cur; - dev = container_of(napi->dev, struct mt76_dev, napi_dev); + dev = mt76_from_netdev(napi->dev); qid = napi - dev->napi; rcu_read_lock(); @@ -940,18 +940,35 @@ static int mt76_dma_init(struct mt76_dev *dev, int (*poll)(struct napi_struct *napi, int budget)) { + struct mt76_dev **priv; int i; - init_dummy_netdev(&dev->napi_dev); - init_dummy_netdev(&dev->tx_napi_dev); - snprintf(dev->napi_dev.name, sizeof(dev->napi_dev.name), "%s", + dev->napi_dev = alloc_netdev_dummy(sizeof(struct mt76_dev *)); + if (!dev->napi_dev) + return -ENOMEM; + + /* napi_dev private data points to mt76_dev parent, so, mt76_dev + * can be retrieved given napi_dev + */ + priv = netdev_priv(dev->napi_dev); + *priv = dev; + + dev->tx_napi_dev = alloc_netdev_dummy(sizeof(struct mt76_dev *)); + if (!dev->tx_napi_dev) { + free_netdev(dev->napi_dev); + return -ENOMEM; + } + priv = netdev_priv(dev->tx_napi_dev); + *priv = dev; + + snprintf(dev->napi_dev->name, sizeof(dev->napi_dev->name), "%s", wiphy_name(dev->hw->wiphy)); - dev->napi_dev.threaded = 1; + dev->napi_dev->threaded = 1; init_completion(&dev->mmio.wed_reset); init_completion(&dev->mmio.wed_reset_complete); mt76_for_each_q_rx(dev, i) { - netif_napi_add(&dev->napi_dev, &dev->napi[i], poll); + netif_napi_add(dev->napi_dev, &dev->napi[i], poll); mt76_dma_rx_fill(dev, &dev->q_rx[i], false); napi_enable(&dev->napi[i]); } @@ -1019,5 +1036,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev) mt76_free_pending_txwi(dev); mt76_free_pending_rxwi(dev); + free_netdev(dev->napi_dev); + free_netdev(dev->tx_napi_dev); } EXPORT_SYMBOL_GPL(mt76_dma_cleanup); diff --git a/drivers/net/wireless/mediatek/mt76/dma.h b/drivers/net/wireless/mediatek/mt76/dma.h index 1de5a2b20f74..6454a5eca13e 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.h +++ b/drivers/net/wireless/mediatek/mt76/dma.h @@ -116,4 +116,9 @@ mt76_dma_should_drop_buf(bool *drop, u32 ctrl, u32 buf1, u32 info) } } +static inline struct mt76_dev *mt76_from_netdev(struct net_device *dev) +{ + return *(struct mt76_dev **)netdev_priv(dev); +} + #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 11b9f22ca7f3..15f83b5adac7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -831,8 +831,8 @@ struct mt76_dev { struct mt76_mcu mcu; - struct net_device napi_dev; - struct net_device tx_napi_dev; + struct net_device *napi_dev; + struct net_device *tx_napi_dev; spinlock_t rx_lock; struct napi_struct napi[__MT_RXQ_MAX]; struct sk_buff_head rx_skb[__MT_RXQ_MAX]; diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c index 14304b063715..ea017f22fff2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c @@ -242,7 +242,7 @@ int mt7603_dma_init(struct mt7603_dev *dev) if (ret) return ret; - netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, + netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, mt7603_poll_tx); napi_enable(&dev->mt76.tx_napi); diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c index e7135b2f1742..966e3d2c295f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c @@ -67,7 +67,7 @@ static int mt7615_poll_tx(struct napi_struct *napi, int budget) { struct mt7615_dev *dev; - dev = container_of(napi, struct mt7615_dev, mt76.tx_napi); + dev = (struct mt7615_dev *)mt76_from_netdev(napi->dev); if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { napi_complete(napi); queue_work(dev->mt76.wq, &dev->pm.wake_work); @@ -89,7 +89,7 @@ static int mt7615_poll_rx(struct napi_struct *napi, int budget) struct mt7615_dev *dev; int done; - dev = container_of(napi->dev, struct mt7615_dev, mt76.napi_dev); + dev = (struct mt7615_dev *)mt76_from_netdev(napi->dev); if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { napi_complete(napi); @@ -282,7 +282,7 @@ int mt7615_dma_init(struct mt7615_dev *dev) if (ret < 0) return ret; - netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, + netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, mt7615_poll_tx); napi_enable(&dev->mt76.tx_napi); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c index e5ad635d3c56..35b7ebc2c9c6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c @@ -239,7 +239,7 @@ int mt76x02_dma_init(struct mt76x02_dev *dev) if (ret) return ret; - netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, + netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, mt76x02_poll_tx); napi_enable(&dev->mt76.tx_napi); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c index 0baa82c8df5a..0c62272fe7d0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c @@ -578,7 +578,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2) if (ret < 0) return ret; - netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, + netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, mt7915_poll_tx); napi_enable(&dev->mt76.tx_napi); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index f768e9389ac6..e75e7b6d3aaf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -219,7 +219,7 @@ static int mt7921_dma_init(struct mt792x_dev *dev) if (ret < 0) return ret; - netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, + netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, mt792x_poll_tx); napi_enable(&dev->mt76.tx_napi); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c index 07b74d492ce1..577574fb7a1e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c @@ -254,7 +254,7 @@ static int mt7925_dma_init(struct mt792x_dev *dev) if (ret < 0) return ret; - netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, + netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, mt792x_poll_tx); napi_enable(&dev->mt76.tx_napi); diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c index 5cc2d59b774a..45aed1e1b1a6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c @@ -340,7 +340,7 @@ int mt792x_poll_rx(struct napi_struct *napi, int budget) struct mt792x_dev *dev; int done; - dev = container_of(napi->dev, struct mt792x_dev, mt76.napi_dev); + dev = (struct mt792x_dev *)mt76_from_netdev(napi->dev); if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { napi_complete(napi); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c index 73e633d0d700..69a7d9b2e38b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c @@ -641,7 +641,7 @@ int mt7996_dma_init(struct mt7996_dev *dev) if (ret < 0) return ret; - netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, + netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, mt7996_poll_tx); napi_enable(&dev->mt76.tx_napi);
Embedding net_device into structures prohibits the usage of flexible arrays in the net_device structure. For more details, see the discussion at [1]. Un-embed the net_devices from struct mt76_dev by converting them into pointers, and allocating them dynamically. Use the leverage alloc_netdev_dummy() to allocate the net_device object at mt76_dma_init(). The free of the device occurs at mt76_dma_cleanup(). Link: https://lore.kernel.org/all/20240229225910.79e224cf@kernel.org/ [1] Signed-off-by: Breno Leitao <leitao@debian.org> --- PS: Due to the lack of hardware, this patch was not tested on a real hardware, unfortunately. PS2: this is the last driver that is still using embedded netdevices. drivers/net/wireless/mediatek/mt76/debugfs.c | 6 ++-- drivers/net/wireless/mediatek/mt76/dma.c | 31 +++++++++++++++---- drivers/net/wireless/mediatek/mt76/dma.h | 5 +++ drivers/net/wireless/mediatek/mt76/mt76.h | 4 +-- .../net/wireless/mediatek/mt76/mt7603/dma.c | 2 +- .../net/wireless/mediatek/mt76/mt7615/dma.c | 6 ++-- .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 2 +- .../net/wireless/mediatek/mt76/mt7915/dma.c | 2 +- .../net/wireless/mediatek/mt76/mt7921/pci.c | 2 +- .../net/wireless/mediatek/mt76/mt7925/pci.c | 2 +- .../net/wireless/mediatek/mt76/mt792x_dma.c | 2 +- .../net/wireless/mediatek/mt76/mt7996/dma.c | 2 +- 12 files changed, 45 insertions(+), 21 deletions(-)