From: Marc Zyngier <maz@kernel.org>
To: Jing Zhang <jingzhangos@google.com>
Cc: KVM <kvm@vger.kernel.org>, KVMARM <kvmarm@lists.linux.dev>,
Oliver Upton <oliver.upton@linux.dev>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Fuad Tabba <fuad.tabba@linux.dev>,
Steffen Eiden <seiden@linux.ibm.com>
Subject: Re: [PATCH] KVM: arm64: vgic-its: Fix O(C*I) loop in vgic_its_free_collection_list
Date: Thu, 20 Aug 2026 14:11:04 +0100 [thread overview]
Message-ID: <87v795ndhz.wl-maz@kernel.org> (raw)
In-Reply-To: <20260818223422.367803-1-jingzhangos@google.com>
[+Fuad, Steffen]
Jing,
Please make sure you add all the relevant reviewers in the Cc: list,
specially as Fuad is doing a lot of work in that particular area.
On Tue, 18 Aug 2026 23:34:22 +0100,
Jing Zhang <jingzhangos@google.com> wrote:
>
> When destroying the vgic-its collection list,
> vgic_its_free_collection_list() iterates over every collection and for
> each, calls vgic_its_free_collection(). This function walks every
> Interrupt Translation Entry (ITE) across all devices via
> for_each_lpi_its() to nullify the collection pointer.
>
> A guest can allocate up to 65536 collections and hundreds of thousands
> of ITEs. By clearing GITS_CTLR.Enable and writing Valid=0 to
> GITS_BASER1, the guest can trigger this teardown path from a single MMIO
> exit. The resulting O(Collections * ITEs) nested loop executes billions
> of iterations without a single cond_resched(). This pins a physical CPU
> and stalls RCU grace periods for seconds or minutes on PREEMPT_NONE
> kernels.
>
> Fix this by replacing the O(Collections * ITEs) teardown with an
> O(Collections + ITEs) pass. Since the entire collection list is being
> freed, we can safely bulk-clear the collection pointers from all ITEs in
> a single pass, and then free all the collections in a second pass.
>
> Signed-off-by: Jing Zhang <jingzhangos@google.com>
> ---
> arch/arm64/kvm/vgic/vgic-its.c | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
> index 36ab3e4929154..a8e819fe97898 100644
> --- a/arch/arm64/kvm/vgic/vgic-its.c
> +++ b/arch/arm64/kvm/vgic/vgic-its.c
> @@ -1133,9 +1133,21 @@ static void vgic_its_free_device_list(struct kvm *kvm, struct vgic_its *its)
> static void vgic_its_free_collection_list(struct kvm *kvm, struct vgic_its *its)
> {
> struct its_collection *cur, *temp;
> + struct its_device *device;
> + struct its_ite *ite;
>
> - list_for_each_entry_safe(cur, temp, &its->collection_list, coll_list)
> - vgic_its_free_collection(its, cur->collection_id);
> + /*
> + * Bulk-clear the collection pointers for all ITEs.
> + * This transforms the teardown complexity from O(Collections * ITEs)
> + * to O(Collections + ITEs), avoiding guest-triggered host RCU stalls.
> + */
I don't think this comment needs to describe this. You already have
described it *extremely thoroughly* in the commit message, and that's
probably enough. I'd rather see a justification of why this is *safe*.
> + for_each_lpi_its(device, ite, its)
> + ite->collection = NULL;
> +
> + list_for_each_entry_safe(cur, temp, &its->collection_list, coll_list) {
> + list_del(&cur->coll_list);
> + kfree(cur);
> + }
The other thing that is missing is the invalidation of the translation
cache. Please see the discussion at [1], and whether this needs to be
taken care of here or in Fuad's series.
Thanks,
M.
[1] https://lore.kernel.org/r/20260819102809.310708-2-fuad.tabba@linux.dev
--
Jazz isn't dead. It just smells funny.
prev parent reply other threads:[~2026-08-20 13:08 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-18 22:34 [PATCH] KVM: arm64: vgic-its: Fix O(C*I) loop in vgic_its_free_collection_list Jing Zhang
2026-08-18 22:47 ` sashiko-bot
2026-08-20 13:11 ` Marc Zyngier [this message]
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=87v795ndhz.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=fuad.tabba@linux.dev \
--cc=jingzhangos@google.com \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=yuzenghui@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.