Commit 9a6d276e authored by Neil Horman's avatar Neil Horman Committed by David S. Miller

core: add stat to track unresolved discards in neighbor cache

in __neigh_event_send, if we have a neighbour entry which is in
NUD_INCOMPLETE state, we enqueue any outbound frames to that neighbour
to the neighbours arp_queue, which is default capped to a length of 3
skbs.  If that queue exceeds its set length, it will drop an skb on
the queue to enqueue the newly arrived skb.  This results in a drop
for which we have no statistics incremented.  This patch adds an
unresolved_discards stat to /proc/net/stat/ndisc_cache to track these
lost frames.
Signed-off-by: default avatarNeil Horman <nhorman@tuxdriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ed88098e
...@@ -75,7 +75,7 @@ struct neigh_statistics ...@@ -75,7 +75,7 @@ struct neigh_statistics
unsigned long destroys; /* number of destroyed neighs */ unsigned long destroys; /* number of destroyed neighs */
unsigned long hash_grows; /* number of hash resizes */ unsigned long hash_grows; /* number of hash resizes */
unsigned long res_failed; /* nomber of failed resolutions */ unsigned long res_failed; /* number of failed resolutions */
unsigned long lookups; /* number of lookups */ unsigned long lookups; /* number of lookups */
unsigned long hits; /* number of hits (among lookups) */ unsigned long hits; /* number of hits (among lookups) */
...@@ -85,6 +85,8 @@ struct neigh_statistics ...@@ -85,6 +85,8 @@ struct neigh_statistics
unsigned long periodic_gc_runs; /* number of periodic GC runs */ unsigned long periodic_gc_runs; /* number of periodic GC runs */
unsigned long forced_gc_runs; /* number of forced GC runs */ unsigned long forced_gc_runs; /* number of forced GC runs */
unsigned long unres_discards; /* number of unresolved drops */
}; };
#define NEIGH_CACHE_STAT_INC(tbl, field) \ #define NEIGH_CACHE_STAT_INC(tbl, field) \
......
...@@ -930,6 +930,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) ...@@ -930,6 +930,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
buff = neigh->arp_queue.next; buff = neigh->arp_queue.next;
__skb_unlink(buff, &neigh->arp_queue); __skb_unlink(buff, &neigh->arp_queue);
kfree_skb(buff); kfree_skb(buff);
NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards);
} }
__skb_queue_tail(&neigh->arp_queue, skb); __skb_queue_tail(&neigh->arp_queue, skb);
} }
...@@ -2462,12 +2463,12 @@ static int neigh_stat_seq_show(struct seq_file *seq, void *v) ...@@ -2462,12 +2463,12 @@ static int neigh_stat_seq_show(struct seq_file *seq, void *v)
struct neigh_statistics *st = v; struct neigh_statistics *st = v;
if (v == SEQ_START_TOKEN) { if (v == SEQ_START_TOKEN) {
seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs\n"); seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards\n");
return 0; return 0;
} }
seq_printf(seq, "%08x %08lx %08lx %08lx %08lx %08lx %08lx " seq_printf(seq, "%08x %08lx %08lx %08lx %08lx %08lx %08lx "
"%08lx %08lx %08lx %08lx\n", "%08lx %08lx %08lx %08lx %08lx\n",
atomic_read(&tbl->entries), atomic_read(&tbl->entries),
st->allocs, st->allocs,
...@@ -2483,7 +2484,8 @@ static int neigh_stat_seq_show(struct seq_file *seq, void *v) ...@@ -2483,7 +2484,8 @@ static int neigh_stat_seq_show(struct seq_file *seq, void *v)
st->rcv_probes_ucast, st->rcv_probes_ucast,
st->periodic_gc_runs, st->periodic_gc_runs,
st->forced_gc_runs st->forced_gc_runs,
st->unres_discards
); );
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment