[NET]: Fix locking in shaper driver.

o use a semaphore instead of an opencoded and racy lock
o move locking out of shaper_kick and into the callers - most just
released the lock before calling shaper_kick
o remove in_interrupt() tests. from ->close we can always block, from
->hard_start_xmit and timer context never

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
b597ef47 4fef0304

+20 -69
+19 -67
drivers/net/shaper.c
··· 100 100 101 101 #define SHAPER_BANNER "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n" 102 102 103 - /* 104 - * Locking 105 - */ 106 - 107 - static int shaper_lock(struct shaper *sh) 108 - { 109 - /* 110 - * Lock in an interrupt must fail 111 - */ 112 - while (test_and_set_bit(0, &sh->locked)) 113 - { 114 - if (!in_interrupt()) 115 - sleep_on(&sh->wait_queue); 116 - else 117 - return 0; 118 - 119 - } 120 - return 1; 121 - } 122 - 123 103 static void shaper_kick(struct shaper *sh); 124 - 125 - static void shaper_unlock(struct shaper *sh) 126 - { 127 - clear_bit(0, &sh->locked); 128 - wake_up(&sh->wait_queue); 129 - shaper_kick(sh); 130 - } 131 104 132 105 /* 133 106 * Compute clocks on a buffer ··· 130 157 * Throw a frame at a shaper. 131 158 */ 132 159 133 - static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) 160 + 161 + static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) 134 162 { 163 + struct shaper *shaper = dev->priv; 135 164 struct sk_buff *ptr; 136 165 137 - /* 138 - * Get ready to work on this shaper. Lock may fail if its 139 - * an interrupt and locked. 140 - */ 141 - 142 - if(!shaper_lock(shaper)) 143 - return -1; 166 + if (down_trylock(&shaper->sem)) 167 + return -1; 168 + 144 169 ptr=shaper->sendq.prev; 145 170 146 171 /* ··· 231 260 dev_kfree_skb(ptr); 232 261 shaper->stats.collisions++; 233 262 } 234 - shaper_unlock(shaper); 263 + shaper_kick(shaper); 264 + up(&shaper->sem); 235 265 return 0; 236 266 } 237 267 ··· 269 297 270 298 static void shaper_timer(unsigned long data) 271 299 { 272 - struct shaper *sh=(struct shaper *)data; 273 - shaper_kick(sh); 300 + struct shaper *shaper = (struct shaper *)data; 301 + 302 + if (!down_trylock(&shaper->sem)) { 303 + shaper_kick(shaper); 304 + up(&shaper->sem); 305 + } else 306 + mod_timer(&shaper->timer, jiffies); 274 307 } 275 308 276 309 /* ··· 287 310 { 288 311 struct sk_buff *skb; 289 312 290 - /* 291 - * Shaper unlock will kick 292 - */ 293 - 294 - if (test_and_set_bit(0, &shaper->locked)) 295 - { 296 - if(sh_debug) 297 - printk("Shaper locked.\n"); 298 - mod_timer(&shaper->timer, jiffies); 299 - return; 300 - } 301 - 302 - 303 313 /* 304 314 * Walk the list (may be empty) 305 315 */ ··· 328 364 329 365 if(skb!=NULL) 330 366 mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); 331 - 332 - clear_bit(0, &shaper->locked); 333 367 } 334 368 335 369 ··· 338 376 static void shaper_flush(struct shaper *shaper) 339 377 { 340 378 struct sk_buff *skb; 341 - if(!shaper_lock(shaper)) 342 - { 343 - printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n"); 344 - return; 345 - } 379 + 380 + down(&shaper->sem); 346 381 while((skb=skb_dequeue(&shaper->sendq))!=NULL) 347 382 dev_kfree_skb(skb); 348 - shaper_unlock(shaper); 383 + shaper_kick(shaper); 384 + up(&shaper->sem); 349 385 } 350 386 351 387 /* ··· 385 425 * for our attached device. This enables us to bandwidth allocate after 386 426 * ARP and other resolutions and not before. 387 427 */ 388 - 389 - 390 - static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) 391 - { 392 - struct shaper *sh=dev->priv; 393 - return shaper_qframe(sh, skb); 394 - } 395 428 396 429 static struct net_device_stats *shaper_get_stats(struct net_device *dev) 397 430 { ··· 576 623 init_timer(&sh->timer); 577 624 sh->timer.function=shaper_timer; 578 625 sh->timer.data=(unsigned long)sh; 579 - init_waitqueue_head(&sh->wait_queue); 580 626 } 581 627 582 628 /*
+1 -2
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 - unsigned long locked; 26 + struct semaphore sem; 27 27 struct net_device_stats stats; 28 28 struct net_device *dev; 29 29 int (*hard_start_xmit) (struct sk_buff *skb, ··· 38 38 int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh); 39 39 void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr); 40 40 struct net_device_stats* (*get_stats)(struct net_device *dev); 41 - wait_queue_head_t wait_queue; 42 41 struct timer_list timer; 43 42 }; 44 43