Skip to content

Commit 8e0c0ec

Browse files
committed
Merge branch 'ethernet-convert-from-tasklet-to-bh-workqueue'
Allen Pais says: ==================== ethernet: Convert from tasklet to BH workqueue [part] The only generic interface to execute asynchronously in the BH context is tasklet; however, it's marked deprecated and has some design flaws. To replace tasklets, BH workqueue support was recently added. A BH workqueue behaves similarly to regular workqueues except that the queued work items are executed in the BH context. This patch converts a few drivers in drivers/ethernet/* from tasklet to BH workqueue. The next set will be sent out after the next -rc is out. v2: https://lore.kernel.org/[email protected] v1: https://lore.kernel.org/[email protected] ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 9bb3ec1 + c5092ba commit 8e0c0ec

File tree

11 files changed

+73
-71
lines changed

11 files changed

+73
-71
lines changed

drivers/net/ethernet/alteon/acenic.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,9 +1560,9 @@ static void ace_watchdog(struct net_device *data, unsigned int txqueue)
15601560
}
15611561

15621562

1563-
static void ace_tasklet(struct tasklet_struct *t)
1563+
static void ace_bh_work(struct work_struct *work)
15641564
{
1565-
struct ace_private *ap = from_tasklet(ap, t, ace_tasklet);
1565+
struct ace_private *ap = from_work(ap, work, ace_bh_work);
15661566
struct net_device *dev = ap->ndev;
15671567
int cur_size;
15681568

@@ -1595,7 +1595,7 @@ static void ace_tasklet(struct tasklet_struct *t)
15951595
#endif
15961596
ace_load_jumbo_rx_ring(dev, RX_JUMBO_SIZE - cur_size);
15971597
}
1598-
ap->tasklet_pending = 0;
1598+
ap->bh_work_pending = 0;
15991599
}
16001600

16011601

@@ -1617,7 +1617,7 @@ static void ace_dump_trace(struct ace_private *ap)
16171617
*
16181618
* Loading rings is safe without holding the spin lock since this is
16191619
* done only before the device is enabled, thus no interrupts are
1620-
* generated and by the interrupt handler/tasklet handler.
1620+
* generated and by the interrupt handler/bh handler.
16211621
*/
16221622
static void ace_load_std_rx_ring(struct net_device *dev, int nr_bufs)
16231623
{
@@ -2160,7 +2160,7 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)
21602160
*/
21612161
if (netif_running(dev)) {
21622162
int cur_size;
2163-
int run_tasklet = 0;
2163+
int run_bh_work = 0;
21642164

21652165
cur_size = atomic_read(&ap->cur_rx_bufs);
21662166
if (cur_size < RX_LOW_STD_THRES) {
@@ -2172,7 +2172,7 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)
21722172
ace_load_std_rx_ring(dev,
21732173
RX_RING_SIZE - cur_size);
21742174
} else
2175-
run_tasklet = 1;
2175+
run_bh_work = 1;
21762176
}
21772177

21782178
if (!ACE_IS_TIGON_I(ap)) {
@@ -2188,7 +2188,7 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)
21882188
ace_load_mini_rx_ring(dev,
21892189
RX_MINI_SIZE - cur_size);
21902190
} else
2191-
run_tasklet = 1;
2191+
run_bh_work = 1;
21922192
}
21932193
}
21942194

@@ -2205,12 +2205,12 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)
22052205
ace_load_jumbo_rx_ring(dev,
22062206
RX_JUMBO_SIZE - cur_size);
22072207
} else
2208-
run_tasklet = 1;
2208+
run_bh_work = 1;
22092209
}
22102210
}
2211-
if (run_tasklet && !ap->tasklet_pending) {
2212-
ap->tasklet_pending = 1;
2213-
tasklet_schedule(&ap->ace_tasklet);
2211+
if (run_bh_work && !ap->bh_work_pending) {
2212+
ap->bh_work_pending = 1;
2213+
queue_work(system_bh_wq, &ap->ace_bh_work);
22142214
}
22152215
}
22162216

@@ -2267,7 +2267,7 @@ static int ace_open(struct net_device *dev)
22672267
/*
22682268
* Setup the bottom half rx ring refill handler
22692269
*/
2270-
tasklet_setup(&ap->ace_tasklet, ace_tasklet);
2270+
INIT_WORK(&ap->ace_bh_work, ace_bh_work);
22712271
return 0;
22722272
}
22732273

