Skip to content

Commit a2d2cad

Browse files
committedApr 24, 2024
Merge branch 'net-dunamic-dummy-device'
Breno Leitao says: ==================== allocate dummy device dynamically struct net_device shouldn't be embedded into any structure, instead, the owner should use the private space to embed their state into net_device. But, in some cases the net_device is embedded inside the private structure, which blocks the usage of zero-length arrays inside net_device. Create a helper to allocate a dummy device at dynamically runtime, and move the Ethernet devices to use it, instead of embedding the dummy device inside the private structure. This fixes all the network cases plus some wireless drivers. PS: Due to lack of hardware, unfortunately most these patches are compiled tested only, except ath11k that was kindly tested by Kalle Valo. --- Changelog: v7: * Document the return value of alloc_netdev_dummy() v6: * No code change. Just added Reviewed-by: and fix a commit message v5: * Added a new patch to fix some typos in the previous code * Rebased to net-net/main v4: * Added a new patch to add dummy device at free_netdev(), as suggested by Jakub. * Added support for some wireless driver. * Added some Acked-by and Reviewed-by. v3: * Use free_netdev() instead of kfree() as suggested by Jakub. * Change the free_netdev() place in ipa driver, as suggested by Alex Elder. * Set err in the error path in the Marvell driver, as suggested by Simon Horman. v2: * Patch 1: Use a pre-defined name ("dummy#") for the dummy net_devices. * Patch 2-5: Added users for the new helper. v1: * https://lore.kernel.org/all/[email protected]/ ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 55972ce + bca592e commit a2d2cad

File tree

19 files changed

+129
-53
lines changed

19 files changed

+129
-53
lines changed
 

‎drivers/net/ethernet/ibm/emac/mal.c

+11-3
Original file line numberDiff line numberDiff line change
@@ -605,9 +605,13 @@ static int mal_probe(struct platform_device *ofdev)
605605
INIT_LIST_HEAD(&mal->list);
606606
spin_lock_init(&mal->lock);
607607

608-
init_dummy_netdev(&mal->dummy_dev);
608+
mal->dummy_dev = alloc_netdev_dummy(0);
609+
if (!mal->dummy_dev) {
610+
err = -ENOMEM;
611+
goto fail_unmap;
612+
}
609613

610-
netif_napi_add_weight(&mal->dummy_dev, &mal->napi, mal_poll,
614+
netif_napi_add_weight(mal->dummy_dev, &mal->napi, mal_poll,
611615
CONFIG_IBM_EMAC_POLL_WEIGHT);
612616

613617
/* Load power-on reset defaults */
@@ -637,7 +641,7 @@ static int mal_probe(struct platform_device *ofdev)
637641
GFP_KERNEL);
638642
if (mal->bd_virt == NULL) {
639643
err = -ENOMEM;
640-
goto fail_unmap;
644+
goto fail_dummy;
641645
}
642646

