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=-13.8 required=3.0 tests=BAYES_00, 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 9B72CC433E6 for ; Mon, 18 Jan 2021 14:24:27 +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 04CBE2231F for ; Mon, 18 Jan 2021 14:24:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 04CBE2231F Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kaod.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:58968 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l1VSE-0003Jb-19 for qemu-devel@archiver.kernel.org; Mon, 18 Jan 2021 09:24:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51856) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l1VR5-00026d-GV for qemu-devel@nongnu.org; Mon, 18 Jan 2021 09:23:17 -0500 Received: from us-smtp-delivery-44.mimecast.com ([207.211.30.44]:30430) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1l1VR3-00022p-9w for qemu-devel@nongnu.org; Mon, 18 Jan 2021 09:23:15 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-513-957IcdytNSmYhtzcJ_wsyA-1; Mon, 18 Jan 2021 09:23:07 -0500 X-MC-Unique: 957IcdytNSmYhtzcJ_wsyA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5BE3B801817; Mon, 18 Jan 2021 14:23:06 +0000 (UTC) Received: from bahia.redhat.com (ovpn-112-20.ams2.redhat.com [10.36.112.20]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8373660CC4; Mon, 18 Jan 2021 14:23:05 +0000 (UTC) From: Greg Kurz To: qemu-devel@nongnu.org Subject: [PATCH 3/3] 9pfs: Improve unreclaim loop Date: Mon, 18 Jan 2021 15:23:00 +0100 Message-Id: <20210118142300.801516-4-groug@kaod.org> In-Reply-To: <20210118142300.801516-1-groug@kaod.org> References: <20210118142300.801516-1-groug@kaod.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: kaod.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=WINDOWS-1252 Received-SPF: softfail client-ip=207.211.30.44; envelope-from=groug@kaod.org; helo=us-smtp-delivery-44.mimecast.com X-Spam_score_int: -11 X-Spam_score: -1.2 X-Spam_bar: - X-Spam_report: (-1.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=no 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: Christian Schoenebeck , Greg Kurz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" If a fid was actually re-open by v9fs_reopen_fid(), we re-traverse the 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 handle on the path that is being unlinked). This is a 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 fi= d) * reclaim won't close the file descriptor */ f->flags |=3D FID_REFERENCED; - QSIMPLEQ_INSERT_HEAD(&s->fid_list, f, next); + QSIMPLEQ_INSERT_TAIL(&s->fid_list, f, next); =20 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(V9fs= PDU *pdu, V9fsPath *path) { int err; V9fsState *s =3D pdu->s; - V9fsFidState *fidp; + V9fsFidState *fidp, *fidp_next; =20 -again: - QSIMPLEQ_FOREACH(fidp, &s->fid_list, next) { - if (fidp->path.size !=3D path->size) { - continue; - } - if (!memcmp(fidp->path.data, path->data, path->size)) { + fidp =3D QSIMPLEQ_FIRST(&s->fid_list); + assert(fidp); + + /* + * 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 wit= h + * the first one. + */ + for (fidp->ref++; fidp; fidp =3D fidp_next) { + if (fidp->path.size =3D=3D path->size && + !memcmp(fidp->path.data, path->data, path->size)) { /* Mark the fid non reclaimable. */ fidp->flags |=3D FID_NON_RECLAIMABLE; =20 /* reopen the file/dir if already closed */ err =3D v9fs_reopen_fid(pdu, fidp); if (err < 0) { + put_fid(pdu, fidp); return err; } + } + + fidp_next =3D 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 duri= ng + * put_fid() below and v9fs_reopen_fid() in the next iteration= . */ - if (err =3D=3D 0) { - goto again; - } + fidp_next->ref++; } + + /* We're done with this fid */ + put_fid(pdu, fidp); } + return 0; } =20 --=20 2.26.2