Skip to content

Commit

Permalink
virtio_net: add support for hash report
Browse files Browse the repository at this point in the history
when hash report feature bit is exchanged by
host, hash value and hash report is updated
by hardware for every packet sent to host

Change-Id: I6e343af2595d6400db4a95baa852e82c773089c0
Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/dataplane/dpu-offload/+/125316
Tested-by: sa_ip-toolkits-Jenkins <sa_ip-toolkits-jenkins@marvell.com>
Reviewed-by: Rahul Bhansali <rbhansali@marvell.com>
Reviewed-by: Jerin Jacob <jerinj@marvell.com>
  • Loading branch information
Rakesh Kudurumalla authored and jerinjacobk committed May 28, 2024
1 parent 07d2b45 commit 2814e2e
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 11 deletions.
7 changes: 7 additions & 0 deletions lib/virtio/spec/virtio_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,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 /** Set HASH REPORT */
#define VIRTIO_NET_F_RSS 60 /** RSS supported */

/** Virtio RSS hash types */
Expand Down Expand Up @@ -102,6 +103,12 @@ struct virtio_net_hdr {
rte_le16_t csum_offset;
/** Number of buffers of packet */
rte_le16_t num_buffers;
/** hash value of packet */
rte_le32_t hash_value;
/** hash report of packet */
rte_le16_t hash_report;
/** padding reserved of packet */
rte_le16_t padding_reserved;
} __rte_packed;

