From nobody Sun Jun 28 10:34:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6DB35C433F5 for ; Tue, 8 Feb 2022 18:15:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1384756AbiBHSPy (ORCPT ); Tue, 8 Feb 2022 13:15:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1384743AbiBHSPq (ORCPT ); Tue, 8 Feb 2022 13:15:46 -0500 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B1EFC061579 for ; Tue, 8 Feb 2022 10:15:45 -0800 (PST) Received: by mail-lf1-x12a.google.com with SMTP id 13so1357758lfp.7 for ; Tue, 08 Feb 2022 10:15:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zwrnbyLNdtTm0btNv2HP1O4KlFU0i9XXxpiCHX2F+Pc=; b=tzNlIqib5jH9XFKGuZa+YMoAj9U8joZMJeU+ui8Zcv/IDBs4+XgzC1gQofsf0pGOJC gSlyGOPLYjc8L/Be+N+wb521dnQ/lkySge3j5SGgV1ALefdhamIqPqWmnALQAD25sNca O3Jvbze4FPuQv7lPe9KA4pU7Ddl7gqac6dVvmtBTxiFNC8fj5iF9Bp/6LyZqJOHiZYWN Nqwq928pL8jsZ7bUVLHpSgRgchGNlAQ4ZpSf+ryLQpNJT3Z34l+7iKpzEkI5rRbhOnSJ Kw+mFk4umJjnNojd/XA58TNTwM7zRvY0QxwPkquwrGILglqytsQEzqcgN+BCfP3bOAGq nRbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zwrnbyLNdtTm0btNv2HP1O4KlFU0i9XXxpiCHX2F+Pc=; b=4egis4rdx6ZWOwdcpjED+RgnH2+lph2+dnTyCcFd0iVA+xhBkFpUAAkHpoZKZniamk UDpoNXMexn4caLM2yyVk7jDC17vsbw+yLfQxYVSAQryXWR3LFfixzt2MpxkuWxSR4Xu9 SFxh+KZ0/jfbK+2NiEe7BJOqXWQeD1JNY6fbaDGVHbG6RYLI/pOygd9FjBjKh0OK592n YlG29Z8V2EIP4SErlICM/GnheNKADKp/vxe8VEepgz02i/SZ/Waz2UgV3/9j6oSa+/+t NZLA3svSYjPQCY6lHG1LmIlgkYpWqLfvj7ZMz4HhysHcISnmiSOxDO4EBg2lpwi6aVMx VOmg== X-Gm-Message-State: AOAM532AwYnMuzycKgyuRm2QMCtwBADRp5Zp4ysO21mNWKYMUF7wfVsB KFhZnewYa5l7X9RWxF02++cwmg== X-Google-Smtp-Source: ABdhPJwAV0zcT5EY4vC/gPjMGB5tdxsfLzkDK1pFzGI5vqPmF/9DgAx4UdfdZdCYsJBKHLDCbJxV1w== X-Received: by 2002:a05:6512:3ba:: with SMTP id v26mr3534983lfp.662.1644344143814; Tue, 08 Feb 2022 10:15:43 -0800 (PST) Received: from navi.cosmonova.net.ua ([95.67.24.131]) by smtp.gmail.com with ESMTPSA id p16sm2125082ljc.86.2022.02.08.10.15.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Feb 2022 10:15:43 -0800 (PST) From: Andrew Melnychenko To: netdev@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, jasowang@redhat.com, mst@redhat.com Cc: yan@daynix.com, yuri.benditovich@daynix.com Subject: [PATCH v3 1/4] drivers/net/virtio_net: Fixed padded vheader to use v1 with hash. Date: Tue, 8 Feb 2022 20:15:07 +0200 Message-Id: <20220208181510.787069-2-andrew@daynix.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220208181510.787069-1-andrew@daynix.com> References: <20220208181510.787069-1-andrew@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The header v1 provides additional info about RSS. Added changes to computing proper header length. In the next patches, the header may contain RSS hash info for the hash population. Signed-off-by: Andrew Melnychenko --- drivers/net/virtio_net.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index a801ea40908f..1404e683a2fd 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -242,13 +242,13 @@ struct virtnet_info { }; =20 struct padded_vnet_hdr { - struct virtio_net_hdr_mrg_rxbuf hdr; + struct virtio_net_hdr_v1_hash hdr; /* * hdr is in a separate sg buffer, and data sg buffer shares same page * with this header sg. This padding makes next sg 16 byte aligned * after the header. */ - char padding[4]; + char padding[12]; }; =20 static bool is_xdp_frame(void *ptr) @@ -1266,7 +1266,8 @@ static unsigned int get_mergeable_buf_len(struct rece= ive_queue *rq, struct ewma_pkt_len *avg_pkt_len, unsigned int room) { - const size_t hdr_len =3D sizeof(struct virtio_net_hdr_mrg_rxbuf); + struct virtnet_info *vi =3D rq->vq->vdev->priv; + const size_t hdr_len =3D vi->hdr_len; unsigned int len; =20 if (room) @@ -2851,7 +2852,7 @@ static void virtnet_del_vqs(struct virtnet_info *vi) */ static unsigned int mergeable_min_buf_len(struct virtnet_info *vi, struct = virtqueue *vq) { - const unsigned int hdr_len =3D sizeof(struct virtio_net_hdr_mrg_rxbuf); + const unsigned int hdr_len =3D vi->hdr_len; unsigned int rq_size =3D virtqueue_get_vring_size(vq); unsigned int packet_len =3D vi->big_packets ? IP_MAX_MTU : vi->dev->max_m= tu; unsigned int buf_len =3D hdr_len + ETH_HLEN + VLAN_HLEN + packet_len; --=20 2.34.1 From nobody Sun Jun 28 10:34:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C76FFC433FE for ; Tue, 8 Feb 2022 18:15:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1384762AbiBHSP5 (ORCPT ); Tue, 8 Feb 2022 13:15:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353226AbiBHSPs (ORCPT ); Tue, 8 Feb 2022 13:15:48 -0500 Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 95C6CC061578 for ; Tue, 8 Feb 2022 10:15:46 -0800 (PST) Received: by mail-lf1-x12d.google.com with SMTP id i34so35004525lfv.2 for ; Tue, 08 Feb 2022 10:15:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=m2OUXlbgRETXvXdisY4Wpn2INj5cvGy8JO2x46WkjKM=; b=KAXolfbuOkDy4a+BDcOIVEzJVPUwshY7F0jyYd+55l0H9I/KiHz4D5yaz+2tPxeB64 yDmJdFTzval0mSVEYhcH8bDffYx45yPz8sAHsi9jk7qW/dAq5xXKt5RgP+8BgQhNgeNl qjLLErWkYNl0A2Ac8EZqRiJeuMUj8MEe7KGHcguZdJSAFBIAiMSjaKcHTWk/orT+DPcI auHOyt3AO85A8JuahL2iZKXcsFtQyCe4iafzC8LjVSmseJ/8R8+iQzm4kJwJG0eJxoWC Eoc5R2H7XOzbiACA2VCZkoHLlvssdu3Zs1j+scJ4rsItYBIsiG6rvzb/KeVHulJKqd04 w9EQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=m2OUXlbgRETXvXdisY4Wpn2INj5cvGy8JO2x46WkjKM=; b=lSxT2TfENCvWedgnNEqKx1RwshEh9wrRDXvLZvNPU5ZnGYmHPwmBplIsb9mMeAThj2 RWu3UNbD3AbBSuRD0wzz/CRPLS9G0c1V1XTXhbE2xfTfpKyEeselNSmYFCfr3jKqcWWv WDfRCgFtit9BjDSTNS51d444Jn15tEsNAXMrNnsa/lcpa1/uw3vhwDNKVD93lkynzDkq CTveI3OrNwVhoJDbBY3ZWqWW1pIPByJSxgpG2TmZZUMJOBbV9C2tBb6tpQ6TBRfo/rA2 JQ0gskbUVdnuz1kMTHsnIg1ryE+/2oZXiZ9o+N8TFtEgkn2QEtIikXW5qeE0a03URN7z ODsg== X-Gm-Message-State: AOAM531unuJObUkeTxQ7bYDCyROshIjPF1bJsd6Fj/+et12AYKiKcTsO Dw11Wgs6mDpZYxuUD1gQ204GPg== X-Google-Smtp-Source: ABdhPJzyHc/pTz21xdJrvfv1TMcXUzWjwPKkPrKK1ufpEvou2tuMNex3+q1ExLmZaB3hOQaHz+fBQQ== X-Received: by 2002:a05:6512:234a:: with SMTP id p10mr3633448lfu.15.1644344144960; Tue, 08 Feb 2022 10:15:44 -0800 (PST) Received: from navi.cosmonova.net.ua ([95.67.24.131]) by smtp.gmail.com with ESMTPSA id p16sm2125082ljc.86.2022.02.08.10.15.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Feb 2022 10:15:44 -0800 (PST) From: Andrew Melnychenko To: netdev@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, jasowang@redhat.com, mst@redhat.com Cc: yan@daynix.com, yuri.benditovich@daynix.com Subject: [PATCH v3 2/4] drivers/net/virtio_net: Added basic RSS support. Date: Tue, 8 Feb 2022 20:15:08 +0200 Message-Id: <20220208181510.787069-3-andrew@daynix.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220208181510.787069-1-andrew@daynix.com> References: <20220208181510.787069-1-andrew@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Added features for RSS. Added initialization, RXHASH feature and ethtool ops. By default RSS/RXHASH is disabled. Virtio RSS "IPv6 extensions" hashes disabled. Added ethtools ops to set key and indirection table. Signed-off-by: Andrew Melnychenko --- drivers/net/virtio_net.c | 191 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 185 insertions(+), 6 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 1404e683a2fd..495aed524e33 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -169,6 +169,24 @@ struct receive_queue { struct xdp_rxq_info xdp_rxq; }; =20 +/* This structure can contain rss message with maximum settings for indire= ction table and keysize + * Note, that default structure that describes RSS configuration virtio_ne= t_rss_config + * contains same info but can't handle table values. + * In any case, structure would be passed to virtio hw through sg_buf spli= t by parts + * because table sizes may be differ according to the device configuration. + */ +#define VIRTIO_NET_RSS_MAX_KEY_SIZE 40 +#define VIRTIO_NET_RSS_MAX_TABLE_LEN 128 +struct virtio_net_ctrl_rss { + u32 hash_types; + u16 indirection_table_mask; + u16 unclassified_queue; + u16 indirection_table[VIRTIO_NET_RSS_MAX_TABLE_LEN]; + u16 max_tx_vq; + u8 hash_key_length; + u8 key[VIRTIO_NET_RSS_MAX_KEY_SIZE]; +}; + /* Control VQ buffers: protected by the rtnl lock */ struct control_buf { struct virtio_net_ctrl_hdr hdr; @@ -178,6 +196,7 @@ struct control_buf { u8 allmulti; __virtio16 vid; __virtio64 offloads; + struct virtio_net_ctrl_rss rss; }; =20 struct virtnet_info { @@ -206,6 +225,12 @@ struct virtnet_info { /* Host will merge rx buffers for big packets (shake it! shake it!) */ bool mergeable_rx_bufs; =20 + /* Host supports rss and/or hash report */ + bool has_rss; + u8 rss_key_size; + u16 rss_indir_table_size; + u32 rss_hash_types_supported; + /* Has control virtqueue */ bool has_cvq; =20 @@ -2184,6 +2209,56 @@ static void virtnet_get_ringparam(struct net_device = *dev, ring->tx_pending =3D ring->tx_max_pending; } =20 +static bool virtnet_commit_rss_command(struct virtnet_info *vi) +{ + struct net_device *dev =3D vi->dev; + struct scatterlist sgs[4]; + unsigned int sg_buf_size; + + /* prepare sgs */ + sg_init_table(sgs, 4); + + sg_buf_size =3D offsetof(struct virtio_net_ctrl_rss, indirection_table); + sg_set_buf(&sgs[0], &vi->ctrl->rss, sg_buf_size); + + sg_buf_size =3D sizeof(uint16_t) * vi->rss_indir_table_size; + sg_set_buf(&sgs[1], vi->ctrl->rss.indirection_table, sg_buf_size); + + sg_buf_size =3D offsetof(struct virtio_net_ctrl_rss, key) + - offsetof(struct virtio_net_ctrl_rss, max_tx_vq); + sg_set_buf(&sgs[2], &vi->ctrl->rss.max_tx_vq, sg_buf_size); + + sg_buf_size =3D vi->rss_key_size; + sg_set_buf(&sgs[3], vi->ctrl->rss.key, sg_buf_size); + + if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ, + VIRTIO_NET_CTRL_MQ_RSS_CONFIG, sgs)) { + dev_warn(&dev->dev, "VIRTIONET issue with committing RSS sgs\n"); + return false; + } + return true; +} + +static void virtnet_init_default_rss(struct virtnet_info *vi) +{ + u32 indir_val =3D 0; + int i =3D 0; + + vi->ctrl->rss.hash_types =3D vi->rss_hash_types_supported; + vi->ctrl->rss.indirection_table_mask =3D vi->rss_indir_table_size - 1; + vi->ctrl->rss.unclassified_queue =3D 0; + + for (; i < vi->rss_indir_table_size; ++i) { + indir_val =3D ethtool_rxfh_indir_default(i, vi->curr_queue_pairs); + vi->ctrl->rss.indirection_table[i] =3D indir_val; + } + + vi->ctrl->rss.max_tx_vq =3D vi->curr_queue_pairs; + vi->ctrl->rss.hash_key_length =3D vi->rss_key_size; + + netdev_rss_key_fill(vi->ctrl->rss.key, vi->rss_key_size); +} + =20 static void virtnet_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -2412,6 +2487,71 @@ static void virtnet_update_settings(struct virtnet_i= nfo *vi) vi->duplex =3D duplex; } =20 +static u32 virtnet_get_rxfh_key_size(struct net_device *dev) +{ + return ((struct virtnet_info *)netdev_priv(dev))->rss_key_size; +} + +static u32 virtnet_get_rxfh_indir_size(struct net_device *dev) +{ + return ((struct virtnet_info *)netdev_priv(dev))->rss_indir_table_size; +} + +static int virtnet_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u= 8 *hfunc) +{ + struct virtnet_info *vi =3D netdev_priv(dev); + int i; + + if (indir) { + for (i =3D 0; i < vi->rss_indir_table_size; ++i) + indir[i] =3D vi->ctrl->rss.indirection_table[i]; + } + + if (key) + memcpy(key, vi->ctrl->rss.key, vi->rss_key_size); + + if (hfunc) + *hfunc =3D ETH_RSS_HASH_TOP; + + return 0; +} + +static int virtnet_set_rxfh(struct net_device *dev, const u32 *indir, cons= t u8 *key, const u8 hfunc) +{ + struct virtnet_info *vi =3D netdev_priv(dev); + int i; + + if (hfunc !=3D ETH_RSS_HASH_NO_CHANGE && hfunc !=3D ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; + + if (indir) { + for (i =3D 0; i < vi->rss_indir_table_size; ++i) + vi->ctrl->rss.indirection_table[i] =3D indir[i]; + } + if (key) + memcpy(vi->ctrl->rss.key, key, vi->rss_key_size); + + virtnet_commit_rss_command(vi); + + return 0; +} + +static int virtnet_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc = *info, u32 *rule_locs) +{ + struct virtnet_info *vi =3D netdev_priv(dev); + int rc =3D 0; + + switch (info->cmd) { + case ETHTOOL_GRXRINGS: + info->data =3D vi->curr_queue_pairs; + break; + default: + rc =3D -EOPNOTSUPP; + } + + return rc; +} + static const struct ethtool_ops virtnet_ethtool_ops =3D { .supported_coalesce_params =3D ETHTOOL_COALESCE_MAX_FRAMES, .get_drvinfo =3D virtnet_get_drvinfo, @@ -2427,6 +2567,11 @@ static const struct ethtool_ops virtnet_ethtool_ops = =3D { .set_link_ksettings =3D virtnet_set_link_ksettings, .set_coalesce =3D virtnet_set_coalesce, .get_coalesce =3D virtnet_get_coalesce, + .get_rxfh_key_size =3D virtnet_get_rxfh_key_size, + .get_rxfh_indir_size =3D virtnet_get_rxfh_indir_size, + .get_rxfh =3D virtnet_get_rxfh, + .set_rxfh =3D virtnet_set_rxfh, + .get_rxnfc =3D virtnet_get_rxnfc, }; =20 static void virtnet_freeze_down(struct virtio_device *vdev) @@ -2679,6 +2824,16 @@ static int virtnet_set_features(struct net_device *d= ev, vi->guest_offloads =3D offloads; } =20 + if ((dev->features ^ features) & NETIF_F_RXHASH) { + if (features & NETIF_F_RXHASH) + vi->ctrl->rss.hash_types =3D vi->rss_hash_types_supported; + else + vi->ctrl->rss.hash_types =3D VIRTIO_NET_HASH_REPORT_NONE; + + if (!virtnet_commit_rss_command(vi)) + return -EINVAL; + } + return 0; } =20 @@ -3073,6 +3228,8 @@ static bool virtnet_validate_features(struct virtio_d= evice *vdev) "VIRTIO_NET_F_CTRL_VQ") || VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_MQ, "VIRTIO_NET_F_CTRL_VQ") || VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR, + "VIRTIO_NET_F_CTRL_VQ") || + VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_RSS, "VIRTIO_NET_F_CTRL_VQ"))) { return false; } @@ -3113,13 +3270,14 @@ static int virtnet_probe(struct virtio_device *vdev) u16 max_queue_pairs; int mtu; =20 - /* Find if host supports multiqueue virtio_net device */ - err =3D virtio_cread_feature(vdev, VIRTIO_NET_F_MQ, - struct virtio_net_config, - max_virtqueue_pairs, &max_queue_pairs); + /* Find if host supports multiqueue/rss virtio_net device */ + max_queue_pairs =3D 1; + if (virtio_has_feature(vdev, VIRTIO_NET_F_MQ) || virtio_has_feature(vdev,= VIRTIO_NET_F_RSS)) + max_queue_pairs =3D + virtio_cread16(vdev, offsetof(struct virtio_net_config, max_virtque= ue_pairs)); =20 /* We need at least 2 queue's */ - if (err || max_queue_pairs < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN || + if (max_queue_pairs < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN || max_queue_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX || !virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) max_queue_pairs =3D 1; @@ -3207,6 +3365,23 @@ static int virtnet_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) vi->mergeable_rx_bufs =3D true; =20 + if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { + vi->has_rss =3D true; + vi->rss_indir_table_size =3D + virtio_cread16(vdev, offsetof(struct virtio_net_config, + rss_max_indirection_table_length)); + vi->rss_key_size =3D + virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size= )); + + vi->rss_hash_types_supported =3D + virtio_cread32(vdev, offsetof(struct virtio_net_config, supported_ha= sh_types)); + vi->rss_hash_types_supported &=3D + ~(VIRTIO_NET_RSS_HASH_TYPE_IP_EX | + VIRTIO_NET_RSS_HASH_TYPE_TCP_EX | + VIRTIO_NET_RSS_HASH_TYPE_UDP_EX); + + dev->hw_features |=3D NETIF_F_RXHASH; + } if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF) || virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) vi->hdr_len =3D sizeof(struct virtio_net_hdr_mrg_rxbuf); @@ -3275,6 +3450,9 @@ static int virtnet_probe(struct virtio_device *vdev) } } =20 + if (vi->has_rss) + virtnet_init_default_rss(vi); + err =3D register_netdev(dev); if (err) { pr_debug("virtio_net: registering device failed\n"); @@ -3406,7 +3584,8 @@ static struct virtio_device_id id_table[] =3D { VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \ VIRTIO_NET_F_CTRL_MAC_ADDR, \ VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \ - VIRTIO_NET_F_SPEED_DUPLEX, VIRTIO_NET_F_STANDBY + VIRTIO_NET_F_SPEED_DUPLEX, VIRTIO_NET_F_STANDBY, \ + VIRTIO_NET_F_RSS =20 static unsigned int features[] =3D { VIRTNET_FEATURES, --=20 2.34.1 From nobody Sun Jun 28 10:34:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DD37BC433F5 for ; Tue, 8 Feb 2022 18:16:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1384804AbiBHSQB (ORCPT ); Tue, 8 Feb 2022 13:16:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353279AbiBHSPt (ORCPT ); Tue, 8 Feb 2022 13:15:49 -0500 Received: from mail-lj1-x231.google.com (mail-lj1-x231.google.com [IPv6:2a00:1450:4864:20::231]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B80A3C061576 for ; Tue, 8 Feb 2022 10:15:47 -0800 (PST) Received: by mail-lj1-x231.google.com with SMTP id e17so86712ljk.5 for ; Tue, 08 Feb 2022 10:15:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SeDa8/+i+0/WSOJjpKaKDeiKBL8K+DH4jQ8xLEyH/fA=; b=K97B6MHUWpfWgbAU2Rh8UCNhcaxz8QGzNF3GU5IeSq1tYKzT7M7gIgFf/OTnFT5eF2 FHQJhInSqqCilz8Sm3uJHfTSH8REwcWhp+GTLyowJLqv3C1i9k6hXFKQxmSLfYY7ougF fZiC5RUC42rGu4Zpa7Cr0wFIfMimdyspg02ofA3/5wEdoF0oRosKtISY3NZIeIkZy8ex YQgy1HvF/gL/+YMZXWHjRx0oQL6r+ZUfRugNmw0zWxi0hP2MPXsD56tK/CX/JLd1Dq+3 Yz83J+/FnLkt7cTlXHtCW5xhDFywoamNVPCKDhydCRrYWyJqmTYI80TDGriIaSi+yZul GRoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SeDa8/+i+0/WSOJjpKaKDeiKBL8K+DH4jQ8xLEyH/fA=; b=q735wZo1DwlfQEaIXTPCn6RuzvjkJZT61IQVqF1BKKp89vFZG5QbvJmTLaJAGw+fTN r2rkyqbrXEum0e2Lz/3wNi1H2knA3ETZx+DCK31AdFl7lVC6Gvfzxd513p48R6m5i6zE B/QyfJ1cliHaLoS16KYsqLcDG8nXMjK3XpDx2GLr/KK8axv+8365cD5HcVJum/lURul3 UUH+mD70GaOCizlFHtgpImAhp82fD7SE6+qNhFYJEsCYHSdsSwRKvLspYBoPZ+fQD7OB f05FlF7rOUW7sCrAYVUz8tH4XzY+JNWfapC7GQGDGnOI+BXEGquOemPoGAPK+WsIJSuz zAAw== X-Gm-Message-State: AOAM531r5tzZvl5g+10mKg08Z+nOkFzI0m6ffIhsj//tABQfCG2fxQKb B71UlS7hYwAnh2E2eBmZSOMiwQ== X-Google-Smtp-Source: ABdhPJykupL7odp9QVTsrBwCWK4bTleiMiC0985vIJCvmAIJxHvKoMeCRDmQM8LqPuK+Rh7y5sj54Q== X-Received: by 2002:a2e:9bd4:: with SMTP id w20mr3612480ljj.324.1644344146110; Tue, 08 Feb 2022 10:15:46 -0800 (PST) Received: from navi.cosmonova.net.ua ([95.67.24.131]) by smtp.gmail.com with ESMTPSA id p16sm2125082ljc.86.2022.02.08.10.15.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Feb 2022 10:15:45 -0800 (PST) From: Andrew Melnychenko To: netdev@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, jasowang@redhat.com, mst@redhat.com Cc: yan@daynix.com, yuri.benditovich@daynix.com Subject: [PATCH v3 3/4] drivers/net/virtio_net: Added RSS hash report. Date: Tue, 8 Feb 2022 20:15:09 +0200 Message-Id: <20220208181510.787069-4-andrew@daynix.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220208181510.787069-1-andrew@daynix.com> References: <20220208181510.787069-1-andrew@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Added features for RSS hash report. If hash is provided - it sets to skb. Added checks if rss and/or hash are enabled together. Signed-off-by: Andrew Melnychenko --- drivers/net/virtio_net.c | 51 ++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 495aed524e33..543da2fbdd2d 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -227,6 +227,7 @@ struct virtnet_info { =20 /* Host supports rss and/or hash report */ bool has_rss; + bool has_rss_hash_report; u8 rss_key_size; u16 rss_indir_table_size; u32 rss_hash_types_supported; @@ -421,7 +422,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info = *vi, =20 hdr_len =3D vi->hdr_len; if (vi->mergeable_rx_bufs) - hdr_padded_len =3D sizeof(*hdr); + hdr_padded_len =3D hdr_len; else hdr_padded_len =3D sizeof(struct padded_vnet_hdr); =20 @@ -1156,6 +1157,8 @@ static void receive_buf(struct virtnet_info *vi, stru= ct receive_queue *rq, struct net_device *dev =3D vi->dev; struct sk_buff *skb; struct virtio_net_hdr_mrg_rxbuf *hdr; + struct virtio_net_hdr_v1_hash *hdr_hash; + enum pkt_hash_types rss_hash_type; =20 if (unlikely(len < vi->hdr_len + ETH_HLEN)) { pr_debug("%s: short packet %i\n", dev->name, len); @@ -1182,6 +1185,29 @@ static void receive_buf(struct virtnet_info *vi, str= uct receive_queue *rq, return; =20 hdr =3D skb_vnet_hdr(skb); + if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report) { + hdr_hash =3D (struct virtio_net_hdr_v1_hash *)(hdr); + + switch (hdr_hash->hash_report) { + case VIRTIO_NET_HASH_REPORT_TCPv4: + case VIRTIO_NET_HASH_REPORT_UDPv4: + case VIRTIO_NET_HASH_REPORT_TCPv6: + case VIRTIO_NET_HASH_REPORT_UDPv6: + case VIRTIO_NET_HASH_REPORT_TCPv6_EX: + case VIRTIO_NET_HASH_REPORT_UDPv6_EX: + rss_hash_type =3D PKT_HASH_TYPE_L4; + break; + case VIRTIO_NET_HASH_REPORT_IPv4: + case VIRTIO_NET_HASH_REPORT_IPv6: + case VIRTIO_NET_HASH_REPORT_IPv6_EX: + rss_hash_type =3D PKT_HASH_TYPE_L3; + break; + case VIRTIO_NET_HASH_REPORT_NONE: + default: + rss_hash_type =3D PKT_HASH_TYPE_NONE; + } + skb_set_hash(skb, hdr_hash->hash_value, rss_hash_type); + } =20 if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID) skb->ip_summed =3D CHECKSUM_UNNECESSARY; @@ -2232,7 +2258,8 @@ static bool virtnet_commit_rss_command(struct virtnet= _info *vi) sg_set_buf(&sgs[3], vi->ctrl->rss.key, sg_buf_size); =20 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ, - VIRTIO_NET_CTRL_MQ_RSS_CONFIG, sgs)) { + vi->has_rss ? VIRTIO_NET_CTRL_MQ_RSS_CONFIG + : VIRTIO_NET_CTRL_MQ_HASH_CONFIG, sgs)) { dev_warn(&dev->dev, "VIRTIONET issue with committing RSS sgs\n"); return false; } @@ -3230,6 +3257,8 @@ static bool virtnet_validate_features(struct virtio_d= evice *vdev) VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR, "VIRTIO_NET_F_CTRL_VQ") || VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_RSS, + "VIRTIO_NET_F_CTRL_VQ") || + VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_HASH_REPORT, "VIRTIO_NET_F_CTRL_VQ"))) { return false; } @@ -3365,8 +3394,13 @@ static int virtnet_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) vi->mergeable_rx_bufs =3D true; =20 - if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { + if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT)) + vi->has_rss_hash_report =3D true; + + if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) vi->has_rss =3D true; + + if (vi->has_rss || vi->has_rss_hash_report) { vi->rss_indir_table_size =3D virtio_cread16(vdev, offsetof(struct virtio_net_config, rss_max_indirection_table_length)); @@ -3382,8 +3416,11 @@ static int virtnet_probe(struct virtio_device *vdev) =20 dev->hw_features |=3D NETIF_F_RXHASH; } - if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF) || - virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) + + if (vi->has_rss_hash_report) + vi->hdr_len =3D sizeof(struct virtio_net_hdr_v1_hash); + else if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF) || + virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) vi->hdr_len =3D sizeof(struct virtio_net_hdr_mrg_rxbuf); else vi->hdr_len =3D sizeof(struct virtio_net_hdr); @@ -3450,7 +3487,7 @@ static int virtnet_probe(struct virtio_device *vdev) } } =20 - if (vi->has_rss) + if (vi->has_rss || vi->has_rss_hash_report) virtnet_init_default_rss(vi); =20 err =3D register_netdev(dev); @@ -3585,7 +3622,7 @@ static struct virtio_device_id id_table[] =3D { VIRTIO_NET_F_CTRL_MAC_ADDR, \ VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \ VIRTIO_NET_F_SPEED_DUPLEX, VIRTIO_NET_F_STANDBY, \ - VIRTIO_NET_F_RSS + VIRTIO_NET_F_RSS, VIRTIO_NET_F_HASH_REPORT =20 static unsigned int features[] =3D { VIRTNET_FEATURES, --=20 2.34.1 From nobody Sun Jun 28 10:34:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28DDBC433F5 for ; Tue, 8 Feb 2022 18:16:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1384817AbiBHSQF (ORCPT ); Tue, 8 Feb 2022 13:16:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1384723AbiBHSPu (ORCPT ); Tue, 8 Feb 2022 13:15:50 -0500 Received: from mail-lj1-x22b.google.com (mail-lj1-x22b.google.com [IPv6:2a00:1450:4864:20::22b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E755EC06157B for ; Tue, 8 Feb 2022 10:15:48 -0800 (PST) Received: by mail-lj1-x22b.google.com with SMTP id k18so30554lji.12 for ; Tue, 08 Feb 2022 10:15:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+37NPEyVD8WMNDuKr+VUpr12blnHBAWksfV9NWdACbw=; b=zwnHJGSXcjyPdbLznzXmWvMRa3UWKL5LIZ5Hgobr6ylhWMO+pojrCi+9nahhBazm7b CHoqYDO5Nn7LxS9eTBQOyfaCRNDzgOEOePJOFMsh/qWI/hLz736UCQw1LO//91wQoWq+ 4wQ+7jZJWFFZvyJz6a/2pu9MJcBmuoXpdu8Y2KMpuz/IThti9omsfsMlR3INKZmKwr5X xcS1BhLqtfXCzrSE2y83j3awjh33Rxm2yOUu9hWzkW9WKy4AhugE/W8yyQAWGGEkCYwu o0vMGodNEtf87qq6mvKgzkQaRnihng8EU7H6BQhPJEebfLWlOgKuQB4aHrbmAAD7vLQP fhLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+37NPEyVD8WMNDuKr+VUpr12blnHBAWksfV9NWdACbw=; b=lSZtKvBxblaaBdeFHVcIV4sFYbEpFdRhJD1XYf1f5gMWesKBsahMMPWPM7fcimf5LJ dWBYXimKwXdXrqFl+qJ6Ax+ccXWocd/MdVmRr61GXxB25EkRqzHXqqvr7TiigtJCI3ul 3pYK/+CKTXaAigmQoYJyNSKumOYyZwK3srmIyhars8W7XydU7LN/MnnQFkZPDBgg/vCs W9bbyG0hnzrGkrxm7qrLtOuv4UgFC8ZNoX2o71BI07H5HqTGVlR5v239j00TAVmL7she aRCzT+pKaUc7uOOb0eMqnT8TBwmg6bmgI3ozN+pvF6tIxAJil/66UxEkSiqxOu9Yvm73 R/Og== X-Gm-Message-State: AOAM532Ujgsd7QXFUcCtC+V/adH/2RchqI5d3Kmtkof/8ic0ji9lvMhO ky7Mo6XGyIDqEA9xZ2YNcyviTzFzeEa5inqd X-Google-Smtp-Source: ABdhPJzyvVblRx20Nb0+M4lqiiWcQd4FDHTeMZG0p9O+KGIhqGeTVjXci+jjWxMcGrDkXaytMx+gUw== X-Received: by 2002:a2e:a41a:: with SMTP id p26mr3602861ljn.176.1644344147317; Tue, 08 Feb 2022 10:15:47 -0800 (PST) Received: from navi.cosmonova.net.ua ([95.67.24.131]) by smtp.gmail.com with ESMTPSA id p16sm2125082ljc.86.2022.02.08.10.15.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Feb 2022 10:15:46 -0800 (PST) From: Andrew Melnychenko To: netdev@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, jasowang@redhat.com, mst@redhat.com Cc: yan@daynix.com, yuri.benditovich@daynix.com Subject: [PATCH v3 4/4] drivers/net/virtio_net: Added RSS hash report control. Date: Tue, 8 Feb 2022 20:15:10 +0200 Message-Id: <20220208181510.787069-5-andrew@daynix.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220208181510.787069-1-andrew@daynix.com> References: <20220208181510.787069-1-andrew@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Now it's possible to control supported hashflows. Added hashflow set/get callbacks. Also, disabling RXH_IP_SRC/DST for TCP would disable then for UDP. TCP and UDP supports only: ethtool -U eth0 rx-flow-hash tcp4 sd RXH_IP_SRC + RXH_IP_DST ethtool -U eth0 rx-flow-hash tcp4 sdfn RXH_IP_SRC + RXH_IP_DST + RXH_L4_B_0_1 + RXH_L4_B_2_3 Signed-off-by: Andrew Melnychenko --- drivers/net/virtio_net.c | 141 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 543da2fbdd2d..88759d5e693c 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -231,6 +231,7 @@ struct virtnet_info { u8 rss_key_size; u16 rss_indir_table_size; u32 rss_hash_types_supported; + u32 rss_hash_types_saved; =20 /* Has control virtqueue */ bool has_cvq; @@ -2272,6 +2273,7 @@ static void virtnet_init_default_rss(struct virtnet_i= nfo *vi) int i =3D 0; =20 vi->ctrl->rss.hash_types =3D vi->rss_hash_types_supported; + vi->rss_hash_types_saved =3D vi->rss_hash_types_supported; vi->ctrl->rss.indirection_table_mask =3D vi->rss_indir_table_size - 1; vi->ctrl->rss.unclassified_queue =3D 0; =20 @@ -2286,6 +2288,121 @@ static void virtnet_init_default_rss(struct virtnet= _info *vi) netdev_rss_key_fill(vi->ctrl->rss.key, vi->rss_key_size); } =20 +static void virtnet_get_hashflow(const struct virtnet_info *vi, struct eth= tool_rxnfc *info) +{ + info->data =3D 0; + switch (info->flow_type) { + case TCP_V4_FLOW: + if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_TCPv4) { + info->data =3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + } else if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_IPv4) { + info->data =3D RXH_IP_SRC | RXH_IP_DST; + } + break; + case TCP_V6_FLOW: + if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_TCPv6) { + info->data =3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + } else if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_IPv6) { + info->data =3D RXH_IP_SRC | RXH_IP_DST; + } + break; + case UDP_V4_FLOW: + if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_UDPv4) { + info->data =3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + } else if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_IPv4) { + info->data =3D RXH_IP_SRC | RXH_IP_DST; + } + break; + case UDP_V6_FLOW: + if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_UDPv6) { + info->data =3D RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3; + } else if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_IPv6) { + info->data =3D RXH_IP_SRC | RXH_IP_DST; + } + break; + case IPV4_FLOW: + if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_IPv4) + info->data =3D RXH_IP_SRC | RXH_IP_DST; + + break; + case IPV6_FLOW: + if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_IPv6) + info->data =3D RXH_IP_SRC | RXH_IP_DST; + + break; + default: + info->data =3D 0; + break; + } +} + +static bool virtnet_set_hashflow(struct virtnet_info *vi, struct ethtool_r= xnfc *info) +{ + u32 new_hashtypes =3D vi->rss_hash_types_saved; + bool is_disable =3D info->data & RXH_DISCARD; + bool is_l4 =3D info->data =3D=3D (RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 = | RXH_L4_B_2_3); + + /* supports only 'sd', 'sdfn' and 'r' */ + if (!((info->data =3D=3D (RXH_IP_SRC | RXH_IP_DST)) | is_l4 | is_disable)) + return false; + + switch (info->flow_type) { + case TCP_V4_FLOW: + new_hashtypes &=3D ~(VIRTIO_NET_RSS_HASH_TYPE_IPv4 | VIRTIO_NET_RSS_HASH= _TYPE_TCPv4); + if (!is_disable) + new_hashtypes |=3D VIRTIO_NET_RSS_HASH_TYPE_IPv4 + | (is_l4 ? VIRTIO_NET_RSS_HASH_TYPE_TCPv4 : 0); + break; + case UDP_V4_FLOW: + new_hashtypes &=3D ~(VIRTIO_NET_RSS_HASH_TYPE_IPv4 | VIRTIO_NET_RSS_HASH= _TYPE_UDPv4); + if (!is_disable) + new_hashtypes |=3D VIRTIO_NET_RSS_HASH_TYPE_IPv4 + | (is_l4 ? VIRTIO_NET_RSS_HASH_TYPE_UDPv4 : 0); + break; + case IPV4_FLOW: + new_hashtypes &=3D ~VIRTIO_NET_RSS_HASH_TYPE_IPv4; + if (!is_disable) + new_hashtypes =3D VIRTIO_NET_RSS_HASH_TYPE_IPv4; + break; + case TCP_V6_FLOW: + new_hashtypes &=3D ~(VIRTIO_NET_RSS_HASH_TYPE_IPv6 | VIRTIO_NET_RSS_HASH= _TYPE_TCPv6); + if (!is_disable) + new_hashtypes |=3D VIRTIO_NET_RSS_HASH_TYPE_IPv6 + | (is_l4 ? VIRTIO_NET_RSS_HASH_TYPE_TCPv6 : 0); + break; + case UDP_V6_FLOW: + new_hashtypes &=3D ~(VIRTIO_NET_RSS_HASH_TYPE_IPv6 | VIRTIO_NET_RSS_HASH= _TYPE_UDPv6); + if (!is_disable) + new_hashtypes |=3D VIRTIO_NET_RSS_HASH_TYPE_IPv6 + | (is_l4 ? VIRTIO_NET_RSS_HASH_TYPE_UDPv6 : 0); + break; + case IPV6_FLOW: + new_hashtypes &=3D ~VIRTIO_NET_RSS_HASH_TYPE_IPv6; + if (!is_disable) + new_hashtypes =3D VIRTIO_NET_RSS_HASH_TYPE_IPv6; + break; + default: + /* unsupported flow */ + return false; + } + + /* if unsupported hashtype was set */ + if (new_hashtypes !=3D (new_hashtypes & vi->rss_hash_types_supported)) + return false; + + if (new_hashtypes !=3D vi->rss_hash_types_saved) { + vi->rss_hash_types_saved =3D new_hashtypes; + vi->ctrl->rss.hash_types =3D vi->rss_hash_types_saved; + if (vi->dev->features & NETIF_F_RXHASH) + return virtnet_commit_rss_command(vi); + } + + return true; +} =20 static void virtnet_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -2571,6 +2688,27 @@ static int virtnet_get_rxnfc(struct net_device *dev,= struct ethtool_rxnfc *info, switch (info->cmd) { case ETHTOOL_GRXRINGS: info->data =3D vi->curr_queue_pairs; + break; + case ETHTOOL_GRXFH: + virtnet_get_hashflow(vi, info); + break; + default: + rc =3D -EOPNOTSUPP; + } + + return rc; +} + +static int virtnet_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc = *info) +{ + struct virtnet_info *vi =3D netdev_priv(dev); + int rc =3D 0; + + switch (info->cmd) { + case ETHTOOL_SRXFH: + if (!virtnet_set_hashflow(vi, info)) + rc =3D -EINVAL; + break; default: rc =3D -EOPNOTSUPP; @@ -2599,6 +2737,7 @@ static const struct ethtool_ops virtnet_ethtool_ops = =3D { .get_rxfh =3D virtnet_get_rxfh, .set_rxfh =3D virtnet_set_rxfh, .get_rxnfc =3D virtnet_get_rxnfc, + .set_rxnfc =3D virtnet_set_rxnfc, }; =20 static void virtnet_freeze_down(struct virtio_device *vdev) @@ -2853,7 +2992,7 @@ static int virtnet_set_features(struct net_device *de= v, =20 if ((dev->features ^ features) & NETIF_F_RXHASH) { if (features & NETIF_F_RXHASH) - vi->ctrl->rss.hash_types =3D vi->rss_hash_types_supported; + vi->ctrl->rss.hash_types =3D vi->rss_hash_types_saved; else vi->ctrl->rss.hash_types =3D VIRTIO_NET_HASH_REPORT_NONE; =20 --=20 2.34.1