Skip to content

Commit

Permalink
net/mlx5: fix Rx metadata leftovers
Browse files Browse the repository at this point in the history
[ upstream commit 4eefb20 ]

The Rx metadata might use the metadata register C0 to keep the
values. The same register C0 might be used by kernel for source
vport value handling, kernel uses upper half of the register,
leaving the lower half for application usage.

In the extended metadata mode 1 (dv_xmeta_en devarg is
assigned with value 1) the metadata width is 16 bits only,
the Rx datapath code fetched the entire 32-bit value of the
metadata register and presented one to application. The patch
provides data masking depending on the chosen metadata mode.

Fixes: 6c55b62 ("net/mlx5: set dynamic flow metadata in Rx queues")

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
  • Loading branch information
viacheslavo authored and cpaelzer committed May 11, 2021
1 parent b9d78a6 commit 8598a62
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 17 deletions.
4 changes: 4 additions & 0 deletions drivers/net/mlx5/mlx5_flow.c
Expand Up @@ -894,10 +894,14 @@ mlx5_flow_rxq_dynf_metadata_set(struct rte_eth_dev *dev)
data->dynf_meta = 0;
data->flow_meta_mask = 0;
data->flow_meta_offset = -1;
data->flow_meta_port_mask = 0;
} else {
data->dynf_meta = 1;
data->flow_meta_mask = rte_flow_dynf_metadata_mask;
data->flow_meta_offset = rte_flow_dynf_metadata_offs;
data->flow_meta_port_mask = (uint32_t)~0;
if (priv->config.dv_xmeta_en == MLX5_XMETA_MODE_META16)
data->flow_meta_port_mask >>= 16;
}
}
}
Expand Down
13 changes: 9 additions & 4 deletions drivers/net/mlx5/mlx5_rxtx.c
Expand Up @@ -1259,10 +1259,15 @@ rxq_cq_to_mbuf(struct mlx5_rxq_data *rxq, struct rte_mbuf *pkt,
pkt->hash.fdir.hi = mlx5_flow_mark_get(mark);
}
}
if (rxq->dynf_meta && cqe->flow_table_metadata) {
pkt->ol_flags |= rxq->flow_meta_mask;
*RTE_MBUF_DYNFIELD(pkt, rxq->flow_meta_offset, uint32_t *) =
cqe->flow_table_metadata;
if (rxq->dynf_meta) {
uint32_t meta = cqe->flow_table_metadata &
rxq->flow_meta_port_mask;

if (meta) {
pkt->ol_flags |= rxq->flow_meta_mask;
*RTE_MBUF_DYNFIELD(pkt, rxq->flow_meta_offset,
uint32_t *) = meta;
}
}
if (rxq->csum)
pkt->ol_flags |= rxq_cq_to_ol_flags(cqe);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/mlx5/mlx5_rxtx.h
Expand Up @@ -156,6 +156,7 @@ struct mlx5_rxq_data {
uint32_t tunnel; /* Tunnel information. */
uint64_t flow_meta_mask;
int32_t flow_meta_offset;
uint32_t flow_meta_port_mask;
} __rte_cache_aligned;

enum mlx5_rxq_obj_type {
Expand Down
11 changes: 6 additions & 5 deletions drivers/net/mlx5/mlx5_rxtx_vec_altivec.h
Expand Up @@ -1036,22 +1036,23 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n,
if (rxq->dynf_meta) {
uint64_t flag = rxq->flow_meta_mask;
int32_t offs = rxq->flow_meta_offset;
uint32_t metadata;
uint32_t metadata, mask;

mask = rxq->flow_meta_port_mask;
/* This code is subject for futher optimization. */
metadata = cq[pos].flow_table_metadata;
metadata = cq[pos].flow_table_metadata & mask;
*RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *) =
metadata;
pkts[pos]->ol_flags |= metadata ? flag : 0ULL;
metadata = cq[pos + 1].flow_table_metadata;
metadata = cq[pos + 1].flow_table_metadata & mask;
*RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *) =
metadata;
pkts[pos + 1]->ol_flags |= metadata ? flag : 0ULL;
metadata = cq[pos + 2].flow_table_metadata;
metadata = cq[pos + 2].flow_table_metadata & mask;
*RTE_MBUF_DYNFIELD(pkts[pos + 2], offs, uint32_t *) =
metadata;
pkts[pos + 2]->ol_flags |= metadata ? flag : 0ULL;
metadata = cq[pos + 3].flow_table_metadata;
metadata = cq[pos + 3].flow_table_metadata & mask;
*RTE_MBUF_DYNFIELD(pkts[pos + 3], offs, uint32_t *) =
metadata;
pkts[pos + 3]->ol_flags |= metadata ? flag : 0ULL;
Expand Down
13 changes: 9 additions & 4 deletions drivers/net/mlx5/mlx5_rxtx_vec_neon.h
Expand Up @@ -713,19 +713,24 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n,
if (rxq->dynf_meta) {
/* This code is subject for futher optimization. */
int32_t offs = rxq->flow_meta_offset;
uint32_t mask = rxq->flow_meta_port_mask;

*RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *) =
container_of(p0, struct mlx5_cqe,
pkt_info)->flow_table_metadata;
pkt_info)->flow_table_metadata &
mask;
*RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *) =
container_of(p1, struct mlx5_cqe,
pkt_info)->flow_table_metadata;
pkt_info)->flow_table_metadata &
mask;
*RTE_MBUF_DYNFIELD(pkts[pos + 2], offs, uint32_t *) =
container_of(p2, struct mlx5_cqe,
pkt_info)->flow_table_metadata;
pkt_info)->flow_table_metadata &
mask;
*RTE_MBUF_DYNFIELD(pkts[pos + 3], offs, uint32_t *) =
container_of(p3, struct mlx5_cqe,
pkt_info)->flow_table_metadata;
pkt_info)->flow_table_metadata &
mask;
if (*RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *))
elts[pos]->ol_flags |= rxq->flow_meta_mask;
if (*RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *))
Expand Down
9 changes: 5 additions & 4 deletions drivers/net/mlx5/mlx5_rxtx_vec_sse.h
Expand Up @@ -665,15 +665,16 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n,
if (rxq->dynf_meta) {
/* This code is subject for futher optimization. */
int32_t offs = rxq->flow_meta_offset;
uint32_t mask = rxq->flow_meta_port_mask;

*RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *) =
cq[pos].flow_table_metadata;
cq[pos].flow_table_metadata & mask;
*RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *) =
cq[pos + p1].flow_table_metadata;
cq[pos + p1].flow_table_metadata & mask;
*RTE_MBUF_DYNFIELD(pkts[pos + 2], offs, uint32_t *) =
cq[pos + p2].flow_table_metadata;
cq[pos + p2].flow_table_metadata & mask;
*RTE_MBUF_DYNFIELD(pkts[pos + 3], offs, uint32_t *) =
cq[pos + p3].flow_table_metadata;
cq[pos + p3].flow_table_metadata & mask;
if (*RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *))
pkts[pos]->ol_flags |= rxq->flow_meta_mask;
if (*RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *))
Expand Down

0 comments on commit 8598a62

Please sign in to comment.