643647
for (i = 0; i < mal->num_tx_chans; ++i)
@@ -703,6 +707,8 @@ static int mal_probe(struct platform_device *ofdev)
703707
free_irq(mal->serr_irq, mal);
704708
fail2:
705709
dma_free_coherent(&ofdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
710+
fail_dummy:
711+
free_netdev(mal->dummy_dev);
706712
fail_unmap:
707713
dcr_unmap(mal->dcr_host, 0x100);
708714
fail:
@@ -734,6 +740,8 @@ static void mal_remove(struct platform_device *ofdev)
734740

735741
mal_reset(mal);
736742

743+
free_netdev(mal->dummy_dev);
744+
737745
dma_free_coherent(&ofdev->dev,
738746
sizeof(struct mal_descriptor) *
739747
(NUM_TX_BUFF * mal->num_tx_chans +

‎drivers/net/ethernet/ibm/emac/mal.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ struct mal_instance {
205205
int index;
206206
spinlock_t lock;
207207

208-
struct net_device dummy_dev;
208+
struct net_device *dummy_dev;
209209

210210
unsigned int features;
211211
};

‎drivers/net/ethernet/marvell/prestera/prestera_rxtx.c

+12-3
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ struct prestera_sdma {
9696
struct dma_pool *desc_pool;
9797
struct work_struct tx_work;
9898
struct napi_struct rx_napi;
99-
struct net_device napi_dev;
99+
struct net_device *napi_dev;
100100
u32 map_addr;
101101
u64 dma_mask;
102102
/* protect SDMA with concurrent access from multiple CPUs */
@@ -654,13 +654,21 @@ static int prestera_sdma_switch_init(struct prestera_switch *sw)
654654
if (err)
655655
goto err_evt_register;
656656

657-
init_dummy_netdev(&sdma->napi_dev);
657+
sdma->napi_dev = alloc_netdev_dummy(0);
658+
if (!sdma->napi_dev) {
659+
dev_err(dev, "not able to initialize dummy device\n");
660+
err = -ENOMEM;
661+
goto err_alloc_dummy;
662+
}
658663

659-
netif_napi_add(&sdma->napi_dev, &sdma->rx_napi, prestera_sdma_rx_poll);
664+
netif_napi_add(sdma->napi_dev, &sdma->rx_napi, prestera_sdma_rx_poll);
660665
napi_enable(&sdma->rx_napi);
661666

662667
return 0;
663668

669+
err_alloc_dummy:
670+
prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_RXTX,
671+
prestera_rxtx_handle_event);
664672
err_evt_register:
665673
err_tx_init:
666674
prestera_sdma_tx_fini(sdma);
@@ -677,6 +685,7 @@ static void prestera_sdma_switch_fini(struct prestera_switch *sw)
677685

678686
napi_disable(&sdma->rx_napi);
679687
netif_napi_del(&sdma->rx_napi);
688+
free_netdev(sdma->napi_dev);
680689
prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_RXTX,
681690
prestera_rxtx_handle_event);
682691
prestera_sdma_tx_fini(sdma);

‎drivers/net/ethernet/mediatek/mtk_eth_soc.c

+13-4
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,7 @@ static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
17101710
if (IS_ERR(pp))
17111711
return pp;
17121712

1713-
err = __xdp_rxq_info_reg(xdp_q, &eth->dummy_dev, id,
1713+
err = __xdp_rxq_info_reg(xdp_q, eth->dummy_dev, id,
17141714
eth->rx_napi.napi_id, PAGE_SIZE);
17151715
if (err < 0)
17161716
goto err_free_pp;
@@ -4188,6 +4188,8 @@ static int mtk_free_dev(struct mtk_eth *eth)
41884188
metadata_dst_free(eth->dsa_meta[i]);
41894189
}
41904190

4191+
free_netdev(eth->dummy_dev);
4192+
41914193
return 0;
41924194
}
41934195

@@ -4983,16 +4985,23 @@ static int mtk_probe(struct platform_device *pdev)
49834985
/* we run 2 devices on the same DMA ring so we need a dummy device
49844986
* for NAPI to work
49854987
*/
4986-
init_dummy_netdev(&eth->dummy_dev);
4987-
netif_napi_add(&eth->dummy_dev, &eth->tx_napi, mtk_napi_tx);
4988-
netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx);
4988+
eth->dummy_dev = alloc_netdev_dummy(0);
4989+
if (!eth->dummy_dev) {
4990+
err = -ENOMEM;
4991+
dev_err(eth->dev, "failed to allocated dummy device\n");
4992+
goto err_unreg_netdev;
4993+
}
4994+
netif_napi_add(eth->dummy_dev, &eth->tx_napi, mtk_napi_tx);
4995+
netif_napi_add(eth->dummy_dev, &eth->rx_napi, mtk_napi_rx);
49894996

49904997
platform_set_drvdata(pdev, eth);
49914998
schedule_delayed_work(&eth->reset.monitor_work,
49924999
MTK_DMA_MONITOR_TIMEOUT);
49935000

49945001
return 0;
49955002

