mptcp: add work queue skeleton
authorPaolo Abeni <pabeni@redhat.com>
Wed, 26 Feb 2020 09:14:47 +0000 (10:14 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 27 Feb 2020 04:46:26 +0000 (20:46 -0800)
Will be extended with functionality in followup patches.
Initial user is moving skbs from subflows receive queue to
the mptcp-level receive queue.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/protocol.c
net/mptcp/protocol.h

index 1d55563..cbf184a 100644 (file)
@@ -551,12 +551,24 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
        }
 }
 
+static void mptcp_worker(struct work_struct *work)
+{
+       struct mptcp_sock *msk = container_of(work, struct mptcp_sock, work);
+       struct sock *sk = &msk->sk.icsk_inet.sk;
+
+       lock_sock(sk);
+
+       release_sock(sk);
+       sock_put(sk);
+}
+
 static int __mptcp_init_sock(struct sock *sk)
 {
        struct mptcp_sock *msk = mptcp_sk(sk);
 
        INIT_LIST_HEAD(&msk->conn_list);
        __set_bit(MPTCP_SEND_SPACE, &msk->flags);
+       INIT_WORK(&msk->work, mptcp_worker);
 
        msk->first = NULL;
 
@@ -571,6 +583,14 @@ static int mptcp_init_sock(struct sock *sk)
        return __mptcp_init_sock(sk);
 }
 
+static void mptcp_cancel_work(struct sock *sk)
+{
+       struct mptcp_sock *msk = mptcp_sk(sk);
+
+       if (cancel_work_sync(&msk->work))
+               sock_put(sk);
+}
+
 static void mptcp_subflow_shutdown(struct sock *ssk, int how)
 {
        lock_sock(ssk);
@@ -616,6 +636,8 @@ static void mptcp_close(struct sock *sk, long timeout)
                __mptcp_close_ssk(sk, ssk, subflow, timeout);
        }
 
+       mptcp_cancel_work(sk);
+
        sk_common_release(sk);
 }
 
index 67895a7..6e6e162 100644 (file)
@@ -70,6 +70,7 @@ struct mptcp_sock {
        u32             token;
        unsigned long   flags;
        bool            can_ack;
+       struct work_struct work;
        struct list_head conn_list;
        struct skb_ext  *cached_ext;    /* for the next sendmsg */
        struct socket   *subflow; /* outgoing connect/listener/!mp_capable */