#include <rte_branch_prediction.h>
#include <rte_ether.h>
#include <rte_cycles.h>
+#include <rte_flow.h>
#include "mlx5.h"
#include "mlx5_utils.h"
MKSTR(path, "%s/%s", MLX5_SYSTEM_LOG_DIR, fname);
fd = fopen(path, "a+");
if (!fd) {
- DRV_LOG(WARNING, "cannot open %s for debug dump\n",
- path);
+ DRV_LOG(WARNING, "cannot open %s for debug dump", path);
MKSTR(path2, "./%s", fname);
fd = fopen(path2, "a+");
if (!fd) {
- DRV_LOG(ERR, "cannot open %s for debug dump\n",
- path2);
+ DRV_LOG(ERR, "cannot open %s for debug dump", path2);
return;
}
- DRV_LOG(INFO, "New debug dump in file %s\n", path2);
+ DRV_LOG(INFO, "New debug dump in file %s", path2);
} else {
- DRV_LOG(INFO, "New debug dump in file %s\n", path);
+ DRV_LOG(INFO, "New debug dump in file %s", path);
}
if (hex_title)
rte_hexdump(fd, hex_title, buf, hex_len);
&rq_attr);
}
if (ret) {
- DRV_LOG(ERR, "Cannot change Rx WQ state to %u - %s\n",
+ DRV_LOG(ERR, "Cannot change Rx WQ state to %u - %s",
sm->state, strerror(errno));
rte_errno = errno;
return ret;
.qp_state = IBV_QPS_RESET,
.port_num = (uint8_t)priv->ibv_port,
};
- struct ibv_qp *qp = txq_ctrl->ibv->qp;
+ struct ibv_qp *qp = txq_ctrl->obj->qp;
ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE);
if (ret) {
DRV_LOG(ERR, "Cannot change the Tx QP state to RESET "
- "%s\n", strerror(errno));
+ "%s", strerror(errno));
rte_errno = errno;
return ret;
}
ret = mlx5_glue->modify_qp(qp, &mod,
(IBV_QP_STATE | IBV_QP_PORT));
if (ret) {
- DRV_LOG(ERR, "Cannot change Tx QP state to INIT %s\n",
+ DRV_LOG(ERR, "Cannot change Tx QP state to INIT %s",
strerror(errno));
rte_errno = errno;
return ret;
mod.qp_state = IBV_QPS_RTR;
ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE);
if (ret) {
- DRV_LOG(ERR, "Cannot change Tx QP state to RTR %s\n",
+ DRV_LOG(ERR, "Cannot change Tx QP state to RTR %s",
strerror(errno));
rte_errno = errno;
return ret;
mod.qp_state = IBV_QPS_RTS;
ret = mlx5_glue->modify_qp(qp, &mod, IBV_QP_STATE);
if (ret) {
- DRV_LOG(ERR, "Cannot change Tx QP state to RTS %s\n",
+ DRV_LOG(ERR, "Cannot change Tx QP state to RTS %s",
strerror(errno));
rte_errno = errno;
return ret;
pkt->hash.fdir.hi = mlx5_flow_mark_get(mark);
}
}
+ if (rte_flow_dynf_metadata_avail() && cqe->flow_table_metadata) {
+ pkt->ol_flags |= PKT_RX_DYNF_METADATA;
+ *RTE_FLOW_DYNF_METADATA(pkt) = cqe->flow_table_metadata;
+ }
if (rxq->csum)
pkt->ol_flags |= rxq_cq_to_ol_flags(cqe);
if (rxq->vlan_strip &&
es->swp_offs = txq_mbuf_to_swp(loc, &es->swp_flags, olx);
/* Fill metadata field if needed. */
es->metadata = MLX5_TXOFF_CONFIG(METADATA) ?
- loc->mbuf->ol_flags & PKT_TX_METADATA ?
- loc->mbuf->tx_metadata : 0 : 0;
+ loc->mbuf->ol_flags & PKT_TX_DYNF_METADATA ?
+ *RTE_FLOW_DYNF_METADATA(loc->mbuf) : 0 : 0;
/* Engage VLAN tag insertion feature if requested. */
if (MLX5_TXOFF_CONFIG(VLAN) &&
loc->mbuf->ol_flags & PKT_TX_VLAN_PKT) {
es->swp_offs = txq_mbuf_to_swp(loc, &es->swp_flags, olx);
/* Fill metadata field if needed. */
es->metadata = MLX5_TXOFF_CONFIG(METADATA) ?
- loc->mbuf->ol_flags & PKT_TX_METADATA ?
- loc->mbuf->tx_metadata : 0 : 0;
+ loc->mbuf->ol_flags & PKT_TX_DYNF_METADATA ?
+ *RTE_FLOW_DYNF_METADATA(loc->mbuf) : 0 : 0;
static_assert(MLX5_ESEG_MIN_INLINE_SIZE ==
(sizeof(uint16_t) +
sizeof(rte_v128u32_t)),
es->swp_offs = txq_mbuf_to_swp(loc, &es->swp_flags, olx);
/* Fill metadata field if needed. */
es->metadata = MLX5_TXOFF_CONFIG(METADATA) ?
- loc->mbuf->ol_flags & PKT_TX_METADATA ?
- loc->mbuf->tx_metadata : 0 : 0;
+ loc->mbuf->ol_flags & PKT_TX_DYNF_METADATA ?
+ *RTE_FLOW_DYNF_METADATA(loc->mbuf) : 0 : 0;
static_assert(MLX5_ESEG_MIN_INLINE_SIZE ==
(sizeof(uint16_t) +
sizeof(rte_v128u32_t)),
es->swp_offs = txq_mbuf_to_swp(loc, &es->swp_flags, olx);
/* Fill metadata field if needed. */
es->metadata = MLX5_TXOFF_CONFIG(METADATA) ?
- loc->mbuf->ol_flags & PKT_TX_METADATA ?
- loc->mbuf->tx_metadata : 0 : 0;
+ loc->mbuf->ol_flags & PKT_TX_DYNF_METADATA ?
+ *RTE_FLOW_DYNF_METADATA(loc->mbuf) : 0 : 0;
static_assert(MLX5_ESEG_MIN_INLINE_SIZE ==
(sizeof(uint16_t) +
sizeof(rte_v128u32_t)),
/* Unrolled implementation of generic rte_memcpy. */
dst = (uintptr_t)&dseg->inline_data[0];
src = (uintptr_t)buf;
+ if (len & 0x08) {
#ifdef RTE_ARCH_STRICT_ALIGN
- memcpy(dst, src, len);
+ assert(dst == RTE_PTR_ALIGN(dst, sizeof(uint32_t)));
+ *(uint32_t *)dst = *(unaligned_uint32_t *)src;
+ dst += sizeof(uint32_t);
+ src += sizeof(uint32_t);
+ *(uint32_t *)dst = *(unaligned_uint32_t *)src;
+ dst += sizeof(uint32_t);
+ src += sizeof(uint32_t);
#else
- if (len & 0x08) {
- *(uint64_t *)dst = *(uint64_t *)src;
+ *(uint64_t *)dst = *(unaligned_uint64_t *)src;
dst += sizeof(uint64_t);
src += sizeof(uint64_t);
+#endif
}
if (len & 0x04) {
- *(uint32_t *)dst = *(uint32_t *)src;
+ *(uint32_t *)dst = *(unaligned_uint32_t *)src;
dst += sizeof(uint32_t);
src += sizeof(uint32_t);
}
if (len & 0x02) {
- *(uint16_t *)dst = *(uint16_t *)src;
+ *(uint16_t *)dst = *(unaligned_uint16_t *)src;
dst += sizeof(uint16_t);
src += sizeof(uint16_t);
}
if (len & 0x01)
*(uint8_t *)dst = *(uint8_t *)src;
-#endif
}
/**
return false;
/* Fill metadata field if needed. */
if (MLX5_TXOFF_CONFIG(METADATA) &&
- es->metadata != (loc->mbuf->ol_flags & PKT_TX_METADATA ?
- loc->mbuf->tx_metadata : 0))
+ es->metadata != (loc->mbuf->ol_flags & PKT_TX_DYNF_METADATA ?
+ *RTE_FLOW_DYNF_METADATA(loc->mbuf) : 0))
return false;
/* There must be no VLAN packets in eMPW loop. */
if (MLX5_TXOFF_CONFIG(VLAN))
unsigned int slen = 0;
next_empw:
+ assert(NB_SEGS(loc->mbuf) == 1);
part = RTE_MIN(pkts_n, MLX5_EMPW_MAX_PACKETS);
if (unlikely(loc->elts_free < part)) {
/* We have no enough elts to save all mbufs. */
return MLX5_TXCMP_CODE_EXIT;
return MLX5_TXCMP_CODE_MULTI;
}
+ assert(NB_SEGS(loc->mbuf) == 1);
if (ret == MLX5_TXCMP_CODE_TSO) {
part -= loop;
mlx5_tx_sdone_empw(txq, loc, part, slen, olx);
unsigned int room, part, nlim;
unsigned int slen = 0;
+ assert(NB_SEGS(loc->mbuf) == 1);
/*
* Limits the amount of packets in one WQE
* to improve CQE latency generation.
return MLX5_TXCMP_CODE_EXIT;
return MLX5_TXCMP_CODE_MULTI;
}
+ assert(NB_SEGS(loc->mbuf) == 1);
if (ret == MLX5_TXCMP_CODE_TSO) {
part -= room;
mlx5_tx_idone_empw(txq, loc, part, slen, olx);
loc.wqe_free = txq->wqe_s -
(uint16_t)(txq->wqe_ci - txq->wqe_pi);
if (unlikely(!loc.elts_free || !loc.wqe_free))
- return loc.pkts_sent;
+ goto burst_exit;
for (;;) {
/*
* Fetch the packet from array. Usually this is
assert(MLX5_TXOFF_CONFIG(INLINE) || loc.pkts_sent >= loc.pkts_copy);
/* Take a shortcut if nothing is sent. */
if (unlikely(loc.pkts_sent == loc.pkts_loop))
- return loc.pkts_sent;
+ goto burst_exit;
/*
* Ring QP doorbell immediately after WQE building completion
* to improve latencies. The pure software related data treatment
* can be completed after doorbell. Tx CQEs for this SQ are
* processed in this thread only by the polling.
+ *
+ * The rdma core library can map doorbell register in two ways,
+ * depending on the environment variable "MLX5_SHUT_UP_BF":
+ *
+ * - as regular cached memory, the variable is either missing or
+ * set to zero. This type of mapping may cause the significant
+ * doorbell register writing latency and requires explicit
+ * memory write barrier to mitigate this issue and prevent
+ * write combining.
+ *
+ * - as non-cached memory, the variable is present and set to
+ * not "0" value. This type of mapping may cause performance
+ * impact under heavy loading conditions but the explicit write
+ * memory barrier is not required and it may improve core
+ * performance.
*/
- mlx5_tx_dbrec_cond_wmb(txq, loc.wqe_last, 0);
+ mlx5_tx_dbrec_cond_wmb(txq, loc.wqe_last, !txq->db_nc);
/* Not all of the mbufs may be stored into elts yet. */
part = MLX5_TXOFF_CONFIG(INLINE) ? 0 : loc.pkts_sent - loc.pkts_copy;
if (!MLX5_TXOFF_CONFIG(INLINE) && part) {
mlx5_tx_copy_elts(txq, pkts + loc.pkts_copy, part, olx);
loc.pkts_copy = loc.pkts_sent;
}
-#ifdef MLX5_PMD_SOFT_COUNTERS
- /* Increment sent packets counter. */
- txq->stats.opackets += loc.pkts_sent;
-#endif
assert(txq->elts_s >= (uint16_t)(txq->elts_head - txq->elts_tail));
assert(txq->wqe_s >= (uint16_t)(txq->wqe_ci - txq->wqe_pi));
if (pkts_n > loc.pkts_sent) {
*/
goto send_loop;
}
+burst_exit:
+#ifdef MLX5_PMD_SOFT_COUNTERS
+ /* Increment sent packets counter. */
+ txq->stats.opackets += loc.pkts_sent;
+#endif
return loc.pkts_sent;
}
*/
olx |= MLX5_TXOFF_CONFIG_EMPW;
}
- if (tx_offloads & DEV_TX_OFFLOAD_MATCH_METADATA) {
+ if (rte_flow_dynf_metadata_avail()) {
/* We should support Flow metadata. */
olx |= MLX5_TXOFF_CONFIG_METADATA;
}