5003+
err_unreg_netdev:
5004+
mtk_unreg_dev(eth);
49965005
err_deinit_ppe:
49975006
mtk_ppe_deinit(eth);
49985007
mtk_mdio_cleanup(eth);

‎drivers/net/ethernet/mediatek/mtk_eth_soc.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,7 @@ struct mtk_eth {
12421242
spinlock_t page_lock;
12431243
spinlock_t tx_irq_lock;
12441244
spinlock_t rx_irq_lock;
1245-
struct net_device dummy_dev;
1245+
struct net_device *dummy_dev;
12461246
struct net_device *netdev[MTK_MAX_DEVS];
12471247
struct mtk_mac *mac[MTK_MAX_DEVS];
12481248
int irq[3];

‎drivers/net/ipa/gsi.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -1728,10 +1728,10 @@ static int gsi_channel_setup_one(struct gsi *gsi, u32 channel_id)
17281728
gsi_channel_program(channel, true);
17291729

17301730
if (channel->toward_ipa)
1731-
netif_napi_add_tx(&gsi->dummy_dev, &channel->napi,
1731+
netif_napi_add_tx(gsi->dummy_dev, &channel->napi,
17321732
gsi_channel_poll);
17331733
else
1734-
netif_napi_add(&gsi->dummy_dev, &channel->napi,
1734+
netif_napi_add(gsi->dummy_dev, &channel->napi,
17351735
gsi_channel_poll);
17361736

17371737
return 0;
@@ -2367,12 +2367,14 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev,
23672367
/* GSI uses NAPI on all channels. Create a dummy network device
23682368
* for the channel NAPI contexts to be associated with.
23692369
*/
2370-
init_dummy_netdev(&gsi->dummy_dev);
2370+
gsi->dummy_dev = alloc_netdev_dummy(0);
2371+
if (!gsi->dummy_dev)
2372+
return -ENOMEM;
23712373
init_completion(&gsi->completion);
23722374

23732375
ret = gsi_reg_init(gsi, pdev);
23742376
if (ret)
2375-
return ret;
2377+
goto err_reg_exit;
23762378

23772379
ret = gsi_irq_init(gsi, pdev); /* No matching exit required */
23782380
if (ret)
@@ -2387,6 +2389,7 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev,
23872389
return 0;
23882390

23892391
err_reg_exit:
2392+
free_netdev(gsi->dummy_dev);
23902393
gsi_reg_exit(gsi);
23912394

23922395
return ret;
@@ -2397,6 +2400,7 @@ void gsi_exit(struct gsi *gsi)
23972400
{
23982401
mutex_destroy(&gsi->mutex);
23992402
gsi_channel_exit(gsi);
2403+
free_netdev(gsi->dummy_dev);
24002404
gsi_reg_exit(gsi);
24012405
}
24022406

‎drivers/net/ipa/gsi.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ struct gsi {
151151
struct mutex mutex; /* protects commands, programming */
152152
struct gsi_channel channel[GSI_CHANNEL_COUNT_MAX];
153153
struct gsi_evt_ring evt_ring[GSI_EVT_RING_COUNT_MAX];
154-
struct net_device dummy_dev; /* needed for NAPI */
154+
struct net_device *dummy_dev; /* needed for NAPI */
155155
};
156156

157157
/**

‎drivers/net/wireless/ath/ath10k/core.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -3673,11 +3673,13 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
36733673
INIT_WORK(&ar->set_coverage_class_work,
36743674
ath10k_core_set_coverage_class_work);
36753675

3676-
init_dummy_netdev(&ar->napi_dev);
3676+
ar->napi_dev = alloc_netdev_dummy(0);
3677+
if (!ar->napi_dev)
3678+
goto err_free_tx_complete;
36773679

36783680
ret = ath10k_coredump_create(ar);
36793681
if (ret)
3680-
goto err_free_tx_complete;
3682+
goto err_free_netdev;
36813683

36823684
ret = ath10k_debug_create(ar);
36833685
if (ret)
@@ -3687,6 +3689,8 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
36873689

36883690
err_free_coredump:
36893691
ath10k_coredump_destroy(ar);
3692+
err_free_netdev:
3693+
free_netdev(ar->napi_dev);
36903694
err_free_tx_complete:
36913695
destroy_workqueue(ar->workqueue_tx_complete);
36923696
err_free_aux_wq:
@@ -3708,6 +3712,7 @@ void ath10k_core_destroy(struct ath10k *ar)
37083712

37093713
destroy_workqueue(ar->workqueue_tx_complete);
37103714

3715+
free_netdev(ar->napi_dev);
37113716
ath10k_debug_destroy(ar);
37123717
ath10k_coredump_destroy(ar);
37133718
ath10k_htt_tx_destroy(&ar->htt);

‎drivers/net/wireless/ath/ath10k/core.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ struct ath10k {
12691269
struct ath10k_per_peer_tx_stats peer_tx_stats;
12701270

12711271
/* NAPI */
1272-
struct net_device napi_dev;
1272+
struct net_device *napi_dev;
12731273
struct napi_struct napi;
12741274

12751275
struct work_struct set_coverage_class_work;

‎drivers/net/wireless/ath/ath10k/pci.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3217,7 +3217,7 @@ static void ath10k_pci_free_irq(struct ath10k *ar)
32173217

32183218
void ath10k_pci_init_napi(struct ath10k *ar)
32193219
{
3220-
netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_pci_napi_poll);
3220+
netif_napi_add(ar->napi_dev, &ar->napi, ath10k_pci_napi_poll);
32213221
}
32223222

32233223
static int ath10k_pci_init_irq(struct ath10k *ar)

‎drivers/net/wireless/ath/ath10k/sdio.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2532,7 +2532,7 @@ static int ath10k_sdio_probe(struct sdio_func *func,
25322532
return -ENOMEM;
25332533
}
25342534

2535-
netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_sdio_napi_poll);
2535+
netif_napi_add(ar->napi_dev, &ar->napi, ath10k_sdio_napi_poll);
25362536

25372537
ath10k_dbg(ar, ATH10K_DBG_BOOT,
25382538
"sdio new func %d vendor 0x%x device 0x%x block 0x%x/0x%x\n",

‎drivers/net/wireless/ath/ath10k/snoc.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ static int ath10k_snoc_hif_start(struct ath10k *ar)
935935

936936
bitmap_clear(ar_snoc->pending_ce_irqs, 0, CE_COUNT_MAX);
937937

938-
dev_set_threaded(&ar->napi_dev, true);
938+
dev_set_threaded(ar->napi_dev, true);
939939
ath10k_core_napi_enable(ar);
940940
ath10k_snoc_irq_enable(ar);
941941
ath10k_snoc_rx_post(ar);
@@ -1253,7 +1253,7 @@ static int ath10k_snoc_napi_poll(struct napi_struct *ctx, int budget)
12531253

12541254
static void ath10k_snoc_init_napi(struct ath10k *ar)
12551255
{
1256-
netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_snoc_napi_poll);
1256+
netif_napi_add(ar->napi_dev, &ar->napi, ath10k_snoc_napi_poll);
12571257
}
12581258

12591259
static int ath10k_snoc_request_irq(struct ath10k *ar)

‎drivers/net/wireless/ath/ath10k/usb.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ static int ath10k_usb_probe(struct usb_interface *interface,
10141014
return -ENOMEM;
10151015
}
10161016

1017-
netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_usb_napi_poll);
1017+
netif_napi_add(ar->napi_dev, &ar->napi, ath10k_usb_napi_poll);
10181018