@@ -2301,7 +2301,7 @@ static int ace_close(struct net_device *dev)
23012301
cmd.idx = 0;
23022302
ace_issue_cmd(regs, &cmd);
23032303

2304-
tasklet_kill(&ap->ace_tasklet);
2304+
cancel_work_sync(&ap->ace_bh_work);
23052305

23062306
/*
23072307
* Make sure one CPU is not processing packets while

drivers/net/ethernet/alteon/acenic.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#ifndef _ACENIC_H_
33
#define _ACENIC_H_
44
#include <linux/interrupt.h>
5-
5+
#include <linux/workqueue.h>
66

77
/*
88
* Generate TX index update each time, when TX ring is closed.
@@ -667,8 +667,8 @@ struct ace_private
667667
struct rx_desc *rx_mini_ring;
668668
struct rx_desc *rx_return_ring;
669669

670-
int tasklet_pending, jumbo;
671-
struct tasklet_struct ace_tasklet;
670+
int bh_work_pending, jumbo;
671+
struct work_struct ace_bh_work;
672672

673673
struct event *evt_ring;
674674

@@ -776,7 +776,7 @@ static int ace_open(struct net_device *dev);
776776
static netdev_tx_t ace_start_xmit(struct sk_buff *skb,
777777
struct net_device *dev);
778778
static int ace_close(struct net_device *dev);
779-
static void ace_tasklet(struct tasklet_struct *t);
779+
static void ace_bh_work(struct work_struct *work);
780780
static void ace_dump_trace(struct ace_private *ap);
781781
static void ace_set_multicast_list(struct net_device *dev);
782782
static int ace_change_mtu(struct net_device *dev, int new_mtu);

drivers/net/ethernet/amd/xgbe/xgbe-drv.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,9 @@ static bool xgbe_ecc_ded(struct xgbe_prv_data *pdata, unsigned long *period,
403403
return false;
404404
}
405405

406-
static void xgbe_ecc_isr_task(struct tasklet_struct *t)
406+
static void xgbe_ecc_isr_bh_work(struct work_struct *work)
407407
{
408-
struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_ecc);
408+
struct xgbe_prv_data *pdata = from_work(pdata, work, ecc_bh_work);
409409
unsigned int ecc_isr;
410410
bool stop = false;
411411

@@ -465,17 +465,17 @@ static irqreturn_t xgbe_ecc_isr(int irq, void *data)
465465
{
466466
struct xgbe_prv_data *pdata = data;
467467

468-
if (pdata->isr_as_tasklet)
469-
tasklet_schedule(&pdata->tasklet_ecc);
468+
if (pdata->isr_as_bh_work)
469+
queue_work(system_bh_wq, &pdata->ecc_bh_work);
470470
else
471-
xgbe_ecc_isr_task(&pdata->tasklet_ecc);
471+
xgbe_ecc_isr_bh_work(&pdata->ecc_bh_work);
472472

473473
return IRQ_HANDLED;
474474
}
475475

476-
static void xgbe_isr_task(struct tasklet_struct *t)
476+
static void xgbe_isr_bh_work(struct work_struct *work)
477477
{
478-
struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_dev);
478+
struct xgbe_prv_data *pdata = from_work(pdata, work, dev_bh_work);
479479
struct xgbe_hw_if *hw_if = &pdata->hw_if;
480480
struct xgbe_channel *channel;
481481
unsigned int dma_isr, dma_ch_isr;
@@ -582,7 +582,7 @@ static void xgbe_isr_task(struct tasklet_struct *t)
582582

583583
/* If there is not a separate ECC irq, handle it here */
584584
if (pdata->vdata->ecc_support && (pdata->dev_irq == pdata->ecc_irq))
585-
xgbe_ecc_isr_task(&pdata->tasklet_ecc);
585+
xgbe_ecc_isr_bh_work(&pdata->ecc_bh_work);
586586

