From: Dominique Martinet <asmadeus@codewreck.org>
To: Nalivayko Sergey <Sergey.Nalivayko@kaspersky.com>
Cc: v9fs-developer@lists.sourceforge.net, netdev@vger.kernel.org,
Eric Van Hensbergen <ericvh@gmail.com>,
Wang Hai <wanghai38@huawei.com>,
Latchesar Ionkov <lucho@ionkov.net>,
lvc-project@linuxtesting.org, stable@vger.kernel.org
Subject: Re: [PATCH] net: 9p: fix double req put in p9_fd_cancelled
Date: Fri, 15 Aug 2025 11:01:00 +0900 [thread overview]
Message-ID: <aJ6U3DQn876wGS4C@codewreck.org> (raw)
In-Reply-To: <20250715154815.3501030-1-Sergey.Nalivayko@kaspersky.com>
Nalivayko Sergey wrote on Tue, Jul 15, 2025 at 06:48:15PM +0300:
> This happens because of a race condition between:
>
> - The 9p client sending an invalid flush request and later cleaning it up;
> - The 9p client in p9_read_work() canceled all pending requests.
>
> Thread 1 Thread 2
> ...
> p9_client_create()
> ...
> p9_fd_create()
> ...
> p9_conn_create()
> ...
> // start Thread 2
> INIT_WORK(&m->rq, p9_read_work);
> p9_read_work()
> ...
> p9_client_rpc()
> ...
> ...
> p9_conn_cancel()
> ...
> spin_lock(&m->req_lock);
> ...
> p9_fd_cancelled()
> ...
> ...
> spin_unlock(&m->req_lock);
> // status rewrite
> p9_client_cb(m->client, req, REQ_STATUS_ERROR)
> // first remove
> list_del(&req->req_list);
> ...
>
> spin_lock(&m->req_lock)
> ...
> // second remove
> list_del(&req->req_list);
> spin_unlock(&m->req_lock)
> ...
>
> Commit 74d6a5d56629 ("9p/trans_fd: Fix concurrency del of req_list in
> p9_fd_cancelled/p9_read_work") fixes a concurrency issue in the 9p filesystem
> client where the req_list could be deleted simultaneously by both
> p9_read_work and p9_fd_cancelled functions, but for the case where req->status
> equals REQ_STATUS_RCVD.
Sorry for the delay,
Thanks for the investigation, this makes sense and deserves fixing.
> Add an explicit check for REQ_STATUS_ERROR in p9_fd_cancelled before
> processing the request. Skip processing if the request is already in the error
> state, as it has been removed and its resources cleaned up.
Looking at the other status, it's quite unlikely but if other thread
would make it FLSHD we should also skip these -- and I don't think it's
possible as far as the logic goes but if it's not sent yet we would have
nothing to flush either, so it's probably better to invert the check,
and make it `if (req != SENT) return` ?
client.c already checks `READ_ONCE(oldreq->status) == REQ_STATUS_SENT`
before calling cancelled but that's without lock, so basically we're
checking nothing raced since that check, and it's not limited to RCVD
and ERROR.
If you can send a v2 with that I'll pick it up.
Thanks,
--
Dominique Martinet | Asmadeus
next prev parent reply other threads:[~2025-08-15 2:01 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-15 15:48 [PATCH] net: 9p: fix double req put in p9_fd_cancelled Nalivayko Sergey
2025-08-15 2:01 ` Dominique Martinet [this message]
2025-08-15 4:50 ` Dominique Martinet
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=aJ6U3DQn876wGS4C@codewreck.org \
--to=asmadeus@codewreck.org \
--cc=Sergey.Nalivayko@kaspersky.com \
--cc=ericvh@gmail.com \
--cc=lucho@ionkov.net \
--cc=lvc-project@linuxtesting.org \
--cc=netdev@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=v9fs-developer@lists.sourceforge.net \
--cc=wanghai38@huawei.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.