udp: add a counter into udp_hslot
authorEric Dumazet <eric.dumazet@gmail.com>
Sun, 8 Nov 2009 10:17:05 +0000 (10:17 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 9 Nov 2009 04:53:04 +0000 (20:53 -0800)
Adds a counter in udp_hslot to keep an accurate count
of sockets present in chain.

This will permit to upcoming UDP lookup algo to chose
the shortest chain when secondary hash is added.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/udp.h
net/ipv4/udp.c

index 22aa2e7eb1d77e1cb075f79e190e36b8ee7aee01..9167281e47dcae8494058f3865137afea7f68a6a 100644 (file)
@@ -50,8 +50,16 @@ struct udp_skb_cb {
 };
 #define UDP_SKB_CB(__skb)      ((struct udp_skb_cb *)((__skb)->cb))
 
+/**
+ *     struct udp_hslot - UDP hash slot
+ *
+ *     @head:  head of list of sockets
+ *     @count: number of sockets in 'head' list
+ *     @lock:  spinlock protecting changes to head/count
+ */
 struct udp_hslot {
        struct hlist_nulls_head head;
+       int                     count;
        spinlock_t              lock;
 } __attribute__((aligned(2 * sizeof(long))));
 
index d5e75e976513ba9f4b8deeed4774cbe2220759dc..ffc837643a04b858173fc489a22f5725d65c6755 100644 (file)
@@ -218,6 +218,7 @@ found:
        sk->sk_hash = snum;
        if (sk_unhashed(sk)) {
                sk_nulls_add_node_rcu(sk, &hslot->head);
+               hslot->count++;
                sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        }
        error = 0;
@@ -1053,6 +1054,7 @@ void udp_lib_unhash(struct sock *sk)
 
                spin_lock_bh(&hslot->lock);
                if (sk_nulls_del_node_init_rcu(sk)) {
+                       hslot->count--;
                        inet_sk(sk)->inet_num = 0;
                        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
                }
@@ -1862,6 +1864,7 @@ void __init udp_table_init(struct udp_table *table, const char *name)
        }
        for (i = 0; i <= table->mask; i++) {
                INIT_HLIST_NULLS_HEAD(&table->hash[i].head, i);
+               table->hash[i].count = 0;
                spin_lock_init(&table->hash[i].lock);
        }
 }