From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6EC33C433E0 for ; Thu, 21 Jan 2021 12:57:32 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0070C239FD for ; Thu, 21 Jan 2021 12:57:31 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0070C239FD Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=crudebyte.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57772 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l2ZWk-0004BK-Oz for qemu-devel@archiver.kernel.org; Thu, 21 Jan 2021 07:57:30 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:42734) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l2ZQq-0006b7-Sb for qemu-devel@nongnu.org; Thu, 21 Jan 2021 07:51:24 -0500 Received: from kylie.crudebyte.com ([5.189.157.229]:53771) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l2ZQn-0003cC-Mv for qemu-devel@nongnu.org; Thu, 21 Jan 2021 07:51:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=crudebyte.com; s=kylie; h=Content-Type:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Content-ID:Content-Description; bh=90+yEAGGjmCEQ5RxfVPk4yE0dcsoCz8m/18bjJ0Tmio=; b=gvT3vr9TxZgFdCLyYi67Zzkpgh tY+g84q4A1LGLbGYvEO8LqCbJaN5nNDcPLdtETok5DdVebmtlUzP0iMpbDiRgLOgnQR6uDXdy4Yct 2VftLHZc6gezTuRXd/+CxuGQPNyvEYHDh7o8uNi6jx2mfK2tcqfAgfIHe9QSZISZUwRtptlG+UsNV ArDa4nhLWEwXTi4pDcZdY4FevmIoXkyI6x02BktMMQEr19P4Redg6YlMNdp5Ov9NZc4nYYAR0MPRq XITeLUzOZdWXDGyIFUC9ncsxz+y8bGKeP3bIcEdjIqy2Pv29smSAaeWCK3Kj93ef/wW3R8tZqODE3 34JFRVXrEiRiHZEuV953qf8JxZ+9sryicnMA1GDFvFhLlI4yfF1kdnNOPqn5hM0ZFCKJ+19Evl2fz esl01nJHnNLOKXY8lx7H2kRI/l+AVeoBLOhcupq5Q1OjSR/Gtd6STqhDhkMnZlcVKKXysKcFWmu7Y jngIVY6BD+lqlzySUvwgzbCjXWWeoiZXabbQDb40ZTwX6MVmw59/ZGoqZ6PD7DJDo3tVuCObpUwVe Hepn9lLzQ8vGH7Y26GlD2EJUb23HjskmphpHsfhYf59GwK4eaBscA/J6TfAFEcgJgheJZvR7gU9KC DBtafM4tFpUoSVgoKthCInEkr6Xdfw3Pvf8IovLWc=; From: Christian Schoenebeck To: qemu-devel@nongnu.org Subject: Re: [PATCH 3/3] 9pfs: Improve unreclaim loop Date: Thu, 21 Jan 2021 13:50:37 +0100 Message-ID: <1978739.Uc7ZUDHExb@silver> In-Reply-To: <20210118142300.801516-4-groug@kaod.org> References: <20210118142300.801516-1-groug@kaod.org> <20210118142300.801516-4-groug@kaod.org> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Received-SPF: pass client-ip=5.189.157.229; envelope-from=qemu_oss@crudebyte.com; helo=kylie.crudebyte.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" On Montag, 18. Januar 2021 15:23:00 CET Greg Kurz wrote: > If a fid was actually re-open by v9fs_reopen_fid(), we re-traverse the "re-opened" > fid list from the head in case some other request created a fid that > needs to be marked unreclaimable as well (ie. the client open a new "i.e." and either "opens" or "opened" > handle on the path that is being unlinked). This is a suboptimal since No "a" here: "This is suboptimal since" > most if not all fids that require it have likely been taken care of > already. > > This is mostly the result of new fids being added to the head of the > list. Since the list is now a QSIMPLEQ, add new fids at the end instead. > Take a reference on the fid to ensure it doesn't go away during > v9fs_reopen_fid() and that it can be safely passed to QSIMPLEQ_NEXT() > afterwards. Since the associated put_fid() can also yield, same is done > with the next fid. So the logic here is to get a reference on a fid and > only put it back during the next iteration after we could get a reference > on the next fid. > > Signed-off-by: Greg Kurz > --- > hw/9pfs/9p.c | 44 ++++++++++++++++++++++++++++++-------------- > 1 file changed, 30 insertions(+), 14 deletions(-) > > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c > index b65f320e6518..b0ab5cf61c1f 100644 > --- a/hw/9pfs/9p.c > +++ b/hw/9pfs/9p.c > @@ -311,7 +311,7 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t > fid) * reclaim won't close the file descriptor > */ > f->flags |= FID_REFERENCED; > - QSIMPLEQ_INSERT_HEAD(&s->fid_list, f, next); > + QSIMPLEQ_INSERT_TAIL(&s->fid_list, f, next); I wondered whether that behaviour change could have negative side effects, but I think the reason why they added it to the head of the list was simply because they only had a head pointer (i.e. they would have needed a loop to insert to tail). So yes, I think that change makes sense now with QSIMPLEQ. > > v9fs_readdir_init(s->proto_version, &f->fs.dir); > v9fs_readdir_init(s->proto_version, &f->fs_reclaim.dir); > @@ -497,32 +497,48 @@ static int coroutine_fn > v9fs_mark_fids_unreclaim(V9fsPDU *pdu, V9fsPath *path) { > int err; > V9fsState *s = pdu->s; > - V9fsFidState *fidp; > + V9fsFidState *fidp, *fidp_next; > > -again: > - QSIMPLEQ_FOREACH(fidp, &s->fid_list, next) { > - if (fidp->path.size != path->size) { > - continue; > - } > - if (!memcmp(fidp->path.data, path->data, path->size)) { > + fidp = QSIMPLEQ_FIRST(&s->fid_list); > + assert(fidp); And fidp is under regular circumstances always non-null here? The assumption is that there is at least the root fid in the list, which the user should not have permission to unlink, right? > + > + /* > + * v9fs_reopen_fid() can yield : a reference on the fid must be held > + * to ensure its pointer remains valid and we can safely pass it to > + * QSIMPLEQ_NEXT(). The corresponding put_fid() can also yield so > + * we must keep a reference on the next fid as well. So the logic here > + * is to get a reference on a fid and only put it back during the next > + * iteration after we could get a reference on the next fid. Start with > + * the first one. > + */ > + for (fidp->ref++; fidp; fidp = fidp_next) { > + if (fidp->path.size == path->size && > + !memcmp(fidp->path.data, path->data, path->size)) { > /* Mark the fid non reclaimable. */ > fidp->flags |= FID_NON_RECLAIMABLE; > > /* reopen the file/dir if already closed */ > err = v9fs_reopen_fid(pdu, fidp); > if (err < 0) { > + put_fid(pdu, fidp); > return err; > } > + } > + > + fidp_next = QSIMPLEQ_NEXT(fidp, next); > + > + if (fidp_next) { > /* > - * Go back to head of fid list because > - * the list could have got updated when > - * switched to the worker thread > + * Ensure the next fid survives a potential clunk request > during + * put_fid() below and v9fs_reopen_fid() in the next > iteration. */ > - if (err == 0) { > - goto again; > - } > + fidp_next->ref++; Mmm, that works as intended if fidp_next matches the requested path. However if it is not (like it would in the majority of cases) then the loop breaks next and the bumped reference count would never be reverted. Or am I missing something here? > } > + > + /* We're done with this fid */ > + put_fid(pdu, fidp); > } > + > return 0; > } Best regards, Christian Schoenebeck