ethdev: support congestion management

NIC HW controllers often come with congestion management support on
various HW objects such as Rx queue depth or mempool queue depth.

Also, it can support various modes of operation such as RED
(Random early discard), WRED etc on those HW objects.

Add a framework to express such modes(enum rte_cman_mode) and
introduce (enum rte_eth_cman_obj) to enumerate the different
objects where the modes can operate on.

Add RTE_CMAN_RED mode of operation and RTE_ETH_CMAN_OBJ_RX_QUEUE,
RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL objects.

Introduce reserved fields in configuration structure
backed by rte_eth_cman_config_init() to add new configuration
parameters without ABI breakage.

Add rte_eth_cman_info_get() API to get the information such as
supported modes and objects.

Add rte_eth_cman_config_init(), rte_eth_cman_config_set() APIs
to configure congestion management on those object with associated mode.

Finally, add rte_eth_cman_config_get() API to retrieve the
applied configuration.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Sunil Kumar Kori <skori@marvell.com>
This commit is contained in:
Jerin Jacob 2022-10-04 12:02:57 +03:00 committed by Andrew Rybchenko
parent fbb7a43a36
commit 6b81dddbb9
11 changed files with 374 additions and 1 deletions

View File

@ -727,6 +727,18 @@ Supports configuring per-queue stat counter mapping.
``rte_eth_dev_set_tx_queue_stats_mapping()``.
.. _nic_features_congestion_management:
Congestion management
---------------------
Supports congestion management.
* **[implements] eth_dev_ops**: ``cman_info_get``, ``cman_config_set``, ``cman_config_get``.
* **[related] API**: ``rte_eth_cman_info_get()``, ``rte_eth_cman_config_init()``,
``rte_eth_cman_config_set()``, ``rte_eth_cman_config_get()``.
.. _nic_features_fw_version:
FW version

View File

@ -40,6 +40,7 @@ DCB =
VLAN filter =
Flow control =
Rate limitation =
Congestion management =
Inline crypto =
Inline protocol =
CRC offload =

View File

@ -63,6 +63,12 @@ New Features
In theory this implementation should work with any target based on
``LoongArch`` ISA.
* **Added support for congestion management in ethdev.**
Added new API functions ``rte_eth_cman_config_init()``,
``rte_eth_cman_config_get()``, ``rte_eth_cman_config_set()``,
``rte_eth_cman_info_get()`` to support congestion management.
* **Added ethdev Rx/Tx descriptor dump API.**
Added the ethdev Rx/Tx descriptor dump API which provides functions

View File

@ -1094,6 +1094,22 @@ typedef int (*eth_rx_queue_avail_thresh_query_t)(struct rte_eth_dev *dev,
uint16_t *rx_queue_id,
uint8_t *avail_thresh);
/** @internal Get congestion management information. */
typedef int (*eth_cman_info_get_t)(struct rte_eth_dev *dev,
struct rte_eth_cman_info *info);
/** @internal Init congestion management structure with default values. */
typedef int (*eth_cman_config_init_t)(struct rte_eth_dev *dev,
struct rte_eth_cman_config *config);
/** @internal Configure congestion management on a port. */
typedef int (*eth_cman_config_set_t)(struct rte_eth_dev *dev,
const struct rte_eth_cman_config *config);
/** @internal Retrieve congestion management configuration of a port. */
typedef int (*eth_cman_config_get_t)(struct rte_eth_dev *dev,
struct rte_eth_cman_config *config);
/**
* @internal
* Dump Rx descriptor info to a file.
@ -1362,6 +1378,15 @@ struct eth_dev_ops {
eth_rx_descriptor_dump_t eth_rx_descriptor_dump;
/** Dump Tx descriptor info */
eth_tx_descriptor_dump_t eth_tx_descriptor_dump;
/** Get congestion management information */
eth_cman_info_get_t cman_info_get;
/** Initialize congestion management structure with default values */
eth_cman_config_init_t cman_config_init;
/** Configure congestion management */
eth_cman_config_set_t cman_config_set;
/** Retrieve congestion management configuration */
eth_cman_config_get_t cman_config_get;
};
/**

View File

@ -37,6 +37,9 @@ struct rte_eth_dev_callback {
extern rte_spinlock_t eth_dev_cb_lock;
/* Convert all error to -EIO if device is removed. */
int eth_err(uint16_t port_id, int ret);
/*
* Convert rte_eth_dev pointer to port ID.
* NULL will be translated to RTE_MAX_ETHPORTS.

View File

@ -8,6 +8,7 @@ sources = files(
'ethdev_trace_points.c',
'rte_class_eth.c',
'rte_ethdev.c',
'rte_ethdev_cman.c',
'rte_flow.c',
'rte_mtr.c',
'rte_tm.c',
@ -19,6 +20,7 @@ sources = files(
)
headers = files(
'rte_cman.h',
'rte_ethdev.h',
'rte_ethdev_trace.h',
'rte_ethdev_trace_fp.h',

55
lib/ethdev/rte_cman.h Normal file
View File

@ -0,0 +1,55 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2022 Marvell International Ltd.
*/
#ifndef RTE_CMAN_H
#define RTE_CMAN_H
#ifdef __cplusplus
extern "C" {
#endif
#include <rte_bitops.h>
/**
* @file
* Congestion management related parameters for DPDK.
*/
/** Congestion management modes */
enum rte_cman_mode {
/**
* Congestion based on Random Early Detection.
*
* https://en.wikipedia.org/wiki/Random_early_detection
* http://www.aciri.org/floyd/papers/red/red.html
* @see struct rte_cman_red_params
*/
RTE_CMAN_RED = RTE_BIT32(0),
};
/**
* RED based congestion management configuration parameters.
*/
struct rte_cman_red_params {
/**
* Minimum threshold (min_th) value
*
* Value expressed as percentage. Value must be in 0 to 100(inclusive).
*/
uint8_t min_th;
/**
* Maximum threshold (max_th) value
*
* Value expressed as percentage. Value must be in 0 to 100(inclusive).
*/
uint8_t max_th;
/** Inverse of packet marking probability maximum value (maxp = 1 / maxp_inv) */
uint16_t maxp_inv;
};
#ifdef __cplusplus
}
#endif
#endif /* RTE_CMAN_H */

