[{"id":3677232,"web_url":"http://patchwork.ozlabs.org/comment/3677232/","msgid":"<CAJaqyWekxXAqacufabHeuhSnSf4veSoQ4nZ73XKnSgvMyjD7kw@mail.gmail.com>","list_archive_url":null,"date":"2026-04-14T14:25:15","subject":"Re: [PATCH v5] hw/net/virtio-net: add support for notification\n coalescing","submitter":{"id":77752,"url":"http://patchwork.ozlabs.org/api/people/77752/","name":"Eugenio Perez Martin","email":"eperezma@redhat.com"},"content":"On Mon, Apr 13, 2026 at 2:13 PM Koushik Dutta <kdutta@redhat.com> wrote:\n>\n> Implement VirtIO Network Notification Coalescing (Bit 53).\n> This allows the guest to manage interrupt frequency using ethtool\n> -C for both RX and TX paths.\n>\n> - Added VIRTIO_NET_F_NOTF_COAL to host features.\n> - Implemented VIRTIO_NET_CTRL_NOTF_COAL class handling in\n>   virtio_net_handle_ctrl_iov.\n> - Added logic to store and apply rx/tx usecs and max_packets.\n> - Added packet counters and threshold logic for both RX and TX data paths.\n> - Dynamic Dispatcher: Implemented a dispatcher mechanism that\n>   dynamically switches/activates the notification callback logic\n>   only after the guest enables TX coalescing via ethtool.\n> - After VM LM coalescing parameters persist in the destination VM.\n>\n> This reduces interrupt overhead by batching notifications based on\n> either a packet count or a time-based threshold.\n>\n> Signed-off-by: Koushik Dutta <kdutta@redhat.com>\n> ---\n>  hw/net/virtio-net.c            | 180 ++++++++++++++++++++++++++++++---\n>  include/hw/virtio/virtio-net.h |   9 ++\n>  net/passt.c                    |   1 +\n>  net/tap.c                      |   1 +\n>  net/vhost-user.c               |   1 +\n>  net/vhost-vdpa.c               |   2 +\n>  6 files changed, 178 insertions(+), 16 deletions(-)\n>\n> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c\n> index 2a5d642a64..a15e9d17bd 100644\n> --- a/hw/net/virtio-net.c\n> +++ b/hw/net/virtio-net.c\n> @@ -157,6 +157,16 @@ static void flush_or_purge_queued_packets(NetClientState *nc)\n>   * - we could suppress RX interrupt if we were so inclined.\n>   */\n>\n> +static void virtio_net_rx_notify(void *opaque)\n> +{\n> +    VirtIONetQueue *q = opaque;\n> +    VirtIONet *n = q->n;\n> +    VirtIODevice *vdev = VIRTIO_DEVICE(n);\n> +\n> +    n->rx_pkt_cnt = 0;\n> +    virtio_notify(vdev, q->rx_vq);\n> +}\n> +\n>  static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)\n>  {\n>      VirtIONet *n = VIRTIO_NET(vdev);\n> @@ -1080,6 +1090,53 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,\n>      }\n>  }\n>\n> +static void virtio_net_tx_timer(void *opaque);\n> +\n> +static int virtio_net_handle_coal(VirtIONet *n, uint8_t cmd,\n> +                                  struct iovec *iov, unsigned int iov_cnt)\n> +{\n> +    struct virtio_net_ctrl_coal coal;\n> +    VirtIONetQueue *q;\n> +    size_t s;\n> +    int i;\n> +\n> +    s = iov_to_buf(iov, iov_cnt, 0, &coal, sizeof(coal));\n> +    if (s != sizeof(coal)) {\n> +        return VIRTIO_NET_ERR;\n> +    }\n> +\n> +    if (cmd == VIRTIO_NET_CTRL_NOTF_COAL_RX_SET) {\n> +        n->rx_coal_usecs = le32_to_cpu(coal.max_usecs);\n> +        n->rx_coal_packets = le32_to_cpu(coal.max_packets);\n> +        if (n->rx_coal_usecs > 0) {\n> +            for (i = 0; i < n->max_queue_pairs; i++) {\n> +                q = &n->vqs[i];\n> +                if (!q->rx_timer) {\n> +                    q->rx_timer = timer_new_us(QEMU_CLOCK_VIRTUAL,\n> +                                               virtio_net_rx_notify,\n> +                                               q);\n> +                }\n> +            }\n> +        }\n\nIf we allocate the timer timer if rx_coal_usecs > 0, should we also\ntimer_free it if rx_coal_usecs == 0? The same question goes to\ntx_timer actually.\n\nAlso, virtio_net_del_queue should free rx_timer should be freed the\nsame way as q->tx_timer.\n\n\n> +    } else if (cmd == VIRTIO_NET_CTRL_NOTF_COAL_TX_SET) {\n> +        n->tx_coal_usecs = le32_to_cpu(coal.max_usecs);\n> +        n->tx_coal_packets = le32_to_cpu(coal.max_packets);\n> +        n->tx_timeout = n->tx_coal_usecs * 1000;\n> +        if (n->tx_coal_usecs > 0) {\n> +            for (i = 0; i < n->max_queue_pairs; i++) {\n> +                q = &n->vqs[i];\n> +                if (!q->tx_timer && n->tx_coal_usecs > 0) {\n> +                    q->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,\n> +                                               virtio_net_tx_timer,\n> +                                               q);\n> +                }\n> +            }\n> +        }\n> +    }\n> +\n> +    return VIRTIO_NET_OK;\n> +}\n> +\n>  static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,\n>                                   struct iovec *iov, unsigned int iov_cnt)\n>  {\n> @@ -1581,6 +1638,8 @@ size_t virtio_net_handle_ctrl_iov(VirtIODevice *vdev,\n>          status = virtio_net_handle_mq(n, ctrl.cmd, iov, out_num);\n>      } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) {\n>          status = virtio_net_handle_offloads(n, ctrl.cmd, iov, out_num);\n> +    } else if (ctrl.class == VIRTIO_NET_CTRL_NOTF_COAL) {\n> +        status = virtio_net_handle_coal(n, ctrl.cmd, iov, out_num);\n>      }\n>\n>      s = iov_from_buf(in_sg, in_num, 0, &status, sizeof(status));\n> @@ -2040,7 +2099,22 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,\n>      }\n>\n>      virtqueue_flush(q->rx_vq, i);\n> -    virtio_notify(vdev, q->rx_vq);\n> +\n> +    /* rx coalescing */\n> +    n->rx_pkt_cnt += i;\n> +    if (n->rx_coal_usecs == 0 || n->rx_pkt_cnt >= n->rx_coal_packets) {\n> +        if (q->rx_timer) {\n> +            timer_del(q->rx_timer);\n> +        }\n> +        virtio_net_rx_notify(q);\n> +    } else {\n> +        if (q->rx_timer) {\n> +            if (!timer_pending(q->rx_timer)) {\n> +                timer_mod(q->rx_timer,\n> +                          qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + n->rx_coal_usecs);\n> +            }\n> +        }\n> +    }\n>\n>      return size;\n>\n> @@ -2817,7 +2891,6 @@ detach:\n>      return -EINVAL;\n>  }\n>\n> -static void virtio_net_tx_timer(void *opaque);\n>\n>  static void virtio_net_handle_tx_timer(VirtIODevice *vdev, VirtQueue *vq)\n>  {\n> @@ -2899,6 +2972,12 @@ static void virtio_net_tx_timer(void *opaque)\n>      if (ret == -EBUSY || ret == -EINVAL) {\n>          return;\n>      }\n> +    if (n->tx_pkt_cnt < ret) {\n> +        n->tx_pkt_cnt = 0;\n> +    } else {\n> +        n->tx_pkt_cnt -= ret;\n> +    }\n> +\n>      /*\n>       * If we flush a full burst of packets, assume there are\n>       * more coming and immediately rearm\n> @@ -2918,6 +2997,7 @@ static void virtio_net_tx_timer(void *opaque)\n>      ret = virtio_net_flush_tx(q);\n>      if (ret > 0) {\n>          virtio_queue_set_notification(q->tx_vq, 0);\n> +        n->tx_pkt_cnt -= ret;\n>          q->tx_waiting = 1;\n>          timer_mod(q->tx_timer,\n>                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);\n> @@ -2973,6 +3053,32 @@ static void virtio_net_tx_bh(void *opaque)\n>      }\n>  }\n>\n> +static void virtio_net_handle_tx_dispatch(VirtIODevice *vdev, VirtQueue *vq)\n> +{\n> +    VirtIONet *n = VIRTIO_NET(vdev);\n> +    VirtIONetQueue *q = &n->vqs[vq2q(virtio_get_queue_index(vq))];\n> +    bool use_timer = n->tx_timer_activate || n->tx_coal_usecs > 0 ||\n> +                     n->tx_coal_packets > 0;\n> +    bool pkt_limit = (n->tx_coal_packets > 0);\n> +\n> +    if (use_timer) {\n> +        n->tx_pkt_cnt++;\n> +        if (!pkt_limit || n->tx_pkt_cnt < n->tx_coal_packets) {\n> +            if (q->tx_timer) {\n> +                virtio_net_handle_tx_timer(vdev, vq);\n> +                return;\n> +            }\n> +        }\n> +        n->tx_pkt_cnt = 0;\n> +        if (q->tx_timer) {\n> +            timer_del(q->tx_timer);\n> +        }\n> +        virtio_net_handle_tx_bh(vdev, vq);\n> +    } else {\n> +        virtio_net_handle_tx_bh(vdev, vq);\n> +    }\n> +}\n> +\n>  static void virtio_net_add_queue(VirtIONet *n, int index)\n>  {\n>      VirtIODevice *vdev = VIRTIO_DEVICE(n);\n> @@ -2980,20 +3086,15 @@ static void virtio_net_add_queue(VirtIONet *n, int index)\n>      n->vqs[index].rx_vq = virtio_add_queue(vdev, n->net_conf.rx_queue_size,\n>                                             virtio_net_handle_rx);\n>\n> -    if (n->net_conf.tx && !strcmp(n->net_conf.tx, \"timer\")) {\n> -        n->vqs[index].tx_vq =\n> -            virtio_add_queue(vdev, n->net_conf.tx_queue_size,\n> -                             virtio_net_handle_tx_timer);\n> -        n->vqs[index].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,\n> -                                              virtio_net_tx_timer,\n> -                                              &n->vqs[index]);\n> -    } else {\n> -        n->vqs[index].tx_vq =\n> -            virtio_add_queue(vdev, n->net_conf.tx_queue_size,\n> -                             virtio_net_handle_tx_bh);\n> -        n->vqs[index].tx_bh = qemu_bh_new_guarded(virtio_net_tx_bh, &n->vqs[index],\n> -                                                  &DEVICE(vdev)->mem_reentrancy_guard);\n> -    }\n> +    n->vqs[index].tx_vq =\n> +        virtio_add_queue(vdev,\n> +                         n->net_conf.tx_queue_size,\n> +                         virtio_net_handle_tx_dispatch);\n> +\n> +    n->vqs[index].tx_bh =\n> +        qemu_bh_new_guarded(virtio_net_tx_bh,\n> +                            &n->vqs[index],\n> +                            &DEVICE(vdev)->mem_reentrancy_guard);\n>\n>      n->vqs[index].tx_waiting = 0;\n>      n->vqs[index].n = n;\n> @@ -3242,6 +3343,36 @@ static int virtio_net_post_load_device(void *opaque, int version_id)\n>      }\n>\n>      virtio_net_commit_rss_config(n);\n> +    if (n->tx_coal_usecs > 0 || n->rx_coal_usecs > 0) {\n> +        n->tx_timeout = n->tx_coal_usecs * 1000;\n> +\n> +        for (i = 0; i < n->max_queue_pairs; i++) {\n> +            VirtIONetQueue *q = &n->vqs[i];\n> +            if (!q->rx_timer && n->rx_coal_usecs > 0) {\n> +                q->rx_timer = timer_new_us(QEMU_CLOCK_VIRTUAL,\n> +                                           virtio_net_rx_notify,\n> +                                           q);\n> +            }\n> +\n> +            if (!q->tx_timer && n->tx_coal_usecs > 0) {\n> +                q->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,\n> +                                           virtio_net_tx_timer,\n> +                                           q);\n> +            }\n> +\n> +            if (n->tx_coal_usecs > 0 && q->tx_timer) {\n> +                n->tx_pkt_cnt = 0;\n> +                timer_mod(q->tx_timer,\n> +                          qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);\n> +            }\n> +\n> +            if (n->rx_coal_usecs > 0 && q->rx_timer) {\n> +                timer_mod(q->rx_timer,\n> +                          qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + n->rx_coal_usecs);\n> +            }\n> +        }\n> +    }\n> +\n>      return 0;\n>  }\n>\n> @@ -3617,6 +3748,10 @@ static const VMStateDescription vmstate_virtio_net_device = {\n>                           vmstate_virtio_net_tx_waiting),\n>          VMSTATE_UINT64_TEST(curr_guest_offloads, VirtIONet,\n>                              has_ctrl_guest_offloads),\n> +        VMSTATE_UINT32(rx_coal_usecs, VirtIONet),\n> +        VMSTATE_UINT32(tx_coal_usecs, VirtIONet),\n> +        VMSTATE_UINT32(rx_coal_packets, VirtIONet),\n> +        VMSTATE_UINT32(tx_coal_packets, VirtIONet),\n>          VMSTATE_END_OF_LIST()\n>      },\n>      .subsections = (const VMStateDescription * const []) {\n> @@ -3970,6 +4105,10 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)\n>          error_printf(\"Defaulting to \\\"bh\\\"\");\n>      }\n>\n> +    if (n->net_conf.tx && strcmp(n->net_conf.tx, \"timer\")) {\n> +        n->tx_timer_activate = true;\n> +    }\n> +\n\nI still think we should disable the coalescing feature if the \"timer\"\ncommand line is enabled. Otherwise the guest can override the\nparameter, which is technically doable but I think it's not a desired\nbehavior. MST, what do you think?\n\n>      n->net_conf.tx_queue_size = MIN(virtio_net_max_tx_queue_size(n),\n>                                      n->net_conf.tx_queue_size);\n>\n> @@ -4046,6 +4185,13 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)\n>              n->rss_data.specified_hash_types.on_bits |\n>              n->rss_data.specified_hash_types.auto_bits;\n>      }\n> +    n->rx_pkt_cnt = 0;\n> +    n->tx_pkt_cnt = 0;\n> +    n->rx_coal_usecs = 0;\n> +    n->tx_coal_usecs = 0;\n> +    n->rx_coal_packets = 0;\n> +    n->tx_coal_packets = 0;\n> +    n->rx_index_timer = NULL;\n>  }\n>\n>  static void virtio_net_device_unrealize(DeviceState *dev)\n> @@ -4258,6 +4404,8 @@ static const Property virtio_net_properties[] = {\n>                        VIRTIO_NET_F_GUEST_USO6, true),\n>      DEFINE_PROP_BIT64(\"host_uso\", VirtIONet, host_features,\n>                        VIRTIO_NET_F_HOST_USO, true),\n> +    DEFINE_PROP_BIT64(\"vq_notf_coal\", VirtIONet, host_features,\n> +                      VIRTIO_NET_F_NOTF_COAL, true),\n>      DEFINE_PROP_ON_OFF_AUTO_BIT64(\"hash-ipv4\", VirtIONet,\n>                                    rss_data.specified_hash_types,\n>                                    VIRTIO_NET_HASH_REPORT_IPv4 - 1,\n> diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h\n> index 371e376428..d88f8aef87 100644\n> --- a/include/hw/virtio/virtio-net.h\n> +++ b/include/hw/virtio/virtio-net.h\n> @@ -158,6 +158,7 @@ typedef struct VirtioNetRssData {\n>  typedef struct VirtIONetQueue {\n>      VirtQueue *rx_vq;\n>      VirtQueue *tx_vq;\n> +    QEMUTimer *rx_timer;\n>      QEMUTimer *tx_timer;\n>      QEMUBH *tx_bh;\n>      uint32_t tx_waiting;\n> @@ -230,6 +231,14 @@ struct VirtIONet {\n>      struct EBPFRSSContext ebpf_rss;\n>      uint32_t nr_ebpf_rss_fds;\n>      char **ebpf_rss_fds;\n> +    QEMUTimer *rx_index_timer;\n> +    uint32_t rx_coal_usecs;\n> +    uint32_t rx_coal_packets;\n> +    uint32_t rx_pkt_cnt;\n> +    uint32_t tx_coal_usecs;\n> +    uint32_t tx_coal_packets;\n> +    uint32_t tx_pkt_cnt;\n> +    bool tx_timer_activate;\n>  };\n>\n>  size_t virtio_net_handle_ctrl_iov(VirtIODevice *vdev,\n> diff --git a/net/passt.c b/net/passt.c\n> index 4ff94ee509..0b0d9e222a 100644\n> --- a/net/passt.c\n> +++ b/net/passt.c\n> @@ -52,6 +52,7 @@ static const int user_feature_bits[] = {\n>      VIRTIO_NET_F_GUEST_USO4,\n>      VIRTIO_NET_F_GUEST_USO6,\n>      VIRTIO_NET_F_HOST_USO,\n> +    VIRTIO_NET_F_NOTF_COAL,\n>\n>      /* This bit implies RARP isn't sent by QEMU out of band */\n>      VIRTIO_NET_F_GUEST_ANNOUNCE,\n> diff --git a/net/tap.c b/net/tap.c\n> index 8d7ab6ba6f..ea5987a3dc 100644\n> --- a/net/tap.c\n> +++ b/net/tap.c\n> @@ -62,6 +62,7 @@ static const int kernel_feature_bits[] = {\n>      VIRTIO_F_NOTIFICATION_DATA,\n>      VIRTIO_NET_F_RSC_EXT,\n>      VIRTIO_NET_F_HASH_REPORT,\n> +    VIRTIO_NET_F_NOTF_COAL,\n>      VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO,\n>      VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO,\n>      VHOST_INVALID_FEATURE_BIT\n> diff --git a/net/vhost-user.c b/net/vhost-user.c\n> index a4bb49bbcf..f0b3752d7c 100644\n> --- a/net/vhost-user.c\n> +++ b/net/vhost-user.c\n> @@ -54,6 +54,7 @@ static const int user_feature_bits[] = {\n>      VIRTIO_NET_F_GUEST_USO4,\n>      VIRTIO_NET_F_GUEST_USO6,\n>      VIRTIO_NET_F_HOST_USO,\n> +    VIRTIO_NET_F_NOTF_COAL,\n>\n>      /* This bit implies RARP isn't sent by QEMU out of band */\n>      VIRTIO_NET_F_GUEST_ANNOUNCE,\n> diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c\n> index 3df6091274..a20db78b81 100644\n> --- a/net/vhost-vdpa.c\n> +++ b/net/vhost-vdpa.c\n> @@ -70,6 +70,7 @@ static const int vdpa_feature_bits[] = {\n>      VIRTIO_NET_F_CTRL_RX,\n>      VIRTIO_NET_F_CTRL_RX_EXTRA,\n>      VIRTIO_NET_F_CTRL_VLAN,\n> +    VIRTIO_NET_F_NOTF_COAL,\n>      VIRTIO_NET_F_CTRL_VQ,\n>      VIRTIO_NET_F_GSO,\n>      VIRTIO_NET_F_GUEST_CSUM,\n> @@ -115,6 +116,7 @@ static const uint64_t vdpa_svq_device_features =\n>      BIT_ULL(VIRTIO_NET_F_HOST_UFO) |\n>      BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) |\n>      BIT_ULL(VIRTIO_NET_F_STATUS) |\n> +    BIT_ULL(VIRTIO_NET_F_NOTF_COAL) |\n\nThis patch does not enable SVQ to handle NOTF_COAL, so this addition is invalid.\n\n>      BIT_ULL(VIRTIO_NET_F_CTRL_VQ) |\n>      BIT_ULL(VIRTIO_NET_F_GSO) |\n>      BIT_ULL(VIRTIO_NET_F_CTRL_RX) |\n> --\n> 2.53.0\n>","headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=HvzhJXAY;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=puiR6CaB;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fw66Y5sPrz1xtJ\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 15 Apr 2026 00:27:00 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wCeiG-0002pq-3u; Tue, 14 Apr 2026 10:26:00 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <eperezma@redhat.com>)\n id 1wCeiF-0002pi-2o\n for qemu-devel@nongnu.org; Tue, 14 Apr 2026 10:25:59 -0400","from us-smtp-delivery-124.mimecast.com ([170.10.133.124])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <eperezma@redhat.com>)\n id 1wCeiB-0007rH-Vg\n for qemu-devel@nongnu.org; Tue, 14 Apr 2026 10:25:58 -0400","from mail-yx1-f72.google.com (mail-yx1-f72.google.com\n [74.125.224.72]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-396-yCIy6VZuN_Ou0Rljg4olzQ-1; Tue, 14 Apr 2026 10:25:53 -0400","by mail-yx1-f72.google.com with SMTP id\n 956f58d0204a3-651c4c4df1aso4748393d50.3\n for <qemu-devel@nongnu.org>; Tue, 14 Apr 2026 07:25:53 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1776176754;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=I0tedh0ex/YXOWLzTGig5NTFylSbjMJGnZxG8WHADgs=;\n b=HvzhJXAY1RdokeKydSWLGg7G64wXrqqoRZLNI2dSUpcCr/NIucSH3JsAkH+9ksSIANHVB7\n y6U2PuopzR1W8VtlHVJivcgBNJ2dEz6j+dcAXqFr4G3hpYKrqa0Bsi7J+4kAoMGH0Gw4zG\n NnAdiXoflDbXsCVLLJ3It92UpOit5V4=","v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=redhat.com; s=google; t=1776176752; x=1776781552; darn=nongnu.org;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:from:to:cc:subject:date\n :message-id:reply-to;\n bh=I0tedh0ex/YXOWLzTGig5NTFylSbjMJGnZxG8WHADgs=;\n b=puiR6CaB9ayiajAuQ2kYwDd/e9qQ1LEtYTfZlRNAQMTehO3OVHRqXD1TH09A45reoV\n wlMfwSsncFo2Hvh73AqN/FwiNzQtjEYtkRVZMN7iKCAEEFAiIYfFaWV1+uMe7hyON2Uo\n EWCz+gSgMwRW8T2xiVhuEIVy/yzKyOs/52k7q2cVZAgIbj7b1XGfzpojrwhXtk5UJK9P\n SCZviLlPMbYlpY4EO1pUddbT+tZCRpiCmD58SzZiMH3G+HgJUiTRwY7B6XwoFccYYJUL\n Xk6Jvb0NElF0fgccGZQcbUC0AuxSA03ZrluIzUEM3niaJsPvr27MiPfJfIQ8zqgioqLC\n /6Xw=="],"X-MC-Unique":"yCIy6VZuN_Ou0Rljg4olzQ-1","X-Mimecast-MFC-AGG-ID":"yCIy6VZuN_Ou0Rljg4olzQ_1776176752","ARC-Seal":"i=1; a=rsa-sha256; t=1776176752; cv=none;\n d=google.com; s=arc-20240605;\n b=hHk1D/YURXKn+TQkP2FU4w/QWOjYeaVql51tVb28SET5Qdgq6dtBUb+Qle/B/Gw9ZB\n MpGkNor7ujejk3Tu2GBuojksmKpGZLtHneHGLp1iiF8ERjJT3P2+uK5bGZqh98KiYPn0\n 6ZTKDozsMAFn6LnxjKOOhPwWC0ZyFCstsox3rz3RItpzD63MYO5RRjudsDLHID3TyxKk\n ZvJM1ucyc/nC54bXGvaQftY9sFpl2cTBC7FljJV2U7K0aXtZDZkcKgUQ6nR/jPMhj06h\n RLX/K8DL2ZMmF/cvl0rnnLizxAlSNIeL/rBvYW7bRKQ5+hHVmcmajMm0/mly9xJGff8B\n l7vg==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:dkim-signature;\n bh=I0tedh0ex/YXOWLzTGig5NTFylSbjMJGnZxG8WHADgs=;\n fh=zgGnWcT/ulYH8APAM2M9+s2IND3POZMAbr8rRTECX3M=;\n b=I/97+KLD3q2xruSQZFfzXyP4nuKzKI5tpHBFXyCSWNucKH16Peq/QZJYh0dRsTPEBy\n ZO5+DRYczkEsrGxgtxyRo6W5G5XqQLKJXe9yKSifjYwUJvh1sUqUCh1wJAc7ttNUnp2l\n G6DkTNWzm02OD1XHiVfGXDJpVvhdaZS1tj2Srv7OgNbCxpoUwMT4LQXTY+IOeQkd5o0H\n H8yASB2WFM3Tw+mLlyE03JFZqZlcMWIugpdJLkoEAihKD3nWZcsyTocIr3xaU5FUNLa0\n R8cqIb0FOztuq+CsLc5qWi+ldajyHtw0NSehtuJNW8h4uK2ExnU40nSsyAYyx876rh/3\n IYAw==; darn=nongnu.org","ARC-Authentication-Results":"i=1; mx.google.com; arc=none","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776176752; x=1776781552;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=I0tedh0ex/YXOWLzTGig5NTFylSbjMJGnZxG8WHADgs=;\n b=ceE6xQmpOsmRVSwmZCocVEh+6iVBWeHmZNEgezAqUxmL7TUMTZLITDBT+ADIpnkww/\n lxK5ZdUVE4om6hiOOzyC5YhR3Lz/CoTMrb5TejlJpBJ1Yfo2OB54wvjSF1MZJVIl4Y4l\n ORclvUYnszx4O4oOIngY5BXq8W+lVyRECe1Ird64eU2+j2MhLtb9bOymKS8IxF7w5XSA\n AV1m1CVGnm2+1KC2JQgRZ+ljvYCaZqEehPprbxZhsd3hioUmJH2ky+3RWswNXK9nWNnq\n af1Po5DDJHYBeXQzNDMipax9W0b1fhA/61Ws8QsIaarqDhAUKRKei+h/vXYeuaDIQhke\n tRbQ==","X-Gm-Message-State":"AOJu0YxS8DEbQaWVlvmQpZJDKNYGM+B1wtUHzQ3wD2xb/2N5EohmtjEN\n JKPyRdHkKtJvjMhyh4ddupNDTv0tcYxpAl6IlxAsPqcuj73Lbo39tF97YhbfghUwL4J3OZExTt8\n d04ct3JqXMOGEfDTU+y18FC6qF0eSdw760AxeWih1nNNL41cgORgvuBL//grKsVlYRB3EKI8aj0\n 4Z8sQU801X2kS3MD07HvqiWkhjiMY8iig=","X-Gm-Gg":"AeBDiesdsUcDKxhbwKwKljzfADbKWTh51d2EkZiK0VUWCFTBw3QZWxhaEWfD9RkMa/1\n uecDV5Oe0SjcFpI1R9C1xd+xerDccQBwDGEYpkPAHIKjZqPAKtwmy4vKne3HOF8ytJSg147JP2m\n nLoKRvPQxWiITkU+giNaBOBrm0llvO/12Aa1X6+Eeaa/1lUljX3G7bZq24IEHMZ5YxyZ48hv10w\n /Y=","X-Received":["by 2002:a53:d110:0:b0:651:9286:578a with SMTP id\n 956f58d0204a3-65198a8aa06mr12515463d50.25.1776176752311;\n Tue, 14 Apr 2026 07:25:52 -0700 (PDT)","by 2002:a53:d110:0:b0:651:9286:578a with SMTP id\n 956f58d0204a3-65198a8aa06mr12515434d50.25.1776176751690; Tue, 14 Apr 2026\n 07:25:51 -0700 (PDT)"],"MIME-Version":"1.0","References":"<20260413121348.655887-1-kdutta@redhat.com>","In-Reply-To":"<20260413121348.655887-1-kdutta@redhat.com>","From":"Eugenio Perez Martin <eperezma@redhat.com>","Date":"Tue, 14 Apr 2026 16:25:15 +0200","X-Gm-Features":"AQROBzA4bevkuCxlb9_0d9VGUZA_gxXIWvA26cW02_j2CBq0DVt4BzFyqq0mw9w","Message-ID":"\n <CAJaqyWekxXAqacufabHeuhSnSf4veSoQ4nZ73XKnSgvMyjD7kw@mail.gmail.com>","Subject":"Re: [PATCH v5] hw/net/virtio-net: add support for notification\n coalescing","To":"Koushik Dutta <kdutta@redhat.com>","Cc":"qemu-devel@nongnu.org, \"Michael S. Tsirkin\" <mst@redhat.com>,\n Jason Wang <jasowang@redhat.com>, Stefano Garzarella <sgarzare@redhat.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","Received-SPF":"pass client-ip=170.10.133.124;\n envelope-from=eperezma@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com","X-Spam_score_int":"-25","X-Spam_score":"-2.6","X-Spam_bar":"--","X-Spam_report":"(-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.54,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"qemu development <qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"}}]