On Fri, Mar 21, 2025 at 11:56 AM Akihiko Odaki <akihiko.od...@daynix.com> wrote:
>
> virtio-net uses the max_tx_vq field of struct virtio_net_rss_config to
> determine the number of queue pairs and emits an error message saying
> "Can't get queue_pairs". However, the field tells only about tx.
>
> Examine the indirection table to determine the number of queues required
> for rx, and correct the name of field in the error message, clarifying
> its correct semantics.
>
> Signed-off-by: Akihiko Odaki <akihiko.od...@daynix.com>
> ---
>  hw/net/virtio-net.c | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index de87cfadffe1..d9ab9e1eb74d 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -1450,23 +1450,28 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
>          err_value = (uint32_t)s;
>          goto error;
>      }
> -    for (i = 0; i < n->rss_data.indirections_len; ++i) {
> -        uint16_t val = n->rss_data.indirections_table[i];
> -        n->rss_data.indirections_table[i] = virtio_lduw_p(vdev, &val);
> -    }
>      offset += size_get;
>      size_get = sizeof(temp);
>      s = iov_to_buf(iov, iov_cnt, offset, &temp, size_get);
>      if (s != size_get) {
> -        err_msg = "Can't get queue_pairs";
> +        err_msg = "Can't get max_tx_vq";
>          err_value = (uint32_t)s;
>          goto error;
>      }
> -    queue_pairs = do_rss ? virtio_lduw_p(vdev, &temp.us) : 
> n->curr_queue_pairs;
> -    if (queue_pairs == 0 || queue_pairs > n->max_queue_pairs) {
> -        err_msg = "Invalid number of queue_pairs";
> -        err_value = queue_pairs;
> -        goto error;
> +    if (do_rss) {
> +        queue_pairs = virtio_lduw_p(vdev, &temp.us);
> +        for (i = 0; i < n->rss_data.indirections_len; ++i) {
> +            uint16_t val = n->rss_data.indirections_table[i];
> +            n->rss_data.indirections_table[i] = virtio_lduw_p(vdev, &val);
> +            queue_pairs = MAX(queue_pairs, 
> n->rss_data.indirections_table[i]);
> +        }

I think this change will create a problem rather than improve something.
curr_queue_pairs is used in virtio_net_can_receive.
Let's say the device has 4 queues and 4 CPUs.
If the OS currently configures the RSS for first 2 queues only the
curr_queue_pairs becomes 2.
The packets that come to queues 2 and 3 will be dropped, see
virtio_net_receive_rcu and virtio_net_can_receive

IMO the curr_queue_pairs should not be changed after it was set by
VIRTIO_NET_CTRL_MQ / VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET

> +        if (queue_pairs == 0 || queue_pairs > n->max_queue_pairs) {
> +            err_msg = "Invalid number of queue_pairs";
> +            err_value = queue_pairs;
> +            goto error;
> +        }
> +    } else {
> +        queue_pairs = n->curr_queue_pairs;
>      }
>      if (temp.b > VIRTIO_NET_RSS_MAX_KEY_SIZE) {
>          err_msg = "Invalid key size";
>
> ---
> base-commit: 825b96dbcee23d134b691fc75618b59c5f53da32
> change-id: 20250321-vq-87aff4f531bf
>
> Best regards,
> --
> Akihiko Odaki <akihiko.od...@daynix.com>
>

Reply via email to