Re: [PATCH v3 1/2] RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request
Anup Patel <[email protected]> Sat, 1 Aug 2026 14:05:02 +0530
| Newsgroups | org.kernel.vger.kvm,org.infradead.lists.kvm-riscv,org.infradead.lists.linux-riscv,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAAhSdy1QwcYv_Dz0s5P_9RjRegJsJQz8fjiskGNmYYFXGOnB2A@mail.gmail.com> |
On Fri, Jul 31, 2026 at 3:12 PM Wang Yechao <[email protected]> wrote: > > 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 <[email protected]> LGTM. Reviewed-by: Anup Patel <[email protected]> Thanks, Anup > --- > arch/riscv/kvm/tlb.c | 20 ++++++++++++-------- > 1 file changed, 12 insertions(+), 8 deletions(-) > > diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c > index 993b25ea94d67..c54522decaa64 100644 > --- a/arch/riscv/kvm/tlb.c > +++ b/arch/riscv/kvm/tlb.c > @@ -332,10 +332,11 @@ 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); > > - 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 || > @@ -345,10 +346,10 @@ static void make_xfence_request(struct kvm *kvm, > continue; > } > > - bitmap_set(vcpu_mask, i, 1); > - > - if (!data || !data->type) > + if (!data || !data->type) { > + bitmap_set(req_vcpu_mask, i, 1); > continue; > + } > > /* > * Enqueue hfence data to VCPU hfence queue. If we don't > @@ -356,10 +357,13 @@ static void make_xfence_request(struct kvm *kvm, > * 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.39.3 >