587587
/* If there is not a separate I2C irq, handle it here */
588588
if (pdata->vdata->i2c_support && (pdata->dev_irq == pdata->i2c_irq))
@@ -604,10 +604,10 @@ static irqreturn_t xgbe_isr(int irq, void *data)
604604
{
605605
struct xgbe_prv_data *pdata = data;
606606

607-
if (pdata->isr_as_tasklet)
608-
tasklet_schedule(&pdata->tasklet_dev);
607+
if (pdata->isr_as_bh_work)
608+
queue_work(system_bh_wq, &pdata->dev_bh_work);
609609
else
610-
xgbe_isr_task(&pdata->tasklet_dev);
610+
xgbe_isr_bh_work(&pdata->dev_bh_work);
611611

612612
return IRQ_HANDLED;
613613
}
@@ -1007,8 +1007,8 @@ static int xgbe_request_irqs(struct xgbe_prv_data *pdata)
10071007
unsigned int i;
10081008
int ret;
10091009

1010-
tasklet_setup(&pdata->tasklet_dev, xgbe_isr_task);
1011-
tasklet_setup(&pdata->tasklet_ecc, xgbe_ecc_isr_task);
1010+
INIT_WORK(&pdata->dev_bh_work, xgbe_isr_bh_work);
1011+
INIT_WORK(&pdata->ecc_bh_work, xgbe_ecc_isr_bh_work);
10121012

10131013
ret = devm_request_irq(pdata->dev, pdata->dev_irq, xgbe_isr, 0,
10141014
netdev_name(netdev), pdata);
@@ -1078,8 +1078,8 @@ static void xgbe_free_irqs(struct xgbe_prv_data *pdata)
10781078

10791079
devm_free_irq(pdata->dev, pdata->dev_irq, pdata);
10801080

1081-
tasklet_kill(&pdata->tasklet_dev);
1082-
tasklet_kill(&pdata->tasklet_ecc);
1081+
cancel_work_sync(&pdata->dev_bh_work);
1082+
cancel_work_sync(&pdata->ecc_bh_work);
10831083

10841084
if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq))
10851085
devm_free_irq(pdata->dev, pdata->ecc_irq, pdata);

drivers/net/ethernet/amd/xgbe/xgbe-i2c.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,9 @@ static void xgbe_i2c_clear_isr_interrupts(struct xgbe_prv_data *pdata,
274274
XI2C_IOREAD(pdata, IC_CLR_STOP_DET);
275275
}
276276

277-
static void xgbe_i2c_isr_task(struct tasklet_struct *t)
277+
static void xgbe_i2c_isr_bh_work(struct work_struct *work)
278278
{
279-
struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_i2c);
279+
struct xgbe_prv_data *pdata = from_work(pdata, work, i2c_bh_work);
280280
struct xgbe_i2c_op_state *state = &pdata->i2c.op_state;
281281
unsigned int isr;
282282

@@ -321,10 +321,10 @@ static irqreturn_t xgbe_i2c_isr(int irq, void *data)
321321
{
322322
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
323323

324-
if (pdata->isr_as_tasklet)
325-
tasklet_schedule(&pdata->tasklet_i2c);
324+
if (pdata->isr_as_bh_work)
325+
queue_work(system_bh_wq, &pdata->i2c_bh_work);
326326
else
327-
xgbe_i2c_isr_task(&pdata->tasklet_i2c);
327+
xgbe_i2c_isr_bh_work(&pdata->i2c_bh_work);
328328

329329
return IRQ_HANDLED;
330330
}
@@ -369,7 +369,7 @@ static void xgbe_i2c_set_target(struct xgbe_prv_data *pdata, unsigned int addr)
369369

370370
static irqreturn_t xgbe_i2c_combined_isr(struct xgbe_prv_data *pdata)
371371
{
372-
xgbe_i2c_isr_task(&pdata->tasklet_i2c);
372+
xgbe_i2c_isr_bh_work(&pdata->i2c_bh_work);
373373

374374
return IRQ_HANDLED;
375375
}
@@ -449,7 +449,7 @@ static void xgbe_i2c_stop(struct xgbe_prv_data *pdata)
449449

450450
if (pdata->dev_irq != pdata->i2c_irq) {
451451
devm_free_irq(pdata->dev, pdata->i2c_irq, pdata);
452-
tasklet_kill(&pdata->tasklet_i2c);
452+
cancel_work_sync(&pdata->i2c_bh_work);
453453
}
454454
}
455455

@@ -464,7 +464,7 @@ static int xgbe_i2c_start(struct xgbe_prv_data *pdata)
464464

