Skip to content

Commit

Permalink
change RTE_INIT
Browse files Browse the repository at this point in the history
Signed-off-by: David Marchand <[email protected]>
  • Loading branch information
david-marchand committed Dec 4, 2024
1 parent 1b3bf11 commit efc8651
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 95 deletions.
3 changes: 3 additions & 0 deletions lib/eal/common/eal_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ struct rte_config {
*/
struct rte_config *rte_eal_get_configuration(void);

void
eal_init_early(void);

/**
* Initialize the memzone subsystem (private to eal).
*
Expand Down
97 changes: 2 additions & 95 deletions lib/eal/include/rte_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include <rte_config.h>

#include <rte_init.h>

/* OS specific include */
#include <rte_os.h>

Expand Down Expand Up @@ -262,101 +264,6 @@ typedef uint16_t unaligned_uint16_t;
#define __rte_dealloc(dealloc, argno)
#endif

#define RTE_PRIORITY_LOG 101
#define RTE_PRIORITY_BUS 110
#define RTE_PRIORITY_CLASS 120
#define RTE_PRIORITY_LAST 65535

#define RTE_PRIO(prio) \
RTE_PRIORITY_ ## prio

/**
* Run function before main() with high priority.
*
* @param func
* Constructor function.
* @param prio
* Priority number must be above 100.
* Lowest number is the first to run.
*/
#ifndef RTE_INIT_PRIO /* Allow to override from EAL */
#ifndef RTE_TOOLCHAIN_MSVC
#define RTE_INIT_PRIO(func, prio) \
static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void)
#else
/* definition from the Microsoft CRT */
typedef int(__cdecl *_PIFV)(void);

#define CTOR_SECTION_LOG ".CRT$XIB"
#define CTOR_SECTION_BUS ".CRT$XIC"
#define CTOR_SECTION_CLASS ".CRT$XID"
#define CTOR_SECTION_LAST ".CRT$XIY"

#define CTOR_PRIORITY_TO_SECTION(priority) CTOR_SECTION_ ## priority

#define RTE_INIT_PRIO(name, priority) \
static void name(void); \
static int __cdecl name ## _thunk(void) { name(); return 0; } \
__pragma(const_seg(CTOR_PRIORITY_TO_SECTION(priority))) \
__declspec(allocate(CTOR_PRIORITY_TO_SECTION(priority))) \
_PIFV name ## _pointer = &name ## _thunk; \
__pragma(const_seg()) \
static void name(void)
#endif
#endif

/**
* Run function before main() with low priority.
*
* The constructor will be run after prioritized constructors.
*
* @param func
* Constructor function.
*/
#define RTE_INIT(func) \
RTE_INIT_PRIO(func, LAST)

/**
* Run after main() with low priority.
*
* @param func
* Destructor function name.
* @param prio
* Priority number must be above 100.
* Lowest number is the last to run.
*/
#ifndef RTE_FINI_PRIO /* Allow to override from EAL */
#ifndef RTE_TOOLCHAIN_MSVC
#define RTE_FINI_PRIO(func, prio) \
static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
#else
#define DTOR_SECTION_LOG "mydtor$B"
#define DTOR_SECTION_BUS "mydtor$C"
#define DTOR_SECTION_CLASS "mydtor$D"
#define DTOR_SECTION_LAST "mydtor$Y"

#define DTOR_PRIORITY_TO_SECTION(priority) DTOR_SECTION_ ## priority

#define RTE_FINI_PRIO(name, priority) \
static void name(void); \
__pragma(const_seg(DTOR_PRIORITY_TO_SECTION(priority))) \
__declspec(allocate(DTOR_PRIORITY_TO_SECTION(priority))) void *name ## _pointer = &name; \
__pragma(const_seg()) \
static void name(void)
#endif
#endif

/**
* Run after main() with high priority.
*
* The destructor will be run *before* prioritized destructors.
*
* @param func
* Destructor function name.
*/
#define RTE_FINI(func) \
RTE_FINI_PRIO(func, LAST)

/**
* Hint never returning function
*/
Expand Down
2 changes: 2 additions & 0 deletions lib/eal/linux/eal.c
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,8 @@ rte_eal_init(int argc, char **argv)
struct internal_config *internal_conf =
eal_get_internal_configuration();

eal_init_early();

