From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dominique Martinet Subject: Re: [PATCH] net/p9/trans_fd.c: fix double list_del() Date: Tue, 24 Jul 2018 12:19:32 +0200 Message-ID: <20180724101932.GA17454@nautica> References: <20180723121902.20201-1-tomasbortoli@gmail.com> <5B568374.9010507@huawei.com> <844e4101-6980-82dd-6f02-0a7193ed438c@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Cc: jiangyiwen , davem@davemloft.net, v9fs-developer@lists.sourceforge.net, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, syzkaller@googlegroups.com To: Tomas Bortoli Return-path: Content-Disposition: inline In-Reply-To: <844e4101-6980-82dd-6f02-0a7193ed438c@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-Id: netdev.vger.kernel.org Tomas Bortoli wrote on Tue, Jul 24, 2018: > >> @@ -228,6 +226,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err) > >> req->t_err = err; > >> p9_client_cb(m->client, req, REQ_STATUS_ERROR); > >> } > >> + spin_unlock(&m->client->lock); > > > > If you want to expand the ranges of client->lock, the cancel_list will not > > be necessary, you can optimize this code. > > > > Unfortunately, not. Moving the spin_lock() before the for makes the > crash appear again. This because the calls to list_move() in the for > before delete all the elements from req->req_list, so the list is empty, > another call to list_del() would trigger a double del. > That's why we hold the lock to update the status of all those requests.. > otherwise we have again the race with p9_fd_cancel(). What (I think) he meant is that since you're holding the lock all the way, you don't need to transfer all the items to a temporary list to loop on it immediately afterwards, but you could call the client cb directly. I'm personally not a fan of this approach as that would duplicate the code, even if the loop isn't big... This code is only called at disconnect time so I think using the extra list doesn't hurt anyone; but as usual do what you feel is better; I don't mind much either way. -- Dominique Martinet