netdev
[Top] [All Lists]

[PATCH] wan: convert taskqueues to workqueues

To: netdev@xxxxxxxxxxx
Subject: [PATCH] wan: convert taskqueues to workqueues
From: "Randy.Dunlap" <rddunlap@xxxxxxxx>
Date: Fri, 19 Sep 2003 11:46:41 -0700
Cc: ncorbic@xxxxxxxxxxx
Organization: OSDL
Sender: netdev-bounce@xxxxxxxxxxx
Hi,

This patch converts (or attempts to convert) drivers/net/wan/*
from task queues to the workqueue API, plus a few other small
cleanups.

I haven't used workqueues much, so some review would be a good
thing (depending on the answer to the following question).

Nenad, what are the plans for drivers/net/wan/ in 2.6?
Will these drivers be updated or will they just bitrot?

Thanks,
--
~Randy


patch_name:     wan_sdla_workqueue.patch
patch_version:  2003-09-19.11:31:30
author:         Randy.Dunlap <rddunlap@xxxxxxxx>
description:    convert wan/sdlamain.c from task queue to workqueue API;
product:        Linux
product_versions: 2.6.0-test5
changelog:      use workqueue API;
                don't init static globals to 0;
                kill 1 unused variable (warning);
                fix spelling/typos;
                convert 2 caller modules to use new interface;
                use request/release_region instead of check_region;
maintainer:     ncorbic@xxxxxxxxxxx
diffstat:       =
 drivers/net/wan/sdla_fr.c  |   30 +++++-------
 drivers/net/wan/sdla_x25.c |   20 +++-----
 drivers/net/wan/sdlamain.c |  104 ++++++++++++++++++++-------------------------
 3 files changed, 68 insertions(+), 86 deletions(-)


diff -Naurp ./drivers/net/wan/sdlamain.c~wrkque ./drivers/net/wan/sdlamain.c
--- ./drivers/net/wan/sdlamain.c~wrkque 2003-09-08 12:50:18.000000000 -0700
+++ ./drivers/net/wan/sdlamain.c        2003-09-19 11:28:13.000000000 -0700
@@ -189,7 +189,6 @@ static int ioctl_exec       (sdla_t* card, sdl
 /* Miscellaneous functions */
 STATIC irqreturn_t sdla_isr    (int irq, void* dev_id, struct pt_regs *regs);
 static void release_hw  (sdla_t *card);
-static void run_wanpipe_tq (unsigned long);
 
 static int check_s508_conflicts (sdla_t* card,wandev_conf_t* conf, int*);
 static int check_s514_conflicts (sdla_t* card,wandev_conf_t* conf, int*);
@@ -203,29 +202,21 @@ static int check_s514_conflicts (sdla_t*
 static char drvname[]  = "wanpipe";
 static char fullname[] = "WANPIPE(tm) Multiprotocol Driver";
 static char copyright[]        = "(c) 1995-2000 Sangoma Technologies Inc.";
-static int ncards = 0; 
-static sdla_t* card_array = NULL;      /* adapter data space */
+static int ncards; 
+static sdla_t* card_array;             /* adapter data space */
 
-/* Wanpipe's own task queue, used for all API's.
- * All protocol specific tasks will be instered
- * into "wanpipe_tq_custom" task_queue. 
-
- * On each rx_interrupt, the whole task queue
- * (wanpipe_tq_custom) will be queued into 
- * IMMEDIATE_BH via wanpipe_mark_bh() call. 
- 
- * The IMMEDIATE_BH will execute run_wanpipe_tq() 
- * function, which will execute all pending,
- * tasks in wanpipe_tq_custom queue */
-
-DECLARE_TASK_QUEUE(wanpipe_tq_custom);
-static struct tq_struct wanpipe_tq_task = 
-{
-       .routine = (void (*)(void *)) run_wanpipe_tq,
-       .data = &wanpipe_tq_custom
-};
+/* Wanpipe's own workqueue, used for all API's.
+ * All protocol specific tasks will be inserted
+ * into the "wanpipe_wq" workqueue. 
+
+ * The kernel workqueue mechanism will execute
+ * all pending tasks in the "wanpipe_wq" workqueue.
+ */
 
-static int wanpipe_bh_critical=0;
+struct workqueue_struct *wanpipe_wq;
+DECLARE_WORK(wanpipe_work, NULL, NULL);
+
+static int wanpipe_bh_critical;
 
 /******* Kernel Loadable Module Entry Points ********************************/
 
@@ -249,6 +240,10 @@ int wanpipe_init(void)
        printk(KERN_INFO "%s v%u.%u %s\n",
                fullname, DRV_VERSION, DRV_RELEASE, copyright);
 
+       wanpipe_wq = create_workqueue("wanpipe_wq");
+       if (!wanpipe_wq)
+               return -ENOMEM;
+
        /* Probe for wanpipe cards and return the number found */
        printk(KERN_INFO "wanpipe: Probing for WANPIPE hardware.\n");
        ncards = wanpipe_hw_probe();
@@ -256,13 +251,16 @@ int wanpipe_init(void)
                printk(KERN_INFO "wanpipe: Allocating maximum %i devices: 
wanpipe%i - wanpipe%i.\n",ncards,1,ncards);
        }else{
                printk(KERN_INFO "wanpipe: No S514/S508 cards found, unloading 
modules!\n");
+               destroy_workqueue(wanpipe_wq);
                return -ENODEV;
        }
        
        /* Verify number of cards and allocate adapter data space */
        card_array = kmalloc(sizeof(sdla_t) * ncards, GFP_KERNEL);
-       if (card_array == NULL)
+       if (card_array == NULL) {
+               destroy_workqueue(wanpipe_wq);
                return -ENOMEM;
+       }
 
        memset(card_array, 0, sizeof(sdla_t) * ncards);
 
@@ -292,6 +290,7 @@ int wanpipe_init(void)
                ncards = cnt;   /* adjust actual number of cards */
        }else {
                kfree(card_array);
+               destroy_workqueue(wanpipe_wq);
                printk(KERN_INFO "IN Init Module: NO Cards registered\n");
                err = -ENODEV;
        }
@@ -316,6 +315,7 @@ static void wanpipe_cleanup(void)
                sdla_t* card = &card_array[i];
                unregister_wan_device(card->devname);
        }
