From: Tonghao Zhang <xiangxia.m....@gmail.com>

This patch introduces last-init queue, user can register a
callback for theirs initialization. Running rte_last_init_run(),
the almost resource of DPDK are available, such as memzone, ring.
With this way, user don't introduce additional codes in eal layer.

[This patch will be used for next patch.]

Signed-off-by: Tonghao Zhang <xiangxia.m....@gmail.com>
---
v2:
* rename rte_last_init_register ->rte_init_register
* rename rte_last_init struct ->rte_init
* rename rte_init_cb ->rte_init_cb_t 
* free the rte_init node when not used.
* remove rte_init and others to eal_private.h
* add comments
* fix checkpatch warning
---
 lib/librte_eal/common/eal_common_init.c | 74 +++++++++++++++++++++++++++++++++
 lib/librte_eal/common/eal_private.h     | 23 ++++++++++
 lib/librte_eal/common/meson.build       |  1 +
 lib/librte_eal/freebsd/Makefile         |  1 +
 lib/librte_eal/freebsd/eal.c            |  6 +++
 lib/librte_eal/include/rte_init.h       | 59 ++++++++++++++++++++++++++
 lib/librte_eal/linux/Makefile           |  1 +
 lib/librte_eal/linux/eal.c              |  6 +++
 8 files changed, 171 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_init.c
 create mode 100644 lib/librte_eal/include/rte_init.h

