diff options
Diffstat (limited to 'drivers/net/shaper.c')
| -rw-r--r-- | drivers/net/shaper.c | 86 |
1 files changed, 19 insertions, 67 deletions
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index e68cf5fb4920..20edeb345792 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c | |||
| @@ -100,35 +100,8 @@ static int sh_debug; /* Debug flag */ | |||
| 100 | 100 | ||
| 101 | #define SHAPER_BANNER "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n" | 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 | static void shaper_kick(struct shaper *sh); | 103 | static void shaper_kick(struct shaper *sh); |
| 124 | 104 | ||
| 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 | |||
| 132 | /* | 105 | /* |
| 133 | * Compute clocks on a buffer | 106 | * Compute clocks on a buffer |
| 134 | */ | 107 | */ |
| @@ -157,17 +130,15 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec) | |||
| 157 | * Throw a frame at a shaper. | 130 | * Throw a frame at a shaper. |
| 158 | */ | 131 | */ |
| 159 | 132 | ||
| 160 | static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) | 133 | |
| 134 | static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
| 161 | { | 135 | { |
| 136 | struct shaper *shaper = dev->priv; | ||
| 162 | struct sk_buff *ptr; | 137 | struct sk_buff *ptr; |
| 163 | 138 | ||
| 164 | /* | 139 | if (down_trylock(&shaper->sem)) |
| 165 | * Get ready to work on this shaper. Lock may fail if its | 140 | return -1; |
| 166 | * an interrupt and locked. | 141 | |
| 167 | */ | ||
| 168 | |||
| 169 | if(!shaper_lock(shaper)) | ||
| 170 | return -1; | ||
| 171 | ptr=shaper->sendq.prev; | 142 | ptr=shaper->sendq.prev; |
| 172 | 143 | ||
| 173 | /* | 144 | /* |
| @@ -260,7 +231,8 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) | |||
| 260 | dev_kfree_skb(ptr); | 231 | dev_kfree_skb(ptr); |
| 261 | shaper->stats.collisions++; | 232 | shaper->stats.collisions++; |
| 262 | } | 233 | } |
| 263 | shaper_unlock(shaper); | 234 | shaper_kick(shaper); |
| 235 | up(&shaper->sem); | ||
| 264 | return 0; | 236 | return 0; |
| 265 | } | 237 | } |
| 266 | 238 | ||
| @@ -297,8 +269,13 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) | |||
| 297 | 269 | ||
| 298 | static void shaper_timer(unsigned long data) | 270 | static void shaper_timer(unsigned long data) |
| 299 | { | 271 | { |
| 300 | struct shaper *sh=(struct shaper *)data; | 272 | struct shaper *shaper = (struct shaper *)data; |
| 301 | shaper_kick(sh); | 273 | |
| 274 | if (!down_trylock(&shaper->sem)) { | ||
| 275 | shaper_kick(shaper); | ||
| 276 | up(&shaper->sem); | ||
| 277 | } else | ||
| 278 | mod_timer(&shaper->timer, jiffies); | ||
| 302 | } | 279 | } |
| 303 | 280 | ||
| 304 | /* | 281 | /* |
| @@ -311,19 +288,6 @@ static void shaper_kick(struct shaper *shaper) | |||
| 311 | struct sk_buff *skb; | 288 | struct sk_buff *skb; |
| 312 | 289 | ||
| 313 | /* | 290 | /* |
| 314 | * Shaper unlock will kick | ||
| 315 | */ | ||
| 316 | |||
| 317 | if (test_and_set_bit(0, &shaper->locked)) | ||
| 318 | { | ||
| 319 | if(sh_debug) | ||
| 320 | printk("Shaper locked.\n"); | ||
| 321 | mod_timer(&shaper->timer, jiffies); | ||
| 322 | return; | ||
| 323 | } | ||
| 324 | |||
| 325 | |||
| 326 | /* | ||
| 327 | * Walk the list (may be empty) | 291 | * Walk the list (may be empty) |
| 328 | */ | 292 | */ |
| 329 | 293 | ||
| @@ -364,8 +328,6 @@ static void shaper_kick(struct shaper *shaper) | |||
| 364 | 328 | ||
| 365 | if(skb!=NULL) | 329 | if(skb!=NULL) |
| 366 | mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); | 330 | mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); |
| 367 | |||
| 368 | clear_bit(0, &shaper->locked); | ||
| 369 | } | 331 | } |
| 370 | 332 | ||
| 371 | 333 | ||
| @@ -376,14 +338,12 @@ static void shaper_kick(struct shaper *shaper) | |||
| 376 | static void shaper_flush(struct shaper *shaper) | 338 | static void shaper_flush(struct shaper *shaper) |
| 377 | { | 339 | { |
| 378 | struct sk_buff *skb; | 340 | struct sk_buff *skb; |
| 379 | if(!shaper_lock(shaper)) | 341 | |
| 380 | { | 342 | down(&shaper->sem); |
| 381 | printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n"); | ||
| 382 | return; | ||
| 383 | } | ||
| 384 | while((skb=skb_dequeue(&shaper->sendq))!=NULL) | 343 | while((skb=skb_dequeue(&shaper->sendq))!=NULL) |
| 385 | dev_kfree_skb(skb); | 344 | dev_kfree_skb(skb); |
| 386 | shaper_unlock(shaper); | 345 | shaper_kick(shaper); |
| 346 | up(&shaper->sem); | ||
| 387 | } | 347 | } |
| 388 | 348 | ||
| 389 | /* | 349 | /* |
| @@ -426,13 +386,6 @@ static int shaper_close(struct net_device *dev) | |||
| 426 | * ARP and other resolutions and not before. | 386 | * ARP and other resolutions and not before. |
| 427 | */ | 387 | */ |
| 428 | 388 | ||
| 429 | |||
| 430 | static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
| 431 | { | ||
| 432 | struct shaper *sh=dev->priv; | ||
| 433 | return shaper_qframe(sh, skb); | ||
| 434 | } | ||
| 435 | |||
| 436 | static struct net_device_stats *shaper_get_stats(struct net_device *dev) | 389 | static struct net_device_stats *shaper_get_stats(struct net_device *dev) |
| 437 | { | 390 | { |
| 438 | struct shaper *sh=dev->priv; | 391 | struct shaper *sh=dev->priv; |
| @@ -623,7 +576,6 @@ static void shaper_init_priv(struct net_device *dev) | |||
| 623 | init_timer(&sh->timer); | 576 | init_timer(&sh->timer); |
| 624 | sh->timer.function=shaper_timer; | 577 | sh->timer.function=shaper_timer; |
| 625 | sh->timer.data=(unsigned long)sh; | 578 | sh->timer.data=(unsigned long)sh; |
| 626 | init_waitqueue_head(&sh->wait_queue); | ||
| 627 | } | 579 | } |
| 628 | 580 | ||
| 629 | /* | 581 | /* |
