diff options
| -rw-r--r-- | net/ipv4/route.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 9fcbb1b0a8d6..726ea5e8180a 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -54,7 +54,7 @@ | |||
| 54 | * Marc Boucher : routing by fwmark | 54 | * Marc Boucher : routing by fwmark |
| 55 | * Robert Olsson : Added rt_cache statistics | 55 | * Robert Olsson : Added rt_cache statistics |
| 56 | * Arnaldo C. Melo : Convert proc stuff to seq_file | 56 | * Arnaldo C. Melo : Convert proc stuff to seq_file |
| 57 | * Eric Dumazet : hashed spinlocks | 57 | * Eric Dumazet : hashed spinlocks and rt_check_expire() fixes. |
| 58 | * | 58 | * |
| 59 | * This program is free software; you can redistribute it and/or | 59 | * This program is free software; you can redistribute it and/or |
| 60 | * modify it under the terms of the GNU General Public License | 60 | * modify it under the terms of the GNU General Public License |
| @@ -606,18 +606,25 @@ static struct rtable **rt_remove_balanced_route(struct rtable **chain_head, | |||
| 606 | /* This runs via a timer and thus is always in BH context. */ | 606 | /* This runs via a timer and thus is always in BH context. */ |
| 607 | static void rt_check_expire(unsigned long dummy) | 607 | static void rt_check_expire(unsigned long dummy) |
| 608 | { | 608 | { |
| 609 | static int rover; | 609 | static unsigned int rover; |
| 610 | int i = rover, t; | 610 | unsigned int i = rover, goal; |
| 611 | struct rtable *rth, **rthp; | 611 | struct rtable *rth, **rthp; |
| 612 | unsigned long now = jiffies; | 612 | unsigned long now = jiffies; |
| 613 | 613 | u64 mult; | |
| 614 | for (t = ip_rt_gc_interval << rt_hash_log; t >= 0; | 614 | |
| 615 | t -= ip_rt_gc_timeout) { | 615 | mult = ((u64)ip_rt_gc_interval) << rt_hash_log; |
| 616 | if (ip_rt_gc_timeout > 1) | ||
| 617 | do_div(mult, ip_rt_gc_timeout); | ||
| 618 | goal = (unsigned int)mult; | ||
| 619 | if (goal > rt_hash_mask) goal = rt_hash_mask + 1; | ||
| 620 | for (; goal > 0; goal--) { | ||
| 616 | unsigned long tmo = ip_rt_gc_timeout; | 621 | unsigned long tmo = ip_rt_gc_timeout; |
| 617 | 622 | ||
| 618 | i = (i + 1) & rt_hash_mask; | 623 | i = (i + 1) & rt_hash_mask; |
| 619 | rthp = &rt_hash_table[i].chain; | 624 | rthp = &rt_hash_table[i].chain; |
| 620 | 625 | ||
| 626 | if (*rthp == 0) | ||
| 627 | continue; | ||
| 621 | spin_lock(rt_hash_lock_addr(i)); | 628 | spin_lock(rt_hash_lock_addr(i)); |
| 622 | while ((rth = *rthp) != NULL) { | 629 | while ((rth = *rthp) != NULL) { |
| 623 | if (rth->u.dst.expires) { | 630 | if (rth->u.dst.expires) { |
| @@ -658,7 +665,7 @@ static void rt_check_expire(unsigned long dummy) | |||
| 658 | break; | 665 | break; |
| 659 | } | 666 | } |
| 660 | rover = i; | 667 | rover = i; |
| 661 | mod_timer(&rt_periodic_timer, now + ip_rt_gc_interval); | 668 | mod_timer(&rt_periodic_timer, jiffies + ip_rt_gc_interval); |
| 662 | } | 669 | } |
| 663 | 670 | ||
| 664 | /* This can run from both BH and non-BH contexts, the latter | 671 | /* This can run from both BH and non-BH contexts, the latter |
