From: Serhii Iliushyk <sil-plv@napatech.com>
To: dev@dpdk.org
Cc: mko-plv@napatech.com, sil-plv@napatech.com, ckm@napatech.com,
stephen@networkplumber.org
Subject: [PATCH v2 4/7] net/ntnic: migrate port event thread to service
Date: Mon, 8 Sep 2025 16:17:36 +0200 [thread overview]
Message-ID: <20250908141740.1312268-5-sil-plv@napatech.com> (raw)
In-Reply-To: <20250908141740.1312268-1-sil-plv@napatech.com>
The port event service is responsible for handling port events.
Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
drivers/net/ntnic/include/ntdrv_4ga.h | 1 -
drivers/net/ntnic/include/ntos_drv.h | 2 +-
drivers/net/ntnic/ntnic_ethdev.c | 271 +++++++++++++++-----------
drivers/net/ntnic/ntutil/nt_service.c | 12 ++
drivers/net/ntnic/rte_pmd_ntnic.h | 2 +
5 files changed, 174 insertions(+), 114 deletions(-)
diff --git a/drivers/net/ntnic/include/ntdrv_4ga.h b/drivers/net/ntnic/include/ntdrv_4ga.h
index c143c0c2b6..ee0e66c4d4 100644
--- a/drivers/net/ntnic/include/ntdrv_4ga.h
+++ b/drivers/net/ntnic/include/ntdrv_4ga.h
@@ -16,7 +16,6 @@ typedef struct ntdrv_4ga_s {
volatile bool b_shutdown;
rte_spinlock_t stat_lck;
- rte_thread_t port_event_thread;
} ntdrv_4ga_t;
#endif /* __NTDRV_4GA_H__ */
diff --git a/drivers/net/ntnic/include/ntos_drv.h b/drivers/net/ntnic/include/ntos_drv.h
index 047c077057..e6e46f8cc1 100644
--- a/drivers/net/ntnic/include/ntos_drv.h
+++ b/drivers/net/ntnic/include/ntos_drv.h
@@ -21,7 +21,7 @@
#define NUM_MULTICAST_ADDRS_PER_PORT (16U)
#define NUM_ADAPTER_MAX (8)
-#define NUM_ADAPTER_PORTS_MAX (128)
+#define NUM_ADAPTER_PORTS_MAX (2)
/* Max RSS queues */
diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 54c9e218bc..7ec1c94a14 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -1549,7 +1549,8 @@ drv_deinit(struct drv_s *p_drv)
if (fpga_info->profile == FPGA_INFO_PROFILE_INLINE) {
nthw_service_del(RTE_NTNIC_SERVICE_FLM_UPDATE);
profile_inline_ops->flm_free_queues();
- THREAD_JOIN(p_nt_drv->port_event_thread);
+ nthw_service_del(RTE_NTNIC_SERVICE_PORT_0_EVENT);
+ nthw_service_del(RTE_NTNIC_SERVICE_PORT_1_EVENT);
/* Free all local flm event queues */
nthw_flm_inf_sta_queue_free_all(FLM_INFO_LOCAL);
/* Free all remote flm event queues */
@@ -1849,135 +1850,168 @@ static struct eth_dev_ops nthw_eth_dev_ops = {
};
/*
- * Port event thread
+ * Port event service
*/
-THREAD_FUNC port_event_thread_fn(void *context)
+static int port_event_service(void *context)
{
struct pmd_internals *internals = context;
- struct drv_s *p_drv = internals->p_drv;
- ntdrv_4ga_t *p_nt_drv = &p_drv->ntdrv;
- struct adapter_info_s *p_adapter_info = &p_nt_drv->adapter_info;
- struct flow_nic_dev *ndev = p_adapter_info->nt4ga_filter.mp_flow_device;
+ RTE_ASSERT(internals != NULL);
- nt4ga_stat_t *p_nt4ga_stat = &p_nt_drv->adapter_info.nt4ga_stat;
- struct rte_eth_dev *eth_dev = &rte_eth_devices[internals->port_id];
- uint8_t port_no = internals->port;
+ const uint8_t port_no = internals->port;
+ if (port_no >= NUM_ADAPTER_PORTS_MAX) {
+ NT_LOG(ERR, NTNIC, "Invalid Port number");
+ return -1;
+ }
- ntnic_flm_load_t flmdata;
- ntnic_port_load_t portdata;
+ static ntdrv_4ga_t *p_nt_drv[NUM_ADAPTER_PORTS_MAX] = {NULL, NULL};
+ static struct rte_eth_dev *eth_dev[NUM_ADAPTER_PORTS_MAX] = {NULL, NULL};
+ static nt4ga_stat_t *p_nt4ga_stat[NUM_ADAPTER_PORTS_MAX] = {NULL, NULL};
+ static ntnic_flm_load_t flmdata[NUM_ADAPTER_PORTS_MAX];
+ static ntnic_port_load_t portdata[NUM_ADAPTER_PORTS_MAX];
- memset(&flmdata, 0, sizeof(flmdata));
- memset(&portdata, 0, sizeof(portdata));
+ const int port_srv_tag[2] = {
+ RTE_NTNIC_SERVICE_PORT_0_EVENT,
+ RTE_NTNIC_SERVICE_PORT_1_EVENT
+ };
- while (ndev != NULL && ndev->eth_base == NULL)
- nt_os_wait_usec(1 * 1000 * 1000);
+ struct nt_service *port_event_srv = nthw_service_get_info(port_srv_tag[port_no]);
+ RTE_ASSERT(port_event_srv != NULL);
+
+ if (!NT_SERVICE_GET_STATE(port_event_srv)) {
+ struct drv_s *p_drv = internals->p_drv;
+ p_nt_drv[port_no] = &p_drv->ntdrv;
+ struct adapter_info_s *p_adapter_info = &p_nt_drv[port_no]->adapter_info;
+ struct flow_nic_dev *ndev = p_adapter_info->nt4ga_filter.mp_flow_device;
+ p_nt4ga_stat[port_no] = &p_nt_drv[port_no]->adapter_info.nt4ga_stat;
+ eth_dev[port_no] = &rte_eth_devices[internals->port_id];
+ if (ndev != NULL && ndev->eth_base == NULL)
+ return -1;
- while (!p_drv->ntdrv.b_shutdown) {
- /*
- * FLM load measurement
- * Do only send event, if there has been a change
- */
- if (p_nt4ga_stat->flm_stat_ver > 22 && p_nt4ga_stat->mp_stat_structs_flm) {
- if (flmdata.lookup != p_nt4ga_stat->mp_stat_structs_flm->load_lps ||
- flmdata.access != p_nt4ga_stat->mp_stat_structs_flm->load_aps) {
- rte_spinlock_lock(&p_nt_drv->stat_lck);
- flmdata.lookup = p_nt4ga_stat->mp_stat_structs_flm->load_lps;
- flmdata.access = p_nt4ga_stat->mp_stat_structs_flm->load_aps;
- flmdata.lookup_maximum =
- p_nt4ga_stat->mp_stat_structs_flm->max_lps;
- flmdata.access_maximum =
- p_nt4ga_stat->mp_stat_structs_flm->max_aps;
- rte_spinlock_unlock(&p_nt_drv->stat_lck);
-
- if (eth_dev && eth_dev->data && eth_dev->data->dev_private) {
- rte_eth_dev_callback_process(eth_dev,
- (enum rte_eth_event_type)RTE_NTNIC_FLM_LOAD_EVENT,
- &flmdata);
- }
+ memset(&flmdata, 0, sizeof(flmdata));
+ memset(&portdata, 0, sizeof(portdata));
+
+
+ NT_LOG(INF, NTNIC, "port[%u] event service started on lcore %i",
+ port_no, rte_lcore_id());
+ port_event_srv->lcore = rte_lcore_id();
+ NT_SERVICE_SET_STATE(port_event_srv, true);
+ return 0;
+ }
+
+ /*
+ * FLM load measurement
+ * Do only send event, if there has been a change
+ */
+
+ nt4ga_stat_t *port_stat = p_nt4ga_stat[port_no];
+ ntnic_flm_load_t *port_flm_load = &flmdata[port_no];
+ ntnic_port_load_t *port_load = &portdata[port_no];
+
+ if (port_stat->flm_stat_ver > 22 && port_stat->mp_stat_structs_flm) {
+ if (port_flm_load->lookup != port_stat->mp_stat_structs_flm->load_lps ||
+ port_flm_load->access != port_stat->mp_stat_structs_flm->load_aps) {
+ rte_spinlock_lock(&p_nt_drv[port_no]->stat_lck);
+ port_flm_load->lookup = port_stat->mp_stat_structs_flm->load_lps;
+ port_flm_load->access = port_stat->mp_stat_structs_flm->load_aps;
+ port_flm_load->lookup_maximum =
+ port_stat->mp_stat_structs_flm->max_lps;
+ port_flm_load->access_maximum =
+ port_stat->mp_stat_structs_flm->max_aps;
+ rte_spinlock_unlock(&p_nt_drv[port_no]->stat_lck);
+
+ if (eth_dev[port_no] &&
+ eth_dev[port_no]->data &&
+ eth_dev[port_no]->data->dev_private) {
+ rte_eth_dev_callback_process(eth_dev[port_no],
+ (enum rte_eth_event_type)RTE_NTNIC_FLM_LOAD_EVENT,
+ &flmdata);
}
}
+ }
- /*
- * Port load measurement
- * Do only send event, if there has been a change.
- */
- if (p_nt4ga_stat->mp_port_load) {
- if (portdata.rx_bps != p_nt4ga_stat->mp_port_load[port_no].rx_bps ||
- portdata.tx_bps != p_nt4ga_stat->mp_port_load[port_no].tx_bps) {
- rte_spinlock_lock(&p_nt_drv->stat_lck);
- portdata.rx_bps = p_nt4ga_stat->mp_port_load[port_no].rx_bps;
- portdata.tx_bps = p_nt4ga_stat->mp_port_load[port_no].tx_bps;
- portdata.rx_pps = p_nt4ga_stat->mp_port_load[port_no].rx_pps;
- portdata.tx_pps = p_nt4ga_stat->mp_port_load[port_no].tx_pps;
- portdata.rx_pps_maximum =
- p_nt4ga_stat->mp_port_load[port_no].rx_pps_max;
- portdata.tx_pps_maximum =
- p_nt4ga_stat->mp_port_load[port_no].tx_pps_max;
- portdata.rx_bps_maximum =
- p_nt4ga_stat->mp_port_load[port_no].rx_bps_max;
- portdata.tx_bps_maximum =
- p_nt4ga_stat->mp_port_load[port_no].tx_bps_max;
- rte_spinlock_unlock(&p_nt_drv->stat_lck);
-
- if (eth_dev && eth_dev->data && eth_dev->data->dev_private) {
- rte_eth_dev_callback_process(eth_dev,
- (enum rte_eth_event_type)RTE_NTNIC_PORT_LOAD_EVENT,
- &portdata);
- }
+ /*
+ * Port load measurement
+ * Do only send event, if there has been a change.
+ */
+ if (port_stat->mp_port_load) {
+ if (port_load->rx_bps != port_stat->mp_port_load[port_no].rx_bps ||
+ port_load->tx_bps != port_stat->mp_port_load[port_no].tx_bps) {
+ rte_spinlock_lock(&p_nt_drv[port_no]->stat_lck);
+ port_load->rx_bps = port_stat->mp_port_load[port_no].rx_bps;
+ port_load->tx_bps = port_stat->mp_port_load[port_no].tx_bps;
+ port_load->rx_pps = port_stat->mp_port_load[port_no].rx_pps;
+ port_load->tx_pps = port_stat->mp_port_load[port_no].tx_pps;
+ port_load->rx_pps_maximum =
+ port_stat->mp_port_load[port_no].rx_pps_max;
+ port_load->tx_pps_maximum =
+ port_stat->mp_port_load[port_no].tx_pps_max;
+ port_load->rx_bps_maximum =
+ port_stat->mp_port_load[port_no].rx_bps_max;
+ port_load->tx_bps_maximum =
+ port_stat->mp_port_load[port_no].tx_bps_max;
+ rte_spinlock_unlock(&p_nt_drv[port_no]->stat_lck);
+
+ if (eth_dev[port_no] && eth_dev[port_no]->data &&
+ eth_dev[port_no]->data->dev_private) {
+ rte_eth_dev_callback_process(eth_dev[port_no],
+ (enum rte_eth_event_type)RTE_NTNIC_PORT_LOAD_EVENT,
+ &portdata);
}
}
+ }
- /* Process events */
- {
- int count = 0;
- bool do_wait = true;
-
- while (count < 5000) {
- /* Local FLM statistic events */
- struct flm_info_event_s data;
-
- if (nthw_flm_inf_queue_get(port_no, FLM_INFO_LOCAL, &data) == 0) {
- if (eth_dev && eth_dev->data &&
- eth_dev->data->dev_private) {
- struct ntnic_flm_statistic_s event_data;
- event_data.bytes = data.bytes;
- event_data.packets = data.packets;
- event_data.cause = data.cause;
- event_data.id = data.id;
- event_data.timestamp = data.timestamp;
- rte_eth_dev_callback_process(eth_dev,
- (enum rte_eth_event_type)
- RTE_NTNIC_FLM_STATS_EVENT,
- &event_data);
- do_wait = false;
- }
- }
-
- /* AGED event */
- /* Note: RTE_FLOW_PORT_FLAG_STRICT_QUEUE flag is not supported so
- * event is always generated
- */
- int aged_event_count = flm_age_event_get(port_no);
-
- if (aged_event_count > 0 && eth_dev && eth_dev->data &&
- eth_dev->data->dev_private) {
- rte_eth_dev_callback_process(eth_dev,
- RTE_ETH_EVENT_FLOW_AGED,
- NULL);
- flm_age_event_clear(port_no);
+ /* Process events */
+ {
+ int count = 0;
+ bool do_wait = true;
+
+ while (count < 5000) {
+ /* Local FLM statistic events */
+ struct flm_info_event_s data;
+
+ if (nthw_flm_inf_queue_get(port_no, FLM_INFO_LOCAL, &data) == 0) {
+ if (eth_dev[port_no] && eth_dev[port_no]->data &&
+ eth_dev[port_no]->data->dev_private) {
+ struct ntnic_flm_statistic_s event_data;
+ event_data.bytes = data.bytes;
+ event_data.packets = data.packets;
+ event_data.cause = data.cause;
+ event_data.id = data.id;
+ event_data.timestamp = data.timestamp;
+ rte_eth_dev_callback_process(eth_dev[port_no],
+ (enum rte_eth_event_type)
+ RTE_NTNIC_FLM_STATS_EVENT,
+ &event_data);
do_wait = false;
}
+ }
- if (do_wait)
- nt_os_wait_usec(10);
-
- count++;
- do_wait = true;
+ /* AGED event */
+ /* Note: RTE_FLOW_PORT_FLAG_STRICT_QUEUE flag is not supported so
+ * event is always generated
+ */
+ int aged_event_count = flm_age_event_get(port_no);
+
+ if (aged_event_count > 0 &&
+ eth_dev[port_no] &&
+ eth_dev[port_no]->data &&
+ eth_dev[port_no]->data->dev_private) {
+ rte_eth_dev_callback_process(eth_dev[port_no],
+ RTE_ETH_EVENT_FLOW_AGED,
+ NULL);
+ flm_age_event_clear(port_no);
+ do_wait = false;
}
+
+ if (do_wait)
+ nt_os_wait_usec(10);
+
+ count++;
+ do_wait = true;
}
}
- return THREAD_RETURN;
+ return 0;
}
/*
@@ -2547,10 +2581,23 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev)
}
}
- /* Port event thread */
+ /* Port event service */
if (fpga_info->profile == FPGA_INFO_PROFILE_INLINE) {
- res = THREAD_CTRL_CREATE(&p_nt_drv->port_event_thread, "nt_port_event_thr",
- port_event_thread_fn, (void *)internals);
+ struct rte_service_spec port_event_spec = {
+ .callback = port_event_service,
+ .socket_id = SOCKET_ID_ANY,
+ .capabilities = RTE_SERVICE_CAP_MT_SAFE,
+ .callback_userdata = internals
+ };
+
+ sprintf(port_event_spec.name, "ntnic-port_%d_event_service", n_intf_no);
+
+ const int port_srv_tag[2] = {
+ RTE_NTNIC_SERVICE_PORT_0_EVENT,
+ RTE_NTNIC_SERVICE_PORT_1_EVENT
+ };
+
+ res = nthw_service_add(&port_event_spec, port_srv_tag[n_intf_no]);
if (res) {
NT_LOG(ERR, NTNIC, "%s: error=%d",
diff --git a/drivers/net/ntnic/ntutil/nt_service.c b/drivers/net/ntnic/ntutil/nt_service.c
index c109b44483..9f22ee2bba 100644
--- a/drivers/net/ntnic/ntutil/nt_service.c
+++ b/drivers/net/ntnic/ntutil/nt_service.c
@@ -24,6 +24,18 @@ static struct nt_service g_nt_services[RTE_NTNIC_SERVICE_MAX] = {
.lcore = RTE_MAX_LCORE,
.initialized = false,
},
+ [RTE_NTNIC_SERVICE_PORT_0_EVENT] = {
+ .tag = RTE_NTNIC_SERVICE_PORT_0_EVENT,
+ .id = NT_SERVICE_UNKNOWN_ID,
+ .lcore = RTE_MAX_LCORE,
+ .initialized = false,
+ },
+ [RTE_NTNIC_SERVICE_PORT_1_EVENT] = {
+ .tag = RTE_NTNIC_SERVICE_PORT_1_EVENT,
+ .id = NT_SERVICE_UNKNOWN_ID,
+ .lcore = RTE_MAX_LCORE,
+ .initialized = false,
+ },
};
inline struct nt_service *nthw_service_get_info(const enum rte_ntnic_service_tag tag)
diff --git a/drivers/net/ntnic/rte_pmd_ntnic.h b/drivers/net/ntnic/rte_pmd_ntnic.h
index 6fe6541984..1a68cb8e37 100644
--- a/drivers/net/ntnic/rte_pmd_ntnic.h
+++ b/drivers/net/ntnic/rte_pmd_ntnic.h
@@ -43,6 +43,8 @@ enum rte_ntnic_event_type {
enum rte_ntnic_service_tag {
RTE_NTNIC_SERVICE_FLM_UPDATE = 0,
RTE_NTNIC_SERVICE_STAT = 1,
+ RTE_NTNIC_SERVICE_PORT_0_EVENT = 2,
+ RTE_NTNIC_SERVICE_PORT_1_EVENT = 3,
RTE_NTNIC_SERVICE_MAX
};
--
2.45.0
next prev parent reply other threads:[~2025-09-08 14:18 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-08 11:04 [PATCH v1 0/7] migrate threads to DPDK service framework Serhii Iliushyk
2025-09-08 11:04 ` [PATCH v1 1/7] net/ntnic: introduce service API for NTNIC PMD Serhii Iliushyk
2025-09-08 11:04 ` [PATCH v1 2/7] net/ntnic: migrate flm update thread to service Serhii Iliushyk
2025-09-08 11:04 ` [PATCH v1 3/7] net/ntnic: migrate statistic " Serhii Iliushyk
2025-09-08 11:04 ` [PATCH v1 4/7] net/ntnic: migrate port event " Serhii Iliushyk
2025-09-08 11:04 ` [PATCH v1 5/7] net/ntnic: migrate adapter mon " Serhii Iliushyk
2025-09-08 11:04 ` [PATCH v1 6/7] net/ntnic: add warning about service cores Serhii Iliushyk
2025-09-08 11:04 ` [PATCH v1 7/7] net/ntnic: cleanup using pthreads and rte_thread Serhii Iliushyk
2025-09-08 14:17 ` [PATCH v2 0/7] migrate threads to DPDK service framework Serhii Iliushyk
2025-09-08 14:17 ` [PATCH v2 1/7] net/ntnic: introduce service API for NTNIC PMD Serhii Iliushyk
2025-09-08 14:17 ` [PATCH v2 2/7] net/ntnic: migrate flm update thread to service Serhii Iliushyk
2025-09-08 14:17 ` [PATCH v2 3/7] net/ntnic: migrate statistic " Serhii Iliushyk
2025-09-08 14:17 ` Serhii Iliushyk [this message]
2025-09-08 14:17 ` [PATCH v2 5/7] net/ntnic: migrate adapter mon " Serhii Iliushyk
2025-09-08 14:17 ` [PATCH v2 6/7] net/ntnic: add warning about service cores Serhii Iliushyk
2025-09-08 14:17 ` [PATCH v2 7/7] net/ntnic: cleanup using pthreads and rte_thread Serhii Iliushyk
2025-09-08 20:08 ` [PATCH v1 0/7] migrate threads to DPDK service framework Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250908141740.1312268-5-sil-plv@napatech.com \
--to=sil-plv@napatech.com \
--cc=ckm@napatech.com \
--cc=dev@dpdk.org \
--cc=mko-plv@napatech.com \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).