All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dust Li <dust.li@linux.alibaba.com>
To: Hidayath Khan <hidayath@linux.ibm.com>,
	alibuda@linux.alibaba.com, sidraya@linux.ibm.com,
	mjambigi@linux.ibm.com, andrew+netdev@lunn.ch
Cc: tonylu@linux.alibaba.com, guwen@linux.alibaba.com,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, horms@kernel.org, pasic@linux.ibm.com,
	linux-s390@vger.kernel.org, netdev@vger.kernel.org
Subject: Re: [PATCH net] net/smc: drop the abort_work reference when the work is cancelled
Date: Thu, 6 Aug 2026 17:20:53 +0800	[thread overview]
Message-ID: <anRR9doLcvlPAj4Q@linux.alibaba.com> (raw)
In-Reply-To: <20260806081549.595001-1-hidayath@linux.ibm.com>

On 2026-08-06 10:15:49, Hidayath Khan wrote:
>The schedulers of conn->abort_work hand a socket reference to the work
>item and rely on it to give the reference back:
>
>        sock_hold(&smc->sk); /* sock_put in abort_work */
>        if (!queue_work(smc_close_wq, &conn->abort_work))
>                sock_put(&smc->sk);
>
>The queue_work() failure case is handled, but the cancellation case is
>not. smc_conn_free() cancels a still-pending abort_work:
>
>        if (current_work() != &conn->abort_work)
>                cancel_work_sync(&conn->abort_work);
>
>and discards the return value.  When cancel_work_sync() returns true the
>work was queued but had not started, so smc_conn_abort_work() never runs
>and its sock_put() never happens.  The reference is lost.
>
>As in smc_switch_conns(), a leaked sk_refcnt means the smc_sock is never
>destroyed: its buffers stay allocated and the network namespace reference
>a user socket holds is never released, so the netns cannot be torn down.
>
>smc_cdc_msg_validate() queues abort_work from the receive tasklet when a
>peer sends a CDC message with an out-of-order sequence number, so a
>remote peer combined with a concurrent local close is enough to reach it.
>
>Drop the reference when the work is cancelled, matching the pattern
>smc_close_cancel_work() already uses for conn->close_work:
>
>        if (cancel_work_sync(&smc->conn.close_work))
>                sock_put(sk);
>
>The sock_put() is safe here: every caller of smc_conn_free() passes the
>connection of a socket it holds a reference to, so this cannot release
>the last one.
>
>Fixes: b286a0651e44 ("net/smc: handle incoming CDC validation message")
>Cc: stable@vger.kernel.org
>Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
>Reviewed-by: Sidraya Jayagond <sidraya@linux.ibm.com>
>Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>

Reviewed-by: Dust Li <dust.li@linux.alibaba.com>

Best regards,
Dust

>---
> net/smc/smc_core.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
>diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
>index c0027d2fe4e8..dd9fffbe41e0 100644
>--- a/net/smc/smc_core.c
>+++ b/net/smc/smc_core.c
>@@ -1254,6 +1254,7 @@ static void smc_buf_unuse(struct smc_connection *conn,
> /* remove a finished connection from its link group */
> void smc_conn_free(struct smc_connection *conn)
> {
>+	struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
> 	struct smc_link_group *lgr = conn->lgr;
> 
> 	if (!lgr || conn->freed)
>@@ -1277,8 +1278,13 @@ void smc_conn_free(struct smc_connection *conn)
> 		tasklet_kill(&conn->rx_tsklet);
> 	} else {
> 		smc_cdc_wait_pend_tx_wr(conn);
>-		if (current_work() != &conn->abort_work)
>-			cancel_work_sync(&conn->abort_work);
>+		/* If the work was pending (cancel returns true) it never ran,
>+		 * so the sock_hold taken by its scheduler was never released.
>+		 */
>+		if (current_work() != &conn->abort_work) {
>+			if (cancel_work_sync(&conn->abort_work))
>+				sock_put(&smc->sk);
>+		}
> 	}
> 	if (!list_empty(&lgr->list)) {
> 		smc_buf_unuse(conn, lgr); /* allow buffer reuse */
>
>base-commit: 2b1c2bc2355fd59cc75045e42d9dc5470ef5fa9a
>-- 
>2.52.0

  reply	other threads:[~2026-08-06  9:20 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-06  8:15 [PATCH net] net/smc: drop the abort_work reference when the work is cancelled Hidayath Khan
2026-08-06  9:20 ` Dust Li [this message]
2026-08-07  8:16 ` sashiko-bot
2026-08-10 23:19 ` Jakub Kicinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=anRR9doLcvlPAj4Q@linux.alibaba.com \
    --to=dust.li@linux.alibaba.com \
    --cc=alibuda@linux.alibaba.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=guwen@linux.alibaba.com \
    --cc=hidayath@linux.ibm.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=mjambigi@linux.ibm.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pasic@linux.ibm.com \
    --cc=sidraya@linux.ibm.com \
    --cc=tonylu@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.