Message ID | 20240213093250.3960069-8-oliver.upton@linux.dev |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-63212-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:bc8a:b0:106:860b:bbdd with SMTP id dn10csp427107dyb; Tue, 13 Feb 2024 01:43:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IHuFIaSOP26iRAF+z5INgGMKA94WHYmSYCwbsvLE8AqNm0Dcqtw41AZuy2ycQd7YJ+Re6US X-Received: by 2002:a17:90b:4ece:b0:298:a3e4:d6b3 with SMTP id ta14-20020a17090b4ece00b00298a3e4d6b3mr1170798pjb.5.1707817428974; Tue, 13 Feb 2024 01:43:48 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707817428; cv=pass; d=google.com; s=arc-20160816; b=gTQW7P0ILD9TSypQwzyzSKTbphrDRVJ1Ms9E6f/eHXgMlRhfQFmEG0NumeSWcrGdra rvQDI90Z6kQmTsDkvVLz6tLQg1S4+JSMMGrlJjSGKdIouPp8EaJMu04MaQL1vHzMw4Ch sLtYQB0M002BifAL1NKaEwDAD4MMW9cUfMPwfb+JrqtgKb6TJfRNOGY+uBGIalotUuTp SUnopn5YbASdjlgnw5VvV4nQH2KcFDMAFs333r3ItsDeA4wcYYRyC3WcCniyp+I8Neqp hH/5wL7SgTjePk/h+lKifbRSQyd2KMbgHD14h6VO+dRI4bOI/84LU5kMScdEGtQMlyc4 dQ4A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=nQ22xtb57Hhh6ukA9UKpHbyaiDwLVQOEd0N6U2bxudQ=; fh=8KOlWUfB6ku5hkQYwHxYJ/+bS4dRLEh4Bb52VJQgfCE=; b=fv25fQKyWXDmr16aSnz8XNLIihNTcA+RW9SyMJuIKrKuH+WeFdfaBSU+dMG82gAxtg mp9+AaOKW2vrrAkY8AKkQkmlWXiNQWXS8rQLUt7eejiCWcn3YhmiPjSrUFeJwjX1NzFN XY2tb8I4Y/N8nhi2gQrPJrIjAqe8aIZjlDLpJ6qA5B97wAJpkIqToSKPILaw4KkK+UDi xFMITjWbfUFpfqUPnWYaq5+8m0CgLi51mPcILvVLwgDnIESBYZ4Ex9diVPDepBSIKm81 p+EFWmcTf1wXnuRhtQ17N9mJTigMQ8ExYI1LIL1oWjmMKtNEFjcxaxIvK/e20YRwHwlR LGvQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=lQLrteem; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-kernel+bounces-63212-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-63212-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev X-Forwarded-Encrypted: i=2; AJvYcCWLJN4ZuM4sAc91gOpy9XKt7zj3UqcrtmY63Dg/eU2AiEbfn0gv3isWI1N7ZS7C5wc37sgD/1ysEFBhEBJj35fQxWXrIA== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id q1-20020a656a81000000b005dc833ef4e6si1034548pgu.75.2024.02.13.01.43.48 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Feb 2024 01:43:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-63212-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=lQLrteem; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-kernel+bounces-63212-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-63212-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 2E90AB25F6A for <ouuuleilei@gmail.com>; Tue, 13 Feb 2024 09:36:22 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2B8223D3A4; Tue, 13 Feb 2024 09:33:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="lQLrteem" Received: from out-185.mta1.migadu.com (out-185.mta1.migadu.com [95.215.58.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF7E036AE4 for <linux-kernel@vger.kernel.org>; Tue, 13 Feb 2024 09:33:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707816808; cv=none; b=X3xDu4K4T1D6l3CJlFycWvw+v7oegHBvQFI6B7mWNdMXjqxZbZQaFJuKyD7MorNLxW+PeinKMXxGW0X350v+xEwn5cMst+KV/izvywtvPbLd7Dz/itbLQ+HXxr4y2mXLRo/7f42BfBeAbiVg9duochqDuJOSLBmyHFk284ZeKS8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707816808; c=relaxed/simple; bh=K1BXK5oYZl6+dA5mTViFGwIhpj458PXsoVl/Nu1w2ig=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qof9YXqfGUgtU+f1na1YDq15ChU0T9Q/aUcMvGzGs8gd83+a5QFVeUflS1MEgvY1pxCyKUHTc5TwaC1YmpPhJSRcbEPjIGBlfUGjyocJwZb7aPoS9w1lCEBa0emIHdxe3LUfX32HmUIiDjp7rXVOEkzphdC2WFn344f8VjQJQtQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=lQLrteem; arc=none smtp.client-ip=95.215.58.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1707816805; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nQ22xtb57Hhh6ukA9UKpHbyaiDwLVQOEd0N6U2bxudQ=; b=lQLrteem+/oNETa88tCfy93s3hWpOQjhHY9udjC6jjluC/ugre068aS/g+cCHk38wmFIsT llzxysWLqD6W5XXtdWNc3eO5DfxFGCce105uksr2XMisqueJ+4opUXNBfUW4IqJp1zCYUn AluLUWq2PU2m0JaY0lo+9urNUaCPJVg= From: Oliver Upton <oliver.upton@linux.dev> To: kvmarm@lists.linux.dev Cc: kvm@vger.kernel.org, Marc Zyngier <maz@kernel.org>, James Morse <james.morse@arm.com>, Suzuki K Poulose <suzuki.poulose@arm.com>, Zenghui Yu <yuzenghui@huawei.com>, linux-kernel@vger.kernel.org, Oliver Upton <oliver.upton@linux.dev> Subject: [PATCH v2 07/23] KVM: arm64: vgic: Use atomics to count LPIs Date: Tue, 13 Feb 2024 09:32:44 +0000 Message-ID: <20240213093250.3960069-8-oliver.upton@linux.dev> In-Reply-To: <20240213093250.3960069-1-oliver.upton@linux.dev> References: <20240213093250.3960069-1-oliver.upton@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790776368403555513 X-GMAIL-MSGID: 1790776368403555513 |
Series |
KVM: arm64: Improvements to LPI injection
|
|
Commit Message
Oliver Upton
Feb. 13, 2024, 9:32 a.m. UTC
Switch to using atomics for LPI accounting, allowing vgic_irq references
to be dropped in parallel.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/vgic/vgic-debug.c | 2 +-
arch/arm64/kvm/vgic/vgic-its.c | 4 ++--
arch/arm64/kvm/vgic/vgic.c | 2 +-
include/kvm/arm_vgic.h | 4 ++--
4 files changed, 6 insertions(+), 6 deletions(-)
Comments
On Tue, 13 Feb 2024 09:32:44 +0000, Oliver Upton <oliver.upton@linux.dev> wrote: > > Switch to using atomics for LPI accounting, allowing vgic_irq references > to be dropped in parallel. > > Signed-off-by: Oliver Upton <oliver.upton@linux.dev> > --- > arch/arm64/kvm/vgic/vgic-debug.c | 2 +- > arch/arm64/kvm/vgic/vgic-its.c | 4 ++-- > arch/arm64/kvm/vgic/vgic.c | 2 +- > include/kvm/arm_vgic.h | 4 ++-- > 4 files changed, 6 insertions(+), 6 deletions(-) > > diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c > index 85606a531dc3..389025ce7749 100644 > --- a/arch/arm64/kvm/vgic/vgic-debug.c > +++ b/arch/arm64/kvm/vgic/vgic-debug.c > @@ -149,7 +149,7 @@ static void print_dist_state(struct seq_file *s, struct vgic_dist *dist) > seq_printf(s, "vgic_model:\t%s\n", v3 ? "GICv3" : "GICv2"); > seq_printf(s, "nr_spis:\t%d\n", dist->nr_spis); > if (v3) > - seq_printf(s, "nr_lpis:\t%d\n", dist->lpi_list_count); > + seq_printf(s, "nr_lpis:\t%d\n", atomic_read(&dist->lpi_count)); > seq_printf(s, "enabled:\t%d\n", dist->enabled); > seq_printf(s, "\n"); > > diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c > index c68164d6cba0..048226812974 100644 > --- a/arch/arm64/kvm/vgic/vgic-its.c > +++ b/arch/arm64/kvm/vgic/vgic-its.c > @@ -97,7 +97,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, > goto out_unlock; > } > > - dist->lpi_list_count++; > + atomic_inc(&dist->lpi_count); > > out_unlock: > if (ret) > @@ -345,7 +345,7 @@ int vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr) > * command). If coming from another path (such as enabling LPIs), > * we must be careful not to overrun the array. > */ > - irq_count = READ_ONCE(dist->lpi_list_count); > + irq_count = atomic_read(&dist->lpi_count); I'd like to propose an alternative approach here. I've always hated this "copy a bunch of INTIDs" thing, and the only purpose of this silly counter is to dimension the resulting array. Could we instead rely on an xarray marking a bunch of entries (the ones we want to 'copy'), and get the reader to clear these marks once done? Of course, we only have 3 marks, so that's a bit restrictive from a concurrency perspective, but since most callers hold a lock, it should be OK. What do you think? M.
Hey, On Wed, Feb 14, 2024 at 04:47:49PM +0000, Marc Zyngier wrote: > I'd like to propose an alternative approach here. I've always hated > this "copy a bunch of INTIDs" thing, Agree. > and the only purpose of this > silly counter is to dimension the resulting array. Well, we also use it to trivially print the number of LPIs for a particular vgic in the debug interface. > Could we instead rely on an xarray marking a bunch of entries (the > ones we want to 'copy'), and get the reader to clear these marks once > done? I think that'd work. I'm trying to convince myself we don't have bugs lurking in some of the existing usage of vgic_copy_lpi_list()... > Of course, we only have 3 marks, so that's a bit restrictive from a > concurrency perspective, but since most callers hold a lock, it should > be OK. They all hold *a* lock, but maybe not the same one! :) Maybe we should serialize the use of markers on the LPI list on the config_lock. A slight misuse, but we need a mutex since we're poking at guest memory. Then we can go through the whole N-dimensional locking puzzle and convince ourselves it is still correct.
On Wed, 14 Feb 2024 18:32:02 +0000, Oliver Upton <oliver.upton@linux.dev> wrote: > > Hey, > > On Wed, Feb 14, 2024 at 04:47:49PM +0000, Marc Zyngier wrote: > > I'd like to propose an alternative approach here. I've always hated > > this "copy a bunch of INTIDs" thing, > > Agree. > > > and the only purpose of this > > silly counter is to dimension the resulting array. > > Well, we also use it to trivially print the number of LPIs for a > particular vgic in the debug interface. I think we can get survive this... ;-) > > > Could we instead rely on an xarray marking a bunch of entries (the > > ones we want to 'copy'), and get the reader to clear these marks once > > done? > > I think that'd work. I'm trying to convince myself we don't have bugs > lurking in some of the existing usage of vgic_copy_lpi_list()... > > > Of course, we only have 3 marks, so that's a bit restrictive from a > > concurrency perspective, but since most callers hold a lock, it should > > be OK. > > They all hold *a* lock, but maybe not the same one! :) Indeed. But as long as there isn't more than 3 locks (and that the xarray is OK being concurrently updated with marks), we're good! > Maybe we should serialize the use of markers on the LPI list on the > config_lock. A slight misuse, but we need a mutex since we're poking at > guest memory. Then we can go through the whole N-dimensional locking > puzzle and convince ourselves it is still correct. Maybe. This thing is already seeing so many abuses that one more may not matter much. Need to see how it fits in the whole hierarchy of GIC-related locks... Thanks, M.
On Wed, Feb 14, 2024 at 08:01:19PM +0000, Marc Zyngier wrote: > > > Of course, we only have 3 marks, so that's a bit restrictive from a > > > concurrency perspective, but since most callers hold a lock, it should > > > be OK. > > > > They all hold *a* lock, but maybe not the same one! :) > > Indeed. But as long as there isn't more than 3 locks (and that the > xarray is OK being concurrently updated with marks), we're good! Oh, you mean to give each existing caller their own mark? > > Maybe we should serialize the use of markers on the LPI list on the > > config_lock. A slight misuse, but we need a mutex since we're poking at > > guest memory. Then we can go through the whole N-dimensional locking > > puzzle and convince ourselves it is still correct. > > Maybe. This thing is already seeing so many abuses that one more may > not matter much. Need to see how it fits in the whole hierarchy of > GIC-related locks... It doesn't work. We have it that the config_lock needs to be taken outside the its_lock. Too many damn locks!
On Wed, 14 Feb 2024 23:01:04 +0000, Oliver Upton <oliver.upton@linux.dev> wrote: > > On Wed, Feb 14, 2024 at 08:01:19PM +0000, Marc Zyngier wrote: > > > > Of course, we only have 3 marks, so that's a bit restrictive from a > > > > concurrency perspective, but since most callers hold a lock, it should > > > > be OK. > > > > > > They all hold *a* lock, but maybe not the same one! :) > > > > Indeed. But as long as there isn't more than 3 locks (and that the > > xarray is OK being concurrently updated with marks), we're good! > > Oh, you mean to give each existing caller their own mark? Well, each caller "class". Where "class" means "holding look 'foo'". Same lock, same mark. With a maximum of 3 (and I think we can get away with 2). > > > Maybe we should serialize the use of markers on the LPI list on the > > > config_lock. A slight misuse, but we need a mutex since we're poking at > > > guest memory. Then we can go through the whole N-dimensional locking > > > puzzle and convince ourselves it is still correct. > > > > Maybe. This thing is already seeing so many abuses that one more may > > not matter much. Need to see how it fits in the whole hierarchy of > > GIC-related locks... > > It doesn't work. We have it that the config_lock needs to be taken > outside the its_lock. > > Too many damn locks! Well, the joys of emulating highly complex HW with a braindead programming interface. I'd explore the above suggestion to avoid introducing a new lock, if at all possible. Thanks, M.
diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c index 85606a531dc3..389025ce7749 100644 --- a/arch/arm64/kvm/vgic/vgic-debug.c +++ b/arch/arm64/kvm/vgic/vgic-debug.c @@ -149,7 +149,7 @@ static void print_dist_state(struct seq_file *s, struct vgic_dist *dist) seq_printf(s, "vgic_model:\t%s\n", v3 ? "GICv3" : "GICv2"); seq_printf(s, "nr_spis:\t%d\n", dist->nr_spis); if (v3) - seq_printf(s, "nr_lpis:\t%d\n", dist->lpi_list_count); + seq_printf(s, "nr_lpis:\t%d\n", atomic_read(&dist->lpi_count)); seq_printf(s, "enabled:\t%d\n", dist->enabled); seq_printf(s, "\n"); diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c index c68164d6cba0..048226812974 100644 --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -97,7 +97,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, goto out_unlock; } - dist->lpi_list_count++; + atomic_inc(&dist->lpi_count); out_unlock: if (ret) @@ -345,7 +345,7 @@ int vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr) * command). If coming from another path (such as enabling LPIs), * we must be careful not to overrun the array. */ - irq_count = READ_ONCE(dist->lpi_list_count); + irq_count = atomic_read(&dist->lpi_count); intids = kmalloc_array(irq_count, sizeof(intids[0]), GFP_KERNEL_ACCOUNT); if (!intids) return -ENOMEM; diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index e58ce68e325c..5988d162b765 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -122,7 +122,7 @@ void __vgic_put_lpi_locked(struct kvm *kvm, struct vgic_irq *irq) return; xa_erase(&dist->lpi_xa, irq->intid); - dist->lpi_list_count--; + atomic_dec(&dist->lpi_count); kfree(irq); } diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index aeff363e3ba6..71e9d719533b 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -273,10 +273,10 @@ struct vgic_dist { */ u64 propbaser; - /* Protects the lpi_list and the count value below. */ + /* Protects the lpi_list. */ raw_spinlock_t lpi_list_lock; struct xarray lpi_xa; - int lpi_list_count; + atomic_t lpi_count; /* LPI translation cache */ struct list_head lpi_translation_cache;