View File

@ -650,7 +650,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
return -ENODEV;
}
static int
int
eth_err(uint16_t port_id, int ret)
{
if (ret == 0)

View File

@ -160,6 +160,7 @@ extern "C" {
#define RTE_ETHDEV_DEBUG_TX
#endif
#include <rte_cman.h>
#include <rte_compat.h>
#include <rte_log.h>
#include <rte_interrupts.h>
@ -5369,6 +5370,169 @@ int rte_eth_tx_descriptor_dump(uint16_t port_id, uint16_t queue_id,
uint16_t offset, uint16_t num, FILE *file);
/* Congestion management */
/** Enumerate list of ethdev congestion management objects */
enum rte_eth_cman_obj {
/** Congestion management based on Rx queue depth */
RTE_ETH_CMAN_OBJ_RX_QUEUE = RTE_BIT32(0),
/**
* Congestion management based on mempool depth associated with Rx queue
* @see rte_eth_rx_queue_setup()
*/
RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL = RTE_BIT32(1),
};
/**
* @warning
* @b EXPERIMENTAL: this structure may change, or be removed, without prior notice
*
* A structure used to retrieve information of ethdev congestion management.
*/
struct rte_eth_cman_info {
/**
* Set of supported congestion management modes
* @see enum rte_cman_mode
*/
uint64_t modes_supported;
/**
* Set of supported congestion management objects
* @see enum rte_eth_cman_obj
*/
uint64_t objs_supported;
/**
* Reserved for future fields. Always returned as 0 when
* rte_eth_cman_info_get() is invoked
*/
uint8_t rsvd[8];
};
/**
* @warning
* @b EXPERIMENTAL: this structure may change, or be removed, without prior notice
*
* A structure used to configure the ethdev congestion management.
*/
struct rte_eth_cman_config {
/** Congestion management object */
enum rte_eth_cman_obj obj;
/** Congestion management mode */
enum rte_cman_mode mode;
union {
/**
* Rx queue to configure congestion management.
*
* Valid when object is RTE_ETH_CMAN_OBJ_RX_QUEUE or
* RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL.
*/
uint16_t rx_queue;
/**
* Reserved for future fields.
* It must be set to 0 when rte_eth_cman_config_set() is invoked
* and will be returned as 0 when rte_eth_cman_config_get() is
* invoked.
*/
uint8_t rsvd_obj_params[4];
} obj_param;
union {
/**
* RED configuration parameters.
*
* Valid when mode is RTE_CMAN_RED.
*/
struct rte_cman_red_params red;
/**
* Reserved for future fields.
* It must be set to 0 when rte_eth_cman_config_set() is invoked
* and will be returned as 0 when rte_eth_cman_config_get() is
* invoked.
*/
uint8_t rsvd_mode_params[4];
} mode_param;
};
/**
* @warning
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
*
* Retrieve the information for ethdev congestion management
*
* @param port_id
* The port identifier of the Ethernet device.
* @param info
* A pointer to a structure of type *rte_eth_cman_info* to be filled with
* the information about congestion management.
* @return
* - (0) if successful.
* - (-ENOTSUP) if support for cman_info_get does not exist.
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
__rte_experimental
int rte_eth_cman_info_get(uint16_t port_id, struct rte_eth_cman_info *info);
/**
* @warning
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
*
* Initialize the ethdev congestion management configuration structure with default values.
*
* @param port_id
* The port identifier of the Ethernet device.
* @param config
* A pointer to a structure of type *rte_eth_cman_config* to be initialized
* with default value.
* @return
* - (0) if successful.
* - (-ENOTSUP) if support for cman_config_init does not exist.
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
__rte_experimental
int rte_eth_cman_config_init(uint16_t port_id, struct rte_eth_cman_config *config);
/**
* @warning
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
*
* Configure ethdev congestion management
*
* @param port_id
* The port identifier of the Ethernet device.
* @param config
* A pointer to a structure of type *rte_eth_cman_config* to be configured.
* @return
* - (0) if successful.
* - (-ENOTSUP) if support for cman_config_set does not exist.
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
__rte_experimental
int rte_eth_cman_config_set(uint16_t port_id, const struct rte_eth_cman_config *config);
/**
* @warning
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
*
* Retrieve the applied ethdev congestion management parameters for the given port.
*
* @param port_id
* The port identifier of the Ethernet device.
* @param config
* A pointer to a structure of type *rte_eth_cman_config* to retrieve
* congestion management parameters for the given object.
* Application must fill all parameters except mode_param parameter in
* struct rte_eth_cman_config.
*
* @return
* - (0) if successful.
* - (-ENOTSUP) if support for cman_config_get does not exist.
* - (-ENODEV) if *port_id* invalid.
* - (-EINVAL) if bad parameter.
*/
__rte_experimental
int rte_eth_cman_config_get(uint16_t port_id, struct rte_eth_cman_config *config);
#include <rte_ethdev_core.h>
/**

View File

@ -0,0 +1,101 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2022 Marvell International Ltd.
*/
#include <stdint.h>
#include <rte_errno.h>
#include "rte_ethdev.h"
#include "ethdev_driver.h"
#include "ethdev_private.h"
/* Get congestion management information for a port */
int
rte_eth_cman_info_get(uint16_t port_id, struct rte_eth_cman_info *info)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (info == NULL) {
RTE_ETHDEV_LOG(ERR, "congestion management info is NULL\n");
return -EINVAL;
}
if (dev->dev_ops->cman_info_get == NULL) {
RTE_ETHDEV_LOG(ERR, "Function not implemented\n");
return -ENOTSUP;
}
memset(info, 0, sizeof(struct rte_eth_cman_info));
return eth_err(port_id, (*dev->dev_ops->cman_info_get)(dev, info));
}
/* Initialize congestion management structure with default values */
int
rte_eth_cman_config_init(uint16_t port_id, struct rte_eth_cman_config *config)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (config == NULL) {
RTE_ETHDEV_LOG(ERR, "congestion management config is NULL\n");
return -EINVAL;
}
if (dev->dev_ops->cman_config_init == NULL) {
RTE_ETHDEV_LOG(ERR, "Function not implemented\n");
return -ENOTSUP;
}
memset(config, 0, sizeof(struct rte_eth_cman_config));
return eth_err(port_id, (*dev->dev_ops->cman_config_init)(dev, config));
}
/* Configure congestion management on a port */
int
rte_eth_cman_config_set(uint16_t port_id, const struct rte_eth_cman_config *config)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (config == NULL) {
RTE_ETHDEV_LOG(ERR, "congestion management config is NULL\n");
return -EINVAL;
}
if (dev->dev_ops->cman_config_set == NULL) {
RTE_ETHDEV_LOG(ERR, "Function not implemented\n");
return -ENOTSUP;
}
return eth_err(port_id, (*dev->dev_ops->cman_config_set)(dev, config));
}
/* Retrieve congestion management configuration of a port */
int
rte_eth_cman_config_get(uint16_t port_id, struct rte_eth_cman_config *config)
{
struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
if (config == NULL) {
RTE_ETHDEV_LOG(ERR, "congestion management config is NULL\n");
return -EINVAL;
}
if (dev->dev_ops->cman_config_get == NULL) {
RTE_ETHDEV_LOG(ERR, "Function not implemented\n");
return -ENOTSUP;
}
memset(config, 0, sizeof(struct rte_eth_cman_config));
return eth_err(port_id, (*dev->dev_ops->cman_config_get)(dev, config));
}

View File

@ -287,6 +287,10 @@ EXPERIMENTAL {
rte_mtr_meter_vlan_table_update;
# added in 22.11
rte_eth_cman_config_get;
rte_eth_cman_config_init;
rte_eth_cman_config_set;
rte_eth_cman_info_get;
rte_eth_rx_descriptor_dump;
rte_eth_tx_descriptor_dump;
rte_flow_async_action_handle_query;