From patchwork Sun Oct 31 04:59:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Melnichenko X-Patchwork-Id: 12594937 X-Patchwork-Delegate: kuba@kernel.org 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA583C43219 for ; Sun, 31 Oct 2021 05:00:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C11A361027 for ; Sun, 31 Oct 2021 05:00:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229790AbhJaFCm (ORCPT ); Sun, 31 Oct 2021 01:02:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40760 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229658AbhJaFCl (ORCPT ); Sun, 31 Oct 2021 01:02:41 -0400 Received: from mail-lj1-x236.google.com (mail-lj1-x236.google.com [IPv6:2a00:1450:4864:20::236]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08549C061764 for ; Sat, 30 Oct 2021 22:00:10 -0700 (PDT) Received: by mail-lj1-x236.google.com with SMTP id u5so23766611ljo.8 for ; Sat, 30 Oct 2021 22:00:09 -0700 (PDT) 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=RHYmDW4cj0b+fRWrxsqrvdCtE0TQdE4s+Q6FmaiNSFo=; b=jGdm0HMDHcggaMA20etNZfrVF20o5nK2DA3HYz/PNoVCj39osaITLJy3tn+/SNXhMW lJjnN10zEDklxTMLl3ShHUYptdNCmcR0WCKA59aDM+H+p19MjjQPpCQjsak3RK6Cuaya BEqED0slWnrYBzQa43SUW7PaxpVT5OUoJnKlNj1hXlm1Lc1BJvJr8EF0W4/ssZaTaKRu DDlyEHNKxs7x3ks2OdqsSR0hYigzzQM7QXe4keUt4hhm3bcyNBWUALAlqKQD1cGTWaGQ LJ2dNTyZmTBsWGA8p63AId0hadl0ddQruU0fRm5SA4/gYwMzmR2lADl5I8+ZtakJ21Yv hLDw== 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=RHYmDW4cj0b+fRWrxsqrvdCtE0TQdE4s+Q6FmaiNSFo=; b=tHqhBTovfYorbC6w7hgIkO23uhxflagqL2JzGl/xmPRLEy+Y0oDrvTjeE1z5nuF/yw VCliftbyEHp1cBEnop5ncYK0YPTxC7DR7eGygsyT8+UHk8w+3gSpbeLG0ld0P6luRI3L 02J5B6FY1a1dtWHaBYn/MqUKrB5P0B6XIn/IzChZgHNk6FVgbi9UnLXZg1+aOVDR8gC6 z32KIDuAcxS97VOeqBUnxZ0smUPVk317uCOLpyJ+FV43euHKpMewu72zgklBfKobHIS6 s05sC6mSUjmlKaf76K76xroVbQBgyywcFLlXBzk3hf1NJEs/a9uCeTXQJeNSEnH5fe3K Z4gw== X-Gm-Message-State: AOAM532gNR5Iy7FP6HMInH4bwEuvQLy3E24u17rB2g9ncTuf6XhDTTM9 PDqIXfsu+4brltZ6WaNz1OHQ9w== X-Google-Smtp-Source: ABdhPJy51ImB5QnAwuNncoRDWpRUz75eZpfxmMKHik9fgjLWnlVke1HtCOQ2gW3SrAxudUpknxNK+g== X-Received: by 2002:a2e:a812:: with SMTP id l18mr22358757ljq.487.1635656408266; Sat, 30 Oct 2021 22:00:08 -0700 (PDT) Received: from navi.cosmonova.net.ua ([95.67.24.131]) by smtp.gmail.com with ESMTPSA id v26sm444766lfo.125.2021.10.30.22.00.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 Oct 2021 22:00:07 -0700 (PDT) From: Andrew Melnychenko To: mst@redhat.com, jasowang@redhat.com, davem@davemloft.net, kuba@kernel.org Cc: virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, yuri.benditovich@daynix.com, yan@daynix.com Subject: [RFC PATCH 1/4] drivers/net/virtio_net: Fixed vheader to use v1. Date: Sun, 31 Oct 2021 06:59:56 +0200 Message-Id: <20211031045959.143001-2-andrew@daynix.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211031045959.143001-1-andrew@daynix.com> References: <20211031045959.143001-1-andrew@daynix.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC 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 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 4ad25a8b0870..b72b21ac8ebd 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -240,13 +240,13 @@ struct virtnet_info { }; 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]; }; static bool is_xdp_frame(void *ptr) @@ -1636,7 +1636,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; struct virtnet_info *vi = sq->vq->vdev->priv; int num_sg; - unsigned hdr_len = vi->hdr_len; + unsigned int hdr_len = vi->hdr_len; bool can_push; pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest); From patchwork Sun Oct 31 04:59:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Melnichenko X-Patchwork-Id: 12594939 X-Patchwork-Delegate: kuba@kernel.org 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ED26EC43217 for ; Sun, 31 Oct 2021 05:00:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D1C3D60EB4 for ; Sun, 31 Oct 2021 05:00:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229839AbhJaFCn (ORCPT ); Sun, 31 Oct 2021 01:02:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40768 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229754AbhJaFCm (ORCPT ); Sun, 31 Oct 2021 01:02:42 -0400 Received: from mail-lf1-x12f.google.com (mail-lf1-x12f.google.com [IPv6:2a00:1450:4864:20::12f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4AC2C061714 for ; Sat, 30 Oct 2021 22:00:10 -0700 (PDT) Received: by mail-lf1-x12f.google.com with SMTP id j2so29647844lfg.3 for ; Sat, 30 Oct 2021 22:00:10 -0700 (PDT) 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=Ac2A+saDFSrL4WFPXx7obgKV7OBZXWGHHh/Jb1Knu3A=; b=XgTo86nFEDxuYlBHZ8Ex/lUcNqT+IBUDagTX/h05JsJRbDmf/VD0AxXwlctC8yY7z8 chpmci1SemrnUVfl5+TYJ0CSxhwqpS9LlVCL+GvnmyYIwUULAU+7Zad2Dmug2kbr3v4k z9aciBwNy7leyYcEexhVMZ5SwmfQRPV4YIR92ggSy5wOR2b/GPr886GWNQpHreb42WLc 22snkjhagk+eVZ+Q+HnukV/oBhOEHtN1qd50nZWbc+VmTMVcaHMkGc8kpw0kfU/junUL 0fB0ODvHK1NRvN+f+yOJ2R3iUgChJ+H7tx+wAZ8vHtp0oa7haGhsO5wajRozLRr1u0id zDZA== 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=Ac2A+saDFSrL4WFPXx7obgKV7OBZXWGHHh/Jb1Knu3A=; b=hBSLcawxm6MvEKQc4MulwJR+OUxkwagqB5xF64sqqNYOOX+eNimTIXZEXzy3cxksTC DeSqtiDBJqIRLePIFYgTqEoo5x1LoZIWm51WIUKon4EmrjG0p0xnRhgx7T/PJpWL2Bdq pPR5Y+UNSrEgG8wrjilKmI3dxuiUVmOyJeapZRocvSpU6QfrpJnC0HDqUUcfDoCB1b8z fi/e/F3SB7MQjxGf5NEOw2589wIKQ9cui1f6j2Gqvz0AasszR9E05DTfDxFVM0VrcWG5 rrRO2/O8ZXkH6VUxynp5BfDKiACn+3XtkAGRQooxqvSFIGoMaZj/0Qb0aBgqNRQDQh2i BGgg== X-Gm-Message-State: AOAM533gGfKnSXwQnSy/2shy+HKqOCoYvhSql7C+TUU86ZGMTN+0CDcU NPXG8Jc7Fy50jygcqsUIteQuTQ== X-Google-Smtp-Source: ABdhPJz2f0KObqWRUWYzUB5tvEZYrjAQO7kPeBXmXhuNvmt861oIX1XGH/g2l+H77FteOVLvylsvzQ== X-Received: by 2002:a05:6512:1102:: with SMTP id l2mr20307442lfg.181.1635656409250; Sat, 30 Oct 2021 22:00:09 -0700 (PDT) Received: from navi.cosmonova.net.ua ([95.67.24.131]) by smtp.gmail.com with ESMTPSA id v26sm444766lfo.125.2021.10.30.22.00.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 Oct 2021 22:00:08 -0700 (PDT) From: Andrew Melnychenko To: mst@redhat.com, jasowang@redhat.com, davem@davemloft.net, kuba@kernel.org Cc: virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, yuri.benditovich@daynix.com, yan@daynix.com Subject: [RFC PATCH 2/4] drivers/net/virtio_net: Changed mergeable buffer length calculation. Date: Sun, 31 Oct 2021 06:59:57 +0200 Message-Id: <20211031045959.143001-3-andrew@daynix.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211031045959.143001-1-andrew@daynix.com> References: <20211031045959.143001-1-andrew@daynix.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Now minimal virtual header length is may include the entire v1 header if the hash report were populated. Signed-off-by: Andrew Melnychenko --- drivers/net/virtio_net.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b72b21ac8ebd..abca2e93355d 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -393,7 +393,9 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, hdr_p = p; hdr_len = vi->hdr_len; - if (vi->mergeable_rx_bufs) + if (vi->has_rss_hash_report) + hdr_padded_len = sizeof(struct virtio_net_hdr_v1_hash); + else if (vi->mergeable_rx_bufs) hdr_padded_len = sizeof(*hdr); else hdr_padded_len = sizeof(struct padded_vnet_hdr); @@ -1252,7 +1254,7 @@ static unsigned int get_mergeable_buf_len(struct receive_queue *rq, struct ewma_pkt_len *avg_pkt_len, unsigned int room) { - const size_t hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf); + const size_t hdr_len = ((struct virtnet_info *)(rq->vq->vdev->priv))->hdr_len; unsigned int len; if (room) @@ -2817,7 +2819,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 = sizeof(struct virtio_net_hdr_mrg_rxbuf); + const unsigned int hdr_len = vi->hdr_len; unsigned int rq_size = virtqueue_get_vring_size(vq); unsigned int packet_len = vi->big_packets ? IP_MAX_MTU : vi->dev->max_mtu; unsigned int buf_len = hdr_len + ETH_HLEN + VLAN_HLEN + packet_len; From patchwork Sun Oct 31 04:59:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Melnichenko X-Patchwork-Id: 12594941 X-Patchwork-Delegate: kuba@kernel.org 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF160C4167B for ; Sun, 31 Oct 2021 05:00:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E312861027 for ; Sun, 31 Oct 2021 05:00:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229939AbhJaFCo (ORCPT ); Sun, 31 Oct 2021 01:02:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40774 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229822AbhJaFCn (ORCPT ); Sun, 31 Oct 2021 01:02:43 -0400 Received: from mail-lj1-x235.google.com (mail-lj1-x235.google.com [IPv6:2a00:1450:4864:20::235]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EDD81C061714 for ; Sat, 30 Oct 2021 22:00:11 -0700 (PDT) Received: by mail-lj1-x235.google.com with SMTP id e2so23722915ljg.13 for ; Sat, 30 Oct 2021 22:00:11 -0700 (PDT) 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=tGK7LATgFTw4kpbrpdJ1pTsP0h4JUZGAbh2LWIq104Y=; b=bdHNYxy6dZ2DBn7T+VRWwS4gyUwBIji0NgmkyTNYug7fl0RG0l4vRVTnow+jMQmnxy Ef3t6dEAGCg/d02Jmnr4dj4D5kbGSkfErH1bpx5lhV2HXeQagTYt0XvHWG4Cf175fwiO ZPNknl1Nc+wyKRoi6JzxuXgxd9SfDrzUsO/6XX7g8Y0EXoXX9w2KZUgxzOurqgmO0AzQ HhWzRraLpaqybA1JG+qCxPfrA6Ee5NUJf5TZ1UDJZo693yy3KW2Hv0BjACV6GcHG98HC BTUcC8Eqk4npl96GriVXPMsVSI0I999sOE2siE9w1HpGRgAKQB6tIt1HUkoXM+EvLJX8 0Blg== 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=tGK7LATgFTw4kpbrpdJ1pTsP0h4JUZGAbh2LWIq104Y=; b=CLKCm6F2j+O9eq4icipPaN0pY9s96WZlhySbRV1xUNk0QnE//hzhtMwjXnEltRsIVZ z7KohQos+yiMb6wJmdwB7dqMBe5ycq18ic3/A3CPtP061VRpTT7INQoVSFFbUkUH5y1x 9sNHaLEd5/fxSI07L4kJnx15R5FOYbSDR7xMvSR8M7AJpczvUrRLS5ss4V9cHEn2NTK8 1EdN/5DAgeo/guLqRIflOpAuhpfeN9gvuBjAmWki0GE7QDFgcEeF8hsb6WvUBLGFy0Uu ynDJs53RLZU4TNM9CU7luKV06g3oiiEPbNgfu+DSCpX6gi3uD2J66LJskYspAZp05X1W i3ew== X-Gm-Message-State: AOAM531iu7FuZs4oBGkPVr8K1IsWWOGcy0omlL3c4ulmFYEMCUK1GLUm jd0ZLTlB/bMoncg9dM5huoGEagyk5JZs7sOE X-Google-Smtp-Source: ABdhPJwB2/RYg8frSkDWH307Xvdqa2+vytLCD+TDmt5f1UWkMzY4FEo24d8g9em68v62mnFVAQJulw== X-Received: by 2002:a2e:1613:: with SMTP id w19mr9281646ljd.497.1635656410314; Sat, 30 Oct 2021 22:00:10 -0700 (PDT) Received: from navi.cosmonova.net.ua ([95.67.24.131]) by smtp.gmail.com with ESMTPSA id v26sm444766lfo.125.2021.10.30.22.00.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 Oct 2021 22:00:09 -0700 (PDT) From: Andrew Melnychenko To: mst@redhat.com, jasowang@redhat.com, davem@davemloft.net, kuba@kernel.org Cc: virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, yuri.benditovich@daynix.com, yan@daynix.com Subject: [RFC PATCH 3/4] drivers/net/virtio_net: Added basic RSS support. Date: Sun, 31 Oct 2021 06:59:58 +0200 Message-Id: <20211031045959.143001-4-andrew@daynix.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211031045959.143001-1-andrew@daynix.com> References: <20211031045959.143001-1-andrew@daynix.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Added features for RSS and RSS hash report. Added initialization, RXHASH feature and ethtool ops. By default RSS/RXHASH is disabled. Added ethtools ops to set key and indirection table. Signed-off-by: Andrew Melnychenko --- drivers/net/virtio_net.c | 232 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 223 insertions(+), 9 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index abca2e93355d..cff7340f40bb 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -167,6 +167,28 @@ struct receive_queue { struct xdp_rxq_info xdp_rxq; }; +/* This structure can contain rss message with maximum settings for indirection table and keysize + * Note, that default structure that describes RSS configuration virtio_net_rss_config + * contains same info but can't handle table values. + * In any case, structure would be passed to virtio hw through sg_buf split 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 { + struct { + __le32 hash_types; + __le16 indirection_table_mask; + __le16 unclassified_queue; + } __packed table_info; + u16 indirection_table[VIRTIO_NET_RSS_MAX_TABLE_LEN]; + struct { + u16 max_tx_vq; /* queues */ + u8 hash_key_length; + } __packed key_info; + 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; @@ -176,6 +198,7 @@ struct control_buf { u8 allmulti; __virtio16 vid; __virtio64 offloads; + struct virtio_net_ctrl_rss rss; }; struct virtnet_info { @@ -204,6 +227,12 @@ struct virtnet_info { /* Host will merge rx buffers for big packets (shake it! shake it!) */ bool mergeable_rx_bufs; + /* Host supports rss and/or hash report */ + bool has_rss; + bool has_rss_hash_report; + u8 rss_key_size; + u16 rss_indir_table_size; + /* Has control virtqueue */ bool has_cvq; @@ -1119,6 +1148,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, struct net_device *dev = 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; if (unlikely(len < vi->hdr_len + ETH_HLEN)) { pr_debug("%s: short packet %i\n", dev->name, len); @@ -1145,6 +1176,29 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, return; hdr = skb_vnet_hdr(skb); + if (vi->has_rss_hash_report && (dev->features & NETIF_F_RXHASH)) { + hdr_hash = (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 = 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 = PKT_HASH_TYPE_L3; + break; + case VIRTIO_NET_HASH_REPORT_NONE: + default: + rss_hash_type = PKT_HASH_TYPE_NONE; + } + skb_set_hash(skb, hdr_hash->hash_value, rss_hash_type); + } if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID) skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2167,6 +2221,57 @@ static void virtnet_get_ringparam(struct net_device *dev, ring->tx_pending = ring->tx_max_pending; } +static bool virtnet_commit_rss_command(struct virtnet_info *vi) +{ + struct net_device *dev = vi->dev; + struct scatterlist sgs[4]; + unsigned int sg_buf_size; + + /* prepare sgs */ + sg_init_table(sgs, 4); + + sg_buf_size = sizeof(vi->ctrl->rss.table_info); + sg_set_buf(&sgs[0], &vi->ctrl->rss.table_info, sg_buf_size); + + sg_buf_size = sizeof(uint16_t) * vi->rss_indir_table_size; + sg_set_buf(&sgs[1], vi->ctrl->rss.indirection_table, sg_buf_size); + + sg_buf_size = sizeof(vi->ctrl->rss.key_info); + sg_set_buf(&sgs[2], &vi->ctrl->rss.key_info, sg_buf_size); + + sg_buf_size = 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, + 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; + } + return true; +} + +static void virtnet_init_default_rss(struct virtnet_info *vi) +{ + u32 indir_val = 0; + int i = 0; + + vi->ctrl->rss.table_info.hash_types = vi->rss_hash_types_supported; + vi->rss_hash_types_saved = vi->rss_hash_types_supported; + vi->ctrl->rss.table_info.indirection_table_mask = vi->rss_indir_table_size - 1; + vi->ctrl->rss.table_info.unclassified_queue = 0; + + for (; i < vi->rss_indir_table_size; ++i) { + indir_val = ethtool_rxfh_indir_default(i, vi->max_queue_pairs); + vi->ctrl->rss.indirection_table[i] = indir_val; + } + + vi->ctrl->rss.key_info.max_tx_vq = vi->curr_queue_pairs; + vi->ctrl->rss.key_info.hash_key_length = vi->rss_key_size; + + netdev_rss_key_fill(vi->ctrl->rss.key, vi->rss_key_size); +} + static void virtnet_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -2395,6 +2500,71 @@ static void virtnet_update_settings(struct virtnet_info *vi) vi->duplex = duplex; } +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, u8 *hfunc) +{ + struct virtnet_info *vi = netdev_priv(dev); + int i; + + if (indir) { + for (i = 0; i < vi->rss_indir_table_size; ++i) + indir[i] = vi->ctrl->rss.indirection_table[i]; + } + + if (key) + memcpy(key, vi->ctrl->rss.key, vi->rss_key_size); + + if (hfunc) + *hfunc = ETH_RSS_HASH_TOP; + + return 0; +} + +static int virtnet_set_rxfh(struct net_device *dev, const u32 *indir, const u8 *key, const u8 hfunc) +{ + struct virtnet_info *vi = netdev_priv(dev); + int i; + + if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; + + if (indir) { + for (i = 0; i < vi->rss_indir_table_size; ++i) + vi->ctrl->rss.indirection_table[i] = 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 = netdev_priv(dev); + int rc = 0; + + switch (info->cmd) { + case ETHTOOL_GRXRINGS: + info->data = vi->curr_queue_pairs; + break; + default: + rc = -EOPNOTSUPP; + } + + return rc; +} + static const struct ethtool_ops virtnet_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_MAX_FRAMES, .get_drvinfo = virtnet_get_drvinfo, @@ -2410,6 +2580,11 @@ static const struct ethtool_ops virtnet_ethtool_ops = { .set_link_ksettings = virtnet_set_link_ksettings, .set_coalesce = virtnet_set_coalesce, .get_coalesce = virtnet_get_coalesce, + .get_rxfh_key_size = virtnet_get_rxfh_key_size, + .get_rxfh_indir_size = virtnet_get_rxfh_indir_size, + .get_rxfh = virtnet_get_rxfh, + .set_rxfh = virtnet_set_rxfh, + .get_rxnfc = virtnet_get_rxnfc, }; static void virtnet_freeze_down(struct virtio_device *vdev) @@ -3040,7 +3215,10 @@ static bool virtnet_validate_features(struct virtio_device *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"))) { + "VIRTIO_NET_F_CTRL_VQ") || + VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_RSS, "VIRTIO_NET_F_RSS") || + VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_HASH_REPORT, + "VIRTIO_NET_F_HASH_REPORT"))) { return false; } @@ -3080,13 +3258,14 @@ static int virtnet_probe(struct virtio_device *vdev) u16 max_queue_pairs; int mtu; - /* Find if host supports multiqueue virtio_net device */ - err = 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 = 0; + if (virtio_has_feature(vdev, VIRTIO_NET_F_MQ) || virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) + max_queue_pairs = + virtio_cread16(vdev, offsetof(struct virtio_net_config, max_virtqueue_pairs)); /* 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 = 1; @@ -3170,8 +3349,36 @@ static int virtnet_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) vi->mergeable_rx_bufs = true; - if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF) || - virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) + if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT)) { + vi->has_rss_hash_report = true; + vi->rss_indir_table_size = 1; + vi->rss_key_size = VIRTIO_NET_RSS_MAX_KEY_SIZE; + } + + if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { + vi->has_rss = true; + vi->rss_indir_table_size = + virtio_cread16(vdev, offsetof(struct virtio_net_config, + rss_max_indirection_table_length)); + vi->rss_key_size = + virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size)); + } + + if (vi->has_rss || vi->has_rss_hash_report) { + vi->rss_hash_types_supported = + virtio_cread32(vdev, offsetof(struct virtio_net_config, supported_hash_types)); + vi->rss_hash_types_supported &= + ~(VIRTIO_NET_RSS_HASH_TYPE_IP_EX | + VIRTIO_NET_RSS_HASH_TYPE_TCP_EX | + VIRTIO_NET_RSS_HASH_TYPE_UDP_EX); + + dev->hw_features |= NETIF_F_RXHASH; + } + + if (vi->has_rss_hash_report) + vi->hdr_len = 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 = sizeof(struct virtio_net_hdr_mrg_rxbuf); else vi->hdr_len = sizeof(struct virtio_net_hdr); @@ -3238,6 +3445,12 @@ static int virtnet_probe(struct virtio_device *vdev) } } + if (vi->has_rss || vi->has_rss_hash_report) { + rtnl_lock(); + virtnet_init_default_rss(vi); + rtnl_unlock(); + } + err = register_netdev(dev); if (err) { pr_debug("virtio_net: registering device failed\n"); @@ -3369,7 +3582,8 @@ static struct virtio_device_id id_table[] = { 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, VIRTIO_NET_F_HASH_REPORT static unsigned int features[] = { VIRTNET_FEATURES, From patchwork Sun Oct 31 04:59:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Melnichenko X-Patchwork-Id: 12594943 X-Patchwork-Delegate: kuba@kernel.org 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 365D4C4167D for ; Sun, 31 Oct 2021 05:00:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2C4DA60EB4 for ; Sun, 31 Oct 2021 05:00:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230121AbhJaFCs (ORCPT ); Sun, 31 Oct 2021 01:02:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229853AbhJaFCo (ORCPT ); Sun, 31 Oct 2021 01:02:44 -0400 Received: from mail-lf1-x136.google.com (mail-lf1-x136.google.com [IPv6:2a00:1450:4864:20::136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 01B6DC061570 for ; Sat, 30 Oct 2021 22:00:13 -0700 (PDT) Received: by mail-lf1-x136.google.com with SMTP id bu18so12471153lfb.0 for ; Sat, 30 Oct 2021 22:00:12 -0700 (PDT) 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=P85tINO6/x7BoGgJyTZxyTXKyP4RCHrmV1AQKxfeWJE=; b=K3GsKwdH/8LPW8YvS2ThbBMjgIpc/wfSPG9So9Q4zUu0FU+hfJJOhK1NNbsVHmyi5o caJNoRHkf0TmBl69GASb4UQWBvcpV7xjQUuB00m0dXNn20DIofK3IlhAFFsM9wmRbgjn sox3xNvSnqdRk4/O2/EGNoAbRJwaHII35SDF59vigu8C7LPQOuRf6v9FA9itxOnH77IA /lp3dabdM/IGyrPUqISmTCkDUPA6Yamg/SFwShMuovNA4tsx7abmIYZ9NNNyhvAnSLRu d3w0oPC7G2eIa8Q83Ka9jXzpwOR/QCB0tQoEhmuO88sNcn2axbHUb6z4y32V5s2KSEgn WnZg== 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=P85tINO6/x7BoGgJyTZxyTXKyP4RCHrmV1AQKxfeWJE=; b=aLcSfjbsZH15jgwbT/f/LNjdJC3oQzBKRajbtABSTlCuxbFyIx9SxupoWI+F+T9yVA y3P+0pUAh3ZZfwWB0chD3yo4Ek4BJ1LmiuzhTpcnBD14ZP7FS4WN/NYawhoi/Am5gwYY hAaG+ccbeL2vWkGJgL0dAd9mCk+syKRhMe+Zqracr3bUMrQ9hlhDALMWgvaxWIeaEk3A xGj84sqnD2uOo2jwXXyZHdLJ/FxLhseTF09pJLEV/NWJ+KgxYvzNMKfA8CAOeGjWQZOQ azE0GHM9TDCKYzmLKJZ75MFMsN+RoZJLMJeyWwB295apYlKNdEQexzMUHn3oTXh3VsvW FhJw== X-Gm-Message-State: AOAM530wd3Zvn7MQdmLP83LdP4jp791sxbAjtxTUBAY42kQ0JYXjRAk4 9rgCqsrIzMnk83YSNZrYuwQ6XA== X-Google-Smtp-Source: ABdhPJy4OWZQTeD5aF2yM3mtFrNa3B26deIualH1okDZv1ZHqVGOWFX7pGvlZQuveOHqVFaEGSlQhA== X-Received: by 2002:a05:6512:31d2:: with SMTP id j18mr197221lfe.229.1635656411408; Sat, 30 Oct 2021 22:00:11 -0700 (PDT) Received: from navi.cosmonova.net.ua ([95.67.24.131]) by smtp.gmail.com with ESMTPSA id v26sm444766lfo.125.2021.10.30.22.00.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 Oct 2021 22:00:11 -0700 (PDT) From: Andrew Melnychenko To: mst@redhat.com, jasowang@redhat.com, davem@davemloft.net, kuba@kernel.org Cc: virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, yuri.benditovich@daynix.com, yan@daynix.com Subject: [RFC PATCH 4/4] drivers/net/virtio_net: Added RSS hash report control. Date: Sun, 31 Oct 2021 06:59:59 +0200 Message-Id: <20211031045959.143001-5-andrew@daynix.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211031045959.143001-1-andrew@daynix.com> References: <20211031045959.143001-1-andrew@daynix.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Added set_hash for skb. Also added hashflow set/get callbacks. Virtio RSS "IPv6 extensions" hashes disabled. 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 | 159 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index cff7340f40bb..b1ed373d942b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -232,6 +232,8 @@ struct virtnet_info { bool has_rss_hash_report; u8 rss_key_size; u16 rss_indir_table_size; + u32 rss_hash_types_supported; + u32 rss_hash_types_saved; /* Has control virtqueue */ bool has_cvq; @@ -2272,6 +2274,131 @@ static void virtnet_init_default_rss(struct virtnet_info *vi) netdev_rss_key_fill(vi->ctrl->rss.key, vi->rss_key_size); } +static void virtnet_get_hashflow(const struct virtnet_info *vi, struct ethtool_rxnfc *info) +{ + info->data = 0; + switch (info->flow_type) { + case TCP_V4_FLOW: + if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_TCPv4) { + info->data = 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 = 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 = 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 = 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 = 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 = 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 = 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 = RXH_IP_SRC | RXH_IP_DST; + } + break; + case IPV4_FLOW: + if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_IPv4) + info->data = RXH_IP_SRC | RXH_IP_DST; + + break; + case IPV6_FLOW: + if (vi->rss_hash_types_saved & VIRTIO_NET_RSS_HASH_TYPE_IPv4) + info->data = RXH_IP_SRC | RXH_IP_DST; + + break; + default: + info->data = 0; + break; + } +} + +static bool virtnet_set_hashflow(struct virtnet_info *vi, struct ethtool_rxnfc *info) +{ + u64 is_iphash = info->data & (RXH_IP_SRC | RXH_IP_DST); + u64 is_porthash = info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3); + u32 new_hashtypes = vi->rss_hash_types_saved; + + if ((is_iphash && (is_iphash != (RXH_IP_SRC | RXH_IP_DST))) || + (is_porthash && (is_porthash != (RXH_L4_B_0_1 | RXH_L4_B_2_3)))) { + return false; + } + + if (!is_iphash && is_porthash) + return false; + + switch (info->flow_type) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + case IPV4_FLOW: + new_hashtypes &= ~VIRTIO_NET_RSS_HASH_TYPE_IPv4; + if (is_iphash) + new_hashtypes |= VIRTIO_NET_RSS_HASH_TYPE_IPv4; + + break; + case TCP_V6_FLOW: + case UDP_V6_FLOW: + case IPV6_FLOW: + new_hashtypes &= ~VIRTIO_NET_RSS_HASH_TYPE_IPv6; + if (is_iphash) + new_hashtypes |= VIRTIO_NET_RSS_HASH_TYPE_IPv6; + + break; + default: + break; + } + + switch (info->flow_type) { + case TCP_V4_FLOW: + new_hashtypes &= ~VIRTIO_NET_RSS_HASH_TYPE_TCPv4; + if (is_porthash) + new_hashtypes |= VIRTIO_NET_RSS_HASH_TYPE_TCPv4; + + break; + case UDP_V4_FLOW: + new_hashtypes &= ~VIRTIO_NET_RSS_HASH_TYPE_UDPv4; + if (is_porthash) + new_hashtypes |= VIRTIO_NET_RSS_HASH_TYPE_UDPv4; + + break; + case TCP_V6_FLOW: + new_hashtypes &= ~VIRTIO_NET_RSS_HASH_TYPE_TCPv6; + if (is_porthash) + new_hashtypes |= VIRTIO_NET_RSS_HASH_TYPE_TCPv6; + + break; + case UDP_V6_FLOW: + new_hashtypes &= ~VIRTIO_NET_RSS_HASH_TYPE_UDPv6; + if (is_porthash) + new_hashtypes |= VIRTIO_NET_RSS_HASH_TYPE_UDPv6; + + break; + default: + break; + } + + if (new_hashtypes != vi->rss_hash_types_saved) { + vi->rss_hash_types_saved = new_hashtypes; + vi->ctrl->rss.table_info.hash_types = vi->rss_hash_types_saved; + if (vi->dev->features & NETIF_F_RXHASH) + return virtnet_commit_rss_command(vi); + } + + return true; +} static void virtnet_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -2557,6 +2684,27 @@ static int virtnet_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, switch (info->cmd) { case ETHTOOL_GRXRINGS: info->data = vi->curr_queue_pairs; + break; + case ETHTOOL_GRXFH: + virtnet_get_hashflow(vi, info); + break; + default: + rc = -EOPNOTSUPP; + } + + return rc; +} + +static int virtnet_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info) +{ + struct virtnet_info *vi = netdev_priv(dev); + int rc = 0; + + switch (info->cmd) { + case ETHTOOL_SRXFH: + if (!virtnet_set_hashflow(vi, info)) + rc = -EINVAL; + break; default: rc = -EOPNOTSUPP; @@ -2585,6 +2733,7 @@ static const struct ethtool_ops virtnet_ethtool_ops = { .get_rxfh = virtnet_get_rxfh, .set_rxfh = virtnet_set_rxfh, .get_rxnfc = virtnet_get_rxnfc, + .set_rxnfc = virtnet_set_rxnfc, }; static void virtnet_freeze_down(struct virtio_device *vdev) @@ -2837,6 +2986,16 @@ static int virtnet_set_features(struct net_device *dev, vi->guest_offloads = offloads; } + if ((dev->features ^ features) & NETIF_F_RXHASH) { + if (features & NETIF_F_RXHASH) + vi->ctrl->rss.table_info.hash_types = vi->rss_hash_types_saved; + else + vi->ctrl->rss.table_info.hash_types = 0; + + if (!virtnet_commit_rss_command(vi)) + return -EINVAL; + } + return 0; }