All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Zyngier <maz@kernel.org>
To: Oliver Upton <oliver.upton@linux.dev>
Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
	James Morse <james.morse@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Zenghui Yu <yuzenghui@huawei.com>,
	Raghavendra Rao Ananta <rananta@google.com>,
	Jing Zhang <jingzhangos@google.com>
Subject: Re: [PATCH 11/15] KVM: arm64: vgic-its: Lazily allocate LPI translation cache
Date: Thu, 25 Jan 2024 10:19:46 +0000	[thread overview]
Message-ID: <8634ul90l9.wl-maz@kernel.org> (raw)
In-Reply-To: <20240124204909.105952-12-oliver.upton@linux.dev>

On Wed, 24 Jan 2024 20:49:05 +0000,
Oliver Upton <oliver.upton@linux.dev> wrote:
> 
> Reusing translation cache entries within a read-side critical section is
> fundamentally incompatible with an rculist. As such, we need to allocate
> a new entry to replace an eviction and free the removed entry
> afterwards.
> 
> Take this as an opportunity to remove the eager allocation of
> translation cache entries altogether in favor of a lazy allocation model
> on cache miss.
> 
> Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
> ---
>  arch/arm64/kvm/vgic/vgic-init.c |  3 --
>  arch/arm64/kvm/vgic/vgic-its.c  | 86 ++++++++++++++-------------------
>  include/kvm/arm_vgic.h          |  1 +
>  3 files changed, 38 insertions(+), 52 deletions(-)
> 
> diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
> index e25672d6e846..660d5ce3b610 100644
> --- a/arch/arm64/kvm/vgic/vgic-init.c
> +++ b/arch/arm64/kvm/vgic/vgic-init.c
> @@ -305,9 +305,6 @@ int vgic_init(struct kvm *kvm)
>  		}
>  	}
>  
> -	if (vgic_has_its(kvm))
> -		vgic_lpi_translation_cache_init(kvm);
> -
>  	/*
>  	 * If we have GICv4.1 enabled, unconditionnaly request enable the
>  	 * v4 support so that we get HW-accelerated vSGIs. Otherwise, only
> diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
> index 8c026a530018..aec82d9a1b3c 100644
> --- a/arch/arm64/kvm/vgic/vgic-its.c
> +++ b/arch/arm64/kvm/vgic/vgic-its.c
> @@ -608,12 +608,20 @@ static struct vgic_irq *vgic_its_check_cache(struct kvm *kvm, phys_addr_t db,
>  	return irq;
>  }
>  
> +/* Default is 16 cached LPIs per vcpu */
> +#define LPI_DEFAULT_PCPU_CACHE_SIZE	16
> +
> +static unsigned int vgic_its_max_cache_size(struct kvm *kvm)
> +{
> +	return atomic_read(&kvm->online_vcpus) * LPI_DEFAULT_PCPU_CACHE_SIZE;
> +}
> +
>  static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
>  				       u32 devid, u32 eventid,
>  				       struct vgic_irq *irq)
>  {
> +	struct vgic_translation_cache_entry *new, *victim;
>  	struct vgic_dist *dist = &kvm->arch.vgic;
> -	struct vgic_translation_cache_entry *cte;
>  	unsigned long flags;
>  	phys_addr_t db;
>  
> @@ -621,10 +629,11 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
>  	if (irq->hw)
>  		return;
>  
> -	raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
> +	new = victim = kzalloc(sizeof(*new), GFP_KERNEL_ACCOUNT);
> +	if (!new)
> +		return;
>  
> -	if (unlikely(list_empty(&dist->lpi_translation_cache)))
> -		goto out;
> +	raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
>  
>  	/*
>  	 * We could have raced with another CPU caching the same
> @@ -635,17 +644,15 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
>  	if (__vgic_its_check_cache(dist, db, devid, eventid))
>  		goto out;
>  
> -	/* Always reuse the last entry (LRU policy) */
> -	cte = list_last_entry(&dist->lpi_translation_cache,
> -			      typeof(*cte), entry);
> -
> -	/*
> -	 * Caching the translation implies having an extra reference
> -	 * to the interrupt, so drop the potential reference on what
> -	 * was in the cache, and increment it on the new interrupt.
> -	 */
> -	if (cte->irq)
> -		vgic_put_irq(kvm, cte->irq);
> +	if (dist->lpi_cache_count >= vgic_its_max_cache_size(kvm)) {
> +		/* Always reuse the last entry (LRU policy) */
> +		victim = list_last_entry(&dist->lpi_translation_cache,
> +				      typeof(*cte), entry);
> +		list_del(&victim->entry);
> +		dist->lpi_cache_count--;
> +	} else {
> +		victim = NULL;
> +	}
>
>  	/*
>  	 * The irq refcount is guaranteed to be nonzero while holding the
> @@ -654,16 +661,26 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
>  	lockdep_assert_held(&its->its_lock);
>  	vgic_get_irq_kref(irq);
>  
> -	cte->db		= db;
> -	cte->devid	= devid;
> -	cte->eventid	= eventid;
> -	cte->irq	= irq;
> +	new->db		= db;
> +	new->devid	= devid;
> +	new->eventid	= eventid;
> +	new->irq	= irq;
>  
>  	/* Move the new translation to the head of the list */
> -	list_move(&cte->entry, &dist->lpi_translation_cache);
> +	list_add(&new->entry, &dist->lpi_translation_cache);
>  
>  out:
>  	raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
> +
> +	/*
> +	 * Caching the translation implies having an extra reference
> +	 * to the interrupt, so drop the potential reference on what
> +	 * was in the cache, and increment it on the new interrupt.
> +	 */
> +	if (victim && victim->irq)
> +		vgic_put_irq(kvm, victim->irq);

The games you play with 'victim' are a bit odd. I'd rather have it
initialised to NULL, and be trusted to have a valid irq if non-NULL.

Is there something special I'm missing?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

  reply	other threads:[~2024-01-25 10:19 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-24 20:48 [PATCH 00/15] KVM: arm64: Improvements to GICv3 LPI injection Oliver Upton
2024-01-24 20:48 ` [PATCH 01/15] KVM: arm64: vgic: Store LPIs in an xarray Oliver Upton
2024-02-05  6:05   ` Dan Carpenter
2024-01-24 20:48 ` [PATCH 02/15] KVM: arm64: vgic: Use xarray to find LPI in vgic_get_lpi() Oliver Upton
2024-01-24 20:48 ` [PATCH 03/15] KVM: arm64: vgic-v3: Iterate the xarray to find pending LPIs Oliver Upton
2024-01-24 20:48 ` [PATCH 04/15] KVM: arm64: vgic-its: Walk the LPI xarray in vgic_copy_lpi_list() Oliver Upton
2024-01-25  9:15   ` Marc Zyngier
2024-01-25  9:24     ` Oliver Upton
2024-01-24 20:48 ` [PATCH 05/15] KVM: arm64: vgic: Get rid of the LPI linked-list Oliver Upton
2024-01-25  9:28   ` Marc Zyngier
2024-01-24 20:49 ` [PATCH 06/15] KVM: arm64: vgic: Use atomics to count LPIs Oliver Upton
2024-01-24 20:49 ` [PATCH 07/15] KVM: arm64: vgic: Free LPI vgic_irq structs in an RCU-safe manner Oliver Upton
2024-01-24 20:49 ` [PATCH 08/15] KVM: arm64: vgic: Rely on RCU protection in vgic_get_lpi() Oliver Upton
2024-01-24 20:49 ` [PATCH 09/15] KVM: arm64: vgic: Ensure the irq refcount is nonzero when taking a ref Oliver Upton
2024-01-25 10:08   ` Marc Zyngier
2024-01-24 20:49 ` [PATCH 10/15] KVM: arm64: vgic: Don't acquire the lpi_list_lock in vgic_put_irq() Oliver Upton
2024-01-24 20:49 ` [PATCH 11/15] KVM: arm64: vgic-its: Lazily allocate LPI translation cache Oliver Upton
2024-01-25 10:19   ` Marc Zyngier [this message]
2024-01-25 15:13     ` Oliver Upton
2024-01-24 20:49 ` [PATCH 12/15] KVM: arm64: vgic-its: Pick cache victim based on usage count Oliver Upton
2024-01-25  9:22   ` Oliver Upton
2024-01-25 10:55   ` Marc Zyngier
2024-01-25 15:34     ` Oliver Upton
2024-01-25 18:07       ` Marc Zyngier
2024-01-24 20:49 ` [PATCH 13/15] KVM: arm64: vgic-its: Protect cached vgic_irq pointers with RCU Oliver Upton
2024-01-29  1:03   ` kernel test robot
2024-01-24 20:49 ` [PATCH 14/15] KVM: arm64: vgic-its: Treat the LPI translation cache as an rculist Oliver Upton
2024-01-24 20:49 ` [PATCH 15/15] KVM: arm64: vgic-its: Rely on RCU to protect translation cache reads Oliver Upton
2024-01-25 11:02 ` [PATCH 00/15] KVM: arm64: Improvements to GICv3 LPI injection Marc Zyngier
2024-01-25 15:47   ` Oliver Upton

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=8634ul90l9.wl-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=james.morse@arm.com \
    --cc=jingzhangos@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=oliver.upton@linux.dev \
    --cc=rananta@google.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.