From: Yanfei Xu <isyanfei.xu@gmail.com>
To: Yanfei Xu <yanfei.xu@bytedance.com>, pbonzini@redhat.com
Cc: kvm@vger.kernel.org, caixiangfeng@bytedance.com,
fangying.tommy@bytedance.com
Subject: Re: [PATCH v2] KVM: irqchip: KVM: Reduce allocation overhead in kvm_set_irq_routing()
Date: Mon, 19 Jan 2026 16:53:53 +0800 [thread overview]
Message-ID: <8b4ff052-e9b8-4e57-a3a9-9383c5cd39c1@gmail.com> (raw)
In-Reply-To: <20251226062741.4014391-1-yanfei.xu@bytedance.com>
gentle ping :)
On 2025/12/26 14:27, Yanfei Xu wrote:
> In guests with many VFIO devices and MSI-X vectors, kvm_set_irq_routing()
> becomes a high-overhead operation. Each invocation walks the entire IRQ
> routing table and reallocates/frees every routing entry.
>
> As the routing table grows on each call, entry allocation and freeing
> dominate the execution time of this function. In scenarios such as VM
> live migration or live upgrade, this behavior can introduce unnecessary
> downtime.
>
> Allocate memory for all routing entries in one shot using kcalloc(),
> allowing them to be freed together with a single kfree() call.
>
> Example: On a VM with 120 vCPUs and 15 VFIO devices (virtio-net), the
> total number of calls to kzalloc and kfree is over 20000. With this
> change, it is reduced to around 30.
>
> Reported-by: Xiangfeng Cai <caixiangfeng@bytedance.com>
> Signed-off-by: Yanfei Xu <yanfei.xu@bytedance.com>
> ---
> v1->v2:
> 1. fix variable 'r' is used uninitialized when a 'if' condition is true
> 2. simplified free_irq_routing_table() by removing the iteration over the
> entries and the hlist cleanup.
>
> include/linux/kvm_host.h | 1 +
> virt/kvm/irqchip.c | 34 +++++++++++-----------------------
> 2 files changed, 12 insertions(+), 23 deletions(-)
>
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index d93f75b05ae2..cc27490bef4b 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -692,6 +692,7 @@ struct kvm_kernel_irq_routing_entry {
> struct kvm_irq_routing_table {
> int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS];
> u32 nr_rt_entries;
> + struct kvm_kernel_irq_routing_entry *entries_addr;
> /*
> * Array indexed by gsi. Each entry contains list of irq chips
> * the gsi is connected to.
> diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
> index 6ccabfd32287..56779394033d 100644
> --- a/virt/kvm/irqchip.c
> +++ b/virt/kvm/irqchip.c
> @@ -98,21 +98,10 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
>
> static void free_irq_routing_table(struct kvm_irq_routing_table *rt)
> {
> - int i;
> -
> if (!rt)
> return;
>
> - for (i = 0; i < rt->nr_rt_entries; ++i) {
> - struct kvm_kernel_irq_routing_entry *e;
> - struct hlist_node *n;
> -
> - hlist_for_each_entry_safe(e, n, &rt->map[i], link) {
> - hlist_del(&e->link);
> - kfree(e);
> - }
> - }
> -
> + kfree(rt->entries_addr);
> kfree(rt);
> }
>
> @@ -186,6 +175,12 @@ int kvm_set_irq_routing(struct kvm *kvm,
> new = kzalloc(struct_size(new, map, nr_rt_entries), GFP_KERNEL_ACCOUNT);
> if (!new)
> return -ENOMEM;
> + e = kcalloc(nr, sizeof(*e), GFP_KERNEL_ACCOUNT);
> + if (!e) {
> + r = -ENOMEM;
> + goto out;
> + }
> + new->entries_addr = e;
>
> new->nr_rt_entries = nr_rt_entries;
> for (i = 0; i < KVM_NR_IRQCHIPS; i++)
> @@ -193,25 +188,20 @@ int kvm_set_irq_routing(struct kvm *kvm,
> new->chip[i][j] = -1;
>
> for (i = 0; i < nr; ++i) {
> - r = -ENOMEM;
> - e = kzalloc(sizeof(*e), GFP_KERNEL_ACCOUNT);
> - if (!e)
> - goto out;
> -
> r = -EINVAL;
> switch (ue->type) {
> case KVM_IRQ_ROUTING_MSI:
> if (ue->flags & ~KVM_MSI_VALID_DEVID)
> - goto free_entry;
> + goto out;
> break;
> default:
> if (ue->flags)
> - goto free_entry;
> + goto out;
> break;
> }
> - r = setup_routing_entry(kvm, new, e, ue);
> + r = setup_routing_entry(kvm, new, e + i, ue);
> if (r)
> - goto free_entry;
> + goto out;
> ++ue;
> }
>
> @@ -228,8 +218,6 @@ int kvm_set_irq_routing(struct kvm *kvm,
> r = 0;
> goto out;
>
> -free_entry:
> - kfree(e);
> out:
> free_irq_routing_table(new);
>
next prev parent reply other threads:[~2026-01-19 8:53 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-26 6:27 [PATCH v2] KVM: irqchip: KVM: Reduce allocation overhead in kvm_set_irq_routing() Yanfei Xu
2026-01-19 8:53 ` Yanfei Xu [this message]
2026-05-15 18:52 ` Sean Christopherson
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=8b4ff052-e9b8-4e57-a3a9-9383c5cd39c1@gmail.com \
--to=isyanfei.xu@gmail.com \
--cc=caixiangfeng@bytedance.com \
--cc=fangying.tommy@bytedance.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=yanfei.xu@bytedance.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox