netlink: eliminate nl_sk_hash_lock
[cascardo/linux.git] / net / netlink / diag.c
index de8c74a..bb59a7e 100644 (file)
@@ -103,7 +103,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
 {
        struct netlink_table *tbl = &nl_table[protocol];
        struct rhashtable *ht = &tbl->hash;
-       const struct bucket_table *htbl = rht_dereference(ht->tbl, ht);
+       const struct bucket_table *htbl = rht_dereference_rcu(ht->tbl, ht);
        struct net *net = sock_net(skb->sk);
        struct netlink_diag_req *req;
        struct netlink_sock *nlsk;
@@ -113,7 +113,9 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
        req = nlmsg_data(cb->nlh);
 
        for (i = 0; i < htbl->size; i++) {
-               rht_for_each_entry(nlsk, htbl->buckets[i], ht, node) {
+               struct rhash_head *pos;
+
+               rht_for_each_entry_rcu(nlsk, pos, htbl, i, node) {
                        sk = (struct sock *)nlsk;
 
                        if (!net_eq(sock_net(sk), net))
@@ -170,7 +172,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
 
        req = nlmsg_data(cb->nlh);
 
-       mutex_lock(&nl_sk_hash_lock);
+       rcu_read_lock();
        read_lock(&nl_table_lock);
 
        if (req->sdiag_protocol == NDIAG_PROTO_ALL) {
@@ -184,7 +186,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
        } else {
                if (req->sdiag_protocol >= MAX_LINKS) {
                        read_unlock(&nl_table_lock);
-                       mutex_unlock(&nl_sk_hash_lock);
+                       rcu_read_unlock();
                        return -ENOENT;
                }
 
@@ -192,7 +194,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
        }
 
        read_unlock(&nl_table_lock);
-       mutex_unlock(&nl_sk_hash_lock);
+       rcu_read_unlock();
 
        return skb->len;
 }