/* setup log as early as possible */
if (eal_parse_log_options(argc, argv) < 0) {
rte_eal_init_alert("invalid log arguments.");
Expand Down
6 changes: 6 additions & 0 deletions lib/init/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024 Red Hat, Inc.

includes += global_inc
sources = files('rte_init.c')
headers = files('rte_init.h')
63 changes: 63 additions & 0 deletions lib/init/rte_init.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include <rte_common.h>

static bool init_called;

RTE_TAILQ_HEAD(, rte_init) rte_init_list;
struct rte_init {
RTE_TAILQ_ENTRY(rte_init) next;
unsigned int priority;
const char *file;
int line;
void (*init)(void);
};

void
rte_init_register(const char *file, int line, void (*init)(void), unsigned int priority)
{
struct rte_init *p;
struct rte_init *i;

/*
* This code has been invoked after rte_eal_init() (common case is with drivers loaded
* as shared libraries).
*/
if (init_called) {
printf("Late init for %s:%d, priority %u\n", file, line, priority);
init();
return;
}

i = malloc(sizeof(*i));
if (i == NULL)
return;

i->priority = priority;
i->file = file;
i->line = line;
i->init = init;

TAILQ_FOREACH(p, &rte_init_list, next) {
if (i->priority >= p->priority)
continue;
TAILQ_INSERT_BEFORE(p, i, next);
}

TAILQ_INSERT_HEAD(&rte_init_list, i, next);
}

void
eal_init_early(void)
{
struct rte_init *i;

init_called = true;

TAILQ_FOREACH(i, &rte_init_list, next) {
printf("Init for %s:%d, priority %u\n", i->file, i->line, i->priority);
i->init();
}
}
118 changes: 118 additions & 0 deletions lib/init/rte_init.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2019 Intel Corporation
*/

#ifndef RTE_INIT_H
#define RTE_INIT_H

#include <rte_compat.h>

__rte_experimental
void
rte_init_register(const char *file, int line, void (*init)(void), unsigned int prio);

__rte_internal
void
eal_init_early(void);

#define RTE_PRIORITY_LOG 101
#define RTE_PRIORITY_BUS 110
#define RTE_PRIORITY_CLASS 120
#define RTE_PRIORITY_LAST 65535

#define RTE_PRIO(prio) \
RTE_PRIORITY_ ## prio

/**
* Run function before main() with high priority.
*
* @param func
* Constructor function.
* @param prio
* Priority number must be above 100.
* Lowest number is the first to run.
*/
#ifndef RTE_INIT_PRIO /* Allow to override from EAL */
#ifndef RTE_TOOLCHAIN_MSVC
#define RTE_INIT_PRIO(func, prio) \
static void func(void); \
static void __attribute__((constructor(RTE_PRIO(prio)), used)) init_ ## func(void) \
{ \
rte_init_register(__FILE__, __LINE__, func, RTE_PRIO(prio)); \
} \
static void func(void)
#else
/* definition from the Microsoft CRT */
typedef int(__cdecl *_PIFV)(void);

#define CTOR_SECTION_LOG ".CRT$XIB"
#define CTOR_SECTION_BUS ".CRT$XIC"
#define CTOR_SECTION_CLASS ".CRT$XID"
#define CTOR_SECTION_LAST ".CRT$XIY"

#define CTOR_PRIORITY_TO_SECTION(priority) CTOR_SECTION_ ## priority

#define RTE_INIT_PRIO(name, priority) \
static void name(void); \
static int __cdecl name ## _thunk(void) { name(); return 0; } \
__pragma(const_seg(CTOR_PRIORITY_TO_SECTION(priority))) \
__declspec(allocate(CTOR_PRIORITY_TO_SECTION(priority))) \
_PIFV name ## _pointer = &name ## _thunk; \
__pragma(const_seg()) \
static void name(void)
#endif
#endif

/**
* Run function before main() with low priority.
*
* The constructor will be run after prioritized constructors.
*
* @param func
* Constructor function.
*/
#define RTE_INIT(func) \
RTE_INIT_PRIO(func, LAST)

/**
* Run after main() with low priority.
*
* @param func
* Destructor function name.
* @param prio
* Priority number must be above 100.
* Lowest number is the last to run.
*/
#ifndef RTE_FINI_PRIO /* Allow to override from EAL */
#ifndef RTE_TOOLCHAIN_MSVC
#define RTE_FINI_PRIO(func, prio) \
static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
#else
#define DTOR_SECTION_LOG "mydtor$B"
#define DTOR_SECTION_BUS "mydtor$C"
#define DTOR_SECTION_CLASS "mydtor$D"
#define DTOR_SECTION_LAST "mydtor$Y"

#define DTOR_PRIORITY_TO_SECTION(priority) DTOR_SECTION_ ## priority

#define RTE_FINI_PRIO(name, priority) \
static void name(void); \
__pragma(const_seg(DTOR_PRIORITY_TO_SECTION(priority))) \
__declspec(allocate(DTOR_PRIORITY_TO_SECTION(priority))) void *name ## _pointer = &name; \
__pragma(const_seg()) \
static void name(void)
#endif
#endif

/**
* Run after main() with high priority.
*
* The destructor will be run *before* prioritized destructors.
*
* @param func
* Destructor function name.
*/
#define RTE_FINI(func) \
RTE_FINI_PRIO(func, LAST)

#endif /* RTE_INIT_H */
13 changes: 13 additions & 0 deletions lib/init/version.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
EXPERIMENTAL {
global:

rte_init_register;

local: *;
};

INTERNAL {
global:

eal_init_early;
};
6 changes: 6 additions & 0 deletions lib/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# given as a dep, no need to mention ring. This is especially true for the
# core libs which are widely reused, so their deps are kept to a minimum.
libraries = [
'init',
'log',
'kvargs', # eal depends on kvargs
'argparse',
Expand Down Expand Up @@ -74,6 +75,7 @@ always_enable = [
'eal',
'ethdev',
'hash',
'init',
'kvargs',
'log',
'mbuf',
Expand Down Expand Up @@ -134,6 +136,10 @@ foreach l:libraries
# external package/library requirements
ext_deps = []
deps = []
# init (that comes first in the libraries list) can't depend on itself
if dpdk_conf.has('RTE_LIB_INIT')
deps += ['init']
endif
# eal is standard dependency once built
if dpdk_conf.has('RTE_LIB_EAL')
deps += ['eal']
Expand Down

0 comments on commit efc8651

Please sign in to comment.