Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SHAPER]: Switch to spinlocks.

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>

authored by

Christoph Hellwig and committed by
David S. Miller
bc971dee 2f36895a

+17 -27
+16 -26
drivers/net/shaper.c
··· 135 135 { 136 136 struct shaper *shaper = dev->priv; 137 137 struct sk_buff *ptr; 138 - 139 - if (down_trylock(&shaper->sem)) 140 - return -1; 141 - 138 + 139 + spin_lock(&shaper->lock); 142 140 ptr=shaper->sendq.prev; 143 141 144 142 /* ··· 230 232 shaper->stats.collisions++; 231 233 } 232 234 shaper_kick(shaper); 233 - up(&shaper->sem); 235 + spin_unlock(&shaper->lock); 234 236 return 0; 235 237 } 236 238 ··· 269 271 { 270 272 struct shaper *shaper = (struct shaper *)data; 271 273 272 - if (!down_trylock(&shaper->sem)) { 273 - shaper_kick(shaper); 274 - up(&shaper->sem); 275 - } else 276 - mod_timer(&shaper->timer, jiffies); 274 + spin_lock(&shaper->lock); 275 + shaper_kick(shaper); 276 + spin_unlock(&shaper->lock); 277 277 } 278 278 279 279 /* ··· 328 332 329 333 330 334 /* 331 - * Flush the shaper queues on a closedown 332 - */ 333 - 334 - static void shaper_flush(struct shaper *shaper) 335 - { 336 - struct sk_buff *skb; 337 - 338 - down(&shaper->sem); 339 - while((skb=skb_dequeue(&shaper->sendq))!=NULL) 340 - dev_kfree_skb(skb); 341 - shaper_kick(shaper); 342 - up(&shaper->sem); 343 - } 344 - 345 - /* 346 335 * Bring the interface up. We just disallow this until a 347 336 * bind. 348 337 */ ··· 356 375 static int shaper_close(struct net_device *dev) 357 376 { 358 377 struct shaper *shaper=dev->priv; 359 - shaper_flush(shaper); 378 + struct sk_buff *skb; 379 + 380 + while ((skb = skb_dequeue(&shaper->sendq)) != NULL) 381 + dev_kfree_skb(skb); 382 + 383 + spin_lock_bh(&shaper->lock); 384 + shaper_kick(shaper); 385 + spin_unlock_bh(&shaper->lock); 386 + 360 387 del_timer_sync(&shaper->timer); 361 388 return 0; 362 389 } ··· 565 576 init_timer(&sh->timer); 566 577 sh->timer.function=shaper_timer; 567 578 sh->timer.data=(unsigned long)sh; 579 + spin_lock_init(&sh->lock); 568 580 } 569 581 570 582 /*
+1 -1
include/linux/if_shaper.h
··· 23 23 __u32 shapeclock; 24 24 unsigned long recovery; /* Time we can next clock a packet out on 25 25 an empty queue */ 26 - struct semaphore sem; 26 + spinlock_t lock; 27 27 struct net_device_stats stats; 28 28 struct net_device *dev; 29 29 int (*hard_start_xmit) (struct sk_buff *skb,