From: Chaoyong He <chaoyong.he@corigine.com>
To: dev@dpdk.org
Cc: oss-drivers@corigine.com, Long Wu <long.wu@corigine.com>,
Chaoyong He <chaoyong.he@corigine.com>,
Peng Zhang <peng.zhang@corigine.com>
Subject: [PATCH 1/4] net/nfp: add synchronize module
Date: Wed, 24 Jan 2024 17:25:38 +0800 [thread overview]
Message-ID: <20240124092541.2011874-2-chaoyong.he@corigine.com> (raw)
In-Reply-To: <20240124092541.2011874-1-chaoyong.he@corigine.com>
From: Long Wu <long.wu@corigine.com>
PMD has some information that needs synchronized:
1. Between devices in one process.
2. Between multiple processes for one device, before creating
"rte_eth_device".
3. Between multiple processes for one device, after creating
"rte_eth_device".
The final one is already support by framework
(eth_dev->data->dev_private), and this patch aims to support
the first two cases by adding a synchronize module.
Signed-off-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
drivers/net/nfp/meson.build | 1 +
drivers/net/nfp/nfp_ethdev.c | 31 ++-
drivers/net/nfp/nfp_net_common.h | 4 +
drivers/net/nfp/nfpcore/nfp_sync.c | 382 +++++++++++++++++++++++++++++
drivers/net/nfp/nfpcore/nfp_sync.h | 29 +++
5 files changed, 444 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/nfp/nfpcore/nfp_sync.c
create mode 100644 drivers/net/nfp/nfpcore/nfp_sync.h
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 46be6f60cd..c625355d7a 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -26,6 +26,7 @@ sources = files(
'nfpcore/nfp_nsp_eth.c',
'nfpcore/nfp_resource.c',
'nfpcore/nfp_rtsym.c',
+ 'nfpcore/nfp_sync.c',
'nfpcore/nfp_target.c',
'nfpcore/nfp6000_pcie.c',
'nfp_cpp_bridge.c',
diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index 07cd32881c..3ece806487 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -19,6 +19,7 @@
#include "nfpcore/nfp_nsp.h"
#include "nfpcore/nfp6000_pcie.h"
#include "nfpcore/nfp_resource.h"
+#include "nfpcore/nfp_sync.h"
#include "nfp_cpp_bridge.h"
#include "nfp_ipsec.h"
@@ -551,6 +552,7 @@ nfp_pf_uninit(struct nfp_pf_dev *pf_dev)
free(pf_dev->nfp_eth_table);
free(pf_dev->hwinfo);
nfp_cpp_free(pf_dev->cpp);
+ nfp_sync_free(pf_dev->sync);
rte_free(pf_dev);
}
@@ -559,6 +561,7 @@ nfp_pf_secondary_uninit(struct nfp_pf_dev *pf_dev)
{
free(pf_dev->sym_tbl);
nfp_cpp_free(pf_dev->cpp);
+ nfp_sync_free(pf_dev->sync);
rte_free(pf_dev);
return 0;
@@ -1612,6 +1615,7 @@ nfp_net_speed_capa_get(struct nfp_pf_dev *pf_dev,
static int
nfp_pf_init(struct rte_pci_device *pci_dev)
{
+ void *sync;
uint32_t i;
uint32_t id;
int ret = 0;
@@ -1652,6 +1656,13 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
return -ENOMEM;
}
+ sync = nfp_sync_alloc();
+ if (sync == NULL) {
+ PMD_INIT_LOG(ERR, "Failed to alloc sync zone.");
+ ret = -ENOMEM;
+ goto pf_cleanup;
+ }
+
/*
* When device bound to UIO, the device could be used, by mistake,
* by two DPDK apps, and the UIO driver does not avoid it. This
@@ -1667,7 +1678,7 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
if (cpp == NULL) {
PMD_INIT_LOG(ERR, "A CPP handle can not be obtained");
ret = -EIO;
- goto pf_cleanup;
+ goto sync_free;
}
hwinfo = nfp_hwinfo_read(cpp);
@@ -1734,6 +1745,7 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
pf_dev->sym_tbl = sym_tbl;
pf_dev->pci_dev = pci_dev;
pf_dev->nfp_eth_table = nfp_eth_table;
+ pf_dev->sync = sync;
/* Get the speed capability */
for (i = 0; i < nfp_eth_table->count; i++) {
@@ -1815,6 +1827,8 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
free(hwinfo);
cpp_cleanup:
nfp_cpp_free(cpp);
+sync_free:
+ nfp_sync_free(sync);
pf_cleanup:
rte_free(pf_dev);
@@ -1878,6 +1892,7 @@ nfp_secondary_init_app_fw_nic(struct nfp_pf_dev *pf_dev)
static int
nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
{
+ void *sync;
int ret = 0;
struct nfp_cpp *cpp;
uint8_t function_id;
@@ -1910,6 +1925,13 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
return -ENOMEM;
}
+ sync = nfp_sync_alloc();
+ if (sync == NULL) {
+ PMD_INIT_LOG(ERR, "Failed to alloc sync zone.");
+ ret = -ENOMEM;
+ goto pf_cleanup;
+ }
+
/*
* When device bound to UIO, the device could be used, by mistake,
* by two DPDK apps, and the UIO driver does not avoid it. This
@@ -1925,7 +1947,7 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
if (cpp == NULL) {
PMD_INIT_LOG(ERR, "A CPP handle can not be obtained");
ret = -EIO;
- goto pf_cleanup;
+ goto sync_free;
}
/*
@@ -1936,7 +1958,7 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
if (sym_tbl == NULL) {
PMD_INIT_LOG(ERR, "Something is wrong with the firmware symbol table");
ret = -EIO;
- goto pf_cleanup;
+ goto sync_free;
}
/* Read the app ID of the firmware loaded */
@@ -1954,6 +1976,7 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
pf_dev->cpp = cpp;
pf_dev->sym_tbl = sym_tbl;
pf_dev->pci_dev = pci_dev;
+ pf_dev->sync = sync;
/* Call app specific init code now */
switch (app_fw_id) {
@@ -1983,6 +2006,8 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
sym_tbl_cleanup:
free(sym_tbl);
+sync_free:
+ nfp_sync_free(sync);
pf_cleanup:
rte_free(pf_dev);
diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h
index 66c900e3b8..110ca015c0 100644
--- a/drivers/net/nfp/nfp_net_common.h
+++ b/drivers/net/nfp/nfp_net_common.h
@@ -12,6 +12,7 @@
#include <nfp_dev.h>
#include <rte_spinlock.h>
+#include "nfpcore/nfp_sync.h"
#include "nfp_net_ctrl.h"
/* Interrupt definitions */
@@ -109,6 +110,9 @@ struct nfp_pf_dev {
/** Supported speeds bitmap */
uint32_t speed_capa;
+
+ /** Synchronized info */
+ struct nfp_sync *sync;
};
#define NFP_NET_FLOW_LIMIT 1024
diff --git a/drivers/net/nfp/nfpcore/nfp_sync.c b/drivers/net/nfp/nfpcore/nfp_sync.c
new file mode 100644
index 0000000000..8bc38d6585
--- /dev/null
+++ b/drivers/net/nfp/nfpcore/nfp_sync.c
@@ -0,0 +1,382 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2024 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include "nfp_sync.h"
+
+#include <rte_dev.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_spinlock.h>
+
+#include "nfp_logs.h"
+
+#define NFP_SYNC_ELEMENT_MAX 8
+#define NFP_SYNC_PCI_MAX 32
+
+struct nfp_sync_element {
+ uint16_t count;
+ /** Element ID, use ASCII - SYN<> */
+ uint32_t magic;
+ void *handle;
+};
+
+struct nfp_sync_common {
+ char pci_name[PCI_PRI_STR_SIZE + 1];
+ uint16_t avail;
+ struct nfp_sync_element element[NFP_SYNC_ELEMENT_MAX];
+};
+
+struct nfp_sync {
+ rte_spinlock_t spinlock;
+
+ uint16_t alloc_count;
+
+ struct nfp_sync_common process;
+
+ struct nfp_sync_common pci[NFP_SYNC_PCI_MAX];
+
+ const struct rte_memzone *mz;
+};
+
+struct nfp_sync *
+nfp_sync_alloc(void)
+{
+ uint16_t i;
+ struct nfp_sync *sync;
+ const struct rte_memzone *mz;
+
+ mz = rte_memzone_lookup("nfp_sync");
+ if (mz != NULL) {
+ sync = mz->addr;
+ sync->alloc_count++;
+
+ return sync;
+ }
+
+ mz = rte_memzone_reserve("nfp_sync", sizeof(*sync), SOCKET_ID_ANY,
+ RTE_MEMZONE_SIZE_HINT_ONLY);
+ if (mz == NULL)
+ return NULL;
+
+ sync = mz->addr;
+
+ memset(sync, 0, sizeof(*sync));
+
+ rte_spinlock_init(&sync->spinlock);
+ sync->alloc_count = 1;
+ sync->mz = mz;
+
+ for (i = 0; i < NFP_SYNC_PCI_MAX; i++)
+ sync->pci[i].avail = NFP_SYNC_ELEMENT_MAX;
+
+ sync->process.avail = NFP_SYNC_ELEMENT_MAX;
+
+ return sync;
+}
+
+void
+nfp_sync_free(struct nfp_sync *sync)
+{
+ uint16_t i;
+
+ rte_spinlock_lock(&sync->spinlock);
+
+ sync->alloc_count--;
+ if (sync->alloc_count != 0) {
+ rte_spinlock_unlock(&sync->spinlock);
+ return;
+ }
+
+ if (sync->process.avail != NFP_SYNC_ELEMENT_MAX)
+ PMD_DRV_LOG(ERR, "Sync process handle residue");
+
+ for (i = 0; i < NFP_SYNC_PCI_MAX; i++) {
+ if (sync->pci[i].avail != NFP_SYNC_ELEMENT_MAX)
+ PMD_DRV_LOG(ERR, "Sync %s pci handle residue",
+ sync->pci[i].pci_name);
+ }
+
+ rte_spinlock_unlock(&sync->spinlock);
+
+ rte_memzone_free(sync->mz);
+}
+
+static void *
+nfp_sync_element_alloc(struct nfp_sync_element *element,
+ uint32_t magic,
+ uint32_t size)
+{
+ void *handle;
+
+ handle = rte_zmalloc(NULL, size, 0);
+ if (handle == NULL)
+ return NULL;
+
+ element->handle = handle;
+ element->count = 1;
+ element->magic = magic;
+
+ return handle;
+}
+
+static void
+nfp_sync_element_free(struct nfp_sync_element *element,
+ void *handle)
+{
+ element->count--;
+ if (element->count != 0)
+ return;
+
+ rte_free(handle);
+ element->handle = NULL;
+ element->magic = 0;
+}
+
+static void *
+nfp_sync_common_handle_alloc(struct nfp_sync_common *common,
+ uint32_t magic,
+ uint32_t size)
+{
+ uint16_t i;
+ void *handle = NULL;
+ uint16_t avail_slot = NFP_SYNC_ELEMENT_MAX;
+
+ for (i = 0; i < NFP_SYNC_ELEMENT_MAX; i++) {
+ if (common->element[i].magic != magic)
+ continue;
+
+ common->element[i].count++;
+
+ return common->element[i].handle;
+ }
+
+ if (common->avail == 0)
+ return NULL;
+
+ for (i = 0; i < NFP_SYNC_ELEMENT_MAX; i++) {
+ if (common->element[i].magic == 0) {
+ avail_slot = i;
+ break;
+ }
+ }
+
+ handle = nfp_sync_element_alloc(&common->element[avail_slot], magic, size);
+ if (handle == NULL)
+ return NULL;
+
+ common->avail--;
+
+ return handle;
+}
+
+static void
+nfp_sync_common_handle_free(struct nfp_sync_common *common,
+ void *handle)
+{
+ uint16_t i;
+
+ if (common->avail == NFP_SYNC_ELEMENT_MAX)
+ return;
+
+ for (i = 0; i < NFP_SYNC_ELEMENT_MAX; i++) {
+ if (common->element[i].handle == handle)
+ break;
+ }
+
+ if (i == NFP_SYNC_ELEMENT_MAX)
+ return;
+
+ nfp_sync_element_free(&common->element[i], handle);
+
+ if (common->element[i].count == 0)
+ common->avail++;
+}
+
+static void *
+nfp_sync_process_inner_handle_alloc(struct nfp_sync *sync,
+ uint32_t magic,
+ uint32_t size)
+{
+ void *handle = NULL;
+
+ rte_spinlock_lock(&sync->spinlock);
+
+ handle = nfp_sync_common_handle_alloc(&sync->process, magic, size);
+ if (handle == NULL)
+ PMD_DRV_LOG(ERR, "Process handle alloc failed");
+
+ rte_spinlock_unlock(&sync->spinlock);
+
+ return handle;
+}
+
+static void
+nfp_sync_process_inner_handle_free(struct nfp_sync *sync,
+ void *handle)
+{
+ rte_spinlock_lock(&sync->spinlock);
+
+ nfp_sync_common_handle_free(&sync->process, handle);
+
+ rte_spinlock_unlock(&sync->spinlock);
+}
+
+static uint16_t
+nfp_sync_process_handle_count_get(struct nfp_sync *sync,
+ void *handle)
+{
+ uint16_t i;
+ uint16_t count = 0;
+
+ rte_spinlock_lock(&sync->spinlock);
+
+ for (i = 0; i < NFP_SYNC_ELEMENT_MAX; i++) {
+ if (sync->process.element[i].handle == handle) {
+ count = sync->process.element[i].count;
+ break;
+ }
+ }
+
+ rte_spinlock_unlock(&sync->spinlock);
+
+ return count;
+}
+
+static void *
+nfp_sync_pci_inner_handle_alloc(struct nfp_sync *sync,
+ const char *pci_name,
+ uint32_t magic,
+ uint32_t size)
+{
+ uint16_t i;
+ void *handle = NULL;
+ uint16_t pci_avail_id = NFP_SYNC_PCI_MAX;
+
+ rte_spinlock_lock(&sync->spinlock);
+
+ for (i = 0; i < NFP_SYNC_PCI_MAX; i++) {
+ if (strcmp(pci_name, sync->pci[i].pci_name) == 0) {
+ pci_avail_id = i;
+ goto common_alloc;
+ }
+ }
+
+ for (i = 0; i < NFP_SYNC_PCI_MAX; i++) {
+ if (strlen(sync->pci[i].pci_name) == 0) {
+ pci_avail_id = i;
+ strcpy(sync->pci[pci_avail_id].pci_name, pci_name);
+ goto common_alloc;
+ }
+ }
+
+ rte_spinlock_unlock(&sync->spinlock);
+
+ return NULL;
+
+common_alloc:
+ handle = nfp_sync_common_handle_alloc(&sync->pci[pci_avail_id],
+ magic, size);
+ if (handle == NULL)
+ PMD_DRV_LOG(ERR, "PCI handle alloc failed");
+
+ rte_spinlock_unlock(&sync->spinlock);
+
+ return handle;
+}
+
+static void
+nfp_sync_pci_inner_handle_free(struct nfp_sync *sync,
+ const char *pci_name,
+ void *handle)
+{
+ uint16_t i;
+ char *name_tmp;
+
+ rte_spinlock_lock(&sync->spinlock);
+
+ for (i = 0; i < NFP_SYNC_PCI_MAX; i++) {
+ name_tmp = sync->pci[i].pci_name;
+ if (strlen(name_tmp) != 0 && strcmp(pci_name, name_tmp) == 0) {
+ nfp_sync_common_handle_free(&sync->pci[i], handle);
+ if (sync->pci[i].avail == NFP_SYNC_ELEMENT_MAX)
+ name_tmp[0] = 0;
+ break;
+ }
+ }
+
+ rte_spinlock_unlock(&sync->spinlock);
+}
+
+static uint16_t
+nfp_sync_pci_handle_count_get(struct nfp_sync *sync,
+ const char *pci_name,
+ void *handle)
+{
+ uint16_t i;
+ uint16_t count = 0;
+ struct nfp_sync_common *pci_common;
+
+ rte_spinlock_lock(&sync->spinlock);
+
+ for (i = 0; i < NFP_SYNC_PCI_MAX; i++) {
+ if (strcmp(sync->pci[i].pci_name, pci_name) == 0)
+ break;
+ }
+
+ if (i == NFP_SYNC_PCI_MAX) {
+ rte_spinlock_unlock(&sync->spinlock);
+ return 0;
+ }
+
+ pci_common = &sync->pci[i];
+
+ for (i = 0; i < NFP_SYNC_ELEMENT_MAX; i++) {
+ if (pci_common->element[i].handle == handle) {
+ count = pci_common->element[i].count;
+ break;
+ }
+ }
+
+ rte_spinlock_unlock(&sync->spinlock);
+
+ return count;
+}
+
+void *
+nfp_sync_handle_alloc(struct nfp_sync *sync,
+ struct rte_pci_device *pci_dev,
+ uint32_t magic,
+ uint32_t size)
+{
+ if (pci_dev == NULL)
+ return nfp_sync_process_inner_handle_alloc(sync, magic, size);
+
+ return nfp_sync_pci_inner_handle_alloc(sync, pci_dev->device.name,
+ magic, size);
+}
+
+void
+nfp_sync_handle_free(struct nfp_sync *sync,
+ struct rte_pci_device *pci_dev,
+ void *handle)
+{
+ if (pci_dev == NULL) {
+ nfp_sync_process_inner_handle_free(sync, handle);
+ return;
+ }
+
+ nfp_sync_pci_inner_handle_free(sync, pci_dev->device.name, handle);
+}
+
+uint16_t
+nfp_sync_handle_count_get(struct nfp_sync *sync,
+ struct rte_pci_device *pci_dev,
+ void *handle)
+{
+ if (pci_dev == NULL)
+ return nfp_sync_process_handle_count_get(sync, handle);
+
+ return nfp_sync_pci_handle_count_get(sync, pci_dev->device.name, handle);
+}
diff --git a/drivers/net/nfp/nfpcore/nfp_sync.h b/drivers/net/nfp/nfpcore/nfp_sync.h
new file mode 100644
index 0000000000..82f01e2652
--- /dev/null
+++ b/drivers/net/nfp/nfpcore/nfp_sync.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2024 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#ifndef __NFP_SYNC_H__
+#define __NFP_SYNC_H__
+
+#include <stdint.h>
+
+#include <bus_pci_driver.h>
+
+struct nfp_sync;
+
+struct nfp_sync *nfp_sync_alloc(void);
+void nfp_sync_free(struct nfp_sync *sync);
+
+void *nfp_sync_handle_alloc(struct nfp_sync *sync,
+ struct rte_pci_device *pci_dev,
+ uint32_t magic,
+ uint32_t size);
+void nfp_sync_handle_free(struct nfp_sync *sync,
+ struct rte_pci_device *pci_dev,
+ void *handle);
+uint16_t nfp_sync_handle_count_get(struct nfp_sync *sync,
+ struct rte_pci_device *pci_dev,
+ void *handle);
+
+#endif /* __NFP_SYNC_H__ */
--
2.39.1
next prev parent reply other threads:[~2024-01-24 9:26 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-24 9:25 [PATCH 0/4] enhance NFP service framework Chaoyong He
2024-01-24 9:25 ` Chaoyong He [this message]
2024-01-24 9:25 ` [PATCH 2/4] net/nfp: create new service code related files Chaoyong He
2024-01-24 9:25 ` [PATCH 3/4] net/nfp: flower driver uses one service core Chaoyong He
2024-01-24 9:25 ` [PATCH 4/4] net/nfp: fix stop cpp service problem Chaoyong He
2024-01-30 12:07 ` Ferruh Yigit
2024-01-30 12:17 ` Kevin Traynor
2024-02-02 3:04 ` [PATCH v2 0/3] enhance NFP service framework Chaoyong He
2024-02-02 3:04 ` [PATCH v2 1/3] net/nfp: add synchronize module Chaoyong He
2024-02-02 3:04 ` [PATCH v2 2/3] net/nfp: create new service code related files Chaoyong He
2024-02-02 3:04 ` [PATCH v2 3/3] net/nfp: flower driver uses one service core Chaoyong He
2024-02-06 15:17 ` [PATCH v2 0/3] enhance NFP service framework Ferruh Yigit
2024-02-08 9:52 ` Chaoyong He
2024-02-08 13:58 ` Ferruh Yigit
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=20240124092541.2011874-2-chaoyong.he@corigine.com \
--to=chaoyong.he@corigine.com \
--cc=dev@dpdk.org \
--cc=long.wu@corigine.com \
--cc=oss-drivers@corigine.com \
--cc=peng.zhang@corigine.com \
/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).