[dpdk-dev] [PATCH v15 3/7] ethdev: add validation to offloads set by PMD
pbhagavatula at marvell.com
pbhagavatula at marvell.com
Tue Oct 29 16:37:18 CET 2019
From: Pavan Nikhilesh <pbhagavatula at marvell.com>
Some PMDs cannot work when certain offloads are enable/disabled, as a
workaround PMDs auto enable/disable offloads internally and expose it
through dev->data->dev_conf.rxmode.offloads.
After device specific dev_configure is called compare the requested
offloads to the offloads exposed by the PMD and, if the PMD failed
to enable a given offload then log it and return -EINVAL from
rte_eth_dev_configure, else if the PMD failed to disable a given offload
log and continue with rte_eth_dev_configure.
Suggested-by: Andrew Rybchenko <arybchenko at solarflare.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula at marvell.com>
---
lib/librte_ethdev/rte_ethdev.c | 59 ++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 3f45b9e9c..8c58da91c 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1135,6 +1135,41 @@ rte_eth_dev_tx_offload_name(uint64_t offload)
return name;
}
+static int
+_rte_eth_dev_validate_offloads(uint16_t port_id, uint64_t req_offloads,
+ uint64_t set_offloads,
+ const char *(*f)(uint64_t))
+{
+ uint64_t offloads_diff = req_offloads ^ set_offloads;
+ uint64_t offloads_req_diff, offloads_set_diff;
+ uint64_t offload;
+ uint8_t err = 0;
+
+ /* Check if any offload is advertised but not enabled. */
+ offloads_req_diff = offloads_diff & req_offloads;
+ while (offloads_req_diff) {
+ offload = 1ULL << __builtin_ctzll(offloads_req_diff);
+ offloads_req_diff &= ~offload;
+ RTE_ETHDEV_LOG(ERR, "Port %u failed to enable %s offload",
+ port_id, f(offload));
+ err = 1;
+ }
+
+ if (err)
+ return -EINVAL;
+
+ /* Chech if any offload couldn't be disabled. */
+ offloads_set_diff = offloads_diff & set_offloads;
+ while (offloads_set_diff) {
+ offload = 1ULL << __builtin_ctzll(offloads_set_diff);
+ offloads_set_diff &= ~offload;
+ RTE_ETHDEV_LOG(INFO, "Port %u failed to disable %s offload",
+ port_id, f(offload));
+ }
+
+ return 0;
+}
+
int
rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
const struct rte_eth_conf *dev_conf)
@@ -1358,6 +1393,30 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
goto rollback;
}
+ /* Validate Rx offloads. */
+ diag = _rte_eth_dev_validate_offloads(port_id,
+ dev_conf->rxmode.offloads,
+ dev->data->dev_conf.rxmode.offloads,
+ rte_eth_dev_rx_offload_name);
+ if (diag != 0) {
+ rte_eth_dev_rx_queue_config(dev, 0);
+ rte_eth_dev_tx_queue_config(dev, 0);
+ ret = diag;
+ goto rollback;
+ }
+
+ /* Validate Tx offloads. */
+ diag = _rte_eth_dev_validate_offloads(port_id,
+ dev_conf->txmode.offloads,
+ dev->data->dev_conf.txmode.offloads,
+ rte_eth_dev_tx_offload_name);
+ if (diag != 0) {
+ rte_eth_dev_rx_queue_config(dev, 0);
+ rte_eth_dev_tx_queue_config(dev, 0);
+ ret = diag;
+ goto rollback;
+ }
+
return 0;
rollback:
--
2.17.1
More information about the dev
mailing list