diff --git a/lib/librte_eal/common/eal_common_init.c 
b/lib/librte_eal/common/eal_common_init.c
new file mode 100644
index 0000000..1d89db3
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_init.c
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2020 DPDK Community
+ */
+
+#include <sys/queue.h>
+
+#include <rte_init.h>
+#include <rte_debug.h>
+#include <rte_tailq.h>
+
+#include "eal_private.h"
+
+static struct rte_init_list rte_init_list =
+       TAILQ_HEAD_INITIALIZER(rte_init_list);
+
+void
+rte_init_register(rte_init_cb_t cb, const void *arg, enum rte_init_type type)
+{
+       struct rte_init *last;
+
+       RTE_VERIFY(cb);
+
+       last = malloc(sizeof(*last));
+       if (last == NULL)
+               rte_panic("Alloc memory for rte_init node failed\n");
+
+       last->type = type;
+       last->arg = arg;
+       last->cb = cb;
+
+       TAILQ_INSERT_TAIL(&rte_init_list, last, next);
+}
+
+static int
+eal_rte_init_run_type(enum rte_init_type type)
+{
+       struct rte_init *last;
+       int ret;
+
+       TAILQ_FOREACH(last, &rte_init_list, next) {
+               if (last->type != type)
+                       continue;
+
+               ret = last->cb(last->arg);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int
+eal_rte_init_run(void)
+{
+       struct rte_init *last;
+       struct rte_init *tmp;
+       int ret;
+
+       ret = eal_rte_init_run_type(RTE_INIT_PRE);
+       if (ret < 0)
+               return ret;
+
+       ret = eal_rte_init_run_type(RTE_INIT_POST);
+       if (ret < 0)
+               return ret;
+
+       /* Free rte_init node, not used anymore. */
+       TAILQ_FOREACH_SAFE(last, &rte_init_list, next, tmp) {
+               TAILQ_REMOVE(&rte_init_list, last, next);
+               free(last);
+       }
+
+       return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h 
b/lib/librte_eal/common/eal_private.h
index ddcfbe2..f0bcc97 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -11,6 +11,7 @@
 
 #include <rte_dev.h>
 #include <rte_lcore.h>
+#include <rte_init.h>
 
 /**
  * Structure storing internal configuration (per-lcore)
@@ -60,6 +61,28 @@ struct rte_config {
 } __attribute__((__packed__));
 
 /**
+ * A structure describing a generic initialization.
+ */
+struct rte_init {
+       TAILQ_ENTRY(rte_init) next;
+       enum rte_init_type type;
+       rte_init_cb_t cb;
+       const void *arg;
+};
+
+/** Double linked list of rte_init. */
+TAILQ_HEAD(rte_init_list, rte_init);
+
+/**
+ * Run the callback registered in the global double linked list.
+ *
+ * @return
+ *   - 0 on success
+ *   - Negative on error
+ */
+int eal_rte_init_run(void);
+
+/**
  * Get the global configuration structure.
  *
  * @return
diff --git a/lib/librte_eal/common/meson.build 
b/lib/librte_eal/common/meson.build
index 02d9280..ad0ce6a 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -43,6 +43,7 @@ sources += files(
        'eal_common_thread.c',
        'eal_common_timer.c',
        'eal_common_uuid.c',
+       'eal_common_init.c',
        'hotplug_mp.c',
        'malloc_elem.c',
        'malloc_heap.c',
diff --git a/lib/librte_eal/freebsd/Makefile b/lib/librte_eal/freebsd/Makefile
index e5d4d8f..89c5649 100644
--- a/lib/librte_eal/freebsd/Makefile
+++ b/lib/librte_eal/freebsd/Makefile
@@ -60,6 +60,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_init.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c
diff --git a/lib/librte_eal/freebsd/eal.c b/lib/librte_eal/freebsd/eal.c
index 6ae37e7..63af98c 100644
--- a/lib/librte_eal/freebsd/eal.c
+++ b/lib/librte_eal/freebsd/eal.c
@@ -874,6 +874,12 @@ static void rte_eal_init_alert(const char *msg)
 
        eal_check_mem_on_local_socket();
 
+       if (eal_rte_init_run() < 0) {
+               rte_eal_init_alert("Cannot init objects in rte-init queue");
+               rte_errno = EFAULT;
+               return -1;
+       }
+
        eal_thread_init_master(rte_config.master_lcore);
 
        ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset));
diff --git a/lib/librte_eal/include/rte_init.h 
b/lib/librte_eal/include/rte_init.h
new file mode 100644
index 0000000..636efff
--- /dev/null
+++ b/lib/librte_eal/include/rte_init.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2020 DPDK Community
+ */
+
+#ifndef _RTE_INIT_H_
+#define _RTE_INIT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <sys/queue.h>
+
+/**
+ * Implementation specific callback function which is
+ * responsible for specificed initialization.
+ *
+ * This is called when almost resources are available.
+ *
+ * @return
+ *     0 for successful callback
+ *     Negative for unsuccessful callback with error value
+ */
+typedef int (*rte_init_cb_t)(const void *arg);
+
+/**
+ * rte_init type.
+ *
+ * The rte_init of RTE_INIT_PRE are called firstly,
+ * and then RTE_INIT_POST.
+ */
+enum rte_init_type {
+       RTE_INIT_PRE,
+       RTE_INIT_POST
+};
+
+/**
+ * Register a rte_init callback.
+ *
+ * @param cb
+ *   A pointer to a rte_init_cb structure, which will be used
+ *   in rte_eal_init().
+ *
+ * @param arg
+ *   The cb will use that as param.
+ *
+ * @param type
+ *   The type of rte_init registered.
+ */
+
+void rte_init_register(rte_init_cb_t cb, const void *arg,
+                      enum rte_init_type type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_INIT_H_ */
diff --git a/lib/librte_eal/linux/Makefile b/lib/librte_eal/linux/Makefile
index e5f4495..918d94b 100644
--- a/lib/librte_eal/linux/Makefile
+++ b/lib/librte_eal/linux/Makefile
@@ -67,6 +67,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_init.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c
diff --git a/lib/librte_eal/linux/eal.c b/lib/librte_eal/linux/eal.c
index 9530ee5..dd0c258 100644
--- a/lib/librte_eal/linux/eal.c
+++ b/lib/librte_eal/linux/eal.c
@@ -1203,6 +1203,12 @@ static void rte_eal_init_alert(const char *msg)
 
        eal_check_mem_on_local_socket();
 
+       if (eal_rte_init_run() < 0) {
+               rte_eal_init_alert("Cannot init objects in rte-init queue");
+               rte_errno = EFAULT;
+               return -1;
+       }
+
        eal_thread_init_master(rte_config.master_lcore);
 
        ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset));
-- 
1.8.3.1

Reply via email to