[SHAPER]: Switch to spinlocks.
authorChristoph Hellwig <hch@lst.de>
Tue, 5 Jul 2005 22:03:46 +0000 (15:03 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 5 Jul 2005 22:03:46 +0000 (15:03 -0700)
Dave, you were right and the sleeping locks in shaper were
broken. Markus Kanet noticed this and also tested the patch below that
switches locking to spinlocks.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/shaper.c
include/linux/if_shaper.h

index 20edeb3457921e5377c68a6e7d69681682fca135..3ad0b6751f6fb3c432ea883d8f753b7831a5c8e4 100644 (file)
@@ -135,10 +135,8 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct shaper *shaper = dev->priv;
        struct sk_buff *ptr;
-   
-       if (down_trylock(&shaper->sem))
-               return -1;
-
+  
+       spin_lock(&shaper->lock);
        ptr=shaper->sendq.prev;
        
        /*
@@ -232,7 +230,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
                 shaper->stats.collisions++;
        }
        shaper_kick(shaper);
-       up(&shaper->sem);
+       spin_unlock(&shaper->lock);
        return 0;
 }
 
@@ -271,11 +269,9 @@ static void shaper_timer(unsigned long data)
 {
        struct shaper *shaper = (struct shaper *)data;
 
-       if (!down_trylock(&shaper->sem)) {
-               shaper_kick(shaper);
-               up(&shaper->sem);
-       } else
-               mod_timer(&shaper->timer, jiffies);
+       spin_lock(&shaper->lock);
+       shaper_kick(shaper);
+       spin_unlock(&shaper->lock);
 }
 
 /*
@@ -331,21 +327,6 @@ static void shaper_kick(struct shaper *shaper)
 }
 
 
-/*
- *     Flush the shaper queues on a closedown
- */
-static void shaper_flush(struct shaper *shaper)
-{
-       struct sk_buff *skb;
-
-       down(&shaper->sem);
-       while((skb=skb_dequeue(&shaper->sendq))!=NULL)
-               dev_kfree_skb(skb);
-       shaper_kick(shaper);
-       up(&shaper->sem);
-}
-
 /*
  *     Bring the interface up. We just disallow this until a 
  *     bind.
@@ -375,7 +356,15 @@ static int shaper_open(struct net_device *dev)
 static int shaper_close(struct net_device *dev)
 {
        struct shaper *shaper=dev->priv;
-       shaper_flush(shaper);
+       struct sk_buff *skb;
+
+       while ((skb = skb_dequeue(&shaper->sendq)) != NULL)
+               dev_kfree_skb(skb);
+
+       spin_lock_bh(&shaper->lock);
+       shaper_kick(shaper);
+       spin_unlock_bh(&shaper->lock);
+
        del_timer_sync(&shaper->timer);
        return 0;
 }
@@ -576,6 +565,7 @@ static void shaper_init_priv(struct net_device *dev)
        init_timer(&sh->timer);
        sh->timer.function=shaper_timer;
        sh->timer.data=(unsigned long)sh;
+       spin_lock_init(&sh->lock);
 }
 
 /*
index 004e6f09a6e2daf89387bb2d1794cdd377c0ec1d..68c896a36a3441b9da82fc65713b334201b06215 100644 (file)
@@ -23,7 +23,7 @@ struct shaper
        __u32 shapeclock;
        unsigned long recovery; /* Time we can next clock a packet out on
                                   an empty queue */
-       struct semaphore sem;
+       spinlock_t lock;
         struct net_device_stats stats;
        struct net_device *dev;
        int  (*hard_start_xmit) (struct sk_buff *skb,