From 67260075a8027558ba0e7ca4d8e79c78f48f4750 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Thu, 14 Jan 2016 15:21:47 -0600 Subject: linux-generic: init: handle local/global init/term cleanly Restructure odp_init_global() and odp_init_local() so that they recover cleanly if initialization fails. At exit any partial initialization is reversed so that system is in the same state as before the failing call was made. This includes adding dummy termination calls for functions that do not require explicit cleanup for symmetry and future-proofing. Note: This patch partially addresses the issues identified by Bug https://bugs.linaro.org/show_bug.cgi?id=1706 Signed-off-by: Bill Fischofer Reviewed-by: Ivan Khoronzhuk Signed-off-by: Maxim Uvarov --- platform/linux-generic/include/odp_internal.h | 24 ++- platform/linux-generic/odp_init.c | 239 ++++++++++++++++++-------- platform/linux-generic/odp_system_info.c | 8 + platform/linux-generic/odp_time.c | 7 +- platform/linux-generic/odp_timer.c | 5 + 5 files changed, 209 insertions(+), 74 deletions(-) (limited to 'platform') diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index 113b7004..b22f9569 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -38,9 +38,29 @@ struct odp_global_data_s { odp_system_info_t system_info; }; +enum init_stage { + NO_INIT = 0, /* No init stages completed */ + TIME_INIT = 1, + SYSINFO_INIT = 2, + SHM_INIT = 3, + THREAD_INIT = 4, + POOL_INIT = 5, + QUEUE_INIT = 6, + SCHED_INIT = 7, + PKTIO_INIT = 8, + TIMER_INIT = 9, + CRYPTO_INIT = 10, + CLASSIFICATION_INIT = 11, + ALL_INIT = 12 /* All init stages completed */ +}; + extern struct odp_global_data_s odp_global_data; +int _odp_term_global(enum init_stage stage); +int _odp_term_local(enum init_stage stage); + int odp_system_info_init(void); +int odp_system_info_term(void); int odp_thread_init_global(void); int odp_thread_init_local(odp_thread_type_t type); @@ -75,9 +95,11 @@ int odp_schedule_init_local(void); int odp_schedule_term_local(void); int odp_timer_init_global(void); +int odp_timer_term_global(void); int odp_timer_disarm_all(void); -int odp_time_global_init(void); +int odp_time_init_global(void); +int odp_time_term_global(void); void _odp_flush_caches(void); diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c index ea997428..3a990d27 100644 --- a/platform/linux-generic/odp_init.c +++ b/platform/linux-generic/odp_init.c @@ -14,6 +14,7 @@ struct odp_global_data_s odp_global_data; int odp_init_global(const odp_init_t *params, const odp_platform_init_t *platform_params ODP_UNUSED) { + enum init_stage stage = NO_INIT; odp_global_data.log_fn = odp_override_log; odp_global_data.abort_fn = odp_override_abort; @@ -24,105 +25,170 @@ int odp_init_global(const odp_init_t *params, odp_global_data.abort_fn = params->abort_fn; } - if (odp_time_global_init()) { + if (odp_time_init_global()) { ODP_ERR("ODP time init failed.\n"); - return -1; + goto init_failed; } + stage = TIME_INIT; if (odp_system_info_init()) { ODP_ERR("ODP system_info init failed.\n"); - return -1; + goto init_failed; } + stage = SYSINFO_INIT; if (odp_shm_init_global()) { ODP_ERR("ODP shm init failed.\n"); - return -1; + goto init_failed; } + stage = SHM_INIT; if (odp_thread_init_global()) { ODP_ERR("ODP thread init failed.\n"); - return -1; + goto init_failed; } + stage = THREAD_INIT; if (odp_pool_init_global()) { ODP_ERR("ODP pool init failed.\n"); - return -1; + goto init_failed; } + stage = POOL_INIT; if (odp_queue_init_global()) { ODP_ERR("ODP queue init failed.\n"); - return -1; + goto init_failed; } + stage = QUEUE_INIT; if (odp_schedule_init_global()) { ODP_ERR("ODP schedule init failed.\n"); - return -1; + goto init_failed; } + stage = SCHED_INIT; if (odp_pktio_init_global()) { ODP_ERR("ODP packet io init failed.\n"); - return -1; + goto init_failed; } + stage = PKTIO_INIT; if (odp_timer_init_global()) { ODP_ERR("ODP timer init failed.\n"); - return -1; + goto init_failed; } + stage = TIMER_INIT; if (odp_crypto_init_global()) { ODP_ERR("ODP crypto init failed.\n"); - return -1; + goto init_failed; } + stage = CRYPTO_INIT; + if (odp_classification_init_global()) { ODP_ERR("ODP classification init failed.\n"); - return -1; + goto init_failed; } + stage = CLASSIFICATION_INIT; return 0; + +init_failed: + _odp_term_global(stage); + return -1; } int odp_term_global(void) { - int rc = 0; - - if (odp_classification_term_global()) { - ODP_ERR("ODP classificatio term failed.\n"); - rc = -1; - } - - if (odp_crypto_term_global()) { - ODP_ERR("ODP crypto term failed.\n"); - rc = -1; - } - - if (odp_pktio_term_global()) { - ODP_ERR("ODP pktio term failed.\n"); - rc = -1; - } - - if (odp_schedule_term_global()) { - ODP_ERR("ODP schedule term failed.\n"); - rc = -1; - } - - if (odp_queue_term_global()) { - ODP_ERR("ODP queue term failed.\n"); - rc = -1; - } - - if (odp_pool_term_global()) { - ODP_ERR("ODP buffer pool term failed.\n"); - rc = -1; - } + return _odp_term_global(ALL_INIT); +} - if (odp_thread_term_global()) { - ODP_ERR("ODP thread term failed.\n"); - rc = -1; - } +int _odp_term_global(enum init_stage stage) +{ + int rc = 0; - if (odp_shm_term_global()) { - ODP_ERR("ODP shm term failed.\n"); - rc = -1; + switch (stage) { + case ALL_INIT: + + case CLASSIFICATION_INIT: + if (odp_classification_term_global()) { + ODP_ERR("ODP classificatio term failed.\n"); + rc = -1; + } + /* Fall through */ + + case CRYPTO_INIT: + if (odp_crypto_term_global()) { + ODP_ERR("ODP crypto term failed.\n"); + rc = -1; + } + /* Fall through */ + + case TIMER_INIT: + if (odp_timer_term_global()) { + ODP_ERR("ODP timer term failed.\n"); + rc = -1; + } + /* Fall through */ + + case PKTIO_INIT: + if (odp_pktio_term_global()) { + ODP_ERR("ODP pktio term failed.\n"); + rc = -1; + } + /* Fall through */ + + case SCHED_INIT: + if (odp_schedule_term_global()) { + ODP_ERR("ODP schedule term failed.\n"); + rc = -1; + } + /* Fall through */ + + case QUEUE_INIT: + if (odp_queue_term_global()) { + ODP_ERR("ODP queue term failed.\n"); + rc = -1; + } + /* Fall through */ + + case POOL_INIT: + if (odp_pool_term_global()) { + ODP_ERR("ODP buffer pool term failed.\n"); + rc = -1; + } + /* Fall through */ + + case THREAD_INIT: + if (odp_thread_term_global()) { + ODP_ERR("ODP thread term failed.\n"); + rc = -1; + } + /* Fall through */ + + case SHM_INIT: + if (odp_shm_term_global()) { + ODP_ERR("ODP shm term failed.\n"); + rc = -1; + } + /* Fall through */ + + case SYSINFO_INIT: + if (odp_system_info_term()) { + ODP_ERR("ODP system info term failed.\n"); + rc = -1; + } + /* Fall through */ + + case TIME_INIT: + if (odp_time_term_global()) { + ODP_ERR("ODP time term failed.\n"); + rc = -1; + } + /* Fall through */ + + case NO_INIT: + ; } return rc; @@ -130,56 +196,85 @@ int odp_term_global(void) int odp_init_local(odp_thread_type_t thr_type) { + enum init_stage stage = NO_INIT; + if (odp_shm_init_local()) { ODP_ERR("ODP shm local init failed.\n"); - return -1; + goto init_fail; } + stage = SHM_INIT; if (odp_thread_init_local(thr_type)) { ODP_ERR("ODP thread local init failed.\n"); - return -1; + goto init_fail; } + stage = THREAD_INIT; if (odp_pktio_init_local()) { ODP_ERR("ODP packet io local init failed.\n"); - return -1; + goto init_fail; } + stage = PKTIO_INIT; if (odp_pool_init_local()) { ODP_ERR("ODP pool local init failed.\n"); - return -1; + goto init_fail; } + stage = POOL_INIT; if (odp_schedule_init_local()) { ODP_ERR("ODP schedule local init failed.\n"); - return -1; + goto init_fail; } + stage = SCHED_INIT; return 0; + +init_fail: + _odp_term_local(stage); + return -1; } int odp_term_local(void) +{ + return _odp_term_local(ALL_INIT); +} + +int _odp_term_local(enum init_stage stage) { int rc = 0; int rc_thd = 0; - if (odp_schedule_term_local()) { - ODP_ERR("ODP schedule local term failed.\n"); - rc = -1; - } - - if (odp_pool_term_local()) { - ODP_ERR("ODP buffer pool local term failed.\n"); - rc = -1; - } - - rc_thd = odp_thread_term_local(); - if (rc_thd < 0) { - ODP_ERR("ODP thread local term failed.\n"); - rc = -1; - } else { - if (!rc) - rc = rc_thd; + switch (stage) { + case ALL_INIT: + + case SCHED_INIT: + if (odp_schedule_term_local()) { + ODP_ERR("ODP schedule local term failed.\n"); + rc = -1; + } + /* Fall through */ + + case POOL_INIT: + if (odp_pool_term_local()) { + ODP_ERR("ODP buffer pool local term failed.\n"); + rc = -1; + } + /* Fall through */ + + case THREAD_INIT: + rc_thd = odp_thread_term_local(); + if (rc_thd < 0) { + ODP_ERR("ODP thread local term failed.\n"); + rc = -1; + } else { + if (!rc) + rc = rc_thd; + } + /* Fall through */ + + default: + break; } return rc; diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index 31df29ed..f556ea20 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -369,6 +369,14 @@ int odp_system_info_init(void) return 0; } +/* + * System info termination + */ +int odp_system_info_term(void) +{ + return 0; +} + /* ************************* * Public access functions diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index 2cb84f2a..c5215e2b 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -192,7 +192,7 @@ uint64_t odp_time_to_u64(odp_time_t time) return time_to_ns(time) / resolution; } -int odp_time_global_init(void) +int odp_time_init_global(void) { int ret; _odp_time_t time; @@ -202,3 +202,8 @@ int odp_time_global_init(void) return ret; } + +int odp_time_term_global(void) +{ + return 0; +} diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 5c1f8ca7..0bb348f7 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -894,3 +894,8 @@ int odp_timer_init_global(void) odp_atomic_init_u32(&num_timer_pools, 0); return 0; } + +int odp_timer_term_global(void) +{ + return 0; +} -- cgit v1.2.3 From 9766969f7077e51ffb86f0d34d931efda9edafef Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 14 Jan 2016 11:24:19 +0200 Subject: linux-generic: define posix extension level once Use only one definition for posix extension level. _GNU_SOURCE defines _POSIX_C_SOURCE based on glibc version, and is the only definition needed under Linux. Signed-off-by: Petri Savolainen Reviewed-by: Ivan Khoronzhuk Signed-off-by: Maxim Uvarov --- platform/linux-generic/Makefile.am | 1 + platform/linux-generic/arch/linux/odp_cpu_cycles.c | 2 +- .../linux-generic/include/odp/plat/time_types.h | 2 +- .../linux-generic/include/odp_posix_extensions.h | 36 ++++++++++++++++++++++ platform/linux-generic/odp_cpumask.c | 5 ++- platform/linux-generic/odp_cpumask_task.c | 5 ++- platform/linux-generic/odp_shared_memory.c | 3 +- platform/linux-generic/odp_system_info.c | 3 +- platform/linux-generic/odp_thread.c | 6 ++-- platform/linux-generic/odp_thrmask.c | 4 --- platform/linux-generic/odp_time.c | 2 +- platform/linux-generic/odp_timer.c | 4 +-- platform/linux-generic/pktio/loop.c | 4 --- platform/linux-generic/pktio/netmap.c | 4 +-- platform/linux-generic/pktio/pcap.c | 4 +-- platform/linux-generic/pktio/pktio_common.c | 4 --- platform/linux-generic/pktio/socket.c | 4 +-- platform/linux-generic/pktio/socket_mmap.c | 5 ++- platform/linux-generic/pktio/tap.c | 4 +-- 19 files changed, 57 insertions(+), 45 deletions(-) create mode 100644 platform/linux-generic/include/odp_posix_extensions.h (limited to 'platform') diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 80641935..279e5e29 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -100,6 +100,7 @@ noinst_HEADERS = \ ${srcdir}/include/odp_packet_socket.h \ ${srcdir}/include/odp_packet_tap.h \ ${srcdir}/include/odp_pool_internal.h \ + ${srcdir}/include/odp_posix_extensions.h \ ${srcdir}/include/odp_queue_internal.h \ ${srcdir}/include/odp_schedule_internal.h \ ${srcdir}/include/odp_spin_internal.h \ diff --git a/platform/linux-generic/arch/linux/odp_cpu_cycles.c b/platform/linux-generic/arch/linux/odp_cpu_cycles.c index 37a4d94f..7509bf28 100644 --- a/platform/linux-generic/arch/linux/odp_cpu_cycles.c +++ b/platform/linux-generic/arch/linux/odp_cpu_cycles.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#define _POSIX_C_SOURCE 199309L +#include #include #include diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h index 14c35f0b..1b9409b2 100644 --- a/platform/linux-generic/include/odp/plat/time_types.h +++ b/platform/linux-generic/include/odp/plat/time_types.h @@ -23,7 +23,7 @@ extern "C" { /** * @internal Time structure used to isolate linux-generic implementation from - * the linux timespec structure, which is dependent on _POSIX_C_SOURCE level. + * the linux timespec structure, which is dependent on POSIX extension level. */ typedef struct odp_time_t { int64_t tv_sec; /**< @internal Seconds */ diff --git a/platform/linux-generic/include/odp_posix_extensions.h b/platform/linux-generic/include/odp_posix_extensions.h new file mode 100644 index 00000000..4b6e3359 --- /dev/null +++ b/platform/linux-generic/include/odp_posix_extensions.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2016, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_POSIX_EXTENSIONS_H +#define ODP_POSIX_EXTENSIONS_H + +/* + * This should be the only file to define POSIX extension levels. When + * extensions are needed it should be included first in each C source file. + * Header files should not include it. + */ + +/* + * Enable POSIX and GNU extensions + * + * This macro defines: + * o _BSD_SOURCE, _SVID_SOURCE, _ATFILE_SOURCE, _LARGEā€FILE64_SOURCE, + * _ISOC99_SOURCE, _XOPEN_SOURCE_EXTENDED, _POSIX_SOURCE + * o _POSIX_C_SOURCE with the value: + * * 200809L since glibc v2.10 (== POSIX.1-2008 base specification) + * * 200112L before glibc v2.10 (== POSIX.1-2001 base specification) + * * 199506L before glibc v2.5 + * * 199309L before glibc v2.1 + * o _XOPEN_SOURCE with the value: + * * 700 since glibc v2.10 + * * 600 before glibc v2.10 + * * 500 before glibc v2.2 + */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#endif diff --git a/platform/linux-generic/odp_cpumask.c b/platform/linux-generic/odp_cpumask.c index 5cd6a388..c5c12602 100644 --- a/platform/linux-generic/odp_cpumask.c +++ b/platform/linux-generic/odp_cpumask.c @@ -4,9 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +#include + #include #include diff --git a/platform/linux-generic/odp_cpumask_task.c b/platform/linux-generic/odp_cpumask_task.c index 49dbdb78..41f2bc94 100644 --- a/platform/linux-generic/odp_cpumask_task.c +++ b/platform/linux-generic/odp_cpumask_task.c @@ -4,9 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +#include + #include #include diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux-generic/odp_shared_memory.c index ab48dda4..7847cc97 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -4,8 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -/*ftruncate _POSIX_C_SOURCE 200809L */ -#define _POSIX_C_SOURCE 200809L +#include #include #include diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index f556ea20..a948fce9 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -4,7 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#define _GNU_SOURCE +#include + #include #include #include diff --git a/platform/linux-generic/odp_thread.c b/platform/linux-generic/odp_thread.c index 06a5dcd5..4ac1c37e 100644 --- a/platform/linux-generic/odp_thread.c +++ b/platform/linux-generic/odp_thread.c @@ -4,11 +4,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include +#include +#include #include #include #include diff --git a/platform/linux-generic/odp_thrmask.c b/platform/linux-generic/odp_thrmask.c index 154ae81b..4545a823 100644 --- a/platform/linux-generic/odp_thrmask.c +++ b/platform/linux-generic/odp_thrmask.c @@ -4,10 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - #include #include diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index c5215e2b..ca8a9551 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#define _POSIX_C_SOURCE 200809L +#include #include #include diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 0bb348f7..4bab481b 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -21,8 +21,8 @@ #define TB_SET_PAD(x) (void)(x) #endif -/* For snprint, POSIX timers and sigevent */ -#define _POSIX_C_SOURCE 200112L +#include + #include #include #include diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index 47745ad8..d51f0d3f 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -5,10 +5,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - #include #include #include diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c index 11ebd558..774e8137 100644 --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@ -6,9 +6,7 @@ #ifdef ODP_NETMAP -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +#include #include #include diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/pktio/pcap.c index 0817bf59..6511132b 100644 --- a/platform/linux-generic/pktio/pcap.c +++ b/platform/linux-generic/pktio/pcap.c @@ -34,9 +34,7 @@ * The total length of the string is limited by PKTIO_NAME_LEN. */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +#include #include #include diff --git a/platform/linux-generic/pktio/pktio_common.c b/platform/linux-generic/pktio/pktio_common.c index 5729db6e..be9db330 100644 --- a/platform/linux-generic/pktio/pktio_common.c +++ b/platform/linux-generic/pktio/pktio_common.c @@ -5,10 +5,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - #include #include diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c index dfdab18d..1417fb42 100644 --- a/platform/linux-generic/pktio/socket.c +++ b/platform/linux-generic/pktio/socket.c @@ -5,9 +5,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +#include #include #include diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c index fcaaaf63..1d2eb3c9 100644 --- a/platform/linux-generic/pktio/socket_mmap.c +++ b/platform/linux-generic/pktio/socket_mmap.c @@ -5,9 +5,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +#include + #include #include diff --git a/platform/linux-generic/pktio/tap.c b/platform/linux-generic/pktio/tap.c index 99e15cee..1eb4f56a 100644 --- a/platform/linux-generic/pktio/tap.c +++ b/platform/linux-generic/pktio/tap.c @@ -27,9 +27,7 @@ * The total length of the 'iface' is limited by IF_NAMESIZE. */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +#include #include #include -- cgit v1.2.3