[PATCH v2 2/2] RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request
Wang Yechao
wang.yechao255 at zte.com.cn
Tue Jul 7 05:50:21 PDT 2026
When handling hfence requests in make_xfence_request(), the current code
uses a single 'actual_req' variable and a single vcpu_mask. If any VCPU
fails to enqueue the hfence data (because its queue is full), the request
falls back to 'fallback_req' for all VCPUs, even if other VCPUs still
have available queue space.
This can cause unnecessary fallback for healthy VCPUs, and more seriously,
those healthy VCPUs will not process their already-enqueued hfence
requests because no 'req' is set for them. As a result, their queues will
quickly become full as well, degrading performance for SMP guests.
Fix this by maintaining two separate bitmaps: one for VCPUs that
successfully enqueued the hfence data (req_vcpu_mask) and another for
those that failed (fallback_req_vcpu_mask). Then send the appropriate
requests to each group. This ensures that fallback is only applied to
VCPUs that actually need it, preserving the efficiency of the normal
path for others.
Fixes: 13acfec2dbcc ("RISC-V: KVM: Add remote HFENCE functions based on VCPU requests")
Signed-off-by: Wang Yechao <wang.yechao255 at zte.com.cn>
---
arch/riscv/kvm/tlb.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c
index 5a9c75e458013..fd445e9fa3f94 100644
--- a/arch/riscv/kvm/tlb.c
+++ b/arch/riscv/kvm/tlb.c
@@ -355,13 +355,14 @@ static void make_xfence_request(struct kvm *kvm,
{
unsigned long i;
struct kvm_vcpu *vcpu;
- unsigned int actual_req = req;
- DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS);
+ DECLARE_BITMAP(req_vcpu_mask, KVM_MAX_VCPUS);
+ DECLARE_BITMAP(fallback_req_vcpu_mask, KVM_MAX_VCPUS);
if (!data || !data->type)
return;
- bitmap_zero(vcpu_mask, KVM_MAX_VCPUS);
+ bitmap_zero(req_vcpu_mask, KVM_MAX_VCPUS);
+ bitmap_zero(fallback_req_vcpu_mask, KVM_MAX_VCPUS);
kvm_for_each_vcpu(i, vcpu, kvm) {
if (hbase != -1UL) {
if (vcpu->vcpu_id < hbase ||
@@ -371,18 +372,19 @@ static void make_xfence_request(struct kvm *kvm,
continue;
}
- bitmap_set(vcpu_mask, i, 1);
-
/*
* Enqueue hfence data to VCPU hfence queue. If we don't
* have space in the VCPU hfence queue then fallback to
* a more conservative hfence request.
*/
if (!vcpu_hfence_enqueue(vcpu, data))
- actual_req = fallback_req;
+ bitmap_set(fallback_req_vcpu_mask, i, 1);
+ else
+ bitmap_set(req_vcpu_mask, i, 1);
}
- kvm_make_vcpus_request_mask(kvm, actual_req, vcpu_mask);
+ kvm_make_vcpus_request_mask(kvm, req, req_vcpu_mask);
+ kvm_make_vcpus_request_mask(kvm, fallback_req, fallback_req_vcpu_mask);
}
void kvm_riscv_fence_i(struct kvm *kvm,
--
2.43.5
More information about the linux-riscv
mailing list