diff mbox series

[mptcp-next] mptcp: use mptcp worker for path management

Message ID 20200619115710.2571-1-fw@strlen.de
State Accepted, archived
Delegated to: Matthieu Baerts
Headers show
Series [mptcp-next] mptcp: use mptcp worker for path management | expand

Commit Message

Florian Westphal June 19, 2020, 11:57 a.m. UTC
We can re-use the existing work queue to handle path management
instead of a dedicated work queue.  Just move pm_worker to protocol.c,
call it from the mptcp worker and get rid of the msk lock (already held).

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 As a followup one could probably also merge 'status' and msk->flags,
 might also be able to remove the 'pending' boolean.

 I can have a look next week.

 net/mptcp/pm.c       | 44 +-------------------------------------------
 net/mptcp/protocol.c | 27 ++++++++++++++++++++++++++-
 net/mptcp/protocol.h |  3 ---
 3 files changed, 27 insertions(+), 47 deletions(-)

Comments

Paolo Abeni June 19, 2020, 2:27 p.m. UTC | #1
On Fri, 2020-06-19 at 13:57 +0200, Florian Westphal wrote:
> @@ -181,35 +179,6 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
>  	return mptcp_pm_nl_get_local_id(msk, skc);
>  }
>  
> -static void pm_worker(struct work_struct *work)
> -{
> -	struct mptcp_pm_data *pm = container_of(work, struct mptcp_pm_data,
> -						work);
> -	struct mptcp_sock *msk = container_of(pm, struct mptcp_sock, pm);
> -	struct sock *sk = (struct sock *)msk;
> -
> -	lock_sock(sk);
> -	spin_lock_bh(&msk->pm.lock);
> -
> -	pr_debug("msk=%p status=%x", msk, pm->status);
> -	if (pm->status & BIT(MPTCP_PM_ADD_ADDR_RECEIVED)) {
> -		pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
> -		mptcp_pm_nl_add_addr_received(msk);
> -	}
> -	if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) {
> -		pm->status &= ~BIT(MPTCP_PM_ESTABLISHED);
> -		mptcp_pm_nl_fully_established(msk);
> -	}
> -	if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) {
> -		pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED);
> -		mptcp_pm_nl_subflow_established(msk);
> -	}
> -
> -	spin_unlock_bh(&msk->pm.lock);
> -	release_sock(sk);
> -	sock_put(sk);
> -}
> -
>  void mptcp_pm_data_init(struct mptcp_sock *msk)
>  {
>  	msk->pm.add_addr_signaled = 0;
> @@ -223,22 +192,11 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
>  	msk->pm.status = 0;
>  
>  	spin_lock_init(&msk->pm.lock);
> -	INIT_WORK(&msk->pm.work, pm_worker);
>  
>  	mptcp_pm_nl_data_init(msk);
>  }
>  
> -void mptcp_pm_close(struct mptcp_sock *msk)
> -{
> -	if (cancel_work_sync(&msk->pm.work))
> -		sock_put((struct sock *)msk);
> -}
> -
>  void __init mptcp_pm_init(void)
>  {
> -	pm_wq = alloc_workqueue("pm_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 8);
> -	if (!pm_wq)
> -		panic("Failed to allocate workqueue");
> -

I'm wondering if we should keep using an MPTCP-specific workqueue.
Server side, we don't expect the work to trigger very often, but should
that ever happen, top will tell easily.

WDYT?

Thanks!

Paolo
Florian Westphal June 22, 2020, 11:18 a.m. UTC | #2
Paolo Abeni <pabeni@redhat.com> wrote:
> I'm wondering if we should keep using an MPTCP-specific workqueue.
> Server side, we don't expect the work to trigger very often, but should
> that ever happen, top will tell easily.

You mean switch msk->work from system_wq to a custom workqueue?
Paolo Abeni June 22, 2020, 11:30 a.m. UTC | #3
On Mon, 2020-06-22 at 13:18 +0200, Florian Westphal wrote:
> Paolo Abeni <pabeni@redhat.com> wrote:
> > I'm wondering if we should keep using an MPTCP-specific workqueue.
> > Server side, we don't expect the work to trigger very often, but should
> > that ever happen, top will tell easily.
> 
> You mean switch msk->work from system_wq to a custom workqueue?

yep, e.g. reusing and renaming 'pm_wq'. When the PM works a lot (in
"ndiffports" mode as in issues/33), the pm_wq is visible in top - at
least in dbg build, I never tested with regular kconfig - and I like
being able to identify it easily. WDYT?

Thanks!

Paolo
Florian Westphal June 22, 2020, 1:03 p.m. UTC | #4
Paolo Abeni <pabeni@redhat.com> wrote:
> On Mon, 2020-06-22 at 13:18 +0200, Florian Westphal wrote:
> > Paolo Abeni <pabeni@redhat.com> wrote:
> > > I'm wondering if we should keep using an MPTCP-specific workqueue.
> > > Server side, we don't expect the work to trigger very often, but should
> > > that ever happen, top will tell easily.
> > 
> > You mean switch msk->work from system_wq to a custom workqueue?
> 
> yep, e.g. reusing and renaming 'pm_wq'. When the PM works a lot (in
> "ndiffports" mode as in issues/33), the pm_wq is visible in top - at
> least in dbg build, I never tested with regular kconfig - and I like
> being able to identify it easily. WDYT?

Can you do this?

I am not at all sure how you would like this to look like 8-(

(Merge parts of protocol.c into pm.c?)
Paolo Abeni June 22, 2020, 2:51 p.m. UTC | #5
On Mon, 2020-06-22 at 15:03 +0200, Florian Westphal wrote:
> Paolo Abeni <pabeni@redhat.com> wrote:
> > On Mon, 2020-06-22 at 13:18 +0200, Florian Westphal wrote:
> > > Paolo Abeni <pabeni@redhat.com> wrote:
> > > > I'm wondering if we should keep using an MPTCP-specific workqueue.
> > > > Server side, we don't expect the work to trigger very often, but should
> > > > that ever happen, top will tell easily.
> > > 
> > > You mean switch msk->work from system_wq to a custom workqueue?
> > 
> > yep, e.g. reusing and renaming 'pm_wq'. When the PM works a lot (in
> > "ndiffports" mode as in issues/33), the pm_wq is visible in top - at
> > least in dbg build, I never tested with regular kconfig - and I like
> > being able to identify it easily. WDYT?
> 
> Can you do this?

I'll try to run the perf tests on non-debug build, but I see your
point. Let's keep the patch simple - as is now. We can look for a
workqueue only if mptcp workqueue usage proves to be relevant in non
debug build.

Thanks,

Paolo
Matthieu Baerts June 24, 2020, 4:29 p.m. UTC | #6
Hi Florian, Paolo

On 22/06/2020 16:51, Paolo Abeni wrote:
> On Mon, 2020-06-22 at 15:03 +0200, Florian Westphal wrote:
>> Paolo Abeni <pabeni@redhat.com> wrote:
>>> On Mon, 2020-06-22 at 13:18 +0200, Florian Westphal wrote:
>>>> Paolo Abeni <pabeni@redhat.com> wrote:
>>>>> I'm wondering if we should keep using an MPTCP-specific workqueue.
>>>>> Server side, we don't expect the work to trigger very often, but should
>>>>> that ever happen, top will tell easily.
>>>>
>>>> You mean switch msk->work from system_wq to a custom workqueue?
>>>
>>> yep, e.g. reusing and renaming 'pm_wq'. When the PM works a lot (in
>>> "ndiffports" mode as in issues/33), the pm_wq is visible in top - at
>>> least in dbg build, I never tested with regular kconfig - and I like
>>> being able to identify it easily. WDYT?
>>
>> Can you do this?
> 
> I'll try to run the perf tests on non-debug build, but I see your
> point. Let's keep the patch simple - as is now. We can look for a
> workqueue only if mptcp workqueue usage proves to be relevant in non
> debug build.

Thank you for the patch and the review!

I just added this patch at the end of the series.

- bcb252d3443b: mptcp: use mptcp worker for path management

Tests and export are in progress.

Cheers,
Matt
diff mbox series

Patch

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 7de09fdd42a3..a8ad20559aaa 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -10,8 +10,6 @@ 
 #include <net/mptcp.h>
 #include "protocol.h"
 
-static struct workqueue_struct *pm_wq;
-
 /* path manager command handlers */
 
 int mptcp_pm_announce_addr(struct mptcp_sock *msk,
@@ -78,7 +76,7 @@  static bool mptcp_pm_schedule_work(struct mptcp_sock *msk,
 		return false;
 
 	msk->pm.status |= BIT(new_status);
-	if (queue_work(pm_wq, &msk->pm.work))
+	if (schedule_work(&msk->work))
 		sock_hold((struct sock *)msk);
 	return true;
 }
@@ -181,35 +179,6 @@  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
 	return mptcp_pm_nl_get_local_id(msk, skc);
 }
 
-static void pm_worker(struct work_struct *work)
-{
-	struct mptcp_pm_data *pm = container_of(work, struct mptcp_pm_data,
-						work);
-	struct mptcp_sock *msk = container_of(pm, struct mptcp_sock, pm);
-	struct sock *sk = (struct sock *)msk;
-
-	lock_sock(sk);
-	spin_lock_bh(&msk->pm.lock);
-
-	pr_debug("msk=%p status=%x", msk, pm->status);
-	if (pm->status & BIT(MPTCP_PM_ADD_ADDR_RECEIVED)) {
-		pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
-		mptcp_pm_nl_add_addr_received(msk);
-	}
-	if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) {
-		pm->status &= ~BIT(MPTCP_PM_ESTABLISHED);
-		mptcp_pm_nl_fully_established(msk);
-	}
-	if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) {
-		pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED);
-		mptcp_pm_nl_subflow_established(msk);
-	}
-
-	spin_unlock_bh(&msk->pm.lock);
-	release_sock(sk);
-	sock_put(sk);
-}
-
 void mptcp_pm_data_init(struct mptcp_sock *msk)
 {
 	msk->pm.add_addr_signaled = 0;
@@ -223,22 +192,11 @@  void mptcp_pm_data_init(struct mptcp_sock *msk)
 	msk->pm.status = 0;
 
 	spin_lock_init(&msk->pm.lock);
-	INIT_WORK(&msk->pm.work, pm_worker);
 
 	mptcp_pm_nl_data_init(msk);
 }
 