+       destroy_workqueue(wanpipe_wq);
        kfree(card_array);
 
        printk(KERN_INFO "\nwanpipe: WANPIPE Modules Unloaded.\n");
@@ -673,15 +673,20 @@ static int check_s508_conflicts (sdla_t*
        
 
        /* Make sure I/O port region is available only if we are the
-        * master device.  If we are running in piggibacking mode, 
-        * we will use the resources of the master card */
-       if (check_region(conf->ioport, SDLA_MAXIORANGE) && 
-           !card->wandev.piggyback) {
-               printk(KERN_INFO
-                       "%s: I/O region 0x%X - 0x%X is in use!\n",
-                       card->wandev.name, conf->ioport,
-                       conf->ioport + SDLA_MAXIORANGE);
-               return -EINVAL;
+        * master device.  If we are running in piggybacking mode, 
+        * we will use the resources of the master card. */
+       if (!card->wandev.piggyback) {
+               struct resource *rr =
+                       request_region(conf->ioport, SDLA_MAXIORANGE, 
"sdlamain");
+               release_region(conf->ioport, SDLA_MAXIORANGE);
+
+               if (!rr) {
+                       printk(KERN_INFO
+                               "%s: I/O region 0x%X - 0x%X is in use!\n",
+                               card->wandev.name, conf->ioport,
+                               conf->ioport + SDLA_MAXIORANGE - 1);
+                       return -EINVAL;
+               }
        }
 
        return 0;
@@ -1029,7 +1034,6 @@ static int ioctl_exec (sdla_t* card, sdl
 STATIC irqreturn_t sdla_isr (int irq, void* dev_id, struct pt_regs *regs)
 {
 #define        card    ((sdla_t*)dev_id)
-       int handled = 0;
 
        if(card->hw.type == SDLA_S514) {        /* handle interrrupt on S514 */
                 u32 int_status;
@@ -1210,6 +1214,7 @@ sdla_t * wanpipe_find_card (char *name)
        }
        return NULL;
 }
+
 sdla_t * wanpipe_find_card_num (int num)
 {
        if (num < 1 || num > ncards)
@@ -1218,35 +1223,20 @@ sdla_t * wanpipe_find_card_num (int num)
        return &card_array[num];
 }
 
-
-static void run_wanpipe_tq (unsigned long data)
-{
-       task_queue *tq_queue = (task_queue *)data;
-       if (test_and_set_bit(2,(void*)&wanpipe_bh_critical))
-               printk(KERN_INFO "CRITICAL IN RUNNING TASK QUEUE\n");
-       run_task_queue (tq_queue);
-       clear_bit(2,(void*)&wanpipe_bh_critical);
-
-}
-
-void wanpipe_queue_tq (struct tq_struct *bh_pointer)
+/*
+ * @work_pointer:      work_struct to be done;
+ *                     should already have PREPARE_WORK() or
+ *                       INIT_WORK() done on it by caller;
+ */
+void wanpipe_queue_work (struct work_struct *work_pointer)
 {
-       if (test_and_set_bit(1,(void*)&wanpipe_bh_critical))
-               printk(KERN_INFO "CRITICAL IN QUEUING TASK\n");
+       if (test_and_set_bit(1, (void*)&wanpipe_bh_critical))
+               printk(KERN_INFO "CRITICAL IN QUEUING WORK\n");
 
-       queue_task(bh_pointer,&wanpipe_tq_custom);
+       queue_work(wanpipe_wq, work_pointer);
        clear_bit(1,(void*)&wanpipe_bh_critical);
 }
 
-void wanpipe_mark_bh (void)
-{
-       if (!test_and_set_bit(0,(void*)&wanpipe_bh_critical)){
-               queue_task(&wanpipe_tq_task,&tq_immediate);
-               mark_bh(IMMEDIATE_BH);
-               clear_bit(0,(void*)&wanpipe_bh_critical);
-       }
-} 
-
 void wakeup_sk_bh(struct net_device *dev)
 {
        wanpipe_common_t *chan = dev->priv;
diff -Naurp ./drivers/net/wan/sdla_fr.c~wrkque ./drivers/net/wan/sdla_fr.c
--- ./drivers/net/wan/sdla_fr.c~wrkque  2003-09-08 12:50:41.000000000 -0700
+++ ./drivers/net/wan/sdla_fr.c 2003-09-19 10:22:24.000000000 -0700
@@ -147,6 +147,7 @@
 #include <linux/slab.h>        /* kmalloc(), kfree() */
 #include <linux/wanrouter.h>   /* WAN router definitions */
 #include <linux/wanpipe.h>     /* WANPIPE common user API definitions */
+#include <linux/workqueue.h>
 #include <linux/if_arp.h>      /* ARPHRD_* defines */
 #include <asm/byteorder.h>     /* htons(), etc. */
 #include <asm/io.h>            /* for inb(), outb(), etc. */
@@ -247,7 +248,7 @@ typedef struct fr_channel
        /* Polling task queue. Each interface
          * has its own task queue, which is used
          * to defer events from the interrupt */
-       struct tq_struct fr_poll_task;
+       struct work_struct fr_poll_work;
        struct timer_list fr_arp_timer;
 
        u32 ip_local;
@@ -987,9 +988,7 @@ static int new_if(struct wan_device* wan
          * We need a poll routine for each network
          * interface. 
          */
-       chan->fr_poll_task.sync = 0;
-       chan->fr_poll_task.routine = (void *)(void *)fr_poll;
-       chan->fr_poll_task.data = dev;
+       INIT_WORK(&chan->fr_poll_work, (void *)fr_poll, dev);
 
        init_timer(&chan->fr_arp_timer);
        chan->fr_arp_timer.data=(unsigned long)dev;
@@ -1212,9 +1211,7 @@ static int if_open(struct net_device* de
        /* Initialize the task queue */
        chan->tq_working=0;
 
-       chan->common.wanpipe_task.sync = 0;
-       chan->common.wanpipe_task.routine = (void *)(void *)fr_bh;
-       chan->common.wanpipe_task.data = dev;
+       INIT_WORK(&chan->common.wanpipe_work, (void *)fr_bh, dev);
 
        /* Allocate and initialize BH circular buffer */
        chan->bh_head = kmalloc((sizeof(bh_data_t)*MAX_BH_BUFF),GFP_ATOMIC);
@@ -2178,7 +2175,7 @@ static void rx_intr (sdla_t* card)
                } 
                
 
-               /* Send a packed up the IP stack */
+               /* Send a packet up the IP stack */
                skb->dev->last_rx = jiffies;
                netif_rx(skb);
                ++chan->drvstats_rx_intr.rx_intr_bfr_passed_to_stack;
@@ -2216,8 +2213,8 @@ rx_done:
  *         dlci number.
  *      2. Check that network interface is up and
  *         properly setup.
- *     3. Check for a buffered packed.
- *      4. Transmit the packed.
+ *     3. Check for a buffered packet.
+ *      4. Transmit the packet.
  *     5. If we are in WANPIPE mode, mark the 
  *         NET_BH handler. 
  *      6. If we are in API mode, kick
@@ -4359,8 +4356,8 @@ void s508_s514_unlock(sdla_t *card, unsi
  * bh_enqueue
  *
  * Description:
- *     Insert a received packed into a circular
- *      rx queue.  This packed will be picked up 
+ *     Insert a received packet into a circular
+ *      rx queue.  This packet will be picked up 
  *      by fr_bh() and sent up the stack to the
  *      user.
  *             
@@ -4411,8 +4408,7 @@ static int bh_enqueue(struct net_device 
 static void trigger_fr_bh (fr_channel_t *chan)
 {
        if (!test_and_set_bit(0,&chan->tq_working)){
-               wanpipe_queue_tq(&chan->common.wanpipe_task);
-               wanpipe_mark_bh();
+               wanpipe_queue_work(&chan->common.wanpipe_work);
        }
 }
 
@@ -4435,10 +4431,10 @@ static void trigger_fr_bh (fr_channel_t 
  *      card into an skb buffer, the skb buffer
  *     is appended to a circular BH buffer.
  *     Then the interrupt kicks fr_bh() to finish the
- *      job at a later time (no within the interrupt).
+ *      job at a later time (not within the interrupt).
  *       
  * Usage:
- *     Interrupts use this to defer a taks to 
+ *     Interrupts use this to defer a task to 
  *      a polling routine.
  *
  */    
@@ -4527,7 +4523,7 @@ static int fr_bh_cleanup(struct net_devi
 static void trigger_fr_poll(struct net_device *dev)
 {
        fr_channel_t* chan = dev->priv;
-       schedule_task(&chan->fr_poll_task);
+       schedule_work(&chan->fr_poll_work);
        return;
 }
 
diff -Naurp ./drivers/net/wan/sdla_x25.c~wrkque ./drivers/net/wan/sdla_x25.c
--- ./drivers/net/wan/sdla_x25.c~wrkque 2003-09-08 12:50:16.000000000 -0700
+++ ./drivers/net/wan/sdla_x25.c        2003-09-19 10:09:03.000000000 -0700
@@ -91,6 +91,7 @@
 #include <linux/slab.h>        /* kmalloc(), kfree() */
 #include <linux/wanrouter.h>   /* WAN router definitions */
 #include <linux/wanpipe.h>     /* WANPIPE common user API definitions */
+#include <linux/workqueue.h>
 #include <asm/byteorder.h>     /* htons(), etc. */
 #include <asm/atomic.h>
 #include <linux/delay.h>       /* Experimental delay */
@@ -790,9 +791,7 @@ int wpx_init (sdla_t* card, wandev_conf_
        
        init_global_statistics(card);   
 
-       card->u.x.x25_poll_task.sync=0;
-       card->u.x.x25_poll_task.routine = (void*)(void*)wpx_poll;
-       card->u.x.x25_poll_task.data = card;
+       INIT_WORK(&card->u.x.x25_poll_work, (void *)wpx_poll, card);
 
        init_timer(&card->u.x.x25_timer);
        card->u.x.x25_timer.data = (unsigned long)card;
@@ -1175,7 +1174,7 @@ static int if_init(struct net_device* de
  * Warnings:   None
  *
  * Return:     0       Ok
- *             <0      Failur: Interface will not come up.
+ *             <0      Failure: Interface will not come up.
  */
 
 static int if_open(struct net_device* dev)
@@ -1190,10 +1189,8 @@ static int if_open(struct net_device* de
 
        chan->tq_working = 0;
 
-       /* Initialize the task queue */
-       chan->common.wanpipe_task.sync = 0;
-       chan->common.wanpipe_task.routine = (void *)(void *)x25api_bh;
-       chan->common.wanpipe_task.data = dev;
+       /* Initialize the workqueue */
+       INIT_WORK(&chan->common.wanpipe_work, (void *)x25api_bh, dev);
 
        /* Allocate and initialize BH circular buffer */
        /* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */
@@ -1732,8 +1729,7 @@ static void rx_intr (sdla_t* card)
 
                chan->rx_skb = NULL;
                if (!test_and_set_bit(0, &chan->tq_working)){
-                       wanpipe_queue_tq(&chan->common.wanpipe_task);
-                       wanpipe_mark_bh();
+                       wanpipe_queue_work(&chan->common.wanpipe_work);
                }
                return;
        }
@@ -2227,7 +2223,7 @@ static void spur_intr (sdla_t* card)
 
 /*====================================================================
  *     Main polling routine.
- *     This routine is repeatedly called by the WANPIPE 'thead' to allow for
+ *     This routine is repeatedly called by the WANPIPE 'thread' to allow for
  *     time-dependent housekeeping work.
  *
  *     Notes:
@@ -2274,7 +2270,7 @@ wpx_poll_exit:
 
 static void trigger_x25_poll(sdla_t *card)
 {
-       schedule_task(&card->u.x.x25_poll_task);
+       schedule_work(&card->u.x.x25_poll_work);
 }
 
 /*====================================================================

<Prev in Thread] Current Thread [Next in Thread>