465465
/* If we have a separate I2C irq, enable it */
466466
if (pdata->dev_irq != pdata->i2c_irq) {
467-
tasklet_setup(&pdata->tasklet_i2c, xgbe_i2c_isr_task);
467+
INIT_WORK(&pdata->i2c_bh_work, xgbe_i2c_isr_bh_work);
468468

469469
ret = devm_request_irq(pdata->dev, pdata->i2c_irq,
470470
xgbe_i2c_isr, 0, pdata->i2c_name,

drivers/net/ethernet/amd/xgbe/xgbe-mdio.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -703,9 +703,9 @@ static void xgbe_an73_isr(struct xgbe_prv_data *pdata)
703703
}
704704
}
705705

706-
static void xgbe_an_isr_task(struct tasklet_struct *t)
706+
static void xgbe_an_isr_bh_work(struct work_struct *work)
707707
{
708-
struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_an);
708+
struct xgbe_prv_data *pdata = from_work(pdata, work, an_bh_work);
709709

710710
netif_dbg(pdata, intr, pdata->netdev, "AN interrupt received\n");
711711

@@ -727,17 +727,17 @@ static irqreturn_t xgbe_an_isr(int irq, void *data)
727727
{
728728
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
729729

730-
if (pdata->isr_as_tasklet)
731-
tasklet_schedule(&pdata->tasklet_an);
730+
if (pdata->isr_as_bh_work)
731+
queue_work(system_bh_wq, &pdata->an_bh_work);
732732
else
733-
xgbe_an_isr_task(&pdata->tasklet_an);
733+
xgbe_an_isr_bh_work(&pdata->an_bh_work);
734734

735735
return IRQ_HANDLED;
736736
}
737737

738738
static irqreturn_t xgbe_an_combined_isr(struct xgbe_prv_data *pdata)
739739
{
740-
xgbe_an_isr_task(&pdata->tasklet_an);
740+
xgbe_an_isr_bh_work(&pdata->an_bh_work);
741741

742742
return IRQ_HANDLED;
743743
}
@@ -1454,7 +1454,7 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
14541454

14551455
if (pdata->dev_irq != pdata->an_irq) {
14561456
devm_free_irq(pdata->dev, pdata->an_irq, pdata);
1457-
tasklet_kill(&pdata->tasklet_an);
1457+
cancel_work_sync(&pdata->an_bh_work);
14581458
}
14591459

14601460
pdata->phy_if.phy_impl.stop(pdata);
@@ -1477,7 +1477,7 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
14771477

14781478
/* If we have a separate AN irq, enable it */
14791479
if (pdata->dev_irq != pdata->an_irq) {
1480-
tasklet_setup(&pdata->tasklet_an, xgbe_an_isr_task);
1480+
INIT_WORK(&pdata->an_bh_work, xgbe_an_isr_bh_work);
14811481

14821482
ret = devm_request_irq(pdata->dev, pdata->an_irq,
14831483
xgbe_an_isr, 0, pdata->an_name,

drivers/net/ethernet/amd/xgbe/xgbe-pci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ static int xgbe_config_multi_msi(struct xgbe_prv_data *pdata)
139139
return ret;
140140
}
141141

142-
pdata->isr_as_tasklet = 1;
142+
pdata->isr_as_bh_work = 1;
143143
pdata->irq_count = ret;
144144

145145
pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
@@ -176,7 +176,7 @@ static int xgbe_config_irqs(struct xgbe_prv_data *pdata)
176176
return ret;
177177
}
178178

179-
pdata->isr_as_tasklet = pdata->pcidev->msi_enabled ? 1 : 0;
179+
pdata->isr_as_bh_work = pdata->pcidev->msi_enabled ? 1 : 0;
180180
pdata->irq_count = 1;
181181
pdata->channel_irq_count = 1;
182182

drivers/net/ethernet/amd/xgbe/xgbe.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,11 +1298,11 @@ struct xgbe_prv_data {
12981298

12991299
unsigned int lpm_ctrl; /* CTRL1 for resume */
13001300

1301-
unsigned int isr_as_tasklet;
1302-
struct tasklet_struct tasklet_dev;
1303-
struct tasklet_struct tasklet_ecc;
1304-
struct tasklet_struct tasklet_i2c;
1305-
struct tasklet_struct tasklet_an;
1301+
unsigned int isr_as_bh_work;
1302+
struct work_struct dev_bh_work;
1303+
struct work_struct ecc_bh_work;
1304+
struct work_struct i2c_bh_work;
1305+
struct work_struct an_bh_work;
13061306

13071307
struct dentry *xgbe_debugfs;
13081308

0 commit comments

Comments
 (0)