10191019
usb_get_dev(dev);
10201020
vendor_id = le16_to_cpu(dev->descriptor.idVendor);

‎drivers/net/wireless/ath/ath11k/ahb.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
442442
free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
443443

444444
netif_napi_del(&irq_grp->napi);
445+
free_netdev(irq_grp->napi_ndev);
445446
}
446447
}
447448

@@ -533,8 +534,12 @@ static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
533534

534535
irq_grp->ab = ab;
535536
irq_grp->grp_id = i;
536-
init_dummy_netdev(&irq_grp->napi_ndev);
537-
netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
537+
538+
irq_grp->napi_ndev = alloc_netdev_dummy(0);
539+
if (!irq_grp->napi_ndev)
540+
return -ENOMEM;
541+
542+
netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
538543
ath11k_ahb_ext_grp_napi_poll);
539544

540545
for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) {

‎drivers/net/wireless/ath/ath11k/core.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ struct ath11k_ext_irq_grp {
174174
u64 timestamp;
175175
bool napi_enabled;
176176
struct napi_struct napi;
177-
struct net_device napi_ndev;
177+
struct net_device *napi_ndev;
178178
};
179179

180180
enum ath11k_smbios_cc_type {

‎drivers/net/wireless/ath/ath11k/pcic.c

+17-4
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ static void ath11k_pcic_free_ext_irq(struct ath11k_base *ab)
316316
free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
317317

318318
netif_napi_del(&irq_grp->napi);
319+
free_netdev(irq_grp->napi_ndev);
319320
}
320321
}
321322

