archnet: Convert from tasklet to BH workqueue
authorAllen Pais <apais@linux.microsoft.com>
Wed, 3 Apr 2024 16:23:06 +0000 (16:23 +0000)
committerJakub Kicinski <kuba@kernel.org>
Tue, 9 Apr 2024 02:44:09 +0000 (19:44 -0700)
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: Allen Pais <allen.lkml@gmail.com>
Link: https://lore.kernel.org/r/20240403162306.20258-1-apais@linux.microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/arcnet/arcdevice.h
drivers/net/arcnet/arcnet.c

index b54275389f8acf1cd11341288f3692ca9e1c9f5d..bee60b377d7c4f0d5b2a8c57ad4962d53f2b1404 100644 (file)
@@ -16,6 +16,7 @@
 
 #ifdef __KERNEL__
 #include <linux/interrupt.h>
+#include <linux/workqueue.h>
 
 /*
  * RECON_THRESHOLD is the maximum number of RECON messages to receive
@@ -268,7 +269,7 @@ struct arcnet_local {
 
        struct net_device *dev;
        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
index 166bfc3c8e6c04a75509000b36c545a99ad7ce7d..530c15d6a5eb8d8f5583acc806d6887a1b2ce2e0 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/errqueue.h>
 
 #include <linux/leds.h>
+#include <linux/workqueue.h>
 
 #include "arcdevice.h"
 #include "com9026.h"
@@ -424,9 +425,9 @@ out:
        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 sock_exterr_skb *serr;
@@ -527,7 +528,7 @@ int arcnet_open(struct net_device *dev)
                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");
 
@@ -620,7 +621,7 @@ int arcnet_close(struct net_device *dev)
        netif_stop_queue(dev);
        netif_carrier_off(dev);
 
-       tasklet_kill(&lp->reply_tasklet);
+       cancel_work_sync(&lp->reply_work);
 
        /* flush TX and disable RX */
        lp->hw.intmask(dev, 0);
@@ -984,7 +985,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
                                                ->ack_tx(dev, 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)
                                release_arcbuf(dev, lp->cur_tx);