X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=net%2Fcore%2Flink_watch.c;h=f2ed09e25dfd63fdba8d1d9f8e9e16550dfab239;hb=52bad64d95bd89e08c49ec5a071fa6dcbe5a1a9c;hp=e82a451d330b88d59cc8c0eeff3d0edde77dcef8;hpb=b00055aacdb172c05067612278ba27265fcd05ce;p=deliverable%2Flinux.git diff --git a/net/core/link_watch.c b/net/core/link_watch.c index e82a451d330b..f2ed09e25dfd 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c @@ -11,7 +11,6 @@ * */ -#include #include #include #include @@ -36,7 +35,7 @@ static unsigned long linkwatch_flags; static unsigned long linkwatch_nextevent; static void linkwatch_event(void *dummy); -static DECLARE_WORK(linkwatch_work, linkwatch_event, NULL); +static DECLARE_DELAYED_WORK(linkwatch_work, linkwatch_event, NULL); static LIST_HEAD(lweventlist); static DEFINE_SPINLOCK(lweventlist_lock); @@ -91,11 +90,10 @@ static void rfc2863_policy(struct net_device *dev) /* Must be called with the rtnl semaphore held */ void linkwatch_run_queue(void) { - LIST_HEAD(head); - struct list_head *n, *next; + struct list_head head, *n, *next; spin_lock_irq(&lweventlist_lock); - list_splice_init(&lweventlist, &head); + list_replace_init(&lweventlist, &head); spin_unlock_irq(&lweventlist_lock); list_for_each_safe(n, next, &head) { @@ -139,9 +137,9 @@ static void linkwatch_event(void *dummy) linkwatch_nextevent = jiffies + HZ; clear_bit(LW_RUNNING, &linkwatch_flags); - rtnl_shlock(); + rtnl_lock(); linkwatch_run_queue(); - rtnl_shunlock(); + rtnl_unlock(); } @@ -170,13 +168,12 @@ void linkwatch_fire_event(struct net_device *dev) spin_unlock_irqrestore(&lweventlist_lock, flags); if (!test_and_set_bit(LW_RUNNING, &linkwatch_flags)) { - unsigned long thisevent = jiffies; + unsigned long delay = linkwatch_nextevent - jiffies; - if (thisevent >= linkwatch_nextevent) { - schedule_work(&linkwatch_work); - } else { - schedule_delayed_work(&linkwatch_work, linkwatch_nextevent - thisevent); - } + /* If we wrap around we'll delay it by at most HZ. */ + if (delay > HZ) + delay = 0; + schedule_delayed_work(&linkwatch_work, delay); } } }