@@ -558,7 +559,7 @@ ath11k_pcic_get_msi_irq(struct ath11k_base *ab, unsigned int vector)
558559

559560
static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab)
560561
{
561-
int i, j, ret, num_vectors = 0;
562+
int i, j, n, ret, num_vectors = 0;
562563
u32 user_base_data = 0, base_vector = 0;
563564
unsigned long irq_flags;
564565

@@ -578,8 +579,11 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab)
578579

579580
irq_grp->ab = ab;
580581
irq_grp->grp_id = i;
581-
init_dummy_netdev(&irq_grp->napi_ndev);
582-
netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
582+
irq_grp->napi_ndev = alloc_netdev_dummy(0);
583+
if (!irq_grp->napi_ndev)
584+
return -ENOMEM;
585+
586+
netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
583587
ath11k_pcic_ext_grp_napi_poll);
584588

585589
if (ab->hw_params.ring_mask->tx[i] ||
@@ -601,8 +605,13 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab)
601605
int vector = (i % num_vectors) + base_vector;
602606
int irq = ath11k_pcic_get_msi_irq(ab, vector);
603607

604-
if (irq < 0)
608+
if (irq < 0) {
609+
for (n = 0; n <= i; n++) {
610+
irq_grp = &ab->ext_irq_grp[n];
611+
free_netdev(irq_grp->napi_ndev);
612+
}
605613
return irq;
614+
}
606615

607616
ab->irq_num[irq_idx] = irq;
608617

@@ -615,6 +624,10 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab)
615624
if (ret) {
616625
ath11k_err(ab, "failed request irq %d: %d\n",
617626
vector, ret);
627+
for (n = 0; n <= i; n++) {
628+
irq_grp = &ab->ext_irq_grp[n];
629+
free_netdev(irq_grp->napi_ndev);
630+
}
618631
return ret;
619632
}
620633
}

‎drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
372372
goto error;
373373
}
374374

375-
bus->mux_dev = alloc_netdev(0, "dummy", NET_NAME_UNKNOWN,
376-
init_dummy_netdev);
375+
bus->mux_dev = alloc_netdev_dummy(0);
377376
if (!bus->mux_dev) {
378377
ret = -ENOMEM;
379378
goto error;

‎include/linux/netdevice.h

+3
Original file line numberDiff line numberDiff line change
@@ -4519,6 +4519,9 @@ static inline void netif_addr_unlock_bh(struct net_device *dev)
45194519

45204520
void ether_setup(struct net_device *dev);
45214521

4522+
/* Allocate dummy net_device */
4523+
struct net_device *alloc_netdev_dummy(int sizeof_priv);
4524+
45224525
/* Support for loadable net-drivers */
45234526
struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
45244527
unsigned char name_assign_type,

0 commit comments

Comments
 (0)
Please sign in to comment.