]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Revert "netlink: Replace rhash_portid with bound"
authorDan Duval <dan.duval@oracle.com>
Wed, 9 Dec 2015 22:13:36 +0000 (17:13 -0500)
committerSantosh Shilimkar <santosh.shilimkar@oracle.com>
Thu, 10 Dec 2015 01:42:09 +0000 (17:42 -0800)
Orabug: 22284865

This reverts commit d48623677191e0f035d7afd344f92cf880b01f8e.

That commit, along with 4e27762, have been shown to provoke a hang
in the Oracle Real Application Clusters (RAC) silent-installation
procedure.

Signed-off-by: Dan Duval <dan.duval@oracle.com>
net/netlink/af_netlink.c
net/netlink/af_netlink.h

index d139c43ac6e50935596ff002444ea080120444b0..eb54d50ecd5172247c00752f9c46838d6ecb8263 100644 (file)
@@ -1017,7 +1017,7 @@ static inline int netlink_compare(struct rhashtable_compare_arg *arg,
        const struct netlink_compare_arg *x = arg->key;
        const struct netlink_sock *nlk = ptr;
 
-       return nlk->portid != x->portid ||
+       return nlk->rhash_portid != x->portid ||
               !net_eq(sock_net(&nlk->sk), read_pnet(&x->pnet));
 }
 
@@ -1043,7 +1043,7 @@ static int __netlink_insert(struct netlink_table *table, struct sock *sk)
 {
        struct netlink_compare_arg arg;
 
-       netlink_compare_arg_init(&arg, sock_net(sk), nlk_sk(sk)->portid);
+       netlink_compare_arg_init(&arg, sock_net(sk), nlk_sk(sk)->rhash_portid);
        return rhashtable_lookup_insert_key(&table->hash, &arg,
                                            &nlk_sk(sk)->node,
                                            netlink_rhashtable_params);
@@ -1096,8 +1096,8 @@ static int netlink_insert(struct sock *sk, u32 portid)
 
        lock_sock(sk);
 
-       err = nlk_sk(sk)->portid == portid ? 0 : -EBUSY;
-       if (nlk_sk(sk)->bound)
+       err = -EBUSY;
+       if (nlk_sk(sk)->portid)
                goto err;
 
        err = -ENOMEM;
@@ -1105,7 +1105,7 @@ static int netlink_insert(struct sock *sk, u32 portid)
            unlikely(atomic_read(&table->hash.nelems) >= UINT_MAX))
                goto err;
 
-       nlk_sk(sk)->portid = portid;
+       nlk_sk(sk)->rhash_portid = portid;
        sock_hold(sk);
 
        err = __netlink_insert(table, sk);
@@ -1120,9 +1120,7 @@ static int netlink_insert(struct sock *sk, u32 portid)
                sock_put(sk);
        }
 
-       /* We need to ensure that the socket is hashed and visible. */
-       smp_wmb();
-       nlk_sk(sk)->bound = portid;
+       nlk_sk(sk)->portid = portid;
 
 err:
        release_sock(sk);
@@ -1503,7 +1501,6 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
        struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
        int err;
        long unsigned int groups = nladdr->nl_groups;
-       bool bound;
 
        if (addr_len < sizeof(struct sockaddr_nl))
                return -EINVAL;
@@ -1520,14 +1517,9 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
                        return err;
        }
 
-       bound = nlk->bound;
-       if (bound) {
-               /* Ensure nlk->portid is up-to-date. */
-               smp_rmb();
-
+       if (nlk->portid)
                if (nladdr->nl_pid != nlk->portid)
                        return -EINVAL;
-       }
 
        if (nlk->netlink_bind && groups) {
                int group;
@@ -1543,10 +1535,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
                }
        }
 
-       /* No need for barriers here as we return to user-space without
-        * using any of the bound attributes.
-        */
-       if (!bound) {
+       if (!nlk->portid) {
                err = nladdr->nl_pid ?
                        netlink_insert(sk, nladdr->nl_pid) :
                        netlink_autobind(sock);
@@ -1594,10 +1583,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
            !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
                return -EPERM;
 
-       /* No need for barriers here as we return to user-space without
-        * using any of the bound attributes.
-        */
-       if (!nlk->bound)
+       if (!nlk->portid)
                err = netlink_autobind(sock);
 
        if (err == 0) {
@@ -2354,13 +2340,10 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
                dst_group = nlk->dst_group;
        }
 
-       if (!nlk->bound) {
+       if (!nlk->portid) {
                err = netlink_autobind(sock);
                if (err)
                        goto out;
-       } else {
-               /* Ensure nlk is hashed and visible. */
-               smp_rmb();
        }
 
        /* It's a really convoluted way for userland to ask for mmaped
@@ -3195,7 +3178,7 @@ static inline u32 netlink_hash(const void *data, u32 len, u32 seed)
        const struct netlink_sock *nlk = data;
        struct netlink_compare_arg arg;
 
-       netlink_compare_arg_init(&arg, sock_net(&nlk->sk), nlk->portid);
+       netlink_compare_arg_init(&arg, sock_net(&nlk->sk), nlk->rhash_portid);
        return jhash2((u32 *)&arg, netlink_compare_arg_len / sizeof(u32), seed);
 }
 
index 14437d9b1965dcf3d3f085e4aba1f804bdc6f652..80b2b7526dfd26641542f4c5868fdd5b830056a0 100644 (file)
@@ -25,6 +25,7 @@ struct netlink_ring {
 struct netlink_sock {
        /* struct sock has to be the first member of netlink_sock */
        struct sock             sk;
+       u32                     rhash_portid;
        u32                     portid;
        u32                     dst_portid;
        u32                     dst_group;
@@ -35,7 +36,6 @@ struct netlink_sock {
        unsigned long           state;
        size_t                  max_recvmsg_len;
        wait_queue_head_t       wait;
-       bool                    bound;
        bool                    cb_running;
        struct netlink_callback cb;
        struct mutex            *cb_mutex;