From: Paolo Abeni Currently a wild producer could keep the backlog flushing operation spinning for an unbound time. Since the previous patch, the amount of data present in the backlog is hard-limited. Move the backlog len update at the end of the flush loop to prevent it spinning forever. Also, no need to splice back the remaining skbs list into the backlog, as such list is always empty after each backlog processing loop. Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) --- net/mptcp/protocol.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 5f7d8340a3d9..7f257419c5ea 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2223,7 +2223,6 @@ static bool __mptcp_move_skbs(struct sock *sk, struct list_head *skbs, u32 *delt struct mptcp_sock *msk = mptcp_sk(sk); bool moved = false; - *delta = 0; while (1) { prefetch(skb->next); list_del(&skb->list); @@ -2260,20 +2259,12 @@ static bool mptcp_can_spool_backlog(struct sock *sk, struct list_head *skbs) return true; } -static void mptcp_backlog_spooled(struct sock *sk, u32 moved, - struct list_head *skbs) -{ - struct mptcp_sock *msk = mptcp_sk(sk); - - WRITE_ONCE(msk->backlog_len, msk->backlog_len - moved); - list_splice(skbs, &msk->backlog_list); -} - static bool mptcp_move_skbs(struct sock *sk) { + struct mptcp_sock *msk = mptcp_sk(sk); struct list_head skbs; bool enqueued = false; - u32 moved; + u32 moved = 0; mptcp_data_lock(sk); while (mptcp_can_spool_backlog(sk, &skbs)) { @@ -2281,8 +2272,8 @@ static bool mptcp_move_skbs(struct sock *sk) enqueued |= __mptcp_move_skbs(sk, &skbs, &moved); mptcp_data_lock(sk); - mptcp_backlog_spooled(sk, moved, &skbs); } + WRITE_ONCE(msk->backlog_len, msk->backlog_len - moved); mptcp_data_unlock(sk); if (enqueued && mptcp_epollin_ready(sk)) @@ -3752,12 +3743,12 @@ static void mptcp_release_cb(struct sock *sk) __must_hold(&sk->sk_lock.slock) { struct mptcp_sock *msk = mptcp_sk(sk); + u32 moved = 0; for (;;) { unsigned long flags = (msk->cb_flags & MPTCP_FLAGS_PROCESS_CTX_NEED); struct list_head join_list, skbs; bool spool_bl; - u32 moved; spool_bl = mptcp_can_spool_backlog(sk, &skbs); if (!flags && !spool_bl) @@ -3790,9 +3781,9 @@ static void mptcp_release_cb(struct sock *sk) cond_resched(); spin_lock_bh(&sk->sk_lock.slock); - if (spool_bl) - mptcp_backlog_spooled(sk, moved, &skbs); } + if (moved) + WRITE_ONCE(msk->backlog_len, msk->backlog_len - moved); if (__test_and_clear_bit(MPTCP_CLEAN_UNA, &msk->cb_flags)) __mptcp_clean_una_wakeup(sk); -- 2.53.0