aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2005-09-27 15:07:44 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-09-27 15:07:44 -0400
commit667347f1ca7e099f6833551f194cf2bcc778871b (patch)
tree6478c6911e69a62b10ad3599d0294372905f5b2d /net
parent56e9b263242ca80a70abd8831343b268315c27dc (diff)
[NEIGH]: Add debugging check when adding timers.
If we double-add a neighbour entry timer, which should be impossible but has been reported, dump the current state of the entry so that we can debug this. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/neighbour.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 5f160082aafc..4128fc76ac3a 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -727,6 +727,13 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
727 p->ucast_probes + p->app_probes + p->mcast_probes); 727 p->ucast_probes + p->app_probes + p->mcast_probes);
728} 728}
729 729
730static inline void neigh_add_timer(struct neighbour *n, unsigned long when)
731{
732 if (unlikely(mod_timer(&n->timer, when))) {
733 printk("NEIGH: BUG, double timer add, state is %x\n",
734 n->nud_state);
735 }
736}
730 737
731/* Called when a timer expires for a neighbour entry. */ 738/* Called when a timer expires for a neighbour entry. */
732 739
@@ -811,8 +818,7 @@ static void neigh_timer_handler(unsigned long arg)
811 neigh_hold(neigh); 818 neigh_hold(neigh);
812 if (time_before(next, jiffies + HZ/2)) 819 if (time_before(next, jiffies + HZ/2))
813 next = jiffies + HZ/2; 820 next = jiffies + HZ/2;
814 neigh->timer.expires = next; 821 neigh_add_timer(neigh, next);
815 add_timer(&neigh->timer);
816 } 822 }
817 if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { 823 if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
818 struct sk_buff *skb = skb_peek(&neigh->arp_queue); 824 struct sk_buff *skb = skb_peek(&neigh->arp_queue);
@@ -854,8 +860,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
854 atomic_set(&neigh->probes, neigh->parms->ucast_probes); 860 atomic_set(&neigh->probes, neigh->parms->ucast_probes);
855 neigh->nud_state = NUD_INCOMPLETE; 861 neigh->nud_state = NUD_INCOMPLETE;
856 neigh_hold(neigh); 862 neigh_hold(neigh);
857 neigh->timer.expires = now + 1; 863 neigh_add_timer(neigh, now + 1);
858 add_timer(&neigh->timer);
859 } else { 864 } else {
860 neigh->nud_state = NUD_FAILED; 865 neigh->nud_state = NUD_FAILED;
861 write_unlock_bh(&neigh->lock); 866 write_unlock_bh(&neigh->lock);
@@ -868,8 +873,8 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
868 NEIGH_PRINTK2("neigh %p is delayed.\n", neigh); 873 NEIGH_PRINTK2("neigh %p is delayed.\n", neigh);
869 neigh_hold(neigh); 874 neigh_hold(neigh);
870 neigh->nud_state = NUD_DELAY; 875 neigh->nud_state = NUD_DELAY;
871 neigh->timer.expires = jiffies + neigh->parms->delay_probe_time; 876 neigh_add_timer(neigh,
872 add_timer(&neigh->timer); 877 jiffies + neigh->parms->delay_probe_time);
873 } 878 }
874 879
875 if (neigh->nud_state == NUD_INCOMPLETE) { 880 if (neigh->nud_state == NUD_INCOMPLETE) {
@@ -1015,10 +1020,10 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
1015 neigh_del_timer(neigh); 1020 neigh_del_timer(neigh);
1016 if (new & NUD_IN_TIMER) { 1021 if (new & NUD_IN_TIMER) {
1017 neigh_hold(neigh); 1022 neigh_hold(neigh);
1018 neigh->timer.expires = jiffies + 1023 neigh_add_timer(neigh, (jiffies +
1019 ((new & NUD_REACHABLE) ? 1024 ((new & NUD_REACHABLE) ?
1020 neigh->parms->reachable_time : 0); 1025 neigh->parms->reachable_time :
1021 add_timer(&neigh->timer); 1026 0)));
1022 } 1027 }
1023 neigh->nud_state = new; 1028 neigh->nud_state = new;
1024 } 1029 }