Commit 775d2e2b authored by Allen Pais's avatar Allen Pais Committed by Jakub Kicinski

archnet: Convert from tasklet to BH workqueue

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 drivers/net/archnet/* from tasklet to BH workqueue.

Based on the work done by Tejun Heo <tj@kernel.org>
Branch: https://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git for-6.10
Signed-off-by: default avatarAllen Pais <allen.lkml@gmail.com>
Link: https://lore.kernel.org/r/20240403162306.20258-1-apais@linux.microsoft.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 39f59c72
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/workqueue.h>
/* /*
* RECON_THRESHOLD is the maximum number of RECON messages to receive * RECON_THRESHOLD is the maximum number of RECON messages to receive
...@@ -268,7 +269,7 @@ struct arcnet_local { ...@@ -268,7 +269,7 @@ struct arcnet_local {
struct net_device *dev; struct net_device *dev;
int reply_status; int reply_status;
struct tasklet_struct reply_tasklet; struct work_struct reply_work;
/* /*
* Buffer management: an ARCnet card has 4 x 512-byte buffers, each of * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include <linux/errqueue.h> #include <linux/errqueue.h>
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/workqueue.h>
#include "arcdevice.h" #include "arcdevice.h"
#include "com9026.h" #include "com9026.h"
...@@ -424,9 +425,9 @@ static void reset_device_work(struct work_struct *work) ...@@ -424,9 +425,9 @@ static void reset_device_work(struct work_struct *work)
rtnl_unlock(); rtnl_unlock();
} }
static void arcnet_reply_tasklet(struct tasklet_struct *t) static void arcnet_reply_work(struct work_struct *t)
{ {
struct arcnet_local *lp = from_tasklet(lp, t, reply_tasklet); struct arcnet_local *lp = from_work(lp, t, reply_work);
struct sk_buff *ackskb, *skb; struct sk_buff *ackskb, *skb;
struct sock_exterr_skb *serr; struct sock_exterr_skb *serr;
...@@ -527,7 +528,7 @@ int arcnet_open(struct net_device *dev) ...@@ -527,7 +528,7 @@ int arcnet_open(struct net_device *dev)
arc_cont(D_PROTO, "\n"); arc_cont(D_PROTO, "\n");
} }
tasklet_setup(&lp->reply_tasklet, arcnet_reply_tasklet); INIT_WORK(&lp->reply_work, arcnet_reply_work);
arc_printk(D_INIT, dev, "arcnet_open: resetting card.\n"); arc_printk(D_INIT, dev, "arcnet_open: resetting card.\n");
...@@ -620,7 +621,7 @@ int arcnet_close(struct net_device *dev) ...@@ -620,7 +621,7 @@ int arcnet_close(struct net_device *dev)
netif_stop_queue(dev); netif_stop_queue(dev);
netif_carrier_off(dev); netif_carrier_off(dev);
tasklet_kill(&lp->reply_tasklet); cancel_work_sync(&lp->reply_work);
/* flush TX and disable RX */ /* flush TX and disable RX */
lp->hw.intmask(dev, 0); lp->hw.intmask(dev, 0);
...@@ -984,7 +985,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) ...@@ -984,7 +985,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
->ack_tx(dev, ackstatus); ->ack_tx(dev, ackstatus);
} }
lp->reply_status = ackstatus; lp->reply_status = ackstatus;
tasklet_hi_schedule(&lp->reply_tasklet); queue_work(system_bh_highpri_wq, &lp->reply_work);
} }
if (lp->cur_tx != -1) if (lp->cur_tx != -1)
release_arcbuf(dev, lp->cur_tx); release_arcbuf(dev, lp->cur_tx);
......
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