#define VIRTIO_NET_CTRL_MQ 4
Expand Down
49 changes: 42 additions & 7 deletions lib/virtio_net/virtio_net_enq.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,14 @@ process_mseg_pkts_enq(struct virtio_net_queue *q, struct dao_dma_vchan_state *me
{
uint64_t *sd_desc_base = q->sd_desc_base;
struct rte_mbuf **mbuf_arr = q->mbuf_arr;
uint16_t q_sz = q->q_sz, vhdr_sz;
uint16_t vhdr_sz = q->virtio_hdr_sz;
uint16_t off = *qoff, cnt, moff;
uint32_t slen, dlen, buf_len;
uint64_t d_flags, avail;
struct rte_mbuf *m_next;
uint16_t q_sz = q->q_sz;
uintptr_t hdr;

vhdr_sz = sizeof(struct virtio_net_hdr);

slen = mbuf->pkt_len + vhdr_sz;
if (flags & VIRTIO_NET_ENQ_OFFLOAD_NOFF)
buf_len = slen % nb_enq ? slen/nb_enq + 1 : slen/nb_enq;
Expand Down Expand Up @@ -126,9 +125,11 @@ static __rte_always_inline int
push_enq_data(struct virtio_net_queue *q, struct dao_dma_vchan_state *mem2dev,
struct rte_mbuf **mbufs, uint16_t nb_mbufs, const uint16_t flags)
{
uint64x2_t rss0, rss1, rss2, rss3, d01, d23, rss0213;
uint64x2_t flags01, flags23, len01, len23;
struct rte_mbuf **mbuf_arr = q->mbuf_arr;
uint64_t *mbuf0, *mbuf1, *mbuf2, *mbuf3;
uint16_t virtio_hdr_sz = q->virtio_hdr_sz;
uint64_t *sd_desc_base = q->sd_desc_base;
uint64_t *data0, *data1, *data2, *data3;
uint16_t off = DESC_OFF(q->last_off);
Expand All @@ -142,6 +143,8 @@ push_enq_data(struct virtio_net_queue *q, struct dao_dma_vchan_state *mem2dev,
uint32x4_t ol_flags, xlen, ylen;
uint64x2_t xflags01, xflags23;
uint64x2_t vdst[4], vsrc[4];
uint32x4_t hash_f, hash_rpt;
uint32_t rss_hf = q->rss_hf;
struct virtio_net_hdr *hdr;
uint64x2_t xtmp0, xtmp1;
uint16_t used = 0, i = 0;
Expand All @@ -164,8 +167,8 @@ push_enq_data(struct virtio_net_queue *q, struct dao_dma_vchan_state *mem2dev,
count = nb_mbufs & ~(0x3u);
for (i = 0; i < count; ) {
const uint64x2_t net_hdr_off = {
sizeof(struct virtio_net_hdr),
sizeof(struct virtio_net_hdr)
virtio_hdr_sz,
virtio_hdr_sz
};
const uint64x2_t xflags = {
~(VIRT_PACKED_RING_DESC_F_USED | (RTE_BIT64(32) - 1)),
Expand Down Expand Up @@ -290,6 +293,33 @@ push_enq_data(struct virtio_net_queue *q, struct dao_dma_vchan_state *mem2dev,
*data3 = 0;
}

if (flags & VIRTIO_NET_ENQ_OFFLOAD_HASH_REPORT) {
rss0 = vld1q_u32((uint32_t *)mbuf0 + 11);
rss1 = vld1q_u32((uint32_t *)mbuf1 + 11);
rss2 = vld1q_u32((uint32_t *)mbuf2 + 11);
rss3 = vld1q_u32((uint32_t *)mbuf3 + 11);

d01 = vzip1q_u64(rss0, rss1);
d23 = vzip1q_u64(rss2, rss3);

/* d01 elements are stored in even places for transposet instr*/
/* d23 elements are stored in odd places for transposet instr*/
rss0213 = vtrn1q_u32(d01, d23);

const uint32x4_t def_hash_val = vdupq_n_u32(0);

hash_f = vdupq_n_u32(rss_hf);
hash_rpt = vandq_u32(vcgtq_u32(rss0213, def_hash_val), hash_f);

d01 = vtrn1q_u32(rss0213, hash_rpt);
d23 = vtrn2q_u32(rss0213, hash_rpt);

*(uint64_t *)((uint32_t *)data0 + 3) = vgetq_lane_u64(d01, 0);
*(uint64_t *)((uint32_t *)data1 + 3) = vgetq_lane_u64(d01, 1);
*(uint64_t *)((uint32_t *)data2 + 3) = vgetq_lane_u64(d23, 0);
*(uint64_t *)((uint32_t *)data3 + 3) = vgetq_lane_u64(d23, 1);
}

*(uint32_t *)(data0 + 1) = 0x10000;
*(uint32_t *)(data1 + 1) = 0x10000;
*(uint32_t *)(data2 + 1) = 0x10000;
Expand Down Expand Up @@ -369,7 +399,7 @@ push_enq_data(struct virtio_net_queue *q, struct dao_dma_vchan_state *mem2dev,

/* Add Virtio header */
hdr = rte_pktmbuf_mtod_offset((struct rte_mbuf *)mbuf0, struct virtio_net_hdr*,
-sizeof(struct virtio_net_hdr));
-(virtio_hdr_sz));
hdr->flags = 0;
hdr->gso_type = 0;
hdr->gso_size = 0;
Expand All @@ -384,9 +414,14 @@ push_enq_data(struct virtio_net_queue *q, struct dao_dma_vchan_state *mem2dev,
hdr->flags = 0;
}

if (flags & VIRTIO_NET_ENQ_OFFLOAD_HASH_REPORT) {
hdr->hash_value = ((struct rte_mbuf *)mbuf0)->hash.rss;
hdr->hash_report = hdr->hash_value ? rss_hf : 0;
}

d_flags = *DESC_PTR_OFF(sd_desc_base, off, 8);
buf_len = d_flags & (RTE_BIT64(32) - 1);
len = ((struct rte_mbuf *)mbuf0)->pkt_len + sizeof(struct virtio_net_hdr);
len = ((struct rte_mbuf *)mbuf0)->pkt_len + virtio_hdr_sz;

if (flags & VIRTIO_NET_ENQ_OFFLOAD_MSEG) {
nb_enq = len % buf_len ? len/buf_len + 1 : len/buf_len;
Expand Down
16 changes: 14 additions & 2 deletions lib/virtio_net/virtio_net_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ struct virtio_net_queue {
uint16_t q_sz;
uint16_t dma_vchan;
uint16_t netdev_id;
uint8_t virtio_hdr_sz;
uint8_t auto_free;

/* Slow path */
struct dao_virtio_netdev *dao_netdev __rte_cache_aligned;
uint16_t qid;
uint32_t rss_hf;

/* Read-Write worker. */
uint16_t pend_sd_mbuf __rte_cache_aligned;
Expand Down Expand Up @@ -145,7 +147,8 @@ VIRTIO_NET_DEQ_FASTPATH_MODES
#define VIRTIO_NET_ENQ_OFFLOAD_NOFF RTE_BIT64(0)
#define VIRTIO_NET_ENQ_OFFLOAD_CHECKSUM RTE_BIT64(1)
#define VIRTIO_NET_ENQ_OFFLOAD_MSEG RTE_BIT64(2)
#define VIRTIO_NET_ENQ_OFFLOAD_LAST RTE_BIT64(2)
#define VIRTIO_NET_ENQ_OFFLOAD_HASH_REPORT RTE_BIT64(3)
#define VIRTIO_NET_ENQ_OFFLOAD_LAST RTE_BIT64(3)

/* Flags to control enqueue function.
* Defining it from backwards to denote its been
Expand All @@ -156,16 +159,25 @@ VIRTIO_NET_DEQ_FASTPATH_MODES
#define NOFF_F VIRTIO_NET_ENQ_OFFLOAD_NOFF
#define CSUM_F VIRTIO_NET_ENQ_OFFLOAD_CHECKSUM
#define MSEG_F VIRTIO_NET_ENQ_OFFLOAD_MSEG
#define HRP_F VIRTIO_NET_ENQ_OFFLOAD_HASH_REPORT

#define VIRTIO_NET_ENQ_FASTPATH_MODES \
T(no_offload, VIRTIO_NET_ENQ_OFFLOAD_NONE) \
T(no_ff, NOFF_F) \
T(cksum, CSUM_F) \
T(mseg, MSEG_F) \
T(hash_report, HRP_F) \
T(no_ff_cksum, NOFF_F | CSUM_F) \
T(no_ff_mseg, NOFF_F | MSEG_F) \
T(no_ff_hash_report, NOFF_F | HRP_F) \
T(cksum_mseg, CSUM_F | MSEG_F) \
T(no_ff_cksum_mseg, NOFF_F | CSUM_F | MSEG_F)
T(cksum_hash_report, CSUM_F | HRP_F) \
T(mseg_hash_report, MSEG_F | HRP_F) \
T(no_ff_cksum_mseg, NOFF_F | CSUM_F | MSEG_F) \
T(no_ff_cksum_hash_report, NOFF_F | CSUM_F | HRP_F) \
T(no_ff_mseg_hash_report, NOFF_F | MSEG_F | HRP_F) \
T(cksum_mseg_hash_report, CSUM_F | MSEG_F | HRP_F) \
T(no_ff_cksum_mseg_hash_report, NOFF_F | CSUM_F | MSEG_F | HRP_F)

#define T(name, flags) \
uint16_t virtio_net_enq_##name(void *q, struct rte_mbuf **pkts, uint16_t nb_pkts); \
Expand Down
32 changes: 30 additions & 2 deletions lib/virtio_net/virtio_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ static int
net_rss_setup(struct virtio_netdev *netdev, struct virtio_net_ctrl *ctrl_cmd)
{
struct virtio_net_ctrl_rss *rss = (struct virtio_net_ctrl_rss *)ctrl_cmd->data;
uint32_t max_vqs = netdev->dev.max_virtio_queues - 1;
struct virtio_net_queue *queue;
uint32_t i;
int rc;

if (user_cbs.rss_cb == NULL)
return -ENOTSUP;
Expand All @@ -39,7 +43,16 @@ net_rss_setup(struct virtio_netdev *netdev, struct virtio_net_ctrl *ctrl_cmd)
/* Update the core map to requested number of queues and
* configure rss.
*/
return user_cbs.rss_cb(netdev->dev.dev_id, rss);
rc = user_cbs.rss_cb(netdev->dev.dev_id, rss);
if (!rc) {
for (i = 0; i < max_vqs; i++) {
queue = netdev->qs[i];
if (queue)
queue->rss_hf = rss->hash_types;
}
}

return rc;
}

static int
Expand Down Expand Up @@ -173,6 +186,7 @@ virtio_netdev_populate_queue_info(struct virtio_netdev *netdev, uint16_t queue_i
uint32_t max_vqs = netdev->dev.max_virtio_queues - 1;
struct virtio_dev *dev = &netdev->dev;
struct virtio_queue_conf *q_conf;
struct virtio_net_hdr *vnet_hdr;
struct virtio_net_queue *queue;
bool cb_enabled = false;
uint32_t shadow_area;
Expand Down Expand Up @@ -233,6 +247,15 @@ virtio_netdev_populate_queue_info(struct virtio_netdev *netdev, uint16_t queue_i
queue->dao_netdev = dao_netdev;
queue->netdev_id = netdev->dev.dev_id;

if (dev->feature_bits & RTE_BIT64(VIRTIO_NET_F_HASH_REPORT))
queue->virtio_hdr_sz =
offsetof(struct virtio_net_hdr, padding_reserved) +
sizeof(vnet_hdr->padding_reserved);
else
queue->virtio_hdr_sz =
offsetof(struct virtio_net_hdr, num_buffers) +
sizeof(vnet_hdr->num_buffers);

queue->driver_area = (((uint64_t)q_conf->queue_avail_hi << 32) | (q_conf->queue_avail_lo));
queue->sd_driver_area = (uintptr_t)queue->sd_desc_base + queue->q_sz * 16;
event_flag = virtio_queue_driver_event_flag(dev, queue);
Expand Down Expand Up @@ -465,6 +488,10 @@ virtio_netdev_status_cb(struct virtio_dev *dev, uint8_t status)
dao_netdev->mgmt_fn_id |= VIRTIO_NET_DESC_MANAGE_MSEG;
}

dao_netdev->enq_fn_id &= ~VIRTIO_NET_ENQ_OFFLOAD_HASH_REPORT;
if (dev->feature_bits & RTE_BIT64(VIRTIO_NET_F_HASH_REPORT))
dao_netdev->enq_fn_id |= VIRTIO_NET_ENQ_OFFLOAD_HASH_REPORT;

return user_cbs.status_cb(netdev->dev.dev_id, status);
} else if (status == VIRTIO_DEV_RESET) {
struct virtio_net_queue *q;
Expand Down Expand Up @@ -544,7 +571,8 @@ dao_virtio_netdev_init(uint16_t devid, struct dao_virtio_netdev_conf *conf)
feature_bits = RTE_BIT64(VIRTIO_NET_F_CTRL_VQ) | RTE_BIT64(VIRTIO_NET_F_MQ) |
RTE_BIT64(VIRTIO_NET_F_RSS) | RTE_BIT64(VIRTIO_NET_F_CTRL_RX) |
RTE_BIT64(VIRTIO_NET_F_STATUS) | RTE_BIT64(VIRTIO_NET_F_MAC) |
RTE_BIT64(VIRTIO_NET_F_MRG_RXBUF);
RTE_BIT64(VIRTIO_NET_F_MRG_RXBUF) |
RTE_BIT64(VIRTIO_NET_F_HASH_REPORT);

/* Enable add MAC support */
feature_bits |= RTE_BIT64(VIRTIO_NET_F_CTRL_MAC_ADDR);
Expand Down

0 comments on commit 2814e2e

Please sign in to comment.