net/sfc: fix MTU change to check Rx scatter consistency
Rx queue setup function checks configured MTU to make sure that no oversized packets can be received. But a following call to set MTU function might make this check irrelevant. Add a function to check MTU size against Rx buffer size and additional Rx queue info, including Rx scatter offload. Fixes: e961cf425e02 ("net/sfc: support MTU change") Cc: stable@dpdk.org Signed-off-by: Igor Romanov <igor.romanov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
This commit is contained in:
parent
f4a9349da8
commit
6c0cc77a2d
@ -865,6 +865,34 @@ fail_inval:
|
||||
return -rc;
|
||||
}
|
||||
|
||||
static int
|
||||
sfc_check_scatter_on_all_rx_queues(struct sfc_adapter *sa, size_t pdu)
|
||||
{
|
||||
struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
|
||||
const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
|
||||
boolean_t scatter_enabled;
|
||||
const char *error;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < sas->rxq_count; i++) {
|
||||
if ((sas->rxq_info[i].state & SFC_RXQ_INITIALIZED) == 0)
|
||||
continue;
|
||||
|
||||
scatter_enabled = (sas->rxq_info[i].type_flags &
|
||||
EFX_RXQ_FLAG_SCATTER);
|
||||
|
||||
if (!sfc_rx_check_scatter(pdu, sa->rxq_ctrl[i].buf_size,
|
||||
encp->enc_rx_prefix_size,
|
||||
scatter_enabled, &error)) {
|
||||
sfc_err(sa, "MTU check for RxQ %u failed: %s", i,
|
||||
error);
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
|
||||
{
|
||||
@ -891,6 +919,10 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
|
||||
|
||||
sfc_adapter_lock(sa);
|
||||
|
||||
rc = sfc_check_scatter_on_all_rx_queues(sa, pdu);
|
||||
if (rc != 0)
|
||||
goto fail_check_scatter;
|
||||
|
||||
if (pdu != sa->port.pdu) {
|
||||
if (sa->state == SFC_ADAPTER_STARTED) {
|
||||
sfc_stop(sa);
|
||||
@ -927,6 +959,8 @@ fail_start:
|
||||
sfc_err(sa, "cannot start with neither new (%u) nor old (%u) "
|
||||
"PDU max size - port is stopped",
|
||||
(unsigned int)pdu, (unsigned int)old_pdu);
|
||||
|
||||
fail_check_scatter:
|
||||
sfc_adapter_unlock(sa);
|
||||
|
||||
fail_inval:
|
||||
|
@ -360,6 +360,18 @@ sfc_efx_rx_qdesc_status(struct sfc_dp_rxq *dp_rxq, uint16_t offset)
|
||||
return RTE_ETH_RX_DESC_UNAVAIL;
|
||||
}
|
||||
|
||||
boolean_t
|
||||
sfc_rx_check_scatter(size_t pdu, size_t rx_buf_size, uint32_t rx_prefix_size,
|
||||
boolean_t rx_scatter_enabled, const char **error)
|
||||
{
|
||||
if ((rx_buf_size < pdu + rx_prefix_size) && !rx_scatter_enabled) {
|
||||
*error = "Rx scatter is disabled and RxQ mbuf pool object size is too small";
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
/** Get Rx datapath ops by the datapath RxQ handle */
|
||||
const struct sfc_dp_rx *
|
||||
sfc_dp_rx_by_dp_rxq(const struct sfc_dp_rxq *dp_rxq)
|
||||
@ -975,6 +987,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
|
||||
struct sfc_dp_rx_qcreate_info info;
|
||||
struct sfc_dp_rx_hw_limits hw_limits;
|
||||
uint16_t rx_free_thresh;
|
||||
const char *error;
|
||||
|
||||
memset(&hw_limits, 0, sizeof(hw_limits));
|
||||
hw_limits.rxq_max_entries = sa->rxq_max_entries;
|
||||
@ -1005,10 +1018,11 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
|
||||
goto fail_bad_conf;
|
||||
}
|
||||
|
||||
if ((buf_size < sa->port.pdu + encp->enc_rx_prefix_size) &&
|
||||
(~offloads & DEV_RX_OFFLOAD_SCATTER)) {
|
||||
sfc_err(sa, "Rx scatter is disabled and RxQ %u mbuf pool "
|
||||
"object size is too small", sw_index);
|
||||
if (!sfc_rx_check_scatter(sa->port.pdu, buf_size,
|
||||
encp->enc_rx_prefix_size,
|
||||
(offloads & DEV_RX_OFFLOAD_SCATTER),
|
||||
&error)) {
|
||||
sfc_err(sa, "RxQ %u MTU check failed: %s", sw_index, error);
|
||||
sfc_err(sa, "RxQ %u calculated Rx buffer size is %u vs "
|
||||
"PDU size %u plus Rx prefix %u bytes",
|
||||
sw_index, buf_size, (unsigned int)sa->port.pdu,
|
||||
|
@ -142,6 +142,10 @@ void sfc_rx_hash_fini(struct sfc_adapter *sa);
|
||||
int sfc_rx_hf_rte_to_efx(struct sfc_adapter *sa, uint64_t rte,
|
||||
efx_rx_hash_type_t *efx);
|
||||
uint64_t sfc_rx_hf_efx_to_rte(struct sfc_rss *rss, efx_rx_hash_type_t efx);
|
||||
boolean_t sfc_rx_check_scatter(size_t pdu, size_t rx_buf_size,
|
||||
uint32_t rx_prefix_size,
|
||||
boolean_t rx_scatter_enabled,
|
||||
const char **error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user