* [PATCH 0/6] add offload support of meter for NFP cards
@ 2022-12-07 2:17 Chaoyong He
2022-12-07 2:17 ` [PATCH 1/6] net/nfp: correct flower cmsg include dependencies Chaoyong He
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Chaoyong He @ 2022-12-07 2:17 UTC (permalink / raw)
To: dev; +Cc: oss-drivers, niklas.soderlund, Chaoyong He
This patch series mainly add the offload support of the meter for NFP
cards, includes:
- Add meter profile
- Add meter policy
- Add meter stats
- Add meter action
- Add meter offload support
Jin Liu (6):
net/nfp: correct flower cmsg include dependencies
net/nfp: add meter profile options
net/nfp: add meter policy options
net/nfp: add meter options
net/nfp: add meter stats options
net/nfp: add meter action logic
doc/guides/nics/features/nfp.ini | 1 +
doc/guides/rel_notes/release_23_03.rst | 4 +
drivers/net/nfp/flower/nfp_flower.c | 13 +-
drivers/net/nfp/flower/nfp_flower.h | 1 +
drivers/net/nfp/flower/nfp_flower_cmsg.c | 88 +-
drivers/net/nfp/flower/nfp_flower_cmsg.h | 25 +
drivers/net/nfp/flower/nfp_flower_ctrl.c | 58 +-
.../net/nfp/flower/nfp_flower_representor.c | 2 +-
drivers/net/nfp/meson.build | 1 +
drivers/net/nfp/nfp_flow.c | 86 +-
drivers/net/nfp/nfp_flow.h | 1 +
drivers/net/nfp/nfp_mtr.c | 1143 +++++++++++++++++
drivers/net/nfp/nfp_mtr.h | 182 +++
13 files changed, 1597 insertions(+), 8 deletions(-)
create mode 100644 drivers/net/nfp/nfp_mtr.c
create mode 100644 drivers/net/nfp/nfp_mtr.h
--
2.29.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/6] net/nfp: correct flower cmsg include dependencies
2022-12-07 2:17 [PATCH 0/6] add offload support of meter for NFP cards Chaoyong He
@ 2022-12-07 2:17 ` Chaoyong He
2022-12-07 2:17 ` [PATCH 2/6] net/nfp: add meter profile options Chaoyong He
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Chaoyong He @ 2022-12-07 2:17 UTC (permalink / raw)
To: dev; +Cc: oss-drivers, niklas.soderlund, Jin Liu, Peng Zhang, Chaoyong He
From: Jin Liu <jin.liu@corigine.com>
The function prototypes in nfp_flower_cmsg.h depends on struct
nfp_app_fw_flower defined in nfp_flow.h, but does not include it.
Avoid having to include both headers for all users of the flower
cmsg helpers by adding the header dependency to the correct header
file.
Signed-off-by: Jin Liu <jin.liu@corigine.com>
Signed-off-by: Peng Zhang <peng.zhang@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
drivers/net/nfp/flower/nfp_flower.c | 1 -
drivers/net/nfp/flower/nfp_flower_cmsg.c | 1 -
drivers/net/nfp/flower/nfp_flower_cmsg.h | 2 ++
drivers/net/nfp/flower/nfp_flower_ctrl.c | 1 -
drivers/net/nfp/flower/nfp_flower_representor.c | 1 -
5 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index e447258d97..5353daa47d 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -15,7 +15,6 @@
#include "../nfp_ctrl.h"
#include "../nfp_cpp_bridge.h"
#include "../nfp_rxtx.h"
-#include "../nfp_flow.h"
#include "../nfpcore/nfp_mip.h"
#include "../nfpcore/nfp_rtsym.h"
#include "../nfpcore/nfp_nsp.h"
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c b/drivers/net/nfp/flower/nfp_flower_cmsg.c
index babdd8e36b..f04b9bd921 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.c
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c
@@ -6,7 +6,6 @@
#include "../nfpcore/nfp_nsp.h"
#include "../nfp_logs.h"
#include "../nfp_common.h"
-#include "../nfp_flow.h"
#include "nfp_flower.h"
#include "nfp_flower_cmsg.h"
#include "nfp_flower_ctrl.h"
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 04601cb0bd..bdfde70fbe 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -9,6 +9,8 @@
#include <rte_byteorder.h>
#include <rte_ether.h>
+#include "../nfp_flow.h"
+
struct nfp_flower_cmsg_hdr {
rte_be16_t pad;
uint8_t type;
diff --git a/drivers/net/nfp/flower/nfp_flower_ctrl.c b/drivers/net/nfp/flower/nfp_flower_ctrl.c
index 3631e764fe..c545007d0c 100644
--- a/drivers/net/nfp/flower/nfp_flower_ctrl.c
+++ b/drivers/net/nfp/flower/nfp_flower_ctrl.c
@@ -11,7 +11,6 @@
#include "../nfp_logs.h"
#include "../nfp_ctrl.h"
#include "../nfp_rxtx.h"
-#include "nfp_flow.h"
#include "nfp_flower.h"
#include "nfp_flower_ctrl.h"
#include "nfp_flower_cmsg.h"
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index 5809c838b3..76be22efa2 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -10,7 +10,6 @@
#include "../nfp_logs.h"
#include "../nfp_ctrl.h"
#include "../nfp_rxtx.h"
-#include "../nfp_flow.h"
#include "../nfpcore/nfp_mip.h"
#include "../nfpcore/nfp_rtsym.h"
#include "../nfpcore/nfp_nsp.h"
--
2.29.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/6] net/nfp: add meter profile options
2022-12-07 2:17 [PATCH 0/6] add offload support of meter for NFP cards Chaoyong He
2022-12-07 2:17 ` [PATCH 1/6] net/nfp: correct flower cmsg include dependencies Chaoyong He
@ 2022-12-07 2:17 ` Chaoyong He
2022-12-07 2:17 ` [PATCH 3/6] net/nfp: add meter policy options Chaoyong He
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Chaoyong He @ 2022-12-07 2:17 UTC (permalink / raw)
To: dev; +Cc: oss-drivers, niklas.soderlund, Jin Liu, Peng Zhang, Chaoyong He
From: Jin Liu <jin.liu@corigine.com>
Add support for meter options, finish DPDK meter architecture
on NFP PMD.
Get meter capabilities function, the meter capabilities indicate
that what meter options NFP card support.
Add support for meter profile functions, include add a new meter
profile and delete a exist profile, the profile include the mode
and specific value of the speed limit, add meter profile to both
driver and firmware.
Signed-off-by: Jin Liu <jin.liu@corigine.com>
Signed-off-by: Peng Zhang <peng.zhang@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
drivers/net/nfp/flower/nfp_flower.c | 12 +-
drivers/net/nfp/flower/nfp_flower.h | 1 +
drivers/net/nfp/flower/nfp_flower_cmsg.c | 58 +++
drivers/net/nfp/flower/nfp_flower_cmsg.h | 5 +
.../net/nfp/flower/nfp_flower_representor.c | 1 +
drivers/net/nfp/meson.build | 1 +
drivers/net/nfp/nfp_mtr.c | 429 ++++++++++++++++++
drivers/net/nfp/nfp_mtr.h | 94 ++++
8 files changed, 600 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/nfp/nfp_mtr.c
create mode 100644 drivers/net/nfp/nfp_mtr.h
diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index 5353daa47d..7b46dc0f6a 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -194,6 +194,8 @@ nfp_flower_pf_close(struct rte_eth_dev *dev)
pf_dev = hw->pf_dev;
app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
+ nfp_mtr_priv_uninit(pf_dev);
+
/*
* We assume that the DPDK application is stopping all the
* threads/queues before calling the device close function.
@@ -1097,13 +1099,19 @@ nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev)
goto app_cleanup;
}
+ ret = nfp_mtr_priv_init(pf_dev);
+ if (ret != 0) {
+ PMD_INIT_LOG(ERR, "Error initializing metering private data");
+ goto flow_priv_cleanup;
+ }
+
/* Allocate memory for the PF AND ctrl vNIC here (hence the * 2) */
pf_hw = rte_zmalloc_socket("nfp_pf_vnic", 2 * sizeof(struct nfp_net_adapter),
RTE_CACHE_LINE_SIZE, numa_node);
if (pf_hw == NULL) {
PMD_INIT_LOG(ERR, "Could not malloc nfp pf vnic");
ret = -ENOMEM;
- goto flow_priv_cleanup;
+ goto mtr_priv_cleanup;
}
/* Map the PF ctrl bar */
@@ -1193,6 +1201,8 @@ nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev)
nfp_cpp_area_free(pf_dev->ctrl_area);
vnic_cleanup:
rte_free(pf_hw);
+mtr_priv_cleanup:
+ nfp_mtr_priv_uninit(pf_dev);
flow_priv_cleanup:
nfp_flow_priv_uninit(pf_dev);
app_cleanup:
diff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h
index c05a761a95..0ce5f7bd9e 100644
--- a/drivers/net/nfp/flower/nfp_flower.h
+++ b/drivers/net/nfp/flower/nfp_flower.h
@@ -76,6 +76,7 @@ struct nfp_app_fw_flower {
uint64_t ext_features;
struct nfp_flow_priv *flow_priv;
+ struct nfp_mtr_priv *mtr_priv;
};
static inline bool
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c b/drivers/net/nfp/flower/nfp_flower_cmsg.c
index f04b9bd921..eaddd6c52c 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.c
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c
@@ -467,3 +467,61 @@ nfp_flower_cmsg_tun_mac_rule(struct nfp_app_fw_flower *app_fw_flower,
return 0;
}
+
+int
+nfp_flower_cmsg_qos_add(struct nfp_app_fw_flower *app_fw_flower,
+ struct nfp_profile_conf *conf)
+{
+ char *msg;
+ uint16_t cnt;
+ uint32_t len;
+ struct rte_mbuf *mbuf;
+
+ mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+ if (mbuf == NULL) {
+ PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for qos add");
+ return -ENOMEM;
+ }
+
+ len = sizeof(struct nfp_profile_conf);
+ msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_QOS_MOD, len);
+ rte_memcpy(msg, conf, len);
+
+ cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+ if (cnt == 0) {
+ PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+ rte_pktmbuf_free(mbuf);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int
+nfp_flower_cmsg_qos_delete(struct nfp_app_fw_flower *app_fw_flower,
+ struct nfp_profile_conf *conf)
+{
+ char *msg;
+ uint16_t cnt;
+ uint32_t len;
+ struct rte_mbuf *mbuf;
+
+ mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+ if (mbuf == NULL) {
+ PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for qos delete");
+ return -ENOMEM;
+ }
+
+ len = sizeof(struct nfp_profile_conf);
+ msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_QOS_DEL, len);
+ rte_memcpy(msg, conf, len);
+
+ cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+ if (cnt == 0) {
+ PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+ rte_pktmbuf_free(mbuf);
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index bdfde70fbe..1894c454d3 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -9,6 +9,7 @@
#include <rte_byteorder.h>
#include <rte_ether.h>
+#include "../nfp_mtr.h"
#include "../nfp_flow.h"
struct nfp_flower_cmsg_hdr {
@@ -923,5 +924,9 @@ int nfp_flower_cmsg_tun_mac_rule(struct nfp_app_fw_flower *app_fw_flower,
struct rte_ether_addr *mac,
uint16_t mac_idx,
bool is_del);
+int nfp_flower_cmsg_qos_add(struct nfp_app_fw_flower *app_fw_flower,
+ struct nfp_profile_conf *conf);
+int nfp_flower_cmsg_qos_delete(struct nfp_app_fw_flower *app_fw_flower,
+ struct nfp_profile_conf *conf);
#endif /* _NFP_CMSG_H_ */
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index 76be22efa2..362c67f7b5 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -553,6 +553,7 @@ static const struct eth_dev_ops nfp_flower_repr_dev_ops = {
.mac_addr_set = nfp_flower_repr_mac_addr_set,
.flow_ops_get = nfp_net_flow_ops_get,
+ .mtr_ops_get = nfp_net_mtr_ops_get,
};
static uint32_t
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 7416fd3706..fc8fd906bc 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -28,6 +28,7 @@ sources = files(
'nfp_ethdev_vf.c',
'nfp_ethdev.c',
'nfp_flow.c',
+ 'nfp_mtr.c',
)
deps += ['hash']
diff --git a/drivers/net/nfp/nfp_mtr.c b/drivers/net/nfp/nfp_mtr.c
new file mode 100644
index 0000000000..50efb56879
--- /dev/null
+++ b/drivers/net/nfp/nfp_mtr.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include <rte_mtr_driver.h>
+#include <bus_pci_driver.h>
+#include <rte_malloc.h>
+
+#include "nfp_common.h"
+#include "nfp_mtr.h"
+#include "nfp_logs.h"
+#include "flower/nfp_flower.h"
+#include "flower/nfp_flower_cmsg.h"
+#include "flower/nfp_flower_representor.h"
+
+#define NFP_FL_QOS_PPS RTE_BIT32(15)
+#define NFP_FL_QOS_METER RTE_BIT32(10)
+#define NFP_FL_QOS_RFC2697 RTE_BIT32(0)
+
+/**
+ * Callback to get MTR capabilities.
+ *
+ * @param[in] dev
+ * Pointer to the device (unused).
+ * @param[out] cap
+ * Pointer to the meter object capabilities.
+ * @param[out] error
+ * Pointer to the error (unused).
+ *
+ * @returns
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_cap_get(struct rte_eth_dev *dev __rte_unused,
+ struct rte_mtr_capabilities *cap,
+ struct rte_mtr_error *error)
+{
+ if (cap == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "NULL pointer for capabilitie argument");
+ }
+
+ memset(cap, 0, sizeof(struct rte_mtr_capabilities));
+
+ cap->n_max = NFP_MAX_MTR_CNT;
+ cap->n_shared_max = NFP_MAX_MTR_CNT;
+ cap->identical = 1;
+ cap->shared_identical = 1;
+ cap->chaining_n_mtrs_per_flow_max = 1;
+ cap->meter_srtcm_rfc2697_n_max = NFP_MAX_MTR_CNT;
+ cap->meter_trtcm_rfc2698_n_max = NFP_MAX_MTR_CNT;
+ cap->meter_rate_max = UINT64_MAX;
+ cap->meter_policy_n_max = NFP_MAX_POLICY_CNT;
+ cap->srtcm_rfc2697_byte_mode_supported = 1;
+ cap->srtcm_rfc2697_packet_mode_supported = 1;
+ cap->trtcm_rfc2698_byte_mode_supported = 1;
+ cap->trtcm_rfc2698_packet_mode_supported = 1;
+ cap->stats_mask = RTE_MTR_STATS_N_PKTS_GREEN |
+ RTE_MTR_STATS_N_PKTS_DROPPED |
+ RTE_MTR_STATS_N_BYTES_GREEN |
+ RTE_MTR_STATS_N_BYTES_DROPPED;
+
+ return 0;
+}
+
+static int
+nfp_mtr_profile_validate(uint32_t mtr_profile_id,
+ struct rte_mtr_meter_profile *profile,
+ struct rte_mtr_error *error)
+{
+ /* Profile must not be NULL. */
+ if (profile == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE,
+ NULL, "Meter profile is null");
+ }
+
+ /* Meter profile ID must be valid. */
+ if (mtr_profile_id >= NFP_MAX_PROFILE_CNT) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "Meter profile id not valid");
+ }
+
+ switch (profile->alg) {
+ case RTE_MTR_SRTCM_RFC2697:
+ case RTE_MTR_TRTCM_RFC2698:
+ return 0;
+ case RTE_MTR_TRTCM_RFC4115:
+ return -rte_mtr_error_set(error, ENOTSUP,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE,
+ NULL, "Unsupported metering algorithm");
+ default:
+ return -rte_mtr_error_set(error, ENOTSUP,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE,
+ NULL, "Unknown metering algorithm");
+ }
+}
+
+static void
+nfp_mtr_profile_config_2698(uint32_t mtr_profile_id,
+ struct rte_mtr_meter_profile *profile,
+ struct nfp_profile_conf *conf)
+{
+ if (profile->packet_mode != 0)
+ conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_PPS);
+
+ conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_METER);
+ conf->head.profile_id = rte_cpu_to_be_32(mtr_profile_id);
+
+ conf->bkt_tkn_c = rte_cpu_to_be_32(profile->trtcm_rfc2698.cbs);
+ conf->bkt_tkn_p = rte_cpu_to_be_32(profile->trtcm_rfc2698.pbs);
+ conf->cbs = rte_cpu_to_be_32(profile->trtcm_rfc2698.cbs);
+ conf->pbs = rte_cpu_to_be_32(profile->trtcm_rfc2698.pbs);
+ conf->cir = rte_cpu_to_be_32(profile->trtcm_rfc2698.cir);
+ conf->pir = rte_cpu_to_be_32(profile->trtcm_rfc2698.pir);
+}
+
+static void
+nfp_mtr_profile_config_2697(uint32_t mtr_profile_id,
+ struct rte_mtr_meter_profile *profile,
+ struct nfp_profile_conf *conf)
+{
+ if (profile->packet_mode != 0)
+ conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_PPS);
+
+ conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_RFC2697);
+ conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_METER);
+ conf->head.profile_id = rte_cpu_to_be_32(mtr_profile_id);
+
+ conf->bkt_tkn_c = rte_cpu_to_be_32(profile->srtcm_rfc2697.cbs);
+ conf->bkt_tkn_p = rte_cpu_to_be_32(profile->srtcm_rfc2697.ebs);
+ conf->cbs = rte_cpu_to_be_32(profile->srtcm_rfc2697.cbs);
+ conf->pbs = rte_cpu_to_be_32(profile->srtcm_rfc2697.ebs);
+ conf->cir = rte_cpu_to_be_32(profile->srtcm_rfc2697.cir);
+ conf->pir = rte_cpu_to_be_32(profile->srtcm_rfc2697.cir);
+}
+
+static int
+nfp_mtr_profile_conf_mod(uint32_t mtr_profile_id,
+ struct rte_mtr_meter_profile *profile,
+ struct nfp_profile_conf *conf)
+{
+ switch (profile->alg) {
+ case RTE_MTR_SRTCM_RFC2697:
+ nfp_mtr_profile_config_2697(mtr_profile_id, profile, conf);
+ return 0;
+ case RTE_MTR_TRTCM_RFC2698:
+ nfp_mtr_profile_config_2698(mtr_profile_id, profile, conf);
+ return 0;
+ case RTE_MTR_TRTCM_RFC4115:
+ return -ENOTSUP;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int
+nfp_mtr_profile_conf_insert(uint32_t mtr_profile_id,
+ struct rte_mtr_meter_profile *profile,
+ struct nfp_mtr_profile *mtr_profile)
+{
+ mtr_profile->profile_id = mtr_profile_id;
+ mtr_profile->in_use = false;
+
+ return nfp_mtr_profile_conf_mod(mtr_profile_id, profile,
+ &mtr_profile->conf);
+}
+
+static struct nfp_mtr_profile *
+nfp_mtr_profile_search(struct nfp_mtr_priv *priv, uint32_t mtr_profile_id)
+{
+ struct nfp_mtr_profile *mtr_profile;
+
+ LIST_FOREACH(mtr_profile, &priv->profiles, next)
+ if (mtr_profile->profile_id == mtr_profile_id)
+ break;
+
+ return mtr_profile;
+}
+
+static int
+nfp_mtr_profile_insert(struct nfp_app_fw_flower *app_fw_flower,
+ struct rte_mtr_meter_profile *profile,
+ uint32_t mtr_profile_id,
+ struct rte_mtr_error *error)
+{
+ int ret;
+ struct nfp_mtr_priv *priv;
+ struct nfp_mtr_profile *mtr_profile;
+
+ priv = app_fw_flower->mtr_priv;
+
+ /* Meter profile memory allocation. */
+ mtr_profile = rte_zmalloc(NULL, sizeof(struct nfp_mtr_profile), 0);
+ if (mtr_profile == NULL) {
+ return -rte_mtr_error_set(error, ENOMEM,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Meter profile alloc failed");
+ }
+
+ ret = nfp_mtr_profile_conf_insert(mtr_profile_id,
+ profile, mtr_profile);
+ if (ret != 0) {
+ rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Insert profile config failed");
+ goto free_profile;
+ }
+
+ ret = nfp_flower_cmsg_qos_add(app_fw_flower, &mtr_profile->conf);
+ if (ret != 0) {
+ rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Add meter to firmware failed");
+ goto free_profile;
+ }
+
+ /* Insert profile into profile list */
+ LIST_INSERT_HEAD(&priv->profiles, mtr_profile, next);
+
+ return 0;
+
+free_profile:
+ rte_free(mtr_profile);
+
+ return ret;
+}
+
+static int
+nfp_mtr_profile_mod(struct nfp_app_fw_flower *app_fw_flower,
+ struct rte_mtr_meter_profile *profile,
+ struct nfp_mtr_profile *mtr_profile,
+ struct rte_mtr_error *error)
+{
+ int ret;
+ struct nfp_profile_conf old_conf;
+
+ /* Get the old profile config */
+ rte_memcpy(&old_conf, &mtr_profile->conf, sizeof(old_conf));
+
+ ret = nfp_mtr_profile_conf_mod(mtr_profile->profile_id,
+ profile, &mtr_profile->conf);
+ if (ret != 0) {
+ rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Mod profile config failed");
+ goto rollback;
+ }
+
+ ret = nfp_flower_cmsg_qos_add(app_fw_flower, &mtr_profile->conf);
+ if (ret != 0) {
+ rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Mod meter to firmware failed");
+ goto rollback;
+ }
+
+ return 0;
+
+rollback:
+ rte_memcpy(&mtr_profile->conf, &old_conf, sizeof(old_conf));
+
+ return ret;
+}
+
+/**
+ * Callback to add MTR profile.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_profile_id
+ * Meter profile id.
+ * @param[in] profile
+ * Pointer to meter profile detail.
+ * @param[out] error
+ * Pointer to the error structure.
+ *
+ * @return
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_profile_add(struct rte_eth_dev *dev,
+ uint32_t mtr_profile_id,
+ struct rte_mtr_meter_profile *profile,
+ struct rte_mtr_error *error)
+{
+ int ret;
+ struct nfp_mtr_priv *priv;
+ struct nfp_mtr_profile *mtr_profile;
+ struct nfp_app_fw_flower *app_fw_flower;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ app_fw_flower = representor->app_fw_flower;
+ priv = app_fw_flower->mtr_priv;
+
+ /* Check input params */
+ ret = nfp_mtr_profile_validate(mtr_profile_id, profile, error);
+ if (ret != 0)
+ return ret;
+
+ /* Check if mtr profile id exist */
+ mtr_profile = nfp_mtr_profile_search(priv, mtr_profile_id);
+ if (mtr_profile == NULL) {
+ ret = nfp_mtr_profile_insert(app_fw_flower,
+ profile, mtr_profile_id, error);
+ } else {
+ ret = nfp_mtr_profile_mod(app_fw_flower,
+ profile, mtr_profile, error);
+ }
+
+ return ret;
+}
+
+/**
+ * Callback to delete MTR profile.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_profile_id
+ * Meter profile id.
+ * @param[out] error
+ * Pointer to the error structure.
+ *
+ * @return
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_profile_delete(struct rte_eth_dev *dev,
+ uint32_t mtr_profile_id,
+ struct rte_mtr_error *error)
+{
+ int ret;
+ struct nfp_mtr_priv *priv;
+ struct nfp_mtr_profile *mtr_profile;
+ struct nfp_app_fw_flower *app_fw_flower;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ app_fw_flower = representor->app_fw_flower;
+ priv = app_fw_flower->mtr_priv;
+
+ /* Check if mtr profile id exist */
+ mtr_profile = nfp_mtr_profile_search(priv, mtr_profile_id);
+ if (mtr_profile == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "Request meter profile not exist");
+ }
+
+ if (mtr_profile->in_use) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE,
+ NULL, "Request meter profile is been used");
+ }
+
+ ret = nfp_flower_cmsg_qos_delete(app_fw_flower, &mtr_profile->conf);
+ if (ret != 0) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Delete meter from firmware failed");
+ }
+
+ /* Remove profile from profile list */
+ LIST_REMOVE(mtr_profile, next);
+ rte_free(mtr_profile);
+
+ return 0;
+}
+
+static const struct rte_mtr_ops nfp_mtr_ops = {
+ .capabilities_get = nfp_mtr_cap_get,
+ .meter_profile_add = nfp_mtr_profile_add,
+ .meter_profile_delete = nfp_mtr_profile_delete,
+};
+
+int
+nfp_net_mtr_ops_get(struct rte_eth_dev *dev, void *arg)
+{
+ if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0) {
+ PMD_DRV_LOG(ERR, "Port is not a representor");
+ return -EINVAL;
+ }
+
+ *(const struct rte_mtr_ops **)arg = &nfp_mtr_ops;
+
+ return 0;
+}
+
+int
+nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev)
+{
+ struct nfp_mtr_priv *priv;
+ struct nfp_app_fw_flower *app_fw_flower;
+
+ priv = rte_zmalloc("nfp_app_mtr_priv", sizeof(struct nfp_mtr_priv), 0);
+ if (priv == NULL) {
+ PMD_INIT_LOG(ERR, "nfp app mtr priv creation failed");
+ return -ENOMEM;
+ }
+
+ app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
+ app_fw_flower->mtr_priv = priv;
+
+ LIST_INIT(&priv->profiles);
+
+ return 0;
+}
+
+void
+nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev)
+{
+ struct nfp_mtr_priv *priv;
+ struct nfp_mtr_profile *mtr_profile;
+ struct nfp_app_fw_flower *app_fw_flower;
+
+ app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
+ priv = app_fw_flower->mtr_priv;
+
+ LIST_FOREACH(mtr_profile, &priv->profiles, next) {
+ LIST_REMOVE(mtr_profile, next);
+ rte_free(mtr_profile);
+ }
+
+ rte_free(priv);
+}
diff --git a/drivers/net/nfp/nfp_mtr.h b/drivers/net/nfp/nfp_mtr.h
new file mode 100644
index 0000000000..05919c2bde
--- /dev/null
+++ b/drivers/net/nfp/nfp_mtr.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#ifndef __NFP_MTR_H__
+#define __NFP_MTR_H__
+
+/**
+ * The max meter count is determined by firmware.
+ * The max count is 65536 defined by OF_METER_COUNT.
+ */
+#define NFP_MAX_MTR_CNT 65536
+#define NFP_MAX_POLICY_CNT NFP_MAX_MTR_CNT
+#define NFP_MAX_PROFILE_CNT NFP_MAX_MTR_CNT
+
+/**
+ * See RFC 2698 for more details.
+ * Word[0](Flag options):
+ * [15] p(pps) 1 for pps, 0 for bps
+ *
+ * Meter control message
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-------------------------------+-+---+-----+-+---------+-+---+-+
+ * | Reserved |p| Y |TYPE |E| TSHFV |P| PC|R|
+ * +-------------------------------+-+---+-----+-+---------+-+---+-+
+ * | Profile ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Token Bucket Peak |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Token Bucket Committed |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Peak Burst Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Committed Burst Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Peak Information Rate |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Committed Information Rate |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_cfg_head {
+ rte_be32_t flags_opts;
+ rte_be32_t profile_id;
+};
+
+/**
+ * Struct nfp_profile_conf - profile config, offload to NIC
+ * @head: config head information
+ * @bkt_tkn_p: token bucket peak
+ * @bkt_tkn_c: token bucket committed
+ * @pbs: peak burst size
+ * @cbs: committed burst size
+ * @pir: peak information rate
+ * @cir: committed information rate
+ */
+struct nfp_profile_conf {
+ struct nfp_cfg_head head;
+ rte_be32_t bkt_tkn_p;
+ rte_be32_t bkt_tkn_c;
+ rte_be32_t pbs;
+ rte_be32_t cbs;
+ rte_be32_t pir;
+ rte_be32_t cir;
+};
+
+/**
+ * Struct nfp_mtr_profile - meter profile, stored in driver
+ * Can only be used by one meter
+ * @next: next meter profile object
+ * @profile_id: meter profile id
+ * @conf: meter profile config
+ * @in_use: if profile is been used by meter
+ */
+struct nfp_mtr_profile {
+ LIST_ENTRY(nfp_mtr_profile) next;
+ uint32_t profile_id;
+ struct nfp_profile_conf conf;
+ bool in_use;
+};
+
+/**
+ * Struct nfp_mtr_priv - meter private data
+ * @profiles: the head node of profile list
+ */
+struct nfp_mtr_priv {
+ LIST_HEAD(, nfp_mtr_profile) profiles;
+};
+
+int nfp_net_mtr_ops_get(struct rte_eth_dev *dev, void *arg);
+int nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev);
+void nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev);
+
+#endif /* __NFP_MTR_H__ */
--
2.29.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/6] net/nfp: add meter policy options
2022-12-07 2:17 [PATCH 0/6] add offload support of meter for NFP cards Chaoyong He
2022-12-07 2:17 ` [PATCH 1/6] net/nfp: correct flower cmsg include dependencies Chaoyong He
2022-12-07 2:17 ` [PATCH 2/6] net/nfp: add meter profile options Chaoyong He
@ 2022-12-07 2:17 ` Chaoyong He
2022-12-07 2:17 ` [PATCH 4/6] net/nfp: add meter options Chaoyong He
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Chaoyong He @ 2022-12-07 2:17 UTC (permalink / raw)
To: dev; +Cc: oss-drivers, niklas.soderlund, Jin Liu, Peng Zhang, Chaoyong He
From: Jin Liu <jin.liu@corigine.com>
Add support for meter policy options, include add a new policy
and delete a exist policy, the meter policy indicate that action
to be performed for messages of different colors.
Signed-off-by: Jin Liu <jin.liu@corigine.com>
Signed-off-by: Peng Zhang <peng.zhang@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
drivers/net/nfp/nfp_mtr.c | 179 ++++++++++++++++++++++++++++++++++++++
drivers/net/nfp/nfp_mtr.h | 18 ++++
2 files changed, 197 insertions(+)
diff --git a/drivers/net/nfp/nfp_mtr.c b/drivers/net/nfp/nfp_mtr.c
index 50efb56879..c8caf97262 100644
--- a/drivers/net/nfp/nfp_mtr.c
+++ b/drivers/net/nfp/nfp_mtr.c
@@ -371,10 +371,182 @@ nfp_mtr_profile_delete(struct rte_eth_dev *dev,
return 0;
}
+static struct nfp_mtr_policy *
+nfp_mtr_policy_search(struct nfp_mtr_priv *priv, uint32_t mtr_policy_id)
+{
+ struct nfp_mtr_policy *mtr_policy;
+
+ LIST_FOREACH(mtr_policy, &priv->policies, next)
+ if (mtr_policy->policy_id == mtr_policy_id)
+ break;
+
+ return mtr_policy;
+}
+
+static int
+nfp_mtr_policy_validate(uint32_t mtr_policy_id,
+ struct rte_mtr_meter_policy_params *policy,
+ struct rte_mtr_error *error)
+{
+ const struct rte_flow_action *action;
+
+ /* Policy must not be NULL */
+ if (policy == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL, "Meter policy is null.");
+ }
+
+ /* Meter policy ID must be valid. */
+ if (mtr_policy_id >= NFP_MAX_POLICY_CNT) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+ NULL, "Meter policy id not valid.");
+ }
+
+ /* Check green action
+ * Actions equal NULL means end action
+ */
+ action = policy->actions[RTE_COLOR_GREEN];
+ if (action != NULL && action->type != RTE_FLOW_ACTION_TYPE_VOID) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL, "Green action must be void or end");
+ }
+
+ /* Check yellow action
+ * Actions equal NULL means end action
+ */
+ action = policy->actions[RTE_COLOR_YELLOW];
+ if (action != NULL && action->type != RTE_FLOW_ACTION_TYPE_VOID) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL, "Yellow action must be void or end");
+ }
+
+ /* Check red action */
+ action = policy->actions[RTE_COLOR_RED];
+ if (action == NULL || action->type != RTE_FLOW_ACTION_TYPE_DROP) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL, "Red action must be drop");
+ }
+
+ return 0;
+}
+
+/**
+ * Callback to add MTR policy.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_policy_id
+ * Meter policy id.
+ * @param[in] policy
+ * Pointer to meter policy detail.
+ * @param[out] error
+ * Pointer to the error structure.
+ *
+ * @return
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_policy_add(struct rte_eth_dev *dev,
+ uint32_t mtr_policy_id,
+ struct rte_mtr_meter_policy_params *policy,
+ struct rte_mtr_error *error)
+{
+ int ret;
+ struct nfp_mtr_priv *priv;
+ struct nfp_mtr_policy *mtr_policy;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ priv = representor->app_fw_flower->mtr_priv;
+
+ /* Check if mtr policy id exist */
+ mtr_policy = nfp_mtr_policy_search(priv, mtr_policy_id);
+ if (mtr_policy != NULL) {
+ return -rte_mtr_error_set(error, EEXIST,
+ RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+ NULL, "Meter policy already exist");
+ }
+
+ /* Check input params */
+ ret = nfp_mtr_policy_validate(mtr_policy_id, policy, error);
+ if (ret != 0)
+ return ret;
+
+ /* Meter policy memory alloc */
+ mtr_policy = rte_zmalloc(NULL, sizeof(struct nfp_mtr_policy), 0);
+ if (mtr_policy == NULL) {
+ return -rte_mtr_error_set(error, ENOMEM,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Meter policy alloc failed");
+ }
+
+ mtr_policy->policy_id = mtr_policy_id;
+ rte_memcpy(&mtr_policy->policy, policy,
+ sizeof(struct rte_mtr_meter_policy_params));
+
+ /* Insert policy into policy list */
+ LIST_INSERT_HEAD(&priv->policies, mtr_policy, next);
+
+ return 0;
+}
+
+/**
+ * Callback to delete MTR policy.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_policy_id
+ * Meter policy id.
+ * @param[out] error
+ * Pointer to the error structure.
+ *
+ * @return
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_policy_delete(struct rte_eth_dev *dev,
+ uint32_t mtr_policy_id,
+ struct rte_mtr_error *error)
+{
+ struct nfp_mtr_priv *priv;
+ struct nfp_mtr_policy *mtr_policy;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ priv = representor->app_fw_flower->mtr_priv;
+
+ /* Check if mtr policy id exist */
+ mtr_policy = nfp_mtr_policy_search(priv, mtr_policy_id);
+ if (mtr_policy == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+ NULL, "Request meter policy not exist");
+ }
+
+ if (mtr_policy->ref_cnt > 0) {
+ return -rte_mtr_error_set(error, EBUSY,
+ RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL, "Request mtr policy is been used");
+ }
+
+ /* Remove profile from profile list */
+ LIST_REMOVE(mtr_policy, next);
+ rte_free(mtr_policy);
+
+ return 0;
+}
+
static const struct rte_mtr_ops nfp_mtr_ops = {
.capabilities_get = nfp_mtr_cap_get,
.meter_profile_add = nfp_mtr_profile_add,
.meter_profile_delete = nfp_mtr_profile_delete,
+ .meter_policy_add = nfp_mtr_policy_add,
+ .meter_policy_delete = nfp_mtr_policy_delete,
};
int
@@ -406,6 +578,7 @@ nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev)
app_fw_flower->mtr_priv = priv;
LIST_INIT(&priv->profiles);
+ LIST_INIT(&priv->policies);
return 0;
}
@@ -414,6 +587,7 @@ void
nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev)
{
struct nfp_mtr_priv *priv;
+ struct nfp_mtr_policy *mtr_policy;
struct nfp_mtr_profile *mtr_profile;
struct nfp_app_fw_flower *app_fw_flower;
@@ -425,5 +599,10 @@ nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev)
rte_free(mtr_profile);
}
+ LIST_FOREACH(mtr_policy, &priv->policies, next) {
+ LIST_REMOVE(mtr_policy, next);
+ rte_free(mtr_policy);
+ }
+
rte_free(priv);
}
diff --git a/drivers/net/nfp/nfp_mtr.h b/drivers/net/nfp/nfp_mtr.h
index 05919c2bde..4fea0cf926 100644
--- a/drivers/net/nfp/nfp_mtr.h
+++ b/drivers/net/nfp/nfp_mtr.h
@@ -6,6 +6,8 @@
#ifndef __NFP_MTR_H__
#define __NFP_MTR_H__
+#include <rte_mtr.h>
+
/**
* The max meter count is determined by firmware.
* The max count is 65536 defined by OF_METER_COUNT.
@@ -79,12 +81,28 @@ struct nfp_mtr_profile {
bool in_use;
};
+/**
+ * Struct nfp_mtr_policy - meter policy information
+ * @next: next meter policy object
+ * @policy_id: meter policy id
+ * @ref_cnt: reference count by meter
+ * @policy: RTE_FLOW policy information
+ */
+struct nfp_mtr_policy {
+ LIST_ENTRY(nfp_mtr_policy) next;
+ uint32_t policy_id;
+ uint32_t ref_cnt;
+ struct rte_mtr_meter_policy_params policy;
+};
+
/**
* Struct nfp_mtr_priv - meter private data
* @profiles: the head node of profile list
+ * @policies: the head node of policy list
*/
struct nfp_mtr_priv {
LIST_HEAD(, nfp_mtr_profile) profiles;
+ LIST_HEAD(, nfp_mtr_policy) policies;
};
int nfp_net_mtr_ops_get(struct rte_eth_dev *dev, void *arg);
--
2.29.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/6] net/nfp: add meter options
2022-12-07 2:17 [PATCH 0/6] add offload support of meter for NFP cards Chaoyong He
` (2 preceding siblings ...)
2022-12-07 2:17 ` [PATCH 3/6] net/nfp: add meter policy options Chaoyong He
@ 2022-12-07 2:17 ` Chaoyong He
2022-12-07 2:17 ` [PATCH 5/6] net/nfp: add meter stats options Chaoyong He
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Chaoyong He @ 2022-12-07 2:17 UTC (permalink / raw)
To: dev; +Cc: oss-drivers, niklas.soderlund, Jin Liu, Peng Zhang, Chaoyong He
From: Jin Liu <jin.liu@corigine.com>
Add function of meter options, a meter include a profile and a
policy.
Meter options include add a new meter object and destroy a exist
meter object, enable meter object and disable meter object, update
profile that been used by meter object to another.
Signed-off-by: Jin Liu <jin.liu@corigine.com>
Signed-off-by: Peng Zhang <peng.zhang@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
drivers/net/nfp/nfp_mtr.c | 357 ++++++++++++++++++++++++++++++++++++++
drivers/net/nfp/nfp_mtr.h | 24 +++
2 files changed, 381 insertions(+)
diff --git a/drivers/net/nfp/nfp_mtr.c b/drivers/net/nfp/nfp_mtr.c
index c8caf97262..1df7103417 100644
--- a/drivers/net/nfp/nfp_mtr.c
+++ b/drivers/net/nfp/nfp_mtr.c
@@ -541,12 +541,362 @@ nfp_mtr_policy_delete(struct rte_eth_dev *dev,
return 0;
}
+struct nfp_mtr *
+nfp_mtr_find_by_mtr_id(struct nfp_mtr_priv *priv, uint32_t mtr_id)
+{
+ struct nfp_mtr *mtr;
+
+ LIST_FOREACH(mtr, &priv->mtrs, next)
+ if (mtr->mtr_id == mtr_id)
+ break;
+
+ return mtr;
+}
+
+static int
+nfp_mtr_validate(uint32_t meter_id,
+ struct rte_mtr_params *params,
+ struct rte_mtr_error *error)
+{
+ /* Params must not be NULL */
+ if (params == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+ NULL, "Meter params is null.");
+ }
+
+ /* Meter policy ID must be valid. */
+ if (meter_id >= NFP_MAX_MTR_CNT) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Meter id not valid.");
+ }
+
+ if (params->use_prev_mtr_color != 0) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+ NULL, "Feature use_prev_mtr_color not support");
+ }
+
+ return 0;
+}
+
+static void
+nfp_mtr_config(uint32_t mtr_id,
+ int shared,
+ struct rte_mtr_params *params,
+ struct nfp_mtr_profile *mtr_profile,
+ struct nfp_mtr_policy *mtr_policy,
+ struct nfp_mtr *mtr)
+{
+ mtr->mtr_id = mtr_id;
+
+ if (shared != 0)
+ mtr->shared = true;
+
+ if (params->meter_enable != 0)
+ mtr->enable = true;
+
+ mtr->mtr_profile = mtr_profile;
+ mtr->mtr_policy = mtr_policy;
+}
+
+/**
+ * Create meter rules.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_id
+ * Meter id.
+ * @param[in] params
+ * Pointer to rte meter parameters.
+ * @param[in] shared
+ * Meter shared with other flow or not.
+ * @param[out] error
+ * Pointer to rte meter error structure.
+ *
+ * @return
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_create(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
+ struct rte_mtr_params *params,
+ int shared,
+ struct rte_mtr_error *error)
+{
+ int ret;
+ struct nfp_mtr *mtr;
+ struct nfp_mtr_priv *priv;
+ struct nfp_mtr_policy *mtr_policy;
+ struct nfp_mtr_profile *mtr_profile;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ priv = representor->app_fw_flower->mtr_priv;
+
+ /* Check if meter id exist */
+ mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
+ if (mtr != NULL) {
+ return -rte_mtr_error_set(error, EEXIST,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Meter already exist");
+ }
+
+ /* Check input meter params */
+ ret = nfp_mtr_validate(mtr_id, params, error);
+ if (ret != 0)
+ return ret;
+
+ mtr_profile = nfp_mtr_profile_search(priv, params->meter_profile_id);
+ if (mtr_profile == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "Request meter profile not exist");
+ }
+
+ if (mtr_profile->in_use) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "Request meter profile is been used");
+ }
+
+ mtr_policy = nfp_mtr_policy_search(priv, params->meter_policy_id);
+ if (mtr_policy == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+ NULL, "Request meter policy not exist");
+ }
+
+ /* Meter param memory alloc */
+ mtr = rte_zmalloc(NULL, sizeof(struct nfp_mtr), 0);
+ if (mtr == NULL) {
+ return -rte_mtr_error_set(error, ENOMEM,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Meter param alloc failed");
+ }
+
+ nfp_mtr_config(mtr_id, shared, params, mtr_profile, mtr_policy, mtr);
+
+ /* Update profile/policy status */
+ mtr->mtr_policy->ref_cnt++;
+ mtr->mtr_profile->in_use = true;
+
+ /* Insert mtr into mtr list */
+ LIST_INSERT_HEAD(&priv->mtrs, mtr, next);
+
+ return 0;
+}
+
+/**
+ * Destroy meter rules.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_id
+ * Meter id.
+ * @param[out] error
+ * Pointer to rte meter error structure.
+ *
+ * @return
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_destroy(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
+ struct rte_mtr_error *error)
+{
+ struct nfp_mtr *mtr;
+ struct nfp_mtr_priv *priv;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ priv = representor->app_fw_flower->mtr_priv;
+
+ /* Check if meter id exist */
+ mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
+ if (mtr == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Request meter not exist");
+ }
+
+ if (mtr->ref_cnt > 0) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Meter object is being used");
+ }
+
+ /* Update profile/policy status */
+ mtr->mtr_policy->ref_cnt--;
+ mtr->mtr_profile->in_use = false;
+
+ /* Remove mtr from mtr list */
+ LIST_REMOVE(mtr, next);
+ rte_free(mtr);
+
+ return 0;
+}
+
+/**
+ * Enable meter object.
+ *
+ * @param[in] dev
+ * Pointer to the device.
+ * @param[in] mtr_id
+ * Id of the meter.
+ * @param[out] error
+ * Pointer to the error.
+ *
+ * @returns
+ * 0 in success, negative value otherwise and rte_errno is set..
+ */
+static int
+nfp_mtr_enable(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
+ struct rte_mtr_error *error)
+{
+ struct nfp_mtr *mtr;
+ struct nfp_mtr_priv *priv;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ priv = representor->app_fw_flower->mtr_priv;
+
+ /* Check if meter id exist */
+ mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
+ if (mtr == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Request meter not exist");
+ }
+
+ mtr->enable = true;
+
+ return 0;
+}
+
+/**
+ * Disable meter object.
+ *
+ * @param[in] dev
+ * Pointer to the device.
+ * @param[in] mtr_id
+ * Id of the meter.
+ * @param[out] error
+ * Pointer to the error.
+ *
+ * @returns
+ * 0 on success, negative value otherwise and rte_errno is set..
+ */
+static int
+nfp_mtr_disable(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
+ struct rte_mtr_error *error)
+{
+ struct nfp_mtr *mtr;
+ struct nfp_mtr_priv *priv;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ priv = representor->app_fw_flower->mtr_priv;
+
+ /* Check if meter id exist */
+ mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
+ if (mtr == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Request meter not exist");
+ }
+
+ if (mtr->ref_cnt > 0) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Can't disable a used meter");
+ }
+
+ mtr->enable = false;
+
+ return 0;
+}
+
+/**
+ * Callback to update meter profile.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_id
+ * Meter id.
+ * @param[in] mtr_profile_id
+ * To be updated meter profile id.
+ * @param[out] error
+ * Pointer to rte meter error structure.
+ *
+ * @return
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_profile_update(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
+ uint32_t mtr_profile_id,
+ struct rte_mtr_error *error)
+{
+ struct nfp_mtr *mtr;
+ struct nfp_mtr_priv *priv;
+ struct nfp_mtr_profile *mtr_profile;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ priv = representor->app_fw_flower->mtr_priv;
+
+ /* Check if meter id exist */
+ mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
+ if (mtr == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Request meter not exist");
+ }
+
+ if (mtr->ref_cnt > 0) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Request meter is been used");
+ }
+
+ if (mtr->mtr_profile->profile_id == mtr_profile_id)
+ return 0;
+
+ mtr_profile = nfp_mtr_profile_search(priv, mtr_profile_id);
+ if (mtr_profile == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "Request meter profile not exist");
+ }
+
+ if (mtr_profile->in_use) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "Request meter profile is been used");
+ }
+
+ mtr_profile->in_use = true;
+ mtr->mtr_profile->in_use = false;
+ mtr->mtr_profile = mtr_profile;
+
+ return 0;
+}
+
static const struct rte_mtr_ops nfp_mtr_ops = {
.capabilities_get = nfp_mtr_cap_get,
.meter_profile_add = nfp_mtr_profile_add,
.meter_profile_delete = nfp_mtr_profile_delete,
.meter_policy_add = nfp_mtr_policy_add,
.meter_policy_delete = nfp_mtr_policy_delete,
+ .create = nfp_mtr_create,
+ .destroy = nfp_mtr_destroy,
+ .meter_enable = nfp_mtr_enable,
+ .meter_disable = nfp_mtr_disable,
+ .meter_profile_update = nfp_mtr_profile_update,
};
int
@@ -577,6 +927,7 @@ nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev)
app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
app_fw_flower->mtr_priv = priv;
+ LIST_INIT(&priv->mtrs);
LIST_INIT(&priv->profiles);
LIST_INIT(&priv->policies);
@@ -586,6 +937,7 @@ nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev)
void
nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev)
{
+ struct nfp_mtr *mtr;
struct nfp_mtr_priv *priv;
struct nfp_mtr_policy *mtr_policy;
struct nfp_mtr_profile *mtr_profile;
@@ -594,6 +946,11 @@ nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev)
app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
priv = app_fw_flower->mtr_priv;
+ LIST_FOREACH(mtr, &priv->mtrs, next) {
+ LIST_REMOVE(mtr, next);
+ rte_free(mtr);
+ }
+
LIST_FOREACH(mtr_profile, &priv->profiles, next) {
LIST_REMOVE(mtr_profile, next);
rte_free(mtr_profile);
diff --git a/drivers/net/nfp/nfp_mtr.h b/drivers/net/nfp/nfp_mtr.h
index 4fea0cf926..1f74e39e17 100644
--- a/drivers/net/nfp/nfp_mtr.h
+++ b/drivers/net/nfp/nfp_mtr.h
@@ -95,18 +95,42 @@ struct nfp_mtr_policy {
struct rte_mtr_meter_policy_params policy;
};
+/**
+ * Struct nfp_mtr - meter object information
+ * @next: next meter object
+ * @mtr_id: meter id
+ * @ref_cnt: reference count by flow
+ * @shared: if meter can be used by multiple flows
+ * @enable: if meter is enable to use
+ * @mtr_profile: the pointer of profile
+ * @mtr_policy: the pointer of policy
+ */
+struct nfp_mtr {
+ LIST_ENTRY(nfp_mtr) next;
+ uint32_t mtr_id;
+ uint32_t ref_cnt;
+ bool shared;
+ bool enable;
+ struct nfp_mtr_profile *mtr_profile;
+ struct nfp_mtr_policy *mtr_policy;
+};
+
/**
* Struct nfp_mtr_priv - meter private data
* @profiles: the head node of profile list
* @policies: the head node of policy list
+ * @mtrs: the head node of mtrs list
*/
struct nfp_mtr_priv {
LIST_HEAD(, nfp_mtr_profile) profiles;
LIST_HEAD(, nfp_mtr_policy) policies;
+ LIST_HEAD(, nfp_mtr) mtrs;
};
int nfp_net_mtr_ops_get(struct rte_eth_dev *dev, void *arg);
int nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev);
void nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev);
+struct nfp_mtr *nfp_mtr_find_by_mtr_id(struct nfp_mtr_priv *priv,
+ uint32_t mtr_id);
#endif /* __NFP_MTR_H__ */
--
2.29.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 5/6] net/nfp: add meter stats options
2022-12-07 2:17 [PATCH 0/6] add offload support of meter for NFP cards Chaoyong He
` (3 preceding siblings ...)
2022-12-07 2:17 ` [PATCH 4/6] net/nfp: add meter options Chaoyong He
@ 2022-12-07 2:17 ` Chaoyong He
2022-12-07 2:17 ` [PATCH 6/6] net/nfp: add meter action logic Chaoyong He
2023-01-19 10:58 ` [PATCH 0/6] add offload support of meter for NFP cards Ferruh Yigit
6 siblings, 0 replies; 8+ messages in thread
From: Chaoyong He @ 2022-12-07 2:17 UTC (permalink / raw)
To: dev; +Cc: oss-drivers, niklas.soderlund, Jin Liu, Peng Zhang, Chaoyong He
From: Jin Liu <jin.liu@corigine.com>
Add support for meter stats mask feature, it indicate what type
meter stats that NFP card support.
Add function of update meter stats mask, it will change the stats
mask used by the meter to another.
Add function of read meter stats, get the meter stats that stored
in driver.
Signed-off-by: Jin Liu <jin.liu@corigine.com>
Signed-off-by: Peng Zhang <peng.zhang@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
doc/guides/rel_notes/release_23_03.rst | 3 +
drivers/net/nfp/flower/nfp_flower_cmsg.c | 29 ++++
drivers/net/nfp/flower/nfp_flower_cmsg.h | 2 +
drivers/net/nfp/flower/nfp_flower_ctrl.c | 57 +++++++-
drivers/net/nfp/nfp_mtr.c | 164 ++++++++++++++++++++++-
drivers/net/nfp/nfp_mtr.h | 44 ++++++
6 files changed, 296 insertions(+), 3 deletions(-)
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index b8c5b68d6c..0ce6fbf8ee 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -55,6 +55,9 @@ New Features
Also, make sure to start the actual text at the margin.
=======================================================
+* **Updated Corigine nfp driver.**
+
+ * Added support for meter options.
Removed Items
-------------
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c b/drivers/net/nfp/flower/nfp_flower_cmsg.c
index eaddd6c52c..430dd9c316 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.c
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c
@@ -525,3 +525,32 @@ nfp_flower_cmsg_qos_delete(struct nfp_app_fw_flower *app_fw_flower,
return 0;
}
+
+int
+nfp_flower_cmsg_qos_stats(struct nfp_app_fw_flower *app_fw_flower,
+ struct nfp_cfg_head *head)
+{
+ char *msg;
+ uint16_t cnt;
+ uint32_t len;
+ struct rte_mbuf *mbuf;
+
+ mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+ if (mbuf == NULL) {
+ PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for qos stats");
+ return -ENOMEM;
+ }
+
+ len = sizeof(struct nfp_cfg_head);
+ msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_QOS_STATS, len);
+ rte_memcpy(msg, head, len);
+
+ cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+ if (cnt == 0) {
+ PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+ rte_pktmbuf_free(mbuf);
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 1894c454d3..2f4cd68730 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -928,5 +928,7 @@ int nfp_flower_cmsg_qos_add(struct nfp_app_fw_flower *app_fw_flower,
struct nfp_profile_conf *conf);
int nfp_flower_cmsg_qos_delete(struct nfp_app_fw_flower *app_fw_flower,
struct nfp_profile_conf *conf);
+int nfp_flower_cmsg_qos_stats(struct nfp_app_fw_flower *app_fw_flower,
+ struct nfp_cfg_head *head);
#endif /* _NFP_CMSG_H_ */
diff --git a/drivers/net/nfp/flower/nfp_flower_ctrl.c b/drivers/net/nfp/flower/nfp_flower_ctrl.c
index c545007d0c..03a2e2e622 100644
--- a/drivers/net/nfp/flower/nfp_flower_ctrl.c
+++ b/drivers/net/nfp/flower/nfp_flower_ctrl.c
@@ -249,7 +249,32 @@ nfp_flower_cmsg_rx_stats(struct nfp_flow_priv *flow_priv,
}
static void
-nfp_flower_cmsg_rx(struct nfp_flow_priv *flow_priv,
+nfp_flower_cmsg_rx_qos_stats(struct nfp_mtr_priv *mtr_priv,
+ struct rte_mbuf *mbuf)
+{
+ char *msg;
+ uint32_t profile_id;
+ struct nfp_mtr *mtr;
+ struct nfp_mtr_stats_reply *mtr_stats;
+
+ msg = rte_pktmbuf_mtod(mbuf, char *) + NFP_FLOWER_CMSG_HLEN;
+
+ mtr_stats = (struct nfp_mtr_stats_reply *)msg;
+ profile_id = rte_be_to_cpu_32(mtr_stats->head.profile_id);
+ mtr = nfp_mtr_find_by_profile_id(mtr_priv, profile_id);
+ if (mtr == NULL)
+ return;
+
+ rte_spinlock_lock(&mtr_priv->mtr_stats_lock);
+ mtr->mtr_stats.curr.pass_bytes = rte_be_to_cpu_64(mtr_stats->pass_bytes);
+ mtr->mtr_stats.curr.pass_pkts = rte_be_to_cpu_64(mtr_stats->pass_pkts);
+ mtr->mtr_stats.curr.drop_bytes = rte_be_to_cpu_64(mtr_stats->drop_bytes);
+ mtr->mtr_stats.curr.drop_pkts = rte_be_to_cpu_64(mtr_stats->drop_pkts);
+ rte_spinlock_unlock(&mtr_priv->mtr_stats_lock);
+}
+
+static void
+nfp_flower_cmsg_rx(struct nfp_app_fw_flower *app_fw_flower,
struct rte_mbuf **pkts_burst,
uint16_t count)
{
@@ -257,8 +282,13 @@ nfp_flower_cmsg_rx(struct nfp_flow_priv *flow_priv,
char *meta;
uint32_t meta_type;
uint32_t meta_info;
+ struct nfp_mtr_priv *mtr_priv;
+ struct nfp_flow_priv *flow_priv;
struct nfp_flower_cmsg_hdr *cmsg_hdr;
+ mtr_priv = app_fw_flower->mtr_priv;
+ flow_priv = app_fw_flower->flow_priv;
+
for (i = 0; i < count; i++) {
meta = rte_pktmbuf_mtod(pkts_burst[i], char *);
@@ -282,21 +312,38 @@ nfp_flower_cmsg_rx(struct nfp_flow_priv *flow_priv,
if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_FLOW_STATS) {
/* We need to deal with stats updates from HW asap */
nfp_flower_cmsg_rx_stats(flow_priv, pkts_burst[i]);
+ } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_QOS_STATS) {
+ /* Handle meter stats */
+ nfp_flower_cmsg_rx_qos_stats(mtr_priv, pkts_burst[i]);
}
rte_pktmbuf_free(pkts_burst[i]);
}
}
+static void
+nfp_mtr_stats_request(struct nfp_app_fw_flower *app_fw_flower)
+{
+ struct nfp_mtr *mtr;
+
+ LIST_FOREACH(mtr, &app_fw_flower->mtr_priv->mtrs, next)
+ (void)nfp_flower_cmsg_qos_stats(app_fw_flower, &mtr->mtr_profile->conf.head);
+}
+
void
nfp_flower_ctrl_vnic_poll(struct nfp_app_fw_flower *app_fw_flower)
{
uint16_t count;
+ uint64_t cur_tsc;
+ uint64_t drain_tsc;
+ uint64_t pre_tsc = 0;
struct nfp_net_rxq *rxq;
struct nfp_net_hw *ctrl_hw;
struct rte_eth_dev *ctrl_eth_dev;
struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+ drain_tsc = app_fw_flower->mtr_priv->drain_tsc;
+
ctrl_hw = app_fw_flower->ctrl_hw;
ctrl_eth_dev = ctrl_hw->eth_dev;
@@ -308,7 +355,13 @@ nfp_flower_ctrl_vnic_poll(struct nfp_app_fw_flower *app_fw_flower)
if (count != 0) {
app_fw_flower->ctrl_vnic_rx_count += count;
/* Process cmsgs here */
- nfp_flower_cmsg_rx(app_fw_flower->flow_priv, pkts_burst, count);
+ nfp_flower_cmsg_rx(app_fw_flower, pkts_burst, count);
+ }
+
+ cur_tsc = rte_rdtsc();
+ if (unlikely(cur_tsc - pre_tsc > drain_tsc)) {
+ nfp_mtr_stats_request(app_fw_flower);
+ pre_tsc = cur_tsc;
}
}
}
diff --git a/drivers/net/nfp/nfp_mtr.c b/drivers/net/nfp/nfp_mtr.c
index 1df7103417..f77381dcb3 100644
--- a/drivers/net/nfp/nfp_mtr.c
+++ b/drivers/net/nfp/nfp_mtr.c
@@ -553,6 +553,48 @@ nfp_mtr_find_by_mtr_id(struct nfp_mtr_priv *priv, uint32_t mtr_id)
return mtr;
}
+struct nfp_mtr *
+nfp_mtr_find_by_profile_id(struct nfp_mtr_priv *priv, uint32_t profile_id)
+{
+ struct nfp_mtr *mtr;
+
+ LIST_FOREACH(mtr, &priv->mtrs, next)
+ if (mtr->mtr_profile->profile_id == profile_id)
+ break;
+
+ return mtr;
+}
+
+static int
+nfp_mtr_stats_mask_validate(uint64_t stats_mask, struct rte_mtr_error *error)
+{
+ if ((stats_mask & RTE_MTR_STATS_N_PKTS_YELLOW) != 0) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+ NULL, "RTE_MTR_STATS_N_PKTS_YELLOW not support");
+ }
+
+ if ((stats_mask & RTE_MTR_STATS_N_PKTS_RED) != 0) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+ NULL, "RTE_MTR_STATS_N_PKTS_RED not support");
+ }
+
+ if ((stats_mask & RTE_MTR_STATS_N_BYTES_YELLOW) != 0) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+ NULL, "RTE_MTR_STATS_N_BYTES_YELLOW not support");
+ }
+
+ if ((stats_mask & RTE_MTR_STATS_N_BYTES_RED) != 0) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+ NULL, "RTE_MTR_STATS_N_BYTES_RED not support");
+ }
+
+ return 0;
+}
+
static int
nfp_mtr_validate(uint32_t meter_id,
struct rte_mtr_params *params,
@@ -578,7 +620,7 @@ nfp_mtr_validate(uint32_t meter_id,
NULL, "Feature use_prev_mtr_color not support");
}
- return 0;
+ return nfp_mtr_stats_mask_validate(params->stats_mask, error);
}
static void
@@ -599,6 +641,7 @@ nfp_mtr_config(uint32_t mtr_id,
mtr->mtr_profile = mtr_profile;
mtr->mtr_policy = mtr_policy;
+ mtr->stats_mask = params->stats_mask;
}
/**
@@ -886,6 +929,119 @@ nfp_mtr_profile_update(struct rte_eth_dev *dev,
return 0;
}
+/**
+ * Callback to update meter stats mask.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_id
+ * Meter id.
+ * @param[in] stats_mask
+ * To be updated stats_mask.
+ * @param[out] error
+ * Pointer to rte meter error structure.
+ *
+ * @return
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_stats_update(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
+ uint64_t stats_mask,
+ struct rte_mtr_error *error)
+{
+ int ret;
+ struct nfp_mtr *mtr;
+ struct nfp_mtr_priv *priv;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ priv = representor->app_fw_flower->mtr_priv;
+
+ /* Check if meter id exist */
+ mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
+ if (mtr == NULL) {
+ return -rte_mtr_error_set(error, EEXIST,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Request meter id not exist");
+ }
+
+ ret = nfp_mtr_stats_mask_validate(stats_mask, error);
+ if (ret != 0)
+ return ret;
+
+ mtr->stats_mask = stats_mask;
+
+ return 0;
+}
+
+/**
+ * Callback to read meter statistics.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_id
+ * Meter id.
+ * @param[out] stats
+ * Pointer to store the statistics.
+ * @param[out] stats_mask
+ * Pointer to store the stats_mask.
+ * @param[in] clear
+ * Statistic to be cleared after read or not.
+ * @param[out] error
+ * Pointer to rte meter error structure.
+ *
+ * @return
+ * 0 on success, a negative value otherwise and rte_errno is set.
+ */
+static int
+nfp_mtr_stats_read(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
+ struct rte_mtr_stats *stats,
+ uint64_t *stats_mask,
+ int clear,
+ struct rte_mtr_error *error)
+{
+ struct nfp_mtr *mtr;
+ struct nfp_mtr_priv *priv;
+ struct nfp_mtr_stats curr;
+ struct nfp_mtr_stats *prev;
+ struct nfp_flower_representor *representor;
+
+ representor = dev->data->dev_private;
+ priv = representor->app_fw_flower->mtr_priv;
+
+ /* Check if meter id exist */
+ mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
+ if (mtr == NULL) {
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID,
+ NULL, "Request meter not exist");
+ }
+
+ *stats_mask = mtr->stats_mask;
+
+ rte_spinlock_lock(&priv->mtr_stats_lock);
+ rte_memcpy(&curr, &mtr->mtr_stats.curr, sizeof(curr));
+ rte_spinlock_unlock(&priv->mtr_stats_lock);
+
+ prev = &mtr->mtr_stats.prev;
+
+ stats->n_pkts[RTE_COLOR_GREEN] = curr.pass_pkts - prev->pass_pkts;
+ stats->n_bytes[RTE_COLOR_GREEN] = curr.pass_bytes - prev->pass_bytes;
+ stats->n_pkts_dropped = curr.drop_pkts - prev->drop_pkts;
+ stats->n_bytes_dropped = curr.drop_bytes - prev->drop_bytes;
+
+ if (clear != 0) {
+ prev->pass_pkts = curr.pass_pkts;
+ prev->pass_bytes = curr.pass_bytes;
+ prev->drop_pkts = curr.drop_pkts;
+ prev->drop_bytes = curr.drop_bytes;
+ }
+
+ return 0;
+}
+
static const struct rte_mtr_ops nfp_mtr_ops = {
.capabilities_get = nfp_mtr_cap_get,
.meter_profile_add = nfp_mtr_profile_add,
@@ -897,6 +1053,8 @@ static const struct rte_mtr_ops nfp_mtr_ops = {
.meter_enable = nfp_mtr_enable,
.meter_disable = nfp_mtr_disable,
.meter_profile_update = nfp_mtr_profile_update,
+ .stats_update = nfp_mtr_stats_update,
+ .stats_read = nfp_mtr_stats_read,
};
int
@@ -927,10 +1085,14 @@ nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev)
app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
app_fw_flower->mtr_priv = priv;
+ priv->drain_tsc = rte_get_tsc_hz();
+
LIST_INIT(&priv->mtrs);
LIST_INIT(&priv->profiles);
LIST_INIT(&priv->policies);
+ rte_spinlock_init(&priv->mtr_stats_lock);
+
return 0;
}
diff --git a/drivers/net/nfp/nfp_mtr.h b/drivers/net/nfp/nfp_mtr.h
index 1f74e39e17..7bfc935e7d 100644
--- a/drivers/net/nfp/nfp_mtr.h
+++ b/drivers/net/nfp/nfp_mtr.h
@@ -66,6 +66,22 @@ struct nfp_profile_conf {
rte_be32_t cir;
};
+/**
+ * Struct nfp_mtr_stats_reply - meter stats, read from firmware
+ * @head: config head information
+ * @pass_bytes: count of passed bytes
+ * @pass_pkts: count of passed packets
+ * @drop_bytes: count of dropped bytes
+ * @drop_pkts: count of dropped packets
+ */
+struct nfp_mtr_stats_reply {
+ struct nfp_cfg_head head;
+ rte_be64_t pass_bytes;
+ rte_be64_t pass_pkts;
+ rte_be64_t drop_bytes;
+ rte_be64_t drop_pkts;
+};
+
/**
* Struct nfp_mtr_profile - meter profile, stored in driver
* Can only be used by one meter
@@ -95,6 +111,20 @@ struct nfp_mtr_policy {
struct rte_mtr_meter_policy_params policy;
};
+/**
+ * Struct nfp_mtr_stats - meter stats information
+ * @pass_bytes: count of passed bytes for meter
+ * @pass_pkts: count of passed packets for meter
+ * @drop_bytes: count of dropped bytes for meter
+ * @drop_pkts: count of dropped packets for meter
+ */
+struct nfp_mtr_stats {
+ uint64_t pass_bytes;
+ uint64_t pass_pkts;
+ uint64_t drop_bytes;
+ uint64_t drop_pkts;
+};
+
/**
* Struct nfp_mtr - meter object information
* @next: next meter object
@@ -104,6 +134,9 @@ struct nfp_mtr_policy {
* @enable: if meter is enable to use
* @mtr_profile: the pointer of profile
* @mtr_policy: the pointer of policy
+ * @stats_mask: supported meter stats mask
+ * @curr: current meter stats
+ * @prev: previous meter stats
*/
struct nfp_mtr {
LIST_ENTRY(nfp_mtr) next;
@@ -113,6 +146,11 @@ struct nfp_mtr {
bool enable;
struct nfp_mtr_profile *mtr_profile;
struct nfp_mtr_policy *mtr_policy;
+ uint64_t stats_mask;
+ struct {
+ struct nfp_mtr_stats curr;
+ struct nfp_mtr_stats prev;
+ } mtr_stats;
};
/**
@@ -120,11 +158,15 @@ struct nfp_mtr {
* @profiles: the head node of profile list
* @policies: the head node of policy list
* @mtrs: the head node of mtrs list
+ * @mtr_stats_lock: spinlock for meter stats
+ * @drain_tsc: clock period
*/
struct nfp_mtr_priv {
LIST_HEAD(, nfp_mtr_profile) profiles;
LIST_HEAD(, nfp_mtr_policy) policies;
LIST_HEAD(, nfp_mtr) mtrs;
+ rte_spinlock_t mtr_stats_lock;
+ uint64_t drain_tsc;
};
int nfp_net_mtr_ops_get(struct rte_eth_dev *dev, void *arg);
@@ -132,5 +174,7 @@ int nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev);
void nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev);
struct nfp_mtr *nfp_mtr_find_by_mtr_id(struct nfp_mtr_priv *priv,
uint32_t mtr_id);
+struct nfp_mtr *nfp_mtr_find_by_profile_id(struct nfp_mtr_priv *priv,
+ uint32_t profile_id);
#endif /* __NFP_MTR_H__ */
--
2.29.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 6/6] net/nfp: add meter action logic
2022-12-07 2:17 [PATCH 0/6] add offload support of meter for NFP cards Chaoyong He
` (4 preceding siblings ...)
2022-12-07 2:17 ` [PATCH 5/6] net/nfp: add meter stats options Chaoyong He
@ 2022-12-07 2:17 ` Chaoyong He
2023-01-19 10:58 ` [PATCH 0/6] add offload support of meter for NFP cards Ferruh Yigit
6 siblings, 0 replies; 8+ messages in thread
From: Chaoyong He @ 2022-12-07 2:17 UTC (permalink / raw)
To: dev; +Cc: oss-drivers, niklas.soderlund, Jin Liu, Peng Zhang, Chaoyong He
From: Jin Liu <jin.liu@corigine.com>
Add the rte_flow meter action logic, flow with meter action can
offload and work well.
Signed-off-by: Jin Liu <jin.liu@corigine.com>
Signed-off-by: Peng Zhang <peng.zhang@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
doc/guides/nics/features/nfp.ini | 1 +
doc/guides/rel_notes/release_23_03.rst | 1 +
drivers/net/nfp/flower/nfp_flower_cmsg.h | 16 +++++
drivers/net/nfp/nfp_flow.c | 86 +++++++++++++++++++++++-
drivers/net/nfp/nfp_flow.h | 1 +
drivers/net/nfp/nfp_mtr.c | 16 +++++
drivers/net/nfp/nfp_mtr.h | 2 +
7 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 9e075a680b..a4eb760675 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -44,6 +44,7 @@ vxlan = Y
count = Y
drop = Y
jump = Y
+meter = Y
of_pop_vlan = Y
of_push_vlan = Y
of_set_vlan_pcp = Y
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index 0ce6fbf8ee..2c45e1f09f 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -58,6 +58,7 @@ New Features
* **Updated Corigine nfp driver.**
* Added support for meter options.
+ * Added support for rte_flow meter action.
Removed Items
-------------
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 2f4cd68730..96e080a8e9 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -901,6 +901,22 @@ struct nfp_fl_act_set_tun {
rte_be16_t tun_proto; /* Only valid for NFP_FL_TUNNEL_GENEVE */
} __rte_packed;
+/*
+ * Meter
+ * 3 2 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | res | opcode | res | len_lw| reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Profile ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct nfp_fl_act_meter {
+ struct nfp_fl_act_head head;
+ rte_be16_t reserved;
+ rte_be32_t profile_id;
+};
+
int nfp_flower_cmsg_mac_repr(struct nfp_app_fw_flower *app_fw_flower);
int nfp_flower_cmsg_repr_reify(struct nfp_app_fw_flower *app_fw_flower,
struct nfp_flower_representor *repr);
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 6f79d950db..ab9a9c23f5 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -356,7 +356,7 @@ nfp_flow_alloc(struct nfp_fl_key_ls *key_layer)
goto free_flow;
nfp_flow->length = len;
-
+ nfp_flow->mtr_id = NFP_MAX_MTR_CNT;
payload = &nfp_flow->payload;
payload->meta = (struct nfp_fl_rule_metadata *)tmp;
payload->unmasked_data = tmp + sizeof(struct nfp_fl_rule_metadata);
@@ -866,6 +866,7 @@ nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],
struct nfp_fl_key_ls *key_ls)
{
int ret = 0;
+ bool meter_flag = false;
bool tc_hl_flag = false;
bool mac_set_flag = false;
bool ip_set_flag = false;
@@ -1012,6 +1013,16 @@ nfp_flow_key_layers_calculate_actions(const struct rte_flow_action actions[],
case RTE_FLOW_ACTION_TYPE_RAW_DECAP:
PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_RAW_DECAP detected");
break;
+ case RTE_FLOW_ACTION_TYPE_METER:
+ PMD_DRV_LOG(DEBUG, "RTE_FLOW_ACTION_TYPE_METER detected");
+ if (!meter_flag) {
+ key_ls->act_size += sizeof(struct nfp_fl_act_meter);
+ meter_flag = true;
+ } else {
+ PMD_DRV_LOG(ERR, "Only support one meter action.");
+ return -ENOTSUP;
+ }
+ break;
default:
PMD_DRV_LOG(ERR, "Action type %d not supported.", action->type);
return -ENOTSUP;
@@ -3232,6 +3243,48 @@ nfp_flow_action_raw_encap(struct nfp_app_fw_flower *app_fw_flower,
return ret;
}
+static int
+nfp_flow_action_meter(struct nfp_flower_representor *representor,
+ const struct rte_flow_action *action,
+ char *act_data,
+ uint32_t *mtr_id)
+{
+ struct nfp_mtr *mtr;
+ struct nfp_fl_act_meter *fl_meter;
+ struct nfp_app_fw_flower *app_fw_flower;
+ const struct rte_flow_action_meter *meter;
+ size_t act_size = sizeof(struct nfp_fl_act_meter);
+
+ meter = action->conf;
+ fl_meter = (struct nfp_fl_act_meter *)act_data;
+ app_fw_flower = representor->app_fw_flower;
+
+ mtr = nfp_mtr_find_by_mtr_id(app_fw_flower->mtr_priv, meter->mtr_id);
+ if (mtr == NULL) {
+ PMD_DRV_LOG(ERR, "Meter id not exist");
+ return -EINVAL;
+ }
+
+ if (!mtr->enable) {
+ PMD_DRV_LOG(ERR, "Requested meter disable");
+ return -EINVAL;
+ }
+
+ if (!mtr->shared && mtr->ref_cnt > 0) {
+ PMD_DRV_LOG(ERR, "Can't use a used unshared meter");
+ return -EINVAL;
+ }
+
+ *mtr_id = meter->mtr_id;
+
+ fl_meter->head.jump_id = NFP_FL_ACTION_OPCODE_METER;
+ fl_meter->head.len_lw = act_size >> NFP_FL_LW_SIZ;
+ fl_meter->reserved = 0;
+ fl_meter->profile_id = rte_cpu_to_be_32(mtr->mtr_profile->profile_id);
+
+ return 0;
+}
+
static int
nfp_flow_compile_action(struct nfp_flower_representor *representor,
const struct rte_flow_action actions[],
@@ -3435,6 +3488,14 @@ nfp_flow_compile_action(struct nfp_flower_representor *representor,
if (action->conf != NULL)
nfp_flow->tun.payload.v6_flag = 1;
break;
+ case RTE_FLOW_ACTION_TYPE_METER:
+ PMD_DRV_LOG(DEBUG, "Process RTE_FLOW_ACTION_TYPE_METER");
+ ret = nfp_flow_action_meter(representor, action,
+ position, &nfp_flow->mtr_id);
+ if (ret != 0)
+ return -EINVAL;
+ position += sizeof(struct nfp_fl_act_meter);
+ break;
default:
PMD_DRV_LOG(ERR, "Unsupported action type: %d", action->type);
return -ENOTSUP;
@@ -3685,6 +3746,18 @@ nfp_flow_create(struct rte_eth_dev *dev,
goto flow_teardown;
}
+ /* Update meter object ref count */
+ if (nfp_flow->mtr_id != NFP_MAX_MTR_CNT) {
+ ret = nfp_mtr_update_ref_cnt(app_fw_flower->mtr_priv,
+ nfp_flow->mtr_id, true);
+ if (ret != 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Update meter ref_cnt failed.");
+ goto flow_teardown;
+ }
+ }
+
return nfp_flow;
flow_teardown:
@@ -3777,6 +3850,17 @@ nfp_flow_destroy(struct rte_eth_dev *dev,
goto exit;
}
+ /* Update meter object ref count */
+ if (nfp_flow->mtr_id != NFP_MAX_MTR_CNT) {
+ ret = nfp_mtr_update_ref_cnt(app_fw_flower->mtr_priv,
+ nfp_flow->mtr_id, false);
+ if (ret != 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Update meter ref_cnt failed.");
+ }
+ }
+
exit:
nfp_flow_free(nfp_flow);
diff --git a/drivers/net/nfp/nfp_flow.h b/drivers/net/nfp/nfp_flow.h
index b0c2aaf6d8..b8da752a9d 100644
--- a/drivers/net/nfp/nfp_flow.h
+++ b/drivers/net/nfp/nfp_flow.h
@@ -222,6 +222,7 @@ struct rte_flow {
struct nfp_fl_tun tun;
size_t length;
uint32_t hash_key;
+ uint32_t mtr_id;
bool install_flag;
enum nfp_flow_type type;
};
diff --git a/drivers/net/nfp/nfp_mtr.c b/drivers/net/nfp/nfp_mtr.c
index f77381dcb3..356bcdb370 100644
--- a/drivers/net/nfp/nfp_mtr.c
+++ b/drivers/net/nfp/nfp_mtr.c
@@ -1125,3 +1125,19 @@ nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev)
rte_free(priv);
}
+
+int
+nfp_mtr_update_ref_cnt(struct nfp_mtr_priv *priv,
+ uint32_t mtr_id,
+ bool add)
+{
+ struct nfp_mtr *mtr;
+
+ mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
+ if (mtr == NULL)
+ return -EINVAL;
+
+ mtr->ref_cnt += add ? 1 : -1;
+
+ return 0;
+}
diff --git a/drivers/net/nfp/nfp_mtr.h b/drivers/net/nfp/nfp_mtr.h
index 7bfc935e7d..41c472f139 100644
--- a/drivers/net/nfp/nfp_mtr.h
+++ b/drivers/net/nfp/nfp_mtr.h
@@ -176,5 +176,7 @@ struct nfp_mtr *nfp_mtr_find_by_mtr_id(struct nfp_mtr_priv *priv,
uint32_t mtr_id);
struct nfp_mtr *nfp_mtr_find_by_profile_id(struct nfp_mtr_priv *priv,
uint32_t profile_id);
+int nfp_mtr_update_ref_cnt(struct nfp_mtr_priv *priv,
+ uint32_t mtr_id, bool add);
#endif /* __NFP_MTR_H__ */
--
2.29.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 0/6] add offload support of meter for NFP cards
2022-12-07 2:17 [PATCH 0/6] add offload support of meter for NFP cards Chaoyong He
` (5 preceding siblings ...)
2022-12-07 2:17 ` [PATCH 6/6] net/nfp: add meter action logic Chaoyong He
@ 2023-01-19 10:58 ` Ferruh Yigit
6 siblings, 0 replies; 8+ messages in thread
From: Ferruh Yigit @ 2023-01-19 10:58 UTC (permalink / raw)
To: Chaoyong He, dev; +Cc: oss-drivers, niklas.soderlund
On 12/7/2022 2:17 AM, Chaoyong He wrote:
> This patch series mainly add the offload support of the meter for NFP
> cards, includes:
> - Add meter profile
> - Add meter policy
> - Add meter stats
> - Add meter action
> - Add meter offload support
>
> Jin Liu (6):
> net/nfp: correct flower cmsg include dependencies
> net/nfp: add meter profile options
> net/nfp: add meter policy options
> net/nfp: add meter options
> net/nfp: add meter stats options
> net/nfp: add meter action logic
Series applied to dpdk-next-net/main, thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-01-19 10:58 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-07 2:17 [PATCH 0/6] add offload support of meter for NFP cards Chaoyong He
2022-12-07 2:17 ` [PATCH 1/6] net/nfp: correct flower cmsg include dependencies Chaoyong He
2022-12-07 2:17 ` [PATCH 2/6] net/nfp: add meter profile options Chaoyong He
2022-12-07 2:17 ` [PATCH 3/6] net/nfp: add meter policy options Chaoyong He
2022-12-07 2:17 ` [PATCH 4/6] net/nfp: add meter options Chaoyong He
2022-12-07 2:17 ` [PATCH 5/6] net/nfp: add meter stats options Chaoyong He
2022-12-07 2:17 ` [PATCH 6/6] net/nfp: add meter action logic Chaoyong He
2023-01-19 10:58 ` [PATCH 0/6] add offload support of meter for NFP cards Ferruh Yigit
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).