sctp: simplify sk_receive_queue locking
[cascardo/linux.git] / net / sctp / socket.c
index e878da0..bf265a4 100644 (file)
@@ -52,6 +52,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <crypto/hash.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/wait.h>
@@ -61,7 +62,6 @@
 #include <linux/fcntl.h>
 #include <linux/poll.h>
 #include <linux/init.h>
-#include <linux/crypto.h>
 #include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/compat.h>
@@ -386,7 +386,8 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
        /* Add the address to the bind address list.
         * Use GFP_ATOMIC since BHs will be disabled.
         */
-       ret = sctp_add_bind_addr(bp, addr, SCTP_ADDR_SRC, GFP_ATOMIC);
+       ret = sctp_add_bind_addr(bp, addr, af->sockaddr_len,
+                                SCTP_ADDR_SRC, GFP_ATOMIC);
 
        /* Copy back into socket for getsockname() use. */
        if (!ret) {
@@ -577,6 +578,7 @@ static int sctp_send_asconf_add_ip(struct sock              *sk,
                        af = sctp_get_af_specific(addr->v4.sin_family);
                        memcpy(&saveaddr, addr, af->sockaddr_len);
                        retval = sctp_add_bind_addr(bp, &saveaddr,
+                                                   sizeof(saveaddr),
                                                    SCTP_ADDR_NEW, GFP_ATOMIC);
                        addr_buf += af->sockaddr_len;
                }
@@ -1389,7 +1391,7 @@ static int sctp_getsockopt_connectx3(struct sock *sk, int len,
        int err = 0;
 
 #ifdef CONFIG_COMPAT
-       if (is_compat_task()) {
+       if (in_compat_syscall()) {
                struct compat_sctp_getaddrs_old param32;
 
                if (len < sizeof(param32))
@@ -4160,7 +4162,7 @@ static void sctp_destruct_sock(struct sock *sk)
        struct sctp_sock *sp = sctp_sk(sk);
 
        /* Free up the HMAC transform. */
-       crypto_free_hash(sp->hmac);
+       crypto_free_shash(sp->hmac);
 
        inet_sock_destruct(sk);
 }
@@ -6106,9 +6108,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
        return retval;
 }
 
-static void sctp_hash(struct sock *sk)
+static int sctp_hash(struct sock *sk)
 {
        /* STUB */
+       return 0;
 }
 
 static void sctp_unhash(struct sock *sk)
@@ -6304,13 +6307,13 @@ static int sctp_listen_start(struct sock *sk, int backlog)
 {
        struct sctp_sock *sp = sctp_sk(sk);
        struct sctp_endpoint *ep = sp->ep;
-       struct crypto_hash *tfm = NULL;
+       struct crypto_shash *tfm = NULL;
        char alg[32];
 
        /* Allocate HMAC for generating cookie. */
        if (!sp->hmac && sp->sctp_hmac_alg) {
                sprintf(alg, "hmac(%s)", sp->sctp_hmac_alg);
-               tfm = crypto_alloc_hash(alg, 0, CRYPTO_ALG_ASYNC);
+               tfm = crypto_alloc_shash(alg, 0, 0);
                if (IS_ERR(tfm)) {
                        net_info_ratelimited("failed to load transform for %s: %ld\n",
                                             sp->sctp_hmac_alg, PTR_ERR(tfm));
@@ -6427,6 +6430,8 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
 
        poll_wait(file, sk_sleep(sk), wait);
 
+       sock_rps_record_flow(sk);
+
        /* A TCP-style listening socket becomes readable when the accept queue
         * is not empty.
         */
@@ -6761,13 +6766,11 @@ struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
                 *  However, this function was correct in any case. 8)
                 */
                if (flags & MSG_PEEK) {
-                       spin_lock_bh(&sk->sk_receive_queue.lock);
                        skb = skb_peek(&sk->sk_receive_queue);
                        if (skb)
                                atomic_inc(&skb->users);
-                       spin_unlock_bh(&sk->sk_receive_queue.lock);
                } else {
-                       skb = skb_dequeue(&sk->sk_receive_queue);
+                       skb = __skb_dequeue(&sk->sk_receive_queue);
                }
 
                if (skb)
@@ -7183,6 +7186,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
        newsk->sk_lingertime = sk->sk_lingertime;
        newsk->sk_rcvtimeo = sk->sk_rcvtimeo;
        newsk->sk_sndtimeo = sk->sk_sndtimeo;
+       newsk->sk_rxhash = sk->sk_rxhash;
 
        newinet = inet_sk(newsk);
 
@@ -7253,14 +7257,12 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
        /* Hook this new socket in to the bind_hash list. */
        head = &sctp_port_hashtable[sctp_phashfn(sock_net(oldsk),
                                                 inet_sk(oldsk)->inet_num)];
-       local_bh_disable();
-       spin_lock(&head->lock);
+       spin_lock_bh(&head->lock);
        pp = sctp_sk(oldsk)->bind_hash;
        sk_add_bind_node(newsk, &pp->owner);
        sctp_sk(newsk)->bind_hash = pp;
        inet_sk(newsk)->inet_num = inet_sk(oldsk)->inet_num;
-       spin_unlock(&head->lock);
-       local_bh_enable();
+       spin_unlock_bh(&head->lock);
 
        /* Copy the bind_addr list from the original endpoint to the new
         * endpoint so that we can handle restarts properly