Hi,

On 1/27/25 8:41 AM, Kommula Shiva Shankar wrote:
This patch adds virtio hash report feature, which is
supported in packet queue mode with scalar version

Why only restrict to packed ring? isn't it also compatible with split
ring?


Signed-off-by: Kommula Shiva Shankar <kshan...@marvell.com>
---
  drivers/net/virtio/virtio.h                   |  2 ++
  drivers/net/virtio/virtio_ethdev.c            | 20 ++++++++++++-
  drivers/net/virtio/virtio_ethdev.h            |  1 +
  drivers/net/virtio/virtio_rxtx.c              | 30 +++++++++++++++++++
  .../net/virtio/virtio_user/virtio_user_dev.c  |  1 +
  drivers/net/virtio/virtqueue.h                | 21 +++++++++++++
  6 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio.h b/drivers/net/virtio/virtio.h
index ef5827c5f5..c2a0fd477c 100644
--- a/drivers/net/virtio/virtio.h
+++ b/drivers/net/virtio/virtio.h
@@ -30,6 +30,7 @@
  #define VIRTIO_NET_F_GUEST_ANNOUNCE 21        /* Guest can announce device on 
the network */
  #define VIRTIO_NET_F_MQ               22      /* Device supports Receive Flow 
Steering */
  #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
+#define VIRTIO_NET_F_HASH_REPORT  57    /* Supports hash report */
  #define VIRTIO_NET_F_RSS      60      /* RSS supported */
/*
@@ -187,6 +188,7 @@ struct virtio_hw {
        uint8_t started;
        uint8_t weak_barriers;
        uint8_t vlan_strip;
+       uint8_t has_hash_report;
        bool rx_ol_scatter;
        uint8_t has_tx_offload;
        uint8_t has_rx_offload;
diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index 70d4839def..caacbce57a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1796,7 +1796,9 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t 
req_features)
                eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
/* Setting up rx_header size for the device */
-       if (virtio_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF) ||
+       if (virtio_with_feature(hw, VIRTIO_NET_F_HASH_REPORT))
+               hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_hash_report);
+       else if (virtio_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF) ||
            virtio_with_feature(hw, VIRTIO_F_VERSION_1) ||
            virtio_with_packed_queue(hw))
                hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
@@ -2181,6 +2183,10 @@ virtio_dev_configure(struct rte_eth_dev *dev)
                        (1ULL << VIRTIO_NET_F_GUEST_TSO4) |
                        (1ULL << VIRTIO_NET_F_GUEST_TSO6);
+ if (rx_offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)
+               req_features |=
+                       (1ULL << VIRTIO_NET_F_HASH_REPORT);
+
        if (tx_offloads & (RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
                           RTE_ETH_TX_OFFLOAD_TCP_CKSUM))
                req_features |= (1ULL << VIRTIO_NET_F_CSUM);
