Re: [PATCH] net/9p: use a dedicated spinlock for trans_fd

From: Christian Schoenebeck
Date: Fri Oct 07 2022 - 05:29:27 EST


On Freitag, 7. Oktober 2022 03:05:39 CEST Dominique Martinet wrote:
> Christian Schoenebeck wrote on Thu, Oct 06, 2022 at 03:16:40PM +0200:
> > > net/9p/trans_fd.c | 42 ++++++++++++++++++++++++++----------------
> > > 1 file changed, 26 insertions(+), 16 deletions(-)
> >
> > Late on the party, sorry. Note that you already queued a slightly
> > different
> > version than this patch here, anyway, one thing ...
>
> Did I? Oh, I apparently reworded the commit message a bit, sorry:
>
> (where HEAD is this patch and 1622... the queued patch)
>
> $ git range-diff HEAD^- 16228c9a4215^-
> 1: e35fb8546af2 ! 1: 16228c9a4215 net/9p: use a dedicated spinlock for
> trans_fd @@ Commit message
>
> Since the locks actually protect different things in client.c and
> in trans_fd.c, just replace trans_fd.c's lock by a new one specific to the
> - transport instead of using spin_lock_irq* variants everywhere -
> (client.c's protect the idr for tag allocations, while
> - trans_fd.c's protects its own req list and request status field
> + transport (client.c's protect the idr for fid/tag allocations,
> + while trans_fd.c's protects its own req list and request status
> field that acts as the transport's state machine)
>
> - Link:
> https://lkml.kernel.org/r/20220904112928.1308799-1-asmadeus@xxxxxxxxxxxxx +
> Link:
> https://lore.kernel.org/r/20220904112928.1308799-1-asmadeus@xxxxxxxxxxxxx
> Link:
> https://lkml.kernel.org/r/2470e028-9b05-2013-7198-1fdad071d999@I-love.SAKUR
> A.ne.jp [1] Link:
> https://syzkaller.appspot.com/bug?extid=2f20b523930c32c160cc [2]
> Reported-by: syzbot <syzbot+2f20b523930c32c160cc@xxxxxxxxxxxxxxxxxxxxxxxxx>

No, that's not what I meant, but my bad, it was the following chunk that
didn't apply here:

diff a/net/9p/trans_fd.c b/net/9p/trans_fd.c (rejected hunks)
@@ -205,7 +207,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
list_move(&req->req_list, &cancel_list);
}

- spin_unlock(&m->client->lock);
+ spin_unlock(&m->req_lock);

list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req);

And that was because this patch was based on:
https://github.com/martinetd/linux/commit/52f1c45dde9136f964d

I usually tag patches depending on another patch not being merged yet (and not
being tied to the same series) like:

Based-on: <message-id>

> > > @@ -832,6 +840,7 @@ static int p9_fd_open(struct p9_client *client, int
> > > rfd, int wfd)
> > >
> > > client->trans = ts;
> > > client->status = Connected;
> > >
> > > + spin_lock_init(&ts->conn.req_lock);
> >
> > Are you sure this is the right place for spin_lock_init()? Not rather in
> > p9_conn_create()?
>
> Good point, 'ts->conn' (named... m over there for some reason...) is
> mostly initialized in p9_conn_create; it makes much more sense to move
> it there despite being slightly further away from the allocation.
>
> It's a bit of a pain to check as the code is spread over many paths (fd,
> unix, tcp) but it looks equivalent to me:
> - p9_fd_open is only called from p9_fd_create which immediately calls
> p9_conn_create
> - below p9_socket_open itself immediately calls p9_conn_create

Yeah, looks pretty much the same, but better to have init code at the same
place. Either or.

> I've moved the init and updated my next branch after very basic check
> https://github.com/martinetd/linux/commit/e5cfd99e9ea6c13b3f0134585f269c5092
> 47ac0e: ----
> diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
> index 5b4807411281..d407f31bb49d 100644
> --- a/net/9p/trans_fd.c
> +++ b/net/9p/trans_fd.c
> @@ -591,6 +591,7 @@ static void p9_conn_create(struct p9_client *client)
> INIT_LIST_HEAD(&m->mux_list);
> m->client = client;
>
> + spin_lock_init(&m->req_lock);
> INIT_LIST_HEAD(&m->req_list);
> INIT_LIST_HEAD(&m->unsent_req_list);
> INIT_WORK(&m->rq, p9_read_work);
> @@ -840,7 +841,6 @@ static int p9_fd_open(struct p9_client *client, int rfd,
> int wfd)
>
> client->trans = ts;
> client->status = Connected;
> - spin_lock_init(&ts->conn.req_lock);
>
> return 0;
>
> @@ -875,7 +875,6 @@ static int p9_socket_open(struct p9_client *client,
> struct socket *csocket) p->wr = p->rd = file;
> client->trans = p;
> client->status = Connected;
> - spin_lock_init(&p->conn.req_lock);
>
> p->rd->f_flags |= O_NONBLOCK;
>
> ----
>
> > The rest LGTM.
>
> Thank you for the look :)

With that changed, you can add my RB-tag. :)

Thanks!

Best regards,
Christian Schoenebeck