net/sfc: support EF100 Tx override prefix

Add internal mbuf dynamic flag and field to request EF100 native
Tx datapath to use Tx prefix descriptor to override egress m-port.
Overriding egress m-port is necessary on representor Tx burst
so that the packet will reach corresponding VF.

Signed-off-by: Igor Romanov <igor.romanov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
This commit is contained in:
Igor Romanov 2021-10-11 17:48:25 +03:00 committed by Ferruh Yigit
parent 4ea8bb7809
commit 3f95dfb9c4
4 changed files with 100 additions and 0 deletions

View File

@ -12,6 +12,9 @@
#include <errno.h>
#include <rte_log.h>
#include <rte_mbuf_dyn.h>
#include "efx.h"
#include "sfc_dp.h"
#include "sfc_log.h"
@ -77,3 +80,46 @@ sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry)
return 0;
}
uint64_t sfc_dp_mport_override;
int sfc_dp_mport_offset = -1;
int
sfc_dp_mport_register(void)
{
static const struct rte_mbuf_dynfield mport = {
.name = "rte_net_sfc_dynfield_mport",
.size = sizeof(efx_mport_id_t),
.align = __alignof__(efx_mport_id_t),
};
static const struct rte_mbuf_dynflag mport_override = {
.name = "rte_net_sfc_dynflag_mport_override",
};
int field_offset;
int flag;
if (sfc_dp_mport_override != 0) {
SFC_GENERIC_LOG(INFO, "%s() already registered", __func__);
return 0;
}
field_offset = rte_mbuf_dynfield_register(&mport);
if (field_offset < 0) {
SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynfield",
__func__);
return -1;
}
flag = rte_mbuf_dynflag_register(&mport_override);
if (flag < 0) {
SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynflag",
__func__);
return -1;
}
sfc_dp_mport_offset = field_offset;
sfc_dp_mport_override = UINT64_C(1) << flag;
return 0;
}

View File

@ -128,6 +128,31 @@ struct sfc_dp *sfc_dp_find_by_caps(struct sfc_dp_list *head,
unsigned int avail_caps);
int sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry);
/**
* Dynamically registered mbuf flag "mport_override" (as a bitmask).
*
* If this flag is set in an mbuf then the dynamically registered
* mbuf field "mport" holds a valid value. This is used to direct
* port representor transmit traffic to the correct target port.
*/
extern uint64_t sfc_dp_mport_override;
/**
* Dynamically registered mbuf field "mport" (mbuf byte offset).
*
* If the dynamically registered "mport_override" flag is set in
* an mbuf then the mbuf "mport" field holds a valid value. This
* is used to direct port representor transmit traffic to the
* correct target port.
*/
extern int sfc_dp_mport_offset;
/**
* Register dynamic mbuf flag and field which can be used to require Tx override
* prefix descriptor with egress mport set.
*/
int sfc_dp_mport_register(void);
#ifdef __cplusplus
}
#endif

View File

@ -10,6 +10,7 @@
#include <stdbool.h>
#include <rte_mbuf.h>
#include <rte_mbuf_dyn.h>
#include <rte_io.h>
#include <rte_net.h>
@ -309,6 +310,19 @@ sfc_ef100_tx_reap(struct sfc_ef100_txq *txq)
sfc_ef100_tx_reap_num_descs(txq, sfc_ef100_tx_process_events(txq));
}
static void
sfc_ef100_tx_qdesc_prefix_create(const struct rte_mbuf *m, efx_oword_t *tx_desc)
{
efx_mport_id_t *mport_id =
RTE_MBUF_DYNFIELD(m, sfc_dp_mport_offset, efx_mport_id_t *);
EFX_POPULATE_OWORD_3(*tx_desc,
ESF_GZ_TX_PREFIX_EGRESS_MPORT,
mport_id->id,
ESF_GZ_TX_PREFIX_EGRESS_MPORT_EN, 1,
ESF_GZ_TX_DESC_TYPE, ESE_GZ_TX_DESC_TYPE_PREFIX);
}
static uint8_t
sfc_ef100_tx_qdesc_cso_inner_l3(uint64_t tx_tunnel)
{
@ -525,6 +539,11 @@ sfc_ef100_tx_pkt_descs_max(const struct rte_mbuf *m)
SFC_MBUF_SEG_LEN_MAX));
}
if (m->ol_flags & sfc_dp_mport_override) {
/* Tx override prefix descriptor will be used */
extra_descs++;
}
/*
* Any segment of scattered packet cannot be bigger than maximum
* segment length. Make sure that subsequent segments do not need
@ -671,6 +690,12 @@ sfc_ef100_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
break;
}
if (m_seg->ol_flags & sfc_dp_mport_override) {
id = added++ & txq->ptr_mask;
sfc_ef100_tx_qdesc_prefix_create(m_seg,
&txq->txq_hw_ring[id]);
}
if (m_seg->ol_flags & PKT_TX_TCP_SEG) {
m_seg = sfc_ef100_xmit_tso_pkt(txq, m_seg, &added);
} else {

View File

@ -2301,6 +2301,10 @@ sfc_eth_dev_init(struct rte_eth_dev *dev)
return 1;
}
rc = sfc_dp_mport_register();
if (rc != 0)
return rc;
sfc_register_dp();
logtype_main = sfc_register_logtype(&pci_dev->addr,