@@ -2233,6 +2239,9 @@ virtio_dev_configure(struct rte_eth_dev *dev)
        if (rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
                hw->vlan_strip = 1;
+ if (rx_offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)
+               hw->has_hash_report = 1;
+
        hw->rx_ol_scatter = (rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER);
if ((rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) &&
@@ -2285,6 +2294,12 @@ virtio_dev_configure(struct rte_eth_dev *dev)
                                        "disabled packed ring vectorized rx for 
TCP_LRO enabled");
                                hw->use_vec_rx = 0;
                        }
+
+                       if (rx_offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH) {
+                               PMD_DRV_LOG(INFO,
+                                       "disabled packed ring vectorized rx for 
RSS_HASH enabled");
+                               hw->use_vec_rx = 0;
+                       }
                }
        } else {
                if (virtio_with_feature(hw, VIRTIO_F_IN_ORDER)) {
@@ -2669,6 +2684,9 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
                dev_info->flow_type_rss_offloads = 0;
        }
+ if (host_features & (1ULL << VIRTIO_NET_F_HASH_REPORT))
+               dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
+
        if (host_features & (1ULL << VIRTIO_F_RING_PACKED)) {
                /*
                 * According to 2.7 Packed Virtqueues,
diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index 7be1c9acd0..7aa771fd2b 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -46,6 +46,7 @@
         1u << VIRTIO_NET_F_CSUM           |      \
         1u << VIRTIO_NET_F_HOST_TSO4      |      \
         1u << VIRTIO_NET_F_HOST_TSO6      |      \
+        1ULL << VIRTIO_NET_F_HASH_REPORT  |    \
         1ULL << VIRTIO_NET_F_RSS)
extern const struct eth_dev_ops virtio_user_secondary_eth_dev_ops;
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index b67f063b31..35bd61350c 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -40,6 +40,19 @@
  #define  VIRTIO_DUMP_PACKET(m, len) do { } while (0)
  #endif
+static const uint32_t vhdr_hash_report_to_mbuf_pkt_type[] = {
+       RTE_PTYPE_UNKNOWN,
+       RTE_PTYPE_L3_IPV4,
+       RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP,
+       RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP,
+       RTE_PTYPE_L3_IPV6,
+       RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP,
+       RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP,
+       RTE_PTYPE_L3_IPV6_EXT,
+       RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_TCP,
+       RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_UDP,
+};
+
  void
  vq_ring_free_inorder(struct virtqueue *vq, uint16_t desc_idx, uint16_t num)
  {
@@ -901,6 +914,16 @@ virtio_discard_rxbuf_inorder(struct virtqueue *vq, struct 
rte_mbuf *m)
        }
  }
+static inline void
+virtio_rx_update_hash_report(struct rte_mbuf *m, struct 
virtio_net_hdr_hash_report *hdr)
+{
+       if (likely(hdr->hash_report)) {
+               m->packet_type = 
vhdr_hash_report_to_mbuf_pkt_type[hdr->hash_report];
+               m->hash.rss = hdr->hash_value;
+               m->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
+       }
+}
+
  /* Optionally fill offload information in structure */
  static inline int
  virtio_rx_offload(struct rte_mbuf *m, struct virtio_net_hdr *hdr)
@@ -1134,6 +1157,9 @@ virtio_recv_pkts_packed(void *rx_queue, struct rte_mbuf 
**rx_pkts,
                hdr = (struct virtio_net_hdr *)((char *)rxm->buf_addr +
                        RTE_PKTMBUF_HEADROOM - hdr_size);
+ if (hw->has_hash_report)
+                       virtio_rx_update_hash_report(rxm,
+                                                   (struct 
virtio_net_hdr_hash_report *)hdr);
                if (hw->vlan_strip)
                        rte_vlan_strip(rxm);
@@ -1617,6 +1643,10 @@ virtio_recv_mergeable_pkts_packed(void *rx_queue,
                if (hw->vlan_strip)
                        rte_vlan_strip(rx_pkts[nb_rx]);
+ if (hw->has_hash_report)
+                       virtio_rx_update_hash_report(rxm,
+                                                   (struct 
virtio_net_hdr_hash_report *)header);
+
                seg_res = seg_num - 1;
/* Merge remaining segments */
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c 
b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 2997d2bd26..187f81b066 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -726,6 +726,7 @@ virtio_user_free_vrings(struct virtio_user_dev *dev)
         1ULL << VIRTIO_F_RING_PACKED             |       \
         1ULL << VIRTIO_F_NOTIFICATION_DATA       |       \
         1ULL << VIRTIO_F_ORDER_PLATFORM        |       \
+        1ULL << VIRTIO_NET_F_HASH_REPORT       |       \
         1ULL << VIRTIO_NET_F_RSS)
int
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 60211a40c9..3b468bd4f4 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -257,6 +257,27 @@ struct virtio_net_hdr_mrg_rxbuf {
        uint16_t num_buffers; /**< Number of merged rx buffers */
  };
+/**
+ * This is the version of the header to use when the HASH_REPORT
+ * feature has been negotiated.
+ */
+struct virtio_net_hdr_hash_report {
+       struct virtio_net_hdr_mrg_rxbuf hdr;
+       uint32_t hash_value;
+#define VIRTIO_NET_HASH_REPORT_NONE    0
+#define VIRTIO_NET_HASH_REPORT_IPV4    1
+#define VIRTIO_NET_HASH_REPORT_TCPV4   2
+#define VIRTIO_NET_HASH_REPORT_UDPV4   3
+#define VIRTIO_NET_HASH_REPORT_IPV6    4
+#define VIRTIO_NET_HASH_REPORT_TCPV6   5
+#define VIRTIO_NET_HASH_REPORT_UDPV6   6
+#define VIRTIO_NET_HASH_REPORT_IPV6_EX 7
+#define VIRTIO_NET_HASH_REPORT_TCPV6_EX        8
+#define VIRTIO_NET_HASH_REPORT_UDPV6_EX        9
+       uint16_t hash_report;
+       uint16_t pad_reserved;
+};
+
  /* Region reserved to allow for transmit header and indirect ring */
  #define VIRTIO_MAX_TX_INDIRECT 8
  struct virtio_tx_region {

Reply via email to