-void mptcp_pm_close(struct mptcp_sock *msk)
-{
-	if (cancel_work_sync(&msk->pm.work))
-		sock_put((struct sock *)msk);
-}
-
 void __init mptcp_pm_init(void)
 {
-	pm_wq = alloc_workqueue("pm_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 8);
-	if (!pm_wq)
-		panic("Failed to allocate workqueue");
-
 	mptcp_pm_nl_init();
 }
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index faa804f63c81..a349d8f06f20 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1237,6 +1237,29 @@  static unsigned int mptcp_sync_mss(struct sock *sk, u32 pmtu)
 	return 0;
 }
 
+static void pm_work(struct mptcp_sock *msk)
+{
+	struct mptcp_pm_data *pm = &msk->pm;
+
+	spin_lock_bh(&msk->pm.lock);
+
+	pr_debug("msk=%p status=%x", msk, pm->status);
+	if (pm->status & BIT(MPTCP_PM_ADD_ADDR_RECEIVED)) {
+		pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
+		mptcp_pm_nl_add_addr_received(msk);
+	}
+	if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) {
+		pm->status &= ~BIT(MPTCP_PM_ESTABLISHED);
+		mptcp_pm_nl_fully_established(msk);
+	}
+	if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) {
+		pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED);
+		mptcp_pm_nl_subflow_established(msk);
+	}
+
+	spin_unlock_bh(&msk->pm.lock);
+}
+
 static void mptcp_worker(struct work_struct *work)
 {
 	struct mptcp_sock *msk = container_of(work, struct mptcp_sock, work);
@@ -1253,6 +1276,9 @@  static void mptcp_worker(struct work_struct *work)
 	__mptcp_flush_join_list(msk);
 	__mptcp_move_skbs(msk);
 
+	if (msk->pm.status)
+		pm_work(msk);
+
 	if (test_and_clear_bit(MPTCP_WORK_EOF, &msk->flags))
 		mptcp_check_for_eof(msk);
 
@@ -1444,7 +1470,6 @@  static void mptcp_close(struct sock *sk, long timeout)
 	}
 
 	mptcp_cancel_work(sk);
-	mptcp_pm_close(msk);
 
 	__skb_queue_purge(&sk->sk_receive_queue);
 
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 2c3deede2469..6d3fff97e3c6 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -174,8 +174,6 @@  struct mptcp_pm_data {
 	u8		local_addr_max;
 	u8		subflows_max;
 	u8		status;
-
-	struct		work_struct work;
 };
 
 struct mptcp_data_frag {
@@ -417,7 +415,6 @@  void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac);
 
 void __init mptcp_pm_init(void);
 void mptcp_pm_data_init(struct mptcp_sock *msk);
-void mptcp_pm_close(struct mptcp_sock *msk);
 void mptcp_pm_new_connection(struct mptcp_sock *msk, int server_side);
 void mptcp_pm_fully_established(struct mptcp_sock *msk);
 bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk);