From 1478e86dd71a358fba1bf6c83f6a1c7f18e5c1f3 Mon Sep 17 00:00:00 2001 From: Kameswar Rao Vaddina Date: Thu, 26 Oct 2023 12:36:59 +0300 Subject: test: harmonize main function signatures Use ODP_UNUSED for intentionally unused variables of functions. Thereby, harmonizing the main function signatures across multiple files. Signed-off-by: Kameswar Rao Vaddina Reviewed-by: Matias Elo --- example/ipfragreass/odp_ipfragreass.c | 2 +- helper/test/debug.c | 2 +- helper/test/macros.c | 2 +- helper/test/parse.c | 2 +- helper/test/version.c | 2 +- test/miscellaneous/odp_api_headers.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/example/ipfragreass/odp_ipfragreass.c b/example/ipfragreass/odp_ipfragreass.c index db5779915..55c76d7cc 100644 --- a/example/ipfragreass/odp_ipfragreass.c +++ b/example/ipfragreass/odp_ipfragreass.c @@ -228,7 +228,7 @@ static int run_worker(void *arg ODP_UNUSED) /** * ODP fragmentation and reassembly example main function */ -int main(void) +int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) { odp_instance_t instance; odp_pool_t fragment_pool; diff --git a/helper/test/debug.c b/helper/test/debug.c index 78ffb6347..8c50edc75 100644 --- a/helper/test/debug.c +++ b/helper/test/debug.c @@ -10,7 +10,7 @@ #include #include -int main(void) +int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) { printf("\nHelper library version is: %s\n\n", odph_version_str()); diff --git a/helper/test/macros.c b/helper/test/macros.c index e6a203e20..7ecf7bb2d 100644 --- a/helper/test/macros.c +++ b/helper/test/macros.c @@ -8,7 +8,7 @@ #include #include -int main(void) +int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) { int a, b; int ret = 0; diff --git a/helper/test/parse.c b/helper/test/parse.c index 6f4dcc16c..e5a6cf17e 100644 --- a/helper/test/parse.c +++ b/helper/test/parse.c @@ -342,7 +342,7 @@ static int test_ipv4(void) return 0; } -int main(void) +int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) { int ret = 0; diff --git a/helper/test/version.c b/helper/test/version.c index 17c971886..6af6df490 100644 --- a/helper/test/version.c +++ b/helper/test/version.c @@ -8,7 +8,7 @@ #include #include -int main(void) +int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) { printf("\nHelper library versions is: %s\n\n", odph_version_str()); diff --git a/test/miscellaneous/odp_api_headers.c b/test/miscellaneous/odp_api_headers.c index 843de2a02..0dd6b0a2e 100644 --- a/test/miscellaneous/odp_api_headers.c +++ b/test/miscellaneous/odp_api_headers.c @@ -8,7 +8,7 @@ #include #include -int main(void) +int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) { odp_instance_t inst; -- cgit v1.2.3 From e928570b1a567cf8137bd15b4f500151ea0e385a Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 25 Oct 2023 15:52:25 +0300 Subject: linux-gen: config: remove ODP_ prefix from internal defines Remove ODP_ prefix from implementation internal config defines to distinguish them from official APIs. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- doc/implementers-guide/implementers-guide.adoc | 2 +- .../linux-generic/include/odp_config_internal.h | 8 +++---- .../linux-generic/include/odp_event_internal.h | 2 +- .../linux-generic/include/odp_packet_internal.h | 2 +- .../linux-generic/include/odp_packet_io_internal.h | 6 ++--- platform/linux-generic/include/odp_pool_internal.h | 2 +- platform/linux-generic/odp_packet_io.c | 18 +++++++------- platform/linux-generic/odp_pcapng.c | 4 ++-- platform/linux-generic/odp_pool.c | 28 +++++++++++----------- platform/linux-generic/odp_schedule_basic.c | 2 +- platform/linux-generic/odp_schedule_scalable.c | 4 ++-- platform/linux-generic/odp_schedule_sp.c | 2 +- platform/linux-generic/odp_system_info.c | 4 ++-- 13 files changed, 42 insertions(+), 42 deletions(-) diff --git a/doc/implementers-guide/implementers-guide.adoc b/doc/implementers-guide/implementers-guide.adoc index 568760e3a..7b234ecea 100644 --- a/doc/implementers-guide/implementers-guide.adoc +++ b/doc/implementers-guide/implementers-guide.adoc @@ -716,7 +716,7 @@ reference implementation in the file /* * Maximum number of pools */ -#define ODP_CONFIG_POOLS 64 +#define CONFIG_POOLS 64 ----- Here two fundamental limits, the number of CPUs supported and the maximum diff --git a/platform/linux-generic/include/odp_config_internal.h b/platform/linux-generic/include/odp_config_internal.h index 279a43687..5a46bf8c8 100644 --- a/platform/linux-generic/include/odp_config_internal.h +++ b/platform/linux-generic/include/odp_config_internal.h @@ -22,7 +22,7 @@ extern "C" { /* * Maximum number of pools. */ -#define ODP_CONFIG_POOLS 32 +#define CONFIG_POOLS 32 /* * Queues reserved for ODP internal use @@ -71,7 +71,7 @@ extern "C" { /* * Maximum number of packet IO resources */ -#define ODP_CONFIG_PKTIO_ENTRIES 64 +#define CONFIG_PKTIO_ENTRIES 64 /* * Maximum buffer alignment @@ -79,7 +79,7 @@ extern "C" { * This defines the maximum supported buffer alignment. Requests for values * above this will fail. */ -#define ODP_CONFIG_BUFFER_ALIGN_MAX (4 * 1024) +#define CONFIG_BUFFER_ALIGN_MAX (4 * 1024) /* * Default packet headroom @@ -138,7 +138,7 @@ extern "C" { * are reserved for per ODP module global data and one block per packet I/O is * reserved for TX completion usage. */ -#define CONFIG_INTERNAL_SHM_BLOCKS ((ODP_CONFIG_POOLS * 3) + 20 + ODP_CONFIG_PKTIO_ENTRIES) +#define CONFIG_INTERNAL_SHM_BLOCKS ((CONFIG_POOLS * 3) + 20 + CONFIG_PKTIO_ENTRIES) /* * Maximum number of shared memory blocks. diff --git a/platform/linux-generic/include/odp_event_internal.h b/platform/linux-generic/include/odp_event_internal.h index 4bc28d708..d9957e530 100644 --- a/platform/linux-generic/include/odp_event_internal.h +++ b/platform/linux-generic/include/odp_event_internal.h @@ -35,7 +35,7 @@ typedef union _odp_event_index_t { } _odp_event_index_t; /* Check that pool index fit into bit field */ -ODP_STATIC_ASSERT(ODP_CONFIG_POOLS <= (0xFF + 1), "TOO_MANY_POOLS"); +ODP_STATIC_ASSERT(CONFIG_POOLS <= (0xFF + 1), "TOO_MANY_POOLS"); /* Check that buffer index fit into bit field */ ODP_STATIC_ASSERT(CONFIG_POOL_MAX_NUM <= (0xFFFFFF + 1), "TOO_LARGE_POOL"); diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index eef0239f2..41a44b83c 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -176,7 +176,7 @@ typedef struct ODP_ALIGNED_CACHE odp_packet_hdr_t { * grow over 256 bytes. */ ODP_STATIC_ASSERT(sizeof(odp_packet_hdr_t) <= 256, "PACKET_HDR_SIZE_ERROR"); -ODP_STATIC_ASSERT(ODP_CONFIG_PKTIO_ENTRIES < UINT8_MAX, "MS_PKTIO_IDX_SIZE_ERROR"); +ODP_STATIC_ASSERT(CONFIG_PKTIO_ENTRIES < UINT8_MAX, "MS_PKTIO_IDX_SIZE_ERROR"); /** * Return the packet header diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h index 5490c3d01..6c8a2305b 100644 --- a/platform/linux-generic/include/odp_packet_io_internal.h +++ b/platform/linux-generic/include/odp_packet_io_internal.h @@ -184,7 +184,7 @@ typedef struct { uint32_t tx_compl_pool_size; } config; - pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES]; + pktio_entry_t entries[CONFIG_PKTIO_ENTRIES]; lso_profile_t lso_profile[PKTIO_LSO_PROFILES]; int num_lso_profiles; @@ -257,9 +257,9 @@ static inline pktio_entry_t *get_pktio_entry(odp_pktio_t pktio) if (odp_unlikely(pktio == ODP_PKTIO_INVALID)) return NULL; - if (odp_unlikely(_odp_typeval(pktio) > ODP_CONFIG_PKTIO_ENTRIES)) { + if (odp_unlikely(_odp_typeval(pktio) > CONFIG_PKTIO_ENTRIES)) { _ODP_DBG("pktio limit %" PRIuPTR "/%d exceed\n", - _odp_typeval(pktio), ODP_CONFIG_PKTIO_ENTRIES); + _odp_typeval(pktio), CONFIG_PKTIO_ENTRIES); return NULL; } diff --git a/platform/linux-generic/include/odp_pool_internal.h b/platform/linux-generic/include/odp_pool_internal.h index c8d2168f3..2c33bb4a2 100644 --- a/platform/linux-generic/include/odp_pool_internal.h +++ b/platform/linux-generic/include/odp_pool_internal.h @@ -116,7 +116,7 @@ typedef struct pool_t { } pool_t; typedef struct pool_global_t { - pool_t pool[ODP_CONFIG_POOLS]; + pool_t pool[CONFIG_POOLS]; odp_shm_t shm; struct { diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 38c1c2b03..a328423ae 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -74,7 +74,7 @@ typedef struct { static pktio_global_t *pktio_global; /* pktio pointer entries ( for inlines) */ -void *_odp_pktio_entry_ptr[ODP_CONFIG_PKTIO_ENTRIES]; +void *_odp_pktio_entry_ptr[CONFIG_PKTIO_ENTRIES]; static inline pktio_entry_t *pktio_entry_by_index(int index) { @@ -145,7 +145,7 @@ int _odp_pktio_init_global(void) return -1; } - for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { + for (i = 0; i < CONFIG_PKTIO_ENTRIES; ++i) { pktio_entry = &pktio_global->entries[i]; pktio_entry->handle = _odp_cast_scalar(odp_pktio_t, i + 1); @@ -311,7 +311,7 @@ static odp_pktio_t setup_pktio_entry(const char *name, odp_pool_t pool, if_name = strip_pktio_type(name, pktio_type); - for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { + for (i = 0; i < CONFIG_PKTIO_ENTRIES; ++i) { pktio_entry = &pktio_global->entries[i]; if (is_free(pktio_entry)) { lock_entry(pktio_entry); @@ -322,7 +322,7 @@ static odp_pktio_t setup_pktio_entry(const char *name, odp_pool_t pool, } } - if (i == ODP_CONFIG_PKTIO_ENTRIES) { + if (i == CONFIG_PKTIO_ENTRIES) { _ODP_ERR("All pktios used already\n"); return ODP_PKTIO_INVALID; } @@ -809,7 +809,7 @@ odp_pktio_t odp_pktio_lookup(const char *name) odp_spinlock_lock(&pktio_global->lock); - for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { + for (i = 0; i < CONFIG_PKTIO_ENTRIES; ++i) { entry = pktio_entry_by_index(i); if (!entry || is_free(entry)) continue; @@ -1509,7 +1509,7 @@ int _odp_pktio_term_global(void) if (pktio_global == NULL) return 0; - for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { + for (i = 0; i < CONFIG_PKTIO_ENTRIES; ++i) { pktio_entry_t *pktio_entry; pktio_entry = &pktio_global->entries[i]; @@ -1626,12 +1626,12 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) return 0; } -ODP_STATIC_ASSERT(ODP_CONFIG_PKTIO_ENTRIES - 1 <= ODP_PKTIO_MAX_INDEX, - "ODP_CONFIG_PKTIO_ENTRIES larger than ODP_PKTIO_MAX_INDEX"); +ODP_STATIC_ASSERT(CONFIG_PKTIO_ENTRIES - 1 <= ODP_PKTIO_MAX_INDEX, + "CONFIG_PKTIO_ENTRIES larger than ODP_PKTIO_MAX_INDEX"); unsigned int odp_pktio_max_index(void) { - return ODP_CONFIG_PKTIO_ENTRIES - 1; + return CONFIG_PKTIO_ENTRIES - 1; } int odp_pktio_stats(odp_pktio_t pktio, diff --git a/platform/linux-generic/odp_pcapng.c b/platform/linux-generic/odp_pcapng.c index 4423b0483..7f11f4340 100644 --- a/platform/linux-generic/odp_pcapng.c +++ b/platform/linux-generic/odp_pcapng.c @@ -99,7 +99,7 @@ typedef struct ODP_ALIGNED_CACHE { int inotify_watch_fd; int inotify_is_running; odp_spinlock_t lock; - pcapng_entry_t entry[ODP_CONFIG_PKTIO_ENTRIES]; + pcapng_entry_t entry[CONFIG_PKTIO_ENTRIES]; } pcapng_global_t; static pcapng_global_t *pcapng_gbl; @@ -230,7 +230,7 @@ static pktio_entry_t *pktio_from_event(struct inotify_event *event) odp_spinlock_lock(&pcapng_gbl->lock); - for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; i++) { + for (i = 0; i < CONFIG_PKTIO_ENTRIES; i++) { pktio_entry_t *entry = pcapng_gbl->entry[i].pktio_entry; if (entry == NULL) diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index b3b6f9c40..6d464cd37 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -63,7 +63,7 @@ ODP_STATIC_ASSERT(CONFIG_PACKET_SEG_SIZE < 0xffff, /* Thread local variables */ typedef struct pool_local_t { - pool_cache_t *cache[ODP_CONFIG_POOLS]; + pool_cache_t *cache[CONFIG_POOLS]; int thr_id; } pool_local_t; @@ -328,7 +328,7 @@ int _odp_pool_init_global(void) return -1; } - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool_t *pool = _odp_pool_entry_from_idx(i); LOCK_INIT(&pool->lock); @@ -357,7 +357,7 @@ int _odp_pool_term_global(void) if (_odp_pool_glb == NULL) return 0; - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool = _odp_pool_entry_from_idx(i); LOCK(&pool->lock); @@ -385,7 +385,7 @@ int _odp_pool_init_local(void) memset(&local, 0, sizeof(pool_local_t)); - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool = _odp_pool_entry_from_idx(i); local.cache[i] = &pool->local_cache[thr_id]; cache_init(local.cache[i]); @@ -399,7 +399,7 @@ int _odp_pool_term_local(void) { int i; - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool_t *pool = _odp_pool_entry_from_idx(i); cache_flush(local.cache[i], pool); @@ -416,7 +416,7 @@ static pool_t *reserve_pool(uint32_t shmflags, uint8_t pool_ext, uint32_t num) pool_t *pool; char ring_name[ODP_POOL_NAME_LEN]; - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool = _odp_pool_entry_from_idx(i); LOCK(&pool->lock); @@ -756,7 +756,7 @@ odp_pool_t _odp_pool_create(const char *name, const odp_pool_param_t *params, } /* Validate requested buffer alignment */ - if (align > ODP_CONFIG_BUFFER_ALIGN_MAX || + if (align > CONFIG_BUFFER_ALIGN_MAX || align != _ODP_ROUNDDOWN_POWER2(align, align)) { _ODP_ERR("Bad align requirement\n"); return ODP_POOL_INVALID; @@ -1205,7 +1205,7 @@ odp_pool_t odp_pool_lookup(const char *name) uint32_t i; pool_t *pool; - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool = _odp_pool_entry_from_idx(i); LOCK(&pool->lock); @@ -1464,7 +1464,7 @@ int odp_pool_capability(odp_pool_capability_t *capa) odp_pool_stats_opt_t supported_stats; uint32_t max_seg_len = CONFIG_PACKET_MAX_SEG_LEN; /* Reserve one for internal usage */ - int max_pools = ODP_CONFIG_POOLS - 1; + int max_pools = CONFIG_POOLS - 1; memset(capa, 0, sizeof(odp_pool_capability_t)); @@ -1483,7 +1483,7 @@ int odp_pool_capability(odp_pool_capability_t *capa) /* Buffer pools */ capa->buf.max_pools = max_pools; - capa->buf.max_align = ODP_CONFIG_BUFFER_ALIGN_MAX; + capa->buf.max_align = CONFIG_BUFFER_ALIGN_MAX; capa->buf.max_size = MAX_SIZE; capa->buf.max_num = CONFIG_POOL_MAX_NUM; capa->buf.max_uarea_size = MAX_UAREA_SIZE; @@ -1614,7 +1614,7 @@ void odp_pool_print_all(void) _ODP_PRINT("-----------------\n"); _ODP_PRINT(" idx %-*s type free tot cache buf_len ext\n", col_width, "name"); - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool_t *pool = _odp_pool_entry_from_idx(i); LOCK(&pool->lock); @@ -1666,7 +1666,7 @@ uint64_t odp_pool_to_u64(odp_pool_t hdl) unsigned int odp_pool_max_index(void) { - return ODP_CONFIG_POOLS - 1; + return CONFIG_POOLS - 1; } int odp_pool_stats(odp_pool_t pool_hdl, odp_pool_stats_t *stats) @@ -1800,7 +1800,7 @@ static pool_t *find_pool(_odp_event_hdr_t *event_hdr) int i; uint8_t *ptr = (uint8_t *)event_hdr; - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool_t *pool = _odp_pool_entry_from_idx(i); if (pool->reserved == 0) @@ -1877,7 +1877,7 @@ int odp_pool_ext_capability(odp_pool_type_t type, odp_pool_ext_capability_t *cap memset(capa, 0, sizeof(odp_pool_ext_capability_t)); capa->type = type; - capa->max_pools = ODP_CONFIG_POOLS - 1; + capa->max_pools = CONFIG_POOLS - 1; capa->min_cache_size = 0; capa->max_cache_size = CONFIG_POOL_CACHE_MAX_SIZE; capa->stats.all = supported_stats.all; diff --git a/platform/linux-generic/odp_schedule_basic.c b/platform/linux-generic/odp_schedule_basic.c index d289f1e21..05eb6aa9f 100644 --- a/platform/linux-generic/odp_schedule_basic.c +++ b/platform/linux-generic/odp_schedule_basic.c @@ -96,7 +96,7 @@ ODP_STATIC_ASSERT((QUEUE_LOAD * CONFIG_MAX_SCHED_QUEUES) < UINT32_MAX, "Load_val #define RANDOM_TBL_SIZE 128 /* Maximum number of packet IO interfaces */ -#define NUM_PKTIO ODP_CONFIG_PKTIO_ENTRIES +#define NUM_PKTIO CONFIG_PKTIO_ENTRIES /* Maximum pktin index. Needs to fit into 8 bits. */ #define MAX_PKTIN_INDEX 255 diff --git a/platform/linux-generic/odp_schedule_scalable.c b/platform/linux-generic/odp_schedule_scalable.c index 28245f66b..bb1549e9b 100644 --- a/platform/linux-generic/odp_schedule_scalable.c +++ b/platform/linux-generic/odp_schedule_scalable.c @@ -67,7 +67,7 @@ typedef struct { odp_spinlock_t init_lock; /** Per thread state */ sched_scalable_thread_state_t thread_state[MAXTHREADS]; - uint16_t poll_count[ODP_CONFIG_PKTIO_ENTRIES]; + uint16_t poll_count[CONFIG_PKTIO_ENTRIES]; /* Scheduler interface config options (not used in fast path) */ schedule_config_t config_if; } sched_global_t; @@ -713,7 +713,7 @@ static void pktio_start(int pktio_idx, queue_entry_t *qentry; sched_elem_t *elem; - _ODP_ASSERT(pktio_idx < ODP_CONFIG_PKTIO_ENTRIES); + _ODP_ASSERT(pktio_idx < CONFIG_PKTIO_ENTRIES); for (i = 0; i < num_in_queue; i++) { rxq = in_queue_idx[i]; _ODP_ASSERT(rxq < ODP_PKTIN_MAX_QUEUES); diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c index c4d18e66e..a42955ee9 100644 --- a/platform/linux-generic/odp_schedule_sp.c +++ b/platform/linux-generic/odp_schedule_sp.c @@ -38,7 +38,7 @@ #define NUM_THREAD ODP_THREAD_COUNT_MAX #define NUM_QUEUE CONFIG_MAX_SCHED_QUEUES -#define NUM_PKTIO ODP_CONFIG_PKTIO_ENTRIES +#define NUM_PKTIO CONFIG_PKTIO_ENTRIES #define NUM_ORDERED_LOCKS 1 #define NUM_STATIC_GROUP 3 #define NUM_GROUP (NUM_STATIC_GROUP + 9) diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index bb0eaa9b1..f95690410 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -599,11 +599,11 @@ void odp_sys_config_print(void) _ODP_PRINT("\n\nodp_config_internal.h values:\n" "-----------------------------\n"); - _ODP_PRINT("ODP_CONFIG_POOLS: %i\n", ODP_CONFIG_POOLS); + _ODP_PRINT("CONFIG_POOLS: %i\n", CONFIG_POOLS); _ODP_PRINT("CONFIG_MAX_PLAIN_QUEUES: %i\n", CONFIG_MAX_PLAIN_QUEUES); _ODP_PRINT("CONFIG_MAX_SCHED_QUEUES: %i\n", CONFIG_MAX_SCHED_QUEUES); _ODP_PRINT("CONFIG_QUEUE_MAX_ORD_LOCKS: %i\n", CONFIG_QUEUE_MAX_ORD_LOCKS); - _ODP_PRINT("ODP_CONFIG_PKTIO_ENTRIES: %i\n", ODP_CONFIG_PKTIO_ENTRIES); + _ODP_PRINT("CONFIG_PKTIO_ENTRIES: %i\n", CONFIG_PKTIO_ENTRIES); _ODP_PRINT("CONFIG_PACKET_HEADROOM: %i\n", CONFIG_PACKET_HEADROOM); _ODP_PRINT("CONFIG_PACKET_TAILROOM: %i\n", CONFIG_PACKET_TAILROOM); _ODP_PRINT("CONFIG_SHM_BLOCKS: %i\n", CONFIG_SHM_BLOCKS); -- cgit v1.2.3 From d51b28dd4d3b3f3b98d268b5899a5a3d6e529f2f Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 25 Oct 2023 16:11:55 +0300 Subject: linux-gen: system: add missing defines to odp_sys_config_print() Print missing implementation internal define values in odp_sys_config_print(). Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-generic/odp_system_info.c | 40 +++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index f95690410..c1e33f8d0 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -599,18 +599,32 @@ void odp_sys_config_print(void) _ODP_PRINT("\n\nodp_config_internal.h values:\n" "-----------------------------\n"); - _ODP_PRINT("CONFIG_POOLS: %i\n", CONFIG_POOLS); - _ODP_PRINT("CONFIG_MAX_PLAIN_QUEUES: %i\n", CONFIG_MAX_PLAIN_QUEUES); - _ODP_PRINT("CONFIG_MAX_SCHED_QUEUES: %i\n", CONFIG_MAX_SCHED_QUEUES); - _ODP_PRINT("CONFIG_QUEUE_MAX_ORD_LOCKS: %i\n", CONFIG_QUEUE_MAX_ORD_LOCKS); - _ODP_PRINT("CONFIG_PKTIO_ENTRIES: %i\n", CONFIG_PKTIO_ENTRIES); - _ODP_PRINT("CONFIG_PACKET_HEADROOM: %i\n", CONFIG_PACKET_HEADROOM); - _ODP_PRINT("CONFIG_PACKET_TAILROOM: %i\n", CONFIG_PACKET_TAILROOM); - _ODP_PRINT("CONFIG_SHM_BLOCKS: %i\n", CONFIG_SHM_BLOCKS); - _ODP_PRINT("CONFIG_BURST_SIZE: %i\n", CONFIG_BURST_SIZE); - _ODP_PRINT("CONFIG_POOL_MAX_NUM: %i\n", CONFIG_POOL_MAX_NUM); - _ODP_PRINT("CONFIG_POOL_CACHE_MAX_SIZE: %i\n", CONFIG_POOL_CACHE_MAX_SIZE); - _ODP_PRINT("CONFIG_TIMER_128BIT_ATOMICS: %i\n", CONFIG_TIMER_128BIT_ATOMICS); - _ODP_PRINT("CONFIG_TIMER_PROFILE_INLINE: %i\n", CONFIG_TIMER_PROFILE_INLINE); + _ODP_PRINT("CONFIG_NUM_CPU_IDS: %i\n", CONFIG_NUM_CPU_IDS); + _ODP_PRINT("CONFIG_INTERNAL_QUEUES: %i\n", CONFIG_INTERNAL_QUEUES); + _ODP_PRINT("CONFIG_MAX_PLAIN_QUEUES: %i\n", CONFIG_MAX_PLAIN_QUEUES); + _ODP_PRINT("CONFIG_MAX_SCHED_QUEUES: %i\n", CONFIG_MAX_SCHED_QUEUES); + _ODP_PRINT("CONFIG_MAX_QUEUES: %i\n", CONFIG_MAX_QUEUES); + _ODP_PRINT("CONFIG_QUEUE_MAX_ORD_LOCKS: %i\n", CONFIG_QUEUE_MAX_ORD_LOCKS); + _ODP_PRINT("CONFIG_MAX_DMA_SESSIONS: %i\n", CONFIG_MAX_DMA_SESSIONS); + _ODP_PRINT("CONFIG_INTERNAL_STASHES: %i\n", CONFIG_INTERNAL_STASHES); + _ODP_PRINT("CONFIG_MAX_STASHES: %i\n", CONFIG_MAX_STASHES); + _ODP_PRINT("CONFIG_PKTIO_ENTRIES: %i\n", CONFIG_PKTIO_ENTRIES); + _ODP_PRINT("CONFIG_BUFFER_ALIGN_MAX: %i\n", CONFIG_BUFFER_ALIGN_MAX); + _ODP_PRINT("CONFIG_PACKET_HEADROOM: %i\n", CONFIG_PACKET_HEADROOM); + _ODP_PRINT("CONFIG_PACKET_TAILROOM: %i\n", CONFIG_PACKET_TAILROOM); + _ODP_PRINT("CONFIG_PACKET_SEG_SIZE: %i\n", CONFIG_PACKET_SEG_SIZE); + _ODP_PRINT("CONFIG_PACKET_MAX_SEG_LEN: %i\n", CONFIG_PACKET_MAX_SEG_LEN); + _ODP_PRINT("CONFIG_PACKET_SEG_LEN_MIN: %i\n", CONFIG_PACKET_SEG_LEN_MIN); + _ODP_PRINT("CONFIG_PACKET_VECTOR_MAX_SIZE: %i\n", CONFIG_PACKET_VECTOR_MAX_SIZE); + _ODP_PRINT("CONFIG_INTERNAL_SHM_BLOCKS: %i\n", CONFIG_INTERNAL_SHM_BLOCKS); + _ODP_PRINT("CONFIG_SHM_BLOCKS: %i\n", CONFIG_SHM_BLOCKS); + _ODP_PRINT("CONFIG_BURST_SIZE: %i\n", CONFIG_BURST_SIZE); + _ODP_PRINT("CONFIG_POOLS: %i\n", CONFIG_POOLS); + _ODP_PRINT("CONFIG_POOL_MAX_NUM: %i\n", CONFIG_POOL_MAX_NUM); + _ODP_PRINT("CONFIG_POOL_CACHE_MAX_SIZE: %i\n", CONFIG_POOL_CACHE_MAX_SIZE); + _ODP_PRINT("CONFIG_POOL_STATISTICS: %i\n", CONFIG_POOL_STATISTICS); + _ODP_PRINT("CONFIG_IPSEC_MAX_NUM_SA: %i\n", CONFIG_IPSEC_MAX_NUM_SA); + _ODP_PRINT("CONFIG_TIMER_128BIT_ATOMICS: %i\n", CONFIG_TIMER_128BIT_ATOMICS); + _ODP_PRINT("CONFIG_TIMER_PROFILE_INLINE: %i\n", CONFIG_TIMER_PROFILE_INLINE); _ODP_PRINT("\n"); } -- cgit v1.2.3 From 237969a30a0d5f503e213365c7e15676e6b9b4e9 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Thu, 26 Oct 2023 07:04:45 +0000 Subject: validation: dma: fix packet length when using segmented packets When testing DMA transfers with potentially segmented packets, ensure that allocated packet length does not exceed allocated transfer destination memory size. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/validation/api/dma/dma.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/validation/api/dma/dma.c b/test/validation/api/dma/dma.c index 7129315ef..787f719a7 100644 --- a/test/validation/api/dma/dma.c +++ b/test/validation/api/dma/dma.c @@ -1108,7 +1108,7 @@ static void test_dma_pkt_segs_to_addr_sync(void) uint8_t *dst; odp_packet_t pkt; uint32_t i, len, num_segs; - uint32_t pkt_len = global.pkt_len; + uint32_t pkt_len = ODPH_MIN(global.pkt_len, global.len); memset(global.dst_addr, 0, global.data_size); @@ -1128,9 +1128,6 @@ static void test_dma_pkt_segs_to_addr_sync(void) CU_ASSERT_FATAL(odp_packet_copy_from_mem(pkt, 0, pkt_len, global.src_addr) == 0); len = pkt_len - OFFSET - TRAILER; - if (len > global.len) - len = global.len; - dst = global.dst_addr + OFFSET; memset(&src_seg, 0, sizeof(odp_dma_seg_t)); -- cgit v1.2.3 From 3180dc0b6b30c0276992ddfc81667f0a1f56e32a Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 30 Oct 2023 09:40:31 +0200 Subject: test: l2fwd: always print interface mac addresses Ease application usage by always printing interface MAC addresses. Also, clean and unify prints in create_pktio() function. Move application options print to the beginning of main(), so that options are printed also in case of setup failures. Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- test/performance/odp_l2fwd.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c index 8b97ba34c..35becb15a 100644 --- a/test/performance/odp_l2fwd.c +++ b/test/performance/odp_l2fwd.c @@ -928,6 +928,7 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_po odp_pktio_op_mode_t mode_tx; pktin_mode_t in_mode = gbl_args->appl.in_mode; odp_pktio_info_t info; + uint8_t *addr; odp_pktio_param_init(&pktio_param); @@ -950,9 +951,6 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_po return -1; } - printf("created pktio %" PRIu64 ", dev: %s, drv: %s\n", - odp_pktio_to_u64(pktio), dev, info.drv_name); - if (gbl_args->appl.verbose) odp_pktio_print(pktio); @@ -968,7 +966,6 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_po config.parser.layer = ODP_PROTO_LAYER_ALL; if (gbl_args->appl.chksum) { - printf("Checksum offload enabled\n"); config.pktout.bit.ipv4_chksum_ena = 1; config.pktout.bit.udp_chksum_ena = 1; config.pktout.bit.tcp_chksum_ena = 1; @@ -1057,16 +1054,16 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_po if (num_rx > (int)pktio_capa.max_input_queues) { num_rx = pktio_capa.max_input_queues; mode_rx = ODP_PKTIO_OP_MT; - printf("Maximum number of input queues: %i\n", num_rx); + printf("Warning: %s: maximum number of input queues: %i\n", dev, num_rx); } if (num_rx < gbl_args->appl.num_workers) - printf("Sharing %i input queues between %i workers\n", - num_rx, gbl_args->appl.num_workers); + printf("Warning: %s: sharing %i input queues between %i workers\n", + dev, num_rx, gbl_args->appl.num_workers); if (num_tx > (int)pktio_capa.max_output_queues) { - printf("Sharing %i output queues between %i workers\n", - pktio_capa.max_output_queues, num_tx); + printf("Warning: %s: sharing %i output queues between %i workers\n", + dev, pktio_capa.max_output_queues, num_tx); num_tx = pktio_capa.max_output_queues; mode_tx = ODP_PKTIO_OP_MT; } @@ -1122,8 +1119,16 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_po } } - printf("created %i input and %i output queues on (%s)\n", - num_rx, num_tx, dev); + if (odp_pktio_mac_addr(pktio, gbl_args->port_eth_addr[idx].addr, + ODPH_ETHADDR_LEN) != ODPH_ETHADDR_LEN) { + ODPH_ERR("Reading interface Ethernet address failed: %s\n", dev); + return -1; + } + addr = gbl_args->port_eth_addr[idx].addr; + + printf(" dev: %s, drv: %s, rx_queues: %i, tx_queues: %i, mac: " + "%02x:%02x:%02x:%02x:%02x:%02x\n", dev, info.drv_name, num_rx, num_tx, + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); gbl_args->pktios[idx].num_rx_queue = num_rx; gbl_args->pktios[idx].num_tx_queue = num_tx; @@ -2094,6 +2099,9 @@ int main(int argc, char *argv[]) gbl_args->appl.num_workers = num_workers; + /* Print application information */ + print_info(); + for (i = 0; i < num_workers; i++) gbl_args->thread_args[i].thr_idx = i; @@ -2260,6 +2268,8 @@ int main(int argc, char *argv[]) pool = pool_tbl[0]; vec_pool = vec_pool_tbl[0]; + printf("\nInterfaces\n----------\n"); + for (i = 0; i < if_count; ++i) { const char *dev = gbl_args->appl.if_names[i]; int num_rx, num_tx; @@ -2286,14 +2296,6 @@ int main(int argc, char *argv[]) if (create_pktio(dev, i, num_rx, num_tx, pool, vec_pool, grp)) exit(EXIT_FAILURE); - /* Save interface ethernet address */ - if (odp_pktio_mac_addr(gbl_args->pktios[i].pktio, - gbl_args->port_eth_addr[i].addr, - ODPH_ETHADDR_LEN) != ODPH_ETHADDR_LEN) { - ODPH_ERR("Interface ethernet address unknown\n"); - exit(EXIT_FAILURE); - } - /* Save destination eth address */ if (gbl_args->appl.dst_change) { /* 02:00:00:00:00:XX */ @@ -2311,9 +2313,6 @@ int main(int argc, char *argv[]) gbl_args->pktios[i].pktio = ODP_PKTIO_INVALID; - /* Print application information */ - print_info(); - bind_queues(); init_port_lookup_tbl(); -- cgit v1.2.3 From 70a56650f3605b141ffaa0f92711b7cff8a9175c Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Mon, 30 Oct 2023 12:28:55 +0000 Subject: linux-gen: pool: add constant for internal pool count Add a new `CONFIG_INTERNAL_POOLS` constant for tracking pools reserved for implementation internal use, such as the pool for IPsec status events. Utilize the new constant when implementation capabilities are queried. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- platform/linux-generic/include/odp_config_internal.h | 18 ++++++++++++------ platform/linux-generic/odp_fdserver.c | 3 ++- platform/linux-generic/odp_pool.c | 9 ++++++--- platform/linux-generic/odp_system_info.c | 1 + 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/platform/linux-generic/include/odp_config_internal.h b/platform/linux-generic/include/odp_config_internal.h index 5a46bf8c8..8fd8c4be7 100644 --- a/platform/linux-generic/include/odp_config_internal.h +++ b/platform/linux-generic/include/odp_config_internal.h @@ -19,10 +19,21 @@ extern "C" { */ #define CONFIG_NUM_CPU_IDS 256 +/* + * Maximum number of packet IO resources + */ +#define CONFIG_PKTIO_ENTRIES 64 + +/* + * Pools reserved for internal usage, 1 for IPsec status events and one per packet + * I/O for TX completion + */ +#define CONFIG_INTERNAL_POOLS (1 + CONFIG_PKTIO_ENTRIES) + /* * Maximum number of pools. */ -#define CONFIG_POOLS 32 +#define CONFIG_POOLS 128 /* * Queues reserved for ODP internal use @@ -68,11 +79,6 @@ extern "C" { */ #define CONFIG_MAX_STASHES 2048 -/* - * Maximum number of packet IO resources - */ -#define CONFIG_PKTIO_ENTRIES 64 - /* * Maximum buffer alignment * diff --git a/platform/linux-generic/odp_fdserver.c b/platform/linux-generic/odp_fdserver.c index 4995efb94..e72df0669 100644 --- a/platform/linux-generic/odp_fdserver.c +++ b/platform/linux-generic/odp_fdserver.c @@ -37,6 +37,7 @@ */ #include +#include #include #include #include @@ -72,7 +73,7 @@ #define FD_DBG 3 /* define the tables of file descriptors handled by this server: */ -#define FDSERVER_MAX_ENTRIES 256 +#define FDSERVER_MAX_ENTRIES (CONFIG_SHM_BLOCKS + CONFIG_INTERNAL_SHM_BLOCKS) typedef struct fdentry_s { fd_server_context_e context; uint64_t key; diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index 6d464cd37..ace071248 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -61,6 +61,9 @@ ODP_STATIC_ASSERT(CONFIG_PACKET_SEG_LEN_MIN >= 256, ODP_STATIC_ASSERT(CONFIG_PACKET_SEG_SIZE < 0xffff, "Segment size must be less than 64k (16 bit offsets)"); +ODP_STATIC_ASSERT(CONFIG_INTERNAL_POOLS < CONFIG_POOLS, + "Internal pool count needs to be less than total configured pool count"); + /* Thread local variables */ typedef struct pool_local_t { pool_cache_t *cache[CONFIG_POOLS]; @@ -1463,8 +1466,8 @@ int odp_pool_capability(odp_pool_capability_t *capa) { odp_pool_stats_opt_t supported_stats; uint32_t max_seg_len = CONFIG_PACKET_MAX_SEG_LEN; - /* Reserve one for internal usage */ - int max_pools = CONFIG_POOLS - 1; + /* Reserve pools for internal usage */ + unsigned int max_pools = CONFIG_POOLS - CONFIG_INTERNAL_POOLS; memset(capa, 0, sizeof(odp_pool_capability_t)); @@ -1877,7 +1880,7 @@ int odp_pool_ext_capability(odp_pool_type_t type, odp_pool_ext_capability_t *cap memset(capa, 0, sizeof(odp_pool_ext_capability_t)); capa->type = type; - capa->max_pools = CONFIG_POOLS - 1; + capa->max_pools = CONFIG_POOLS - CONFIG_INTERNAL_POOLS; capa->min_cache_size = 0; capa->max_cache_size = CONFIG_POOL_CACHE_MAX_SIZE; capa->stats.all = supported_stats.all; diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index c1e33f8d0..52f1000f1 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -619,6 +619,7 @@ void odp_sys_config_print(void) _ODP_PRINT("CONFIG_INTERNAL_SHM_BLOCKS: %i\n", CONFIG_INTERNAL_SHM_BLOCKS); _ODP_PRINT("CONFIG_SHM_BLOCKS: %i\n", CONFIG_SHM_BLOCKS); _ODP_PRINT("CONFIG_BURST_SIZE: %i\n", CONFIG_BURST_SIZE); + _ODP_PRINT("CONFIG_INTERNAL_POOLS: %i\n", CONFIG_INTERNAL_POOLS); _ODP_PRINT("CONFIG_POOLS: %i\n", CONFIG_POOLS); _ODP_PRINT("CONFIG_POOL_MAX_NUM: %i\n", CONFIG_POOL_MAX_NUM); _ODP_PRINT("CONFIG_POOL_CACHE_MAX_SIZE: %i\n", CONFIG_POOL_CACHE_MAX_SIZE); -- cgit v1.2.3 From 26a55f9639239e5190288454f5fe846e65c91dbc Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Mon, 30 Oct 2023 09:22:07 +0000 Subject: abi: dma: increase default transfer ID size Increase default `odp_dma_transfer_id_t` size to 64 bit from 32 bit. This enables different implementations to potentially utilize pointers as the transfer ID. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- include/odp/api/abi-default/dma_types.h | 2 +- platform/linux-generic/odp_dma.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/odp/api/abi-default/dma_types.h b/include/odp/api/abi-default/dma_types.h index ce133661e..1d27a11aa 100644 --- a/include/odp/api/abi-default/dma_types.h +++ b/include/odp/api/abi-default/dma_types.h @@ -29,7 +29,7 @@ typedef _odp_abi_dma_t *odp_dma_compl_t; #define ODP_DMA_COMPL_INVALID ((odp_dma_compl_t)0) -typedef uint32_t odp_dma_transfer_id_t; +typedef uint64_t odp_dma_transfer_id_t; #define ODP_DMA_TRANSFER_ID_INVALID ((odp_dma_transfer_id_t)0) diff --git a/platform/linux-generic/odp_dma.c b/platform/linux-generic/odp_dma.c index 82d737073..5ffeb20ce 100644 --- a/platform/linux-generic/odp_dma.c +++ b/platform/linux-generic/odp_dma.c @@ -31,6 +31,8 @@ #define MAX_SEGS 16 #define MAX_SEG_LEN (128 * 1024) +ODP_STATIC_ASSERT(MAX_TRANSFERS < UINT32_MAX, "Too many inflight transfers"); + typedef struct segment_t { void *addr; uint32_t len; @@ -597,6 +599,7 @@ int odp_dma_transfer_start(odp_dma_t dma, const odp_dma_transfer_param_t *transf { int ret; dma_session_t *session = dma_session_from_handle(dma); + const uint32_t transfer_id = compl->transfer_id; if (odp_unlikely(dma == ODP_DMA_INVALID)) { _ODP_ERR("Bad DMA handle\n"); @@ -608,9 +611,8 @@ int odp_dma_transfer_start(odp_dma_t dma, const odp_dma_transfer_param_t *transf case ODP_DMA_COMPL_NONE: break; case ODP_DMA_COMPL_POLL: - if (compl->transfer_id == ODP_DMA_TRANSFER_ID_INVALID || - compl->transfer_id > MAX_TRANSFERS) { - _ODP_ERR("Bad transfer ID: %u\n", compl->transfer_id); + if (transfer_id == ODP_DMA_TRANSFER_ID_INVALID || transfer_id > MAX_TRANSFERS) { + _ODP_ERR("Bad transfer ID: %u\n", transfer_id); return -1; } break; @@ -632,7 +634,7 @@ int odp_dma_transfer_start(odp_dma_t dma, const odp_dma_transfer_param_t *transf return ret; if (compl->compl_mode == ODP_DMA_COMPL_POLL) { - uint32_t index = index_from_transfer_id(compl->transfer_id); + uint32_t index = index_from_transfer_id(transfer_id); session->result[index].user_ptr = compl->user_ptr; @@ -687,20 +689,20 @@ int odp_dma_transfer_done(odp_dma_t dma, odp_dma_transfer_id_t transfer_id, odp_dma_result_t *result) { dma_session_t *session = dma_session_from_handle(dma); + const uint32_t id = transfer_id; if (odp_unlikely(dma == ODP_DMA_INVALID)) { _ODP_ERR("Bad DMA handle\n"); return -1; } - if (odp_unlikely(transfer_id == ODP_DMA_TRANSFER_ID_INVALID || - transfer_id > MAX_TRANSFERS)) { - _ODP_ERR("Bad transfer ID: %u\n", transfer_id); + if (odp_unlikely(id == ODP_DMA_TRANSFER_ID_INVALID || id > MAX_TRANSFERS)) { + _ODP_ERR("Bad transfer ID: %u\n", id); return -1; } if (result) { - uint32_t index = index_from_transfer_id(transfer_id); + uint32_t index = index_from_transfer_id(id); result->success = 1; result->user_ptr = session->result[index].user_ptr; -- cgit v1.2.3 From bbf24c4825fde1d65ad9f7468d9c9ac48be5310d Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Mon, 30 Oct 2023 10:20:45 +0000 Subject: linux-gen: dma: utilize _odp_pri() Utilize `_odp_pri()` to get rid of repetitive `(uint64_t)(uintptr_t)` casts. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- platform/linux-generic/odp_dma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/linux-generic/odp_dma.c b/platform/linux-generic/odp_dma.c index 5ffeb20ce..b3439498c 100644 --- a/platform/linux-generic/odp_dma.c +++ b/platform/linux-generic/odp_dma.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -758,12 +759,12 @@ odp_pool_t odp_dma_pool_create(const char *name, const odp_dma_pool_param_t *dma uint64_t odp_dma_to_u64(odp_dma_t dma) { - return (uint64_t)(uintptr_t)dma; + return _odp_pri(dma); } uint64_t odp_dma_compl_to_u64(odp_dma_compl_t dma_compl) { - return (uint64_t)(uintptr_t)dma_compl; + return _odp_pri(dma_compl); } void odp_dma_print(odp_dma_t dma) @@ -796,12 +797,11 @@ void odp_dma_compl_print(odp_dma_compl_t dma_compl) _ODP_PRINT("\nDMA completion\n"); _ODP_PRINT("--------------\n"); - _ODP_PRINT(" Compl event handle: 0x%" PRIx64 "\n", (uint64_t)(uintptr_t)dma_compl); + _ODP_PRINT(" Compl event handle: 0x%" PRIx64 "\n", _odp_pri(dma_compl)); if (ret == 0) { _ODP_PRINT(" Result: %s\n", result.success ? "success" : "fail"); - _ODP_PRINT(" User pointer: 0x%" PRIx64 "\n", - (uint64_t)(uintptr_t)result.user_ptr); + _ODP_PRINT(" User pointer: 0x%" PRIx64 "\n", _odp_pri(result.user_ptr)); } else { _ODP_PRINT(" No result metadata\n"); } -- cgit v1.2.3 From e0f03416da00a1e001af36791026d50afc5ff050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jere=20Lepp=C3=A4nen?= Date: Fri, 27 Oct 2023 11:08:34 +0300 Subject: linux-gen: timer: avoid overrun debug prints if no timers started MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't print timer pool "overrun" and "scans missed" debug prints, if no timers have been started. Signed-off-by: Jere Leppänen Reviewed-by: Matias Elo --- platform/linux-generic/odp_timer.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index eaedcea8c..3baffde2b 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -184,7 +184,12 @@ typedef struct timer_pool_s { odp_timer_pool_param_t param; char name[ODP_TIMER_POOL_NAME_LEN]; timer_t timerid; - int notify_overrun; + /* + * Timer pool overrun notification (debug print). Initialize to 0 + * (don't notify). When value is 0 and a timer is started, set to 1 + * (notify). When notification is done, set to 2 (don't notify). + */ + odp_atomic_u32_t notify_overrun; int owner; pthread_t thr_pthread; /* pthread_t of timer thread */ pid_t thr_pid; /* gettid() for timer thread */ @@ -828,14 +833,15 @@ static inline void timer_pool_scan_inline(int num, odp_time_t now) continue; if (odp_atomic_cas_u64(&tp->cur_tick, &old_tick, new_tick)) { - if (tp->notify_overrun && diff > 1) { + if (ODP_DEBUG_PRINT && odp_atomic_load_u32(&tp->notify_overrun) == 1 && + diff > 1) { if (old_tick == 0) { _ODP_DBG("Timer pool (%s) missed %" PRIi64 " scans in start up\n", tp->name, diff - 1); } else { _ODP_DBG("Timer pool (%s) resolution too high: %" PRIi64 " scans missed\n", tp->name, diff - 1); - tp->notify_overrun = 0; + odp_atomic_store_u32(&tp->notify_overrun, 2); } } timer_pool_scan(tp, nsec); @@ -896,12 +902,12 @@ static inline void timer_run_posix(timer_pool_t *tp) uint64_t nsec; int overrun; - if (tp->notify_overrun) { + if (ODP_DEBUG_PRINT && odp_atomic_load_u32(&tp->notify_overrun) == 1) { overrun = timer_getoverrun(tp->timerid); if (overrun) { _ODP_DBG("\n\t%d ticks overrun on timer pool \"%s\", timer resolution too high\n", overrun, tp->name); - tp->notify_overrun = 0; + odp_atomic_store_u32(&tp->notify_overrun, 2); } } @@ -1089,6 +1095,12 @@ static void posix_timer_start(timer_pool_t *tp) * processed. Warm up helps avoiding overrun on the first timeout. */ while (odp_atomic_load_acq_u32(&tp->thr_ready) == 0) sched_yield(); + + if (ODP_DEBUG_PRINT) { + uint32_t old_val = 0; + + odp_atomic_cas_u32(&tp->notify_overrun, &old_val, 1); + } } static odp_timer_pool_t timer_pool_new(const char *name, const odp_timer_pool_param_t *param) @@ -1234,8 +1246,8 @@ static odp_timer_pool_t timer_pool_new(const char *name, const odp_timer_pool_pa } tp->num_alloc = 0; odp_atomic_init_u32(&tp->high_wm, 0); + odp_atomic_init_u32(&tp->notify_overrun, 0); tp->first_free = 0; - tp->notify_overrun = 1; tp->owner = -1; if (param->priv) @@ -1620,6 +1632,12 @@ int odp_timer_start(odp_timer_t timer, const odp_timer_start_t *start_param) odp_event_free(tmo_ev); } + if (ODP_DEBUG_PRINT) { + uint32_t old_val = 0; + + odp_atomic_cas_u32(&tp->notify_overrun, &old_val, 1); + } + return ODP_TIMER_SUCCESS; } -- cgit v1.2.3 From fd091a65416412bc780bcc2627fe2fa7c73264b9 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 7 Nov 2023 15:40:03 +0200 Subject: github_ci: remove ubuntu 18.04 tests Ubuntu 18.04 is already EOL, so remove the OS specific tests from CI. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- .github/workflows/ci-pipeline-arm64.yml | 4 ++-- .github/workflows/ci-pipeline.yml | 22 +++------------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci-pipeline-arm64.yml b/.github/workflows/ci-pipeline-arm64.yml index 84f52b75a..f152e9305 100644 --- a/.github/workflows/ci-pipeline-arm64.yml +++ b/.github/workflows/ci-pipeline-arm64.yml @@ -59,7 +59,7 @@ jobs: fail-fast: false matrix: cc: [gcc, clang] - os: ['ubuntu_18.04', 'rocky_linux_8'] + os: ['rocky_linux_8'] steps: - uses: OpenDataPlane/action-clean-up@main - uses: actions/checkout@v3 @@ -174,7 +174,7 @@ jobs: strategy: fail-fast: false matrix: - os: ['ubuntu_18.04', 'ubuntu_22.04'] + os: ['ubuntu_22.04'] steps: - uses: OpenDataPlane/action-clean-up@main - uses: actions/checkout@v3 diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index 8124e3753..2cef615eb 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -128,22 +128,6 @@ jobs: - if: ${{ failure() }} uses: ./.github/actions/build-failure-log - Build_arm64_u18: - runs-on: ubuntu-20.04 - env: - ARCH: arm64 - OS: ubuntu_18.04 - strategy: - fail-fast: false - matrix: - cc: [gcc, clang] - steps: - - uses: actions/checkout@v3 - - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" - -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/build_${ARCH}.sh - - if: ${{ failure() }} - uses: ./.github/actions/build-failure-log - Build_armhf: runs-on: ubuntu-20.04 env: @@ -225,10 +209,10 @@ jobs: - if: ${{ failure() }} uses: ./.github/actions/build-failure-log - Build_gcc_u18: + Build_gcc_u20: runs-on: ubuntu-20.04 env: - OS: ubuntu_18.04 + OS: ubuntu_20.04 strategy: fail-fast: false matrix: @@ -321,7 +305,7 @@ jobs: fail-fast: false matrix: cc: [gcc, clang] - os: ['ubuntu_18.04', 'ubuntu_22.04'] + os: ['ubuntu_22.04'] steps: - uses: actions/checkout@v3 - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e ARCH="${ARCH}" -- cgit v1.2.3 From bfa73fb940f6ddd7c4176a9d42216afe5623de08 Mon Sep 17 00:00:00 2001 From: Janne Peltonen Date: Wed, 8 Nov 2023 16:52:52 +0200 Subject: linux-gen: fix unaligned access in checksum calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Architectures that support unaligned access do not necessarily support it for all instructions that a compiler might choose to use. Therefore we should not mispresent the alignment of an object to the compiler even when unaligned access is typically supported. The current checksum code casts a potentially unaligned address to a pointer to uint32_t when _ODP_UNALIGNED is set. This typically works but may, in some cases, result in generation of invalid code. In particular, when targeting AArch32 (which supports unaligned access for regular loads and stores) gcc-12.2 generated LDM instructions which always reguire 4-byte alignment. Fix the problem by informing the compiler about the non-standard alignment by using a type attribute. Signed-off-by: Janne Peltonen Reviewed-by: Jere Leppänen --- .../linux-generic/include/odp_chksum_internal.h | 29 ++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/platform/linux-generic/include/odp_chksum_internal.h b/platform/linux-generic/include/odp_chksum_internal.h index 5a134ae2d..e589ecb94 100644 --- a/platform/linux-generic/include/odp_chksum_internal.h +++ b/platform/linux-generic/include/odp_chksum_internal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2020, Nokia +/* Copyright (c) 2020, 2023, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -62,8 +62,23 @@ static inline uint16_t chksum_finalize(uint64_t sum) static uint64_t chksum_partial(const void *addr, uint32_t len, uint32_t offset) { const uint8_t *b; - const uint16_t *w; - const uint32_t *d; +#if _ODP_UNALIGNED + /* + * _ODP_UNALIGNED does not guarantee that all possible ways of + * accessing memory can be unaligned. Make the compiler aware + * of the possible unalignment so that it does not generate + * instructions (such as LDM of AArch32) that require higher + * alignment than one byte. + */ + typedef uint32_t x_uint32_t ODP_ALIGNED(1); + typedef uint16_t x_uint16_t ODP_ALIGNED(1); +#else + /* In this case we can use normal types as we align manually. */ + typedef uint32_t x_uint32_t; + typedef uint16_t x_uint16_t; +#endif + const x_uint16_t *w; + const x_uint32_t *d; uint64_t sum = 0; /* @@ -77,7 +92,7 @@ static uint64_t chksum_partial(const void *addr, uint32_t len, uint32_t offset) * We have efficient unaligned access. Just read * dwords starting at the given address. */ - d = (const uint32_t *)addr; + d = (const x_uint32_t *)addr; } else { /* * We must avoid unaligned access, so align to 4 bytes @@ -102,7 +117,7 @@ static uint64_t chksum_partial(const void *addr, uint32_t len, uint32_t offset) * This cast increases alignment, but it's OK, since * we've made sure that the pointer value is aligned. */ - w = (const uint16_t *)(uintptr_t)b; + w = (const x_uint16_t *)(uintptr_t)b; if ((uintptr_t)w & 2 && len >= 2) { /* Align bytes by handling an odd word. */ @@ -111,7 +126,7 @@ static uint64_t chksum_partial(const void *addr, uint32_t len, uint32_t offset) } /* Increases alignment. */ - d = (const uint32_t *)(uintptr_t)w; + d = (const x_uint32_t *)(uintptr_t)w; } while (len >= 32) { @@ -159,7 +174,7 @@ static uint64_t chksum_partial(const void *addr, uint32_t len, uint32_t offset) len &= 3; - w = (const uint16_t *)d; + w = (const x_uint16_t *)d; if (len > 1) { /* Last word. */ sum += *w++; -- cgit v1.2.3 From 4549b265e299fca093dbba5be2d108d77735eecf Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 15 Nov 2023 11:46:57 +0200 Subject: validation: pool: check only requested thread statistics When testing odp_pool_stats(), check thread.cache_available[] counters only for the number of threads requested. Also, added statistics struct initialization to catch more robustly output errors in the functions. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo Acked-by: Ashwin Sekhar T K --- test/validation/api/pool/pool.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/test/validation/api/pool/pool.c b/test/validation/api/pool/pool.c index 8515f9b64..6f9b054ac 100644 --- a/test/validation/api/pool/pool.c +++ b/test/validation/api/pool/pool.c @@ -1324,7 +1324,7 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) odp_pool_stats_selected_t selected; odp_pool_param_t param; odp_pool_stats_opt_t supported; - uint32_t i, j, num_pool, num_obj, cache_size; + uint32_t i, j, num_pool, num_obj, cache_size, num_thr; uint32_t max_pools = 2; uint16_t first = 0; uint16_t last = ODP_POOL_MAX_THREAD_STATS - 1; @@ -1407,9 +1407,14 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) uint32_t num_events = 0; uint32_t num_fails = 0; + memset(&stats, 0xff, sizeof(odp_pool_stats_t)); + memset(&selected, 0xff, sizeof(odp_pool_stats_selected_t)); + CU_ASSERT_FATAL(odp_pool_stats_reset(pool[i]) == 0); + stats.thread.first = first; stats.thread.last = last; + num_thr = last - first + 1; CU_ASSERT_FATAL(odp_pool_stats(pool[i], &stats) == 0); CU_ASSERT_FATAL(odp_pool_stats_selected(pool[i], &selected, &supported) == 0); @@ -1440,7 +1445,8 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) CU_ASSERT(stats.thread.first == first); CU_ASSERT(stats.thread.last == last); - for (j = 0; j < ODP_POOL_MAX_THREAD_STATS; j++) + + for (j = 0; j < num_thr; j++) CU_ASSERT(stats.thread.cache_available[j] <= stats.cache_available); /* Allocate the events */ @@ -1488,12 +1494,15 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) CU_ASSERT(selected.cache_available <= num_obj - num_events); while (first_id < odp_thread_count_max()) { + memset(&stats, 0xff, sizeof(odp_pool_stats_t)); + stats.thread.first = first_id; stats.thread.last = last_id; + num_thr = last_id - first_id + 1; CU_ASSERT_FATAL(odp_pool_stats(pool[i], &stats) == 0); - for (int i = 0; i < ODP_POOL_MAX_THREAD_STATS; i++) { - uint64_t cached = stats.thread.cache_available[i]; + for (uint32_t k = 0; k < num_thr; k++) { + uint64_t cached = stats.thread.cache_available[k]; CU_ASSERT(cached <= num_obj - num_events); total_cached += cached; @@ -1515,8 +1524,12 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) /* Allow implementation some time to update counters */ odp_time_wait_ns(ODP_TIME_MSEC_IN_NS); + memset(&stats, 0xff, sizeof(odp_pool_stats_t)); + memset(&selected, 0xff, sizeof(odp_pool_stats_selected_t)); + stats.thread.first = first; stats.thread.last = last; + num_thr = last - first + 1; CU_ASSERT_FATAL(odp_pool_stats(pool[i], &stats) == 0); CU_ASSERT_FATAL(odp_pool_stats_selected(pool[i], &selected, &supported) == 0); @@ -1528,7 +1541,7 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) CU_ASSERT(stats.cache_available == 0); if (supported.bit.cache_available) CU_ASSERT(selected.cache_available == 0); - for (j = 0; j < ODP_POOL_MAX_THREAD_STATS; j++) + for (j = 0; j < num_thr; j++) CU_ASSERT(stats.thread.cache_available[j] == 0); if (supported.bit.alloc_ops) { CU_ASSERT(stats.alloc_ops > 0 && stats.alloc_ops <= num_allocs); -- cgit v1.2.3 From 7b6e4293fa15f99ae00985f098383ac853d3bbbd Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 28 Nov 2023 12:35:37 +0200 Subject: example: timer_accuracy: fix CPU count default value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to help, test runs on single CPU by default. Signed-off-by: Petri Savolainen Reviewed-by: Jere Leppänen --- example/timer/odp_timer_accuracy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/example/timer/odp_timer_accuracy.c b/example/timer/odp_timer_accuracy.c index 9a4593a9a..05e4e9181 100644 --- a/example/timer/odp_timer_accuracy.c +++ b/example/timer/odp_timer_accuracy.c @@ -197,6 +197,7 @@ static int parse_options(int argc, char *argv[], test_opt_t *test_opt) memset(test_opt, 0, sizeof(*test_opt)); + test_opt->cpu_count = 1; test_opt->period_ns = 200 * ODP_TIME_MSEC_IN_NS; test_opt->res_ns = 0; test_opt->res_hz = 0; -- cgit v1.2.3 From e1647a1a8e4255a2a335d54e67ff509732f05731 Mon Sep 17 00:00:00 2001 From: Fan Hong Date: Mon, 6 Nov 2023 07:11:45 +0000 Subject: linux-gen: llsc: fix type casts error with CXX Fix casts to union type erros with CXX on aarch64. When "odp_cpu.h" is included in some head files, "odp_api_from_cpp.cpp" would include "odp_cpu.h" as well. Build failure and error of 'unknown conversion of types' show as going through this file with CXX. Signed-off-by: Fan Hong Reviewed-by: Matias Elo --- platform/linux-generic/arch/aarch64/odp_llsc.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/linux-generic/arch/aarch64/odp_llsc.h b/platform/linux-generic/arch/aarch64/odp_llsc.h index ba7a447d4..498785bd4 100644 --- a/platform/linux-generic/arch/aarch64/odp_llsc.h +++ b/platform/linux-generic/arch/aarch64/odp_llsc.h @@ -150,15 +150,15 @@ static inline uint32_t scd(_odp_u128_t *var, _odp_u128_t neu, int mm) if (mm == __ATOMIC_RELEASE) __asm__ volatile("stlxp %w0, %1, %2, [%3]" : "=&r" (ret) - : "r" (((union i128)neu).i64[0]), - "r" (((union i128)neu).i64[1]), + : "r" (((*(union i128 *)&neu)).i64[0]), + "r" (((*(union i128 *)&neu)).i64[1]), "r" (var) : "memory"); else if (mm == __ATOMIC_RELAXED) __asm__ volatile("stxp %w0, %1, %2, [%3]" : "=&r" (ret) - : "r" (((union i128)neu).i64[0]), - "r" (((union i128)neu).i64[1]), + : "r" (((*(union i128 *)&neu)).i64[0]), + "r" (((*(union i128 *)&neu)).i64[1]), "r" (var) : ); else -- cgit v1.2.3 From 84931a91770ad29532b20d738418bb7be3e9263f Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 10 Nov 2023 13:37:54 +0200 Subject: linux-gen: m4: add configuration option for enabling wfe locks Add new configuration option '--enable-wfe-locks' for enabling WFE based lock implementations on aarch64. Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- include/odp/autoheader_external.h.in | 3 +++ platform/linux-generic/m4/configure.m4 | 8 +++++--- platform/linux-generic/m4/odp_wfe.m4 | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 platform/linux-generic/m4/odp_wfe.m4 diff --git a/include/odp/autoheader_external.h.in b/include/odp/autoheader_external.h.in index 74662b2e0..ebdb9fbc6 100644 --- a/include/odp/autoheader_external.h.in +++ b/include/odp/autoheader_external.h.in @@ -14,4 +14,7 @@ /* Define to 1 or 2 to enable event validation */ #undef _ODP_EVENT_VALIDATION +/* Define to 1 to enable WFE based lock implementation on aarch64 */ +#undef _ODP_WFE_LOCKS + #endif diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4 index 556f01c19..61b65540f 100644 --- a/platform/linux-generic/m4/configure.m4 +++ b/platform/linux-generic/m4/configure.m4 @@ -29,6 +29,7 @@ m4_include([platform/linux-generic/m4/odp_crypto.m4]) m4_include([platform/linux-generic/m4/odp_ipsec_mb.m4]) m4_include([platform/linux-generic/m4/odp_pcapng.m4]) m4_include([platform/linux-generic/m4/odp_dpdk.m4]) +m4_include([platform/linux-generic/m4/odp_wfe.m4]) m4_include([platform/linux-generic/m4/odp_xdp.m4]) ODP_EVENT_VALIDATION ODP_SCHEDULER @@ -42,9 +43,10 @@ AS_VAR_APPEND([PLAT_CFG_TEXT], [" openssl: ${with_openssl} openssl_rand: ${openssl_rand} crypto: ${with_crypto} - pcap: ${have_pcap} - pcapng: ${have_pcapng} - default_config_path: ${default_config_path}"]) + pcap: ${have_pcap} + pcapng: ${have_pcapng} + wfe_locks: ${use_wfe_locks} + default_config_path: ${default_config_path}"]) # Ignore Clang specific errors about fields with variable sized type not at the # end of a struct. This style is used by e.g. odp_packet_hdr_t and diff --git a/platform/linux-generic/m4/odp_wfe.m4 b/platform/linux-generic/m4/odp_wfe.m4 new file mode 100644 index 000000000..f0f0542f7 --- /dev/null +++ b/platform/linux-generic/m4/odp_wfe.m4 @@ -0,0 +1,14 @@ +########################################################################## +# Enable/disable WFE based lock implementations +########################################################################## +use_wfe_locks=no +AC_ARG_ENABLE([wfe-locks], + [AS_HELP_STRING([--enable-wfe-locks], + [enable WFE based lock implementations on aarch64] + [[default=disabled] (linux-generic)])], + [use_wfe_locks=$enableval]) + +if test x$use_wfe_locks = xyes; then + AC_DEFINE([_ODP_WFE_LOCKS], [1], + [Define to 1 to enable WFE based lock implementations on aarch64]) +fi -- cgit v1.2.3 From c20e1fe14fd5f91de99663a7dd22bdd797871d65 Mon Sep 17 00:00:00 2001 From: Fan Hong Date: Mon, 6 Nov 2023 07:43:38 +0000 Subject: linux-gen: ticketlock: enable WFE on aarch64 Use WFE instruction on aarch64 to replace cpu_wait in ticketlock_lock, making threads waiting for their turn into low-power state. Performance test with "odp_lock_perf" shows that it could reduce IPC while maintain similar performance. WFE_LOCKS is an optional configuration. Signed-off-by: Fan Hong Reviewed-by: Matias Elo --- platform/linux-generic/Makefile.am | 20 ++++++--- .../arch/aarch64/odp/api/abi/wait_until.h | 47 ++++++++++++++++++++++ .../arch/default/odp/api/abi/wait_until.h | 5 +++ .../arch/default/odp/api/abi/wait_until_generic.h | 25 ++++++++++++ .../include/odp/api/plat/ticketlock_inlines.h | 5 +-- 5 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 platform/linux-generic/arch/aarch64/odp/api/abi/wait_until.h create mode 100644 platform/linux-generic/arch/default/odp/api/abi/wait_until.h create mode 100644 platform/linux-generic/arch/default/odp/api/abi/wait_until_generic.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 92d87b441..3b645460b 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -340,7 +340,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/arm/odp/api/abi/cpu_inlines.h \ arch/arm/odp/api/abi/cpu.h \ arch/default/odp/api/abi/sync_inlines.h \ - arch/default/odp/api/abi/time_inlines.h + arch/default/odp/api/abi/time_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/default/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/arm/odp_atomic.h \ arch/arm/odp_cpu.h \ @@ -370,7 +372,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/aarch64/odp/api/abi/cpu.h \ arch/aarch64/odp/api/abi/sync_inlines.h \ arch/common/odp/api/abi/time_cpu_inlines.h \ - arch/aarch64/odp/api/abi/time_inlines.h + arch/aarch64/odp/api/abi/time_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/aarch64/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/aarch64/odp_atomic.h \ arch/aarch64/odp_cpu.h \ @@ -394,7 +398,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/default/odp/api/abi/cpu_inlines.h \ arch/default/odp/api/abi/cpu.h \ arch/default/odp/api/abi/sync_inlines.h \ - arch/default/odp/api/abi/time_inlines.h + arch/default/odp/api/abi/time_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/default/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/default/odp_atomic.h \ arch/default/odp_cpu.h \ @@ -416,7 +422,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/default/odp/api/abi/cpu_inlines.h \ arch/powerpc/odp/api/abi/cpu.h \ arch/default/odp/api/abi/sync_inlines.h \ - arch/default/odp/api/abi/time_inlines.h + arch/default/odp/api/abi/time_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/default/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/default/odp_atomic.h \ arch/default/odp_cpu.h \ @@ -442,7 +450,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/x86/odp/api/abi/cpu.h \ arch/x86/odp/api/abi/sync_inlines.h \ arch/common/odp/api/abi/time_cpu_inlines.h \ - arch/x86/odp/api/abi/time_inlines.h + arch/x86/odp/api/abi/time_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/default/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/x86/cpu_flags.h \ arch/x86/odp_cpu.h \ diff --git a/platform/linux-generic/arch/aarch64/odp/api/abi/wait_until.h b/platform/linux-generic/arch/aarch64/odp/api/abi/wait_until.h new file mode 100644 index 000000000..73a3d476a --- /dev/null +++ b/platform/linux-generic/arch/aarch64/odp/api/abi/wait_until.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 ARM Limited + */ + +#ifndef ODP_API_ABI_WAIT_UNTIL_H_ +#define ODP_API_ABI_WAIT_UNTIL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef _ODP_WFE_LOCKS + +#include + +#include + +static inline void +_odp_wait_until_equal_acq_u32(odp_atomic_u32_t *addr, uint32_t expected) +{ + uint32_t value; + uint32_t *var = &addr->v; + + __asm__ volatile("sevl" : : : "memory"); + do { + __asm__ volatile("wfe" : : : "memory"); + __asm__ volatile("ldaxr %w0, [%1]" + : "=&r" (value) + : "r" (var) + : "memory"); + } while (expected != value); +} + +#else /* !_ODP_WFE_LOCKS*/ + +/* Use generic implementation */ +#include + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/arch/default/odp/api/abi/wait_until.h b/platform/linux-generic/arch/default/odp/api/abi/wait_until.h new file mode 100644 index 000000000..35e8d2566 --- /dev/null +++ b/platform/linux-generic/arch/default/odp/api/abi/wait_until.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 ARM Limited + */ + +#include diff --git a/platform/linux-generic/arch/default/odp/api/abi/wait_until_generic.h b/platform/linux-generic/arch/default/odp/api/abi/wait_until_generic.h new file mode 100644 index 000000000..3d3fce175 --- /dev/null +++ b/platform/linux-generic/arch/default/odp/api/abi/wait_until_generic.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 ARM Limited + */ + +#ifndef ODP_API_ABI_WAIT_UNTIL_GENERIC_H_ +#define ODP_API_ABI_WAIT_UNTIL_GENERIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +static inline void +_odp_wait_until_equal_acq_u32(odp_atomic_u32_t *addr, uint32_t expected) +{ + while (odp_atomic_load_acq_u32(addr) != expected) + odp_cpu_pause(); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/include/odp/api/plat/ticketlock_inlines.h b/platform/linux-generic/include/odp/api/plat/ticketlock_inlines.h index eef052f8d..b596d1609 100644 --- a/platform/linux-generic/include/odp/api/plat/ticketlock_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/ticketlock_inlines.h @@ -11,7 +11,7 @@ #include #include - +#include /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ #ifndef _ODP_NO_INLINE @@ -47,8 +47,7 @@ _ODP_INLINE void odp_ticketlock_lock(odp_ticketlock_t *ticketlock) /* Spin waiting for our turn. Use load-acquire so that we acquire * all stores from the previous lock owner */ - while (ticket != odp_atomic_load_acq_u32(&ticketlock->cur_ticket)) - odp_cpu_pause(); + _odp_wait_until_equal_acq_u32(&ticketlock->cur_ticket, ticket); } _ODP_INLINE int odp_ticketlock_trylock(odp_ticketlock_t *tklock) -- cgit v1.2.3 From 38e6c8ef067f98178e3fcc1ceb22563385a5bb7b Mon Sep 17 00:00:00 2001 From: Janne Peltonen Date: Tue, 28 Nov 2023 09:27:01 +0200 Subject: test: performance: improve warmup in common test bench Run a warmup round for each test just before the actual test run instead of running it for all tests before any actual test runs. This way other tests do not run between the warmup and the actual test run and the code becomes a bit cleaner too. Test specific init functions are still run after the warmup, which may skew the results. Signed-off-by: Janne Peltonen Reviewed-by: Matias Elo --- test/performance/bench_common.c | 115 ++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 63 deletions(-) diff --git a/test/performance/bench_common.c b/test/performance/bench_common.c index 5a948c9c7..f838954ab 100644 --- a/test/performance/bench_common.c +++ b/test/performance/bench_common.c @@ -51,36 +51,35 @@ int bench_run(void *arg) bench_suite_t *suite = arg; const uint64_t repeat_count = suite->repeat_count; const odp_bool_t meas_time = suite->measure_time; + double result; printf("\nAverage %s per function call\n", meas_time ? "time (nsec)" : "CPU cycles"); printf("-------------------------------------------------\n"); - /* Run each test twice. Results from the first warm-up round are ignored. */ - for (int i = 0; i < 2; i++) { + for (int j = 0; j < suite->num_bench; j++) { + int ret; + const char *desc; + const bench_info_t *bench = &suite->bench[j]; + uint64_t max_rounds = suite->rounds; uint64_t total = 0; - uint64_t round = 1; - - for (int j = 0; j < suite->num_bench; round++) { - int ret; - const char *desc; - const bench_info_t *bench = &suite->bench[j]; - uint64_t max_rounds = suite->rounds; - - if (bench->max_rounds && bench->max_rounds < max_rounds) - max_rounds = bench->max_rounds; - - /* Run selected test indefinitely */ - if (suite->indef_idx) { - if ((j + 1) != suite->indef_idx) { - j++; - continue; - } - bench_run_indef(&suite->bench[j], &suite->exit_worker); - return 0; + + if (bench->max_rounds && bench->max_rounds < max_rounds) + max_rounds = bench->max_rounds; + + /* Run selected test indefinitely */ + if (suite->indef_idx) { + if ((j + 1) != suite->indef_idx) { + j++; + continue; } + bench_run_indef(&suite->bench[j], &suite->exit_worker); + return 0; + } - desc = bench->desc != NULL ? bench->desc : bench->name; + desc = bench->desc != NULL ? bench->desc : bench->name; + /* The zeroeth round is a warmup round that will be ignored */ + for (uint64_t round = 0; round <= max_rounds; round++) { if (bench->init != NULL) bench->init(); @@ -105,29 +104,20 @@ int bench_run(void *arg) return -1; } + if (odp_unlikely(round == 0)) + continue; if (meas_time) total += odp_time_diff_ns(t2, t1); else total += odp_cpu_cycles_diff(c2, c1); + } - if (round >= max_rounds) { - double result; - - /* Each benchmark runs internally 'repeat_count' times. */ - result = ((double)total) / (max_rounds * repeat_count); - - /* No print or results from warm-up round */ - if (i > 0) { - printf("[%02d] odp_%-26s: %12.2f\n", j + 1, desc, result); + /* Each benchmark runs internally 'repeat_count' times. */ + result = ((double)total) / (max_rounds * repeat_count); - if (suite->result) - suite->result[j] = result; - } - j++; - total = 0; - round = 1; - } - } + printf("[%02d] odp_%-26s: %12.2f\n", j + 1, desc, result); + if (suite->result) + suite->result[j] = result; } printf("\n"); /* Print dummy result to prevent compiler to optimize it away*/ @@ -205,29 +195,31 @@ int bench_tm_run(void *arg) printf("\nLatency (nsec) per function call min avg max\n"); printf("------------------------------------------------------------------------------\n"); - /* Run each test twice. Results from the first warm-up round are ignored. */ - for (uint32_t i = 0; i < 2; i++) { - for (uint32_t j = 0; j < suite->num_bench; j++) { - const bench_tm_info_t *bench = &suite->bench[j]; - uint64_t rounds = suite->rounds; - bench_tm_result_t res; + for (uint32_t j = 0; j < suite->num_bench; j++) { + const bench_tm_info_t *bench = &suite->bench[j]; + uint64_t rounds = suite->rounds; + bench_tm_result_t res; - if (odp_atomic_load_u32(&suite->exit_worker)) - return 0; + /* Run only selected test case */ + if (suite->bench_idx && (j + 1) != suite->bench_idx) + continue; - /* Run only selected test case */ - if (suite->bench_idx && (j + 1) != suite->bench_idx) - continue; + if (bench->cond != NULL && !bench->cond()) { + printf("[%02d] %-41s n/a n/a n/a\n", + j + 1, bench->name); + continue; + } - if (bench->max_rounds && bench->max_rounds < rounds) - rounds = bench->max_rounds; + if (bench->max_rounds && bench->max_rounds < rounds) + rounds = bench->max_rounds; - if (bench->cond != NULL && !bench->cond()) { - if (i > 0) - printf("[%02d] %-41s n/a n/a n/a\n", - j + 1, bench->name); - continue; - } + /* + * Run each test twice. + * Results from the first warm-up round are ignored. + */ + for (uint32_t i = 0; i < 2; i++) { + if (odp_atomic_load_u32(&suite->exit_worker)) + return 0; init_result(&res); @@ -243,12 +235,9 @@ int bench_tm_run(void *arg) if (bench->term != NULL) bench->term(); - /* No print or results from warm-up round */ - if (i > 0) { - printf("[%02d] %-26s\n", j + 1, bench->name); - print_results(&res); - } } + printf("[%02d] %-26s\n", j + 1, bench->name); + print_results(&res); } printf("\n"); -- cgit v1.2.3 From 899f192c15417cb63e38eed7c6e72a20d9aadab0 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 23 Nov 2023 11:08:57 +0200 Subject: test: bench_misc: short and long time stamps Time stamp value may affect result of some test cases. Also, test results are more consistent with fixed time stamp values than currrent time (changes between test runs). Added short (1 msec) and long (10 sec) time stamps, and use those in short/long time_to_nsec test cases. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen --- test/performance/odp_bench_misc.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/test/performance/odp_bench_misc.c b/test/performance/odp_bench_misc.c index e21208ff2..dd23c0c14 100644 --- a/test/performance/odp_bench_misc.c +++ b/test/performance/odp_bench_misc.c @@ -47,10 +47,17 @@ typedef struct { /* Common benchmark suite data */ bench_suite_t suite; - /* Test case input / output data */ + /* Time stamp 1 */ odp_time_t t1[REPEAT_COUNT]; + /* Time stamp 2 */ odp_time_t t2[REPEAT_COUNT]; + /* Resulting time stamp */ odp_time_t t3[REPEAT_COUNT]; + + odp_time_t global_short[REPEAT_COUNT]; + odp_time_t global_long[REPEAT_COUNT]; + + /* Integer input / output data */ uint64_t a1[REPEAT_COUNT]; uint64_t a2[REPEAT_COUNT]; uint32_t b1[REPEAT_COUNT]; @@ -266,14 +273,28 @@ static int time_sum(void) return i; } -static int time_to_ns(void) +static int time_to_ns_short(void) { int i; - odp_time_t *t1 = gbl_args->t1; + odp_time_t *t = gbl_args->global_short; + uint64_t res = 0; + + for (i = 0; i < REPEAT_COUNT; i++) + res += odp_time_to_ns(t[i]); + + gbl_args->suite.dummy += res; + + return i; +} + +static int time_to_ns_long(void) +{ + int i; + odp_time_t *t = gbl_args->global_long; uint64_t res = 0; for (i = 0; i < REPEAT_COUNT; i++) - res += odp_time_to_ns(t1[i]); + res += odp_time_to_ns(t[i]); gbl_args->suite.dummy += res; @@ -698,7 +719,8 @@ bench_info_t test_suite[] = { BENCH_INFO(time_diff, init_time_local, 0, "time_diff (local)"), BENCH_INFO(time_diff_ns, init_time_global, 0, NULL), BENCH_INFO(time_sum, init_time_global, 0, NULL), - BENCH_INFO(time_to_ns, init_time_global, 0, NULL), + BENCH_INFO(time_to_ns_short, NULL, 0, "time_to_ns (short)"), + BENCH_INFO(time_to_ns_long, NULL, 0, "time_to_ns (long)"), BENCH_INFO(time_local_from_ns, init_time_global, 0, NULL), BENCH_INFO(time_global_from_ns, init_time_global, 0, NULL), BENCH_INFO(time_cmp, init_time_global, 0, NULL), @@ -884,6 +906,8 @@ int main(int argc, char *argv[]) gbl_args->t1[i] = ODP_TIME_NULL; gbl_args->t2[i] = ODP_TIME_NULL; gbl_args->t3[i] = ODP_TIME_NULL; + gbl_args->global_short[i] = odp_time_global_from_ns(ODP_TIME_MSEC_IN_NS); + gbl_args->global_long[i] = odp_time_global_from_ns(10 * ODP_TIME_SEC_IN_NS); gbl_args->a1[i] = i; gbl_args->a2[i] = i; gbl_args->b1[i] = i; -- cgit v1.2.3 From aea921d33cc85e55ef941f29f77368e5e378d0ed Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 1 Dec 2023 14:15:07 +0200 Subject: linux-gen: pool: use odp_thread_count_max() as maximum thread count odp_thread_count_max() may return a lower value than ODP_THREAD_COUNT_MAX, so use that when applicable to minimize overhead. Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- platform/linux-generic/odp_pool.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index ace071248..8aa2f8f71 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -149,10 +149,11 @@ static inline int cache_available(pool_t *pool, odp_pool_stats_t *stats) const uint16_t first = stats->thread.first; const uint16_t last = stats->thread.last; const odp_bool_t per_thread = pool->params.stats.bit.thread_cache_available; + const int max_threads = odp_thread_count_max(); uint16_t out_idx = 0; if (per_thread) { - if (first > last || last >= odp_thread_count_max()) { + if (first > last || last >= max_threads) { _ODP_ERR("Bad thread ids: first=%" PRIu16 " last=%" PRIu16 "\n", first, last); return -1; @@ -164,7 +165,7 @@ static inline int cache_available(pool_t *pool, odp_pool_stats_t *stats) } } - for (int i = 0; i < ODP_THREAD_COUNT_MAX; i++) { + for (int i = 0; i < max_threads; i++) { uint32_t cur = odp_atomic_load_u32(&pool->local_cache[i].cache_num); if (per_thread && i >= first && i <= last) @@ -182,8 +183,9 @@ static inline int cache_available(pool_t *pool, odp_pool_stats_t *stats) static inline uint64_t cache_total_available(pool_t *pool) { uint64_t cached = 0; + const int max_threads = odp_thread_count_max(); - for (int i = 0; i < ODP_THREAD_COUNT_MAX; i++) + for (int i = 0; i < max_threads; i++) cached += odp_atomic_load_u32(&pool->local_cache[i].cache_num); return cached; @@ -1169,6 +1171,7 @@ odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *params) int odp_pool_destroy(odp_pool_t pool_hdl) { pool_t *pool = _odp_pool_entry(pool_hdl); + const int max_threads = odp_thread_count_max(); int i; if (pool == NULL) @@ -1186,7 +1189,7 @@ int odp_pool_destroy(odp_pool_t pool_hdl) pool->mem_src_ops->unbind(pool->mem_src_data); /* Make sure local caches are empty */ - for (i = 0; i < ODP_THREAD_COUNT_MAX; i++) + for (i = 0; i < max_threads; i++) cache_flush(&pool->local_cache[i], pool); if (pool->pool_ext == 0) -- cgit v1.2.3 From 28249252309e60bf954f5da06de112c676a313fd Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 1 Dec 2023 14:54:52 +0200 Subject: linux-gen: pool: optimize odp_pool_stats() implementation If 'thread_cache_available' is enabled and 'cache_available' is not, it's enough to read only the selected per thread counters. Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- platform/linux-generic/odp_pool.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index 8aa2f8f71..59908644d 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -148,9 +148,11 @@ static inline int cache_available(pool_t *pool, odp_pool_stats_t *stats) uint64_t cached = 0; const uint16_t first = stats->thread.first; const uint16_t last = stats->thread.last; + const odp_bool_t cache_available = pool->params.stats.bit.cache_available; const odp_bool_t per_thread = pool->params.stats.bit.thread_cache_available; const int max_threads = odp_thread_count_max(); uint16_t out_idx = 0; + int i, idx_limit; if (per_thread) { if (first > last || last >= max_threads) { @@ -165,7 +167,15 @@ static inline int cache_available(pool_t *pool, odp_pool_stats_t *stats) } } - for (int i = 0; i < max_threads; i++) { + if (cache_available) { + i = 0; + idx_limit = max_threads; + } else { + i = first; + idx_limit = last + 1; + } + + for (; i < idx_limit; i++) { uint32_t cur = odp_atomic_load_u32(&pool->local_cache[i].cache_num); if (per_thread && i >= first && i <= last) @@ -174,7 +184,7 @@ static inline int cache_available(pool_t *pool, odp_pool_stats_t *stats) cached += cur; } - if (pool->params.stats.bit.cache_available) + if (cache_available) stats->cache_available = cached; return 0; -- cgit v1.2.3 From 98bd57096fd797642d525b67a04b331205aaca95 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 7 Dec 2023 17:32:54 +0200 Subject: validation: timer: tick should not wrap in 10 years Check that ticks and converted nanosecond value will not wrap in 10 years. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo --- test/validation/api/timer/timer.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c index db66b3664..980372c35 100644 --- a/test/validation/api/timer/timer.c +++ b/test/validation/api/timer/timer.c @@ -37,6 +37,7 @@ #define THREE_POINT_THREE_MSEC (10 * ODP_TIME_MSEC_IN_NS / 3) #define USER_PTR ((void *)0xdead) #define TICK_INVALID (~(uint64_t)0) +#define YEAR_IN_NS (365 * 24 * ODP_TIME_HOUR_IN_NS) /* Test case options */ #define PRIV 1 @@ -1217,7 +1218,7 @@ static void timer_pool_current_tick_run(odp_timer_clk_src_t clk_src) odp_timer_capability_t capa; odp_timer_pool_param_t tp_param; odp_timer_pool_t tp; - uint64_t t1, t2, ticks, min, max; + uint64_t t1, t2, ticks, min, max, limit; uint64_t nsec = 100 * ODP_TIME_MSEC_IN_NS; memset(&capa, 0, sizeof(capa)); @@ -1252,6 +1253,13 @@ static void timer_pool_current_tick_run(odp_timer_clk_src_t clk_src) CU_ASSERT(ticks >= min); CU_ASSERT(ticks <= max); + /* Timer tick (or tick in nsec) should not wrap in at least 10 years from ODP start. + * Ignoring delay from start up and other test cases, which should be few seconds. */ + limit = 10 * YEAR_IN_NS; + nsec = odp_timer_tick_to_ns(tp, t1); + CU_ASSERT(UINT64_MAX - nsec > limit); + CU_ASSERT(UINT64_MAX - t1 > odp_timer_ns_to_tick(tp, limit)); + printf("\nClock source %i\n", clk_src); printf(" Time nsec: %" PRIu64 "\n", nsec); printf(" Measured ticks: %" PRIu64 "\n", ticks); -- cgit v1.2.3 From d3b3f0ddbb15a68b42cae6717d48efed232a5dfe Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 7 Dec 2023 15:50:06 +0200 Subject: test: timer_perf: measure timer start cycles Measure and report timer start cycles in expire and start mode (-m 2). Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo --- test/performance/odp_timer_perf.c | 110 ++++++++++++++++++++++++++++++++------ 1 file changed, 95 insertions(+), 15 deletions(-) diff --git a/test/performance/odp_timer_perf.c b/test/performance/odp_timer_perf.c index 279c5600e..11a3c7864 100644 --- a/test/performance/odp_timer_perf.c +++ b/test/performance/odp_timer_perf.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022, Nokia +/* Copyright (c) 2019-2023, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -45,7 +45,8 @@ typedef struct test_stat_t { uint64_t rounds; uint64_t events; uint64_t nsec; - uint64_t cycles; + uint64_t cycles_0; + uint64_t cycles_1; uint64_t cancels; uint64_t sets; @@ -59,7 +60,8 @@ typedef struct test_stat_sum_t { uint64_t rounds; uint64_t events; uint64_t nsec; - uint64_t cycles; + uint64_t cycles_0; + uint64_t cycles_1; uint64_t cancels; uint64_t sets; @@ -133,7 +135,8 @@ static void print_usage(void) " -m, --mode Select test mode. Default: 0\n" " 0: Measure odp_schedule() overhead when using timers\n" " 1: Measure timer set + cancel performance\n" - " 2: Measure odp_schedule() overhead while continuously restarting expiring timers\n" + " 2: Measure schedule and timer start overhead while continuously\n" + " restarting expiring timers\n" " -R, --rounds Number of test rounds in timer set + cancel test.\n" " Default: 100000\n" " -h, --help This help\n" @@ -637,7 +640,7 @@ static int sched_mode_worker(void *arg) /* Update stats*/ global->stat[thr].events = events; - global->stat[thr].cycles = cycles; + global->stat[thr].cycles_0 = cycles; global->stat[thr].rounds = rounds; global->stat[thr].nsec = nsec; global->stat[thr].before = before; @@ -818,7 +821,7 @@ static int set_cancel_mode_worker(void *arg) global->stat[thr].events = num_tmo; global->stat[thr].rounds = test_options->test_rounds - test_rounds; global->stat[thr].nsec = nsec; - global->stat[thr].cycles = diff; + global->stat[thr].cycles_0 = diff; global->stat[thr].cancels = num_cancel; global->stat[thr].sets = num_set; @@ -832,7 +835,7 @@ static int set_expire_mode_worker(void *arg) uint32_t i, j, exit_test; odp_event_t ev; odp_timeout_t tmo; - uint64_t c2, diff, nsec, time_ns, target_ns, period_tick; + uint64_t c2, c3, c4, diff, nsec, time_ns, target_ns, period_tick; odp_timer_t timer; odp_timer_start_t start_param; odp_time_t t1, t2; @@ -842,7 +845,8 @@ static int set_expire_mode_worker(void *arg) test_global_t *global = thread_arg->global; test_options_t *opt = &global->test_options; uint32_t num_tp = opt->num_tp; - uint64_t cycles = 0; + uint64_t sched_cycles = 0; + uint64_t start_cycles = 0; uint64_t events = 0; uint64_t rounds = 0; uint64_t c1 = 0; @@ -874,7 +878,7 @@ static int set_expire_mode_worker(void *arg) c2 = odp_cpu_cycles(); diff = odp_cpu_cycles_diff(c2, c1); - cycles += diff; + sched_cycles += diff; if (ev == ODP_EVENT_INVALID && exit_test >= num_tp) break; @@ -914,8 +918,14 @@ static int set_expire_mode_worker(void *arg) ctx->target_tick += period_tick; start_param.tick = ctx->target_tick; start_param.tmo_ev = ev; + c3 = odp_cpu_cycles(); + status = odp_timer_start(timer, &start_param); + c4 = odp_cpu_cycles(); + diff = odp_cpu_cycles_diff(c4, c3); + start_cycles += diff; + if (status != ODP_TIMER_SUCCESS) { ODPH_ERR("Timer set (tmo) failed (ret %i)\n", status); ret = -1; @@ -939,7 +949,8 @@ static int set_expire_mode_worker(void *arg) /* Update stats*/ global->stat[thr].events = events; - global->stat[thr].cycles = cycles; + global->stat[thr].cycles_0 = sched_cycles; + global->stat[thr].cycles_1 = start_cycles; global->stat[thr].rounds = rounds; global->stat[thr].nsec = nsec; global->stat[thr].before = before; @@ -1001,7 +1012,8 @@ static void sum_stat(test_global_t *global) sum->num++; sum->events += global->stat[i].events; sum->rounds += global->stat[i].rounds; - sum->cycles += global->stat[i].cycles; + sum->cycles_0 += global->stat[i].cycles_0; + sum->cycles_1 += global->stat[i].cycles_1; sum->nsec += global->stat[i].nsec; sum->cancels += global->stat[i].cancels; sum->sets += global->stat[i].sets; @@ -1041,7 +1053,7 @@ static void print_stat_sched_mode(test_global_t *global) if ((num % 10) == 0) printf("\n "); - printf("%6.1f ", (double)global->stat[i].cycles / global->stat[i].rounds); + printf("%6.1f ", (double)global->stat[i].cycles_0 / global->stat[i].rounds); num++; } } @@ -1087,7 +1099,7 @@ static void print_stat_set_cancel_mode(test_global_t *global) if ((num % 10) == 0) printf("\n "); - printf("%6.1f ", (double)global->stat[i].cycles / global->stat[i].sets); + printf("%6.1f ", (double)global->stat[i].cycles_0 / global->stat[i].sets); num++; } } @@ -1107,6 +1119,72 @@ static void print_stat_set_cancel_mode(test_global_t *global) printf("\n"); } +static void print_stat_expire_mode(test_global_t *global) +{ + int i; + test_stat_sum_t *sum = &global->stat_sum; + double round_ave = 0.0; + double before_ave = 0.0; + double after_ave = 0.0; + int num = 0; + + printf("\n"); + printf("RESULTS\n"); + printf("odp_schedule() cycles per thread:\n"); + printf("-------------------------------------------------\n"); + printf(" 1 2 3 4 5 6 7 8 9 10"); + + for (i = 0; i < ODP_THREAD_COUNT_MAX; i++) { + if (global->stat[i].rounds) { + if ((num % 10) == 0) + printf("\n "); + + printf("%6.1f ", (double)global->stat[i].cycles_0 / global->stat[i].rounds); + num++; + } + } + + printf("\n\n"); + + num = 0; + printf("odp_timer_start() cycles per thread:\n"); + printf("-------------------------------------------------\n"); + printf(" 1 2 3 4 5 6 7 8 9 10"); + + for (i = 0; i < ODP_THREAD_COUNT_MAX; i++) { + if (global->stat[i].rounds) { + if ((num % 10) == 0) + printf("\n "); + + printf("%6.1f ", (double)global->stat[i].cycles_1 / global->stat[i].events); + num++; + } + } + + printf("\n\n"); + + if (sum->num) + round_ave = (double)sum->rounds / sum->num; + + if (sum->before.num) + before_ave = (double)sum->before.sum_ns / sum->before.num; + + if (sum->after.num) + after_ave = (double)sum->after.sum_ns / sum->after.num; + + printf("TOTAL (%i workers)\n", sum->num); + printf(" events: %" PRIu64 "\n", sum->events); + printf(" ave time: %.2f sec\n", sum->time_ave); + printf(" ave rounds per sec: %.2fM\n", (round_ave / sum->time_ave) / 1000000.0); + printf(" num before: %" PRIu64 "\n", sum->before.num); + printf(" ave before: %.1f nsec\n", before_ave); + printf(" max before: %" PRIu64 " nsec\n", sum->before.max_ns); + printf(" num after: %" PRIu64 "\n", sum->after.num); + printf(" ave after: %.1f nsec\n", after_ave); + printf(" max after: %" PRIu64 " nsec\n", sum->after.max_ns); + printf("\n"); +} + static void sig_handler(int signo) { (void)signo; @@ -1240,10 +1318,12 @@ int main(int argc, char **argv) sum_stat(global); - if (mode == MODE_SCHED_OVERH || mode == MODE_START_EXPIRE) + if (mode == MODE_SCHED_OVERH) print_stat_sched_mode(global); - else + else if (mode == MODE_START_CANCEL) print_stat_set_cancel_mode(global); + else + print_stat_expire_mode(global); destroy_timer_pool(global); -- cgit v1.2.3 From 7f2b288ecb8b5176c50dc62f9a033489670ab104 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 5 Dec 2023 10:55:16 +0200 Subject: linux-gen: timer: no need to start tick from zero API does not require tick to start from zero. Optimize timer implementation by removing per timer pool start time subtraction. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo --- platform/linux-generic/odp_timer.c | 47 +++++++++++--------------------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 3baffde2b..9cc305816 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -1,5 +1,5 @@ /* Copyright (c) 2013-2018, Linaro Limited - * Copyright (c) 2019-2022, Nokia + * Copyright (c) 2019-2023, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -170,7 +170,6 @@ typedef struct { typedef struct timer_pool_s { /* Put frequently accessed fields in the first cache line */ uint64_t nsec_per_scan; - odp_time_t start_time; odp_atomic_u64_t cur_tick;/* Current tick value */ uint64_t min_rel_tck; uint64_t max_rel_tck; @@ -784,22 +783,6 @@ static inline void timer_pool_scan(timer_pool_t *tp, uint64_t tick) * Inline timer processing *****************************************************************************/ -static inline uint64_t time_nsec(timer_pool_t *tp, odp_time_t now) -{ - odp_time_t start = tp->start_time; - - return odp_time_diff_ns(now, start); -} - -static inline uint64_t current_nsec(timer_pool_t *tp) -{ - odp_time_t now; - - now = odp_time_global(); - - return time_nsec(tp, now); -} - static inline void timer_pool_scan_inline(int num, odp_time_t now) { timer_pool_t *tp; @@ -824,7 +807,7 @@ static inline void timer_pool_scan_inline(int num, odp_time_t now) continue; } - nsec = time_nsec(tp, now); + nsec = odp_time_to_ns(now); new_tick = nsec / tp->nsec_per_scan; old_tick = odp_atomic_load_u64(&tp->cur_tick); diff = new_tick - old_tick; @@ -917,7 +900,7 @@ static inline void timer_run_posix(timer_pool_t *tp) for (i = 0; i < 32; i += ODP_CACHE_LINE_SIZE / sizeof(array[0])) __builtin_prefetch(&array[i], 0, 0); - nsec = current_nsec(tp); + nsec = odp_time_global_ns(); timer_pool_scan(tp, nsec); } @@ -1271,7 +1254,6 @@ static odp_timer_pool_t timer_pool_new(const char *name, const odp_timer_pool_pa } tp->tp_idx = tp_idx; odp_spinlock_init(&tp->lock); - tp->start_time = odp_time_global(); odp_ticketlock_lock(&timer_global->lock); @@ -1471,16 +1453,15 @@ void odp_timer_pool_destroy(odp_timer_pool_t tpid) uint64_t odp_timer_current_tick(odp_timer_pool_t tpid) { - timer_pool_t *tp = timer_pool_from_hdl(tpid); + (void)tpid; - return current_nsec(tp); + return odp_time_global_ns(); } int odp_timer_sample_ticks(odp_timer_pool_t timer_pool[], uint64_t tick[], uint64_t clk_count[], int num) { - timer_pool_t *tp[MAX_TIMER_POOLS]; - odp_time_t now; + uint64_t nsec; int i; if (num <= 0 || num > MAX_TIMER_POOLS) { @@ -1493,14 +1474,12 @@ int odp_timer_sample_ticks(odp_timer_pool_t timer_pool[], uint64_t tick[], uint6 _ODP_ERR("Invalid timer pool\n"); return -1; } - - tp[i] = timer_pool_from_hdl(timer_pool[i]); } - now = odp_time_global(); + nsec = odp_time_global_ns(); for (i = 0; i < num; i++) { - tick[i] = time_nsec(tp[i], now); + tick[i] = nsec; if (clk_count) clk_count[i] = tick[i]; @@ -1568,7 +1547,7 @@ odp_event_t odp_timer_free(odp_timer_t hdl) int ODP_DEPRECATE(odp_timer_set_abs)(odp_timer_t hdl, uint64_t abs_tck, odp_event_t *tmo_ev) { timer_pool_t *tp = handle_to_tp(hdl); - uint64_t cur_tick = current_nsec(tp); + uint64_t cur_tick = odp_time_global_ns(); uint32_t idx = handle_to_idx(hdl, tp); if (odp_unlikely(abs_tck < cur_tick + tp->min_rel_tck)) @@ -1584,7 +1563,7 @@ int ODP_DEPRECATE(odp_timer_set_abs)(odp_timer_t hdl, uint64_t abs_tck, odp_even int ODP_DEPRECATE(odp_timer_set_rel)(odp_timer_t hdl, uint64_t rel_tck, odp_event_t *tmo_ev) { timer_pool_t *tp = handle_to_tp(hdl); - uint64_t cur_tick = current_nsec(tp); + uint64_t cur_tick = odp_time_global_ns(); uint64_t abs_tck = cur_tick + rel_tck; uint32_t idx = handle_to_idx(hdl, tp); @@ -1602,7 +1581,7 @@ int odp_timer_start(odp_timer_t timer, const odp_timer_start_t *start_param) { uint64_t abs_tick, rel_tick; timer_pool_t *tp = handle_to_tp(timer); - uint64_t cur_tick = current_nsec(tp); + uint64_t cur_tick = odp_time_global_ns(); uint32_t idx = handle_to_idx(timer, tp); odp_event_t tmo_ev = start_param->tmo_ev; @@ -1645,7 +1624,7 @@ int odp_timer_restart(odp_timer_t timer, const odp_timer_start_t *start_param) { uint64_t abs_tick, rel_tick; timer_pool_t *tp = handle_to_tp(timer); - uint64_t cur_tick = current_nsec(tp); + uint64_t cur_tick = odp_time_global_ns(); uint32_t idx = handle_to_idx(timer, tp); if (start_param->tick_type == ODP_TIMER_TICK_ABS) { @@ -1676,7 +1655,7 @@ int odp_timer_periodic_start(odp_timer_t timer, const odp_timer_periodic_start_t { uint64_t abs_tick, period_ns; timer_pool_t *tp = handle_to_tp(timer); - uint64_t cur_tick = current_nsec(tp); + uint64_t cur_tick = odp_time_global_ns(); uint32_t idx = handle_to_idx(timer, tp); odp_event_t tmo_ev = start_param->tmo_ev; _odp_timer_t *tim = &tp->timers[idx]; -- cgit v1.2.3 From 063e2f067bc0c7e71c0e6d07bd4321d8a7da14d5 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 8 Dec 2023 10:46:45 +0200 Subject: linux-gen: timer: inline odp_timer_current_tick() Inline current tick function as it does not depend on timer pool structure any more. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo --- platform/linux-generic/include/odp/api/plat/timer_inlines.h | 11 +++++++++++ platform/linux-generic/odp_timer.c | 7 ------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/platform/linux-generic/include/odp/api/plat/timer_inlines.h b/platform/linux-generic/include/odp/api/plat/timer_inlines.h index 9ba0287e0..d2982079f 100644 --- a/platform/linux-generic/include/odp/api/plat/timer_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/timer_inlines.h @@ -10,6 +10,8 @@ #include #include +#include + #include #include @@ -24,6 +26,7 @@ #define odp_timeout_tick __odp_timeout_tick #define odp_timeout_user_ptr __odp_timeout_user_ptr #define odp_timeout_user_area __odp_timeout_user_area + #define odp_timer_current_tick __odp_timer_current_tick #define odp_timer_tick_to_ns __odp_timer_tick_to_ns #define odp_timer_ns_to_tick __odp_timer_ns_to_tick #define odp_timeout_from_event __odp_timeout_from_event @@ -53,6 +56,14 @@ _ODP_INLINE void *odp_timeout_user_area(odp_timeout_t tmo) return _odp_timeout_hdr_field(tmo, void *, uarea_addr); } +_ODP_INLINE uint64_t odp_timer_current_tick(odp_timer_pool_t tpid) +{ + (void)tpid; + + /* This is equal to odp_time_global_ns(). Cannot call inlined API function from here. */ + return _odp_time_to_ns(_odp_time_cur()); +} + _ODP_INLINE uint64_t odp_timer_tick_to_ns(odp_timer_pool_t tp, uint64_t ticks) { (void)tp; diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 9cc305816..986875c6f 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -1451,13 +1451,6 @@ void odp_timer_pool_destroy(odp_timer_pool_t tpid) odp_timer_pool_del(timer_pool_from_hdl(tpid)); } -uint64_t odp_timer_current_tick(odp_timer_pool_t tpid) -{ - (void)tpid; - - return odp_time_global_ns(); -} - int odp_timer_sample_ticks(odp_timer_pool_t timer_pool[], uint64_t tick[], uint64_t clk_count[], int num) { -- cgit v1.2.3 From fdbd5327dbf36970c04791ca6438bf61056ef7ce Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 8 Dec 2023 15:56:15 +0200 Subject: github_ci: split build job into gcc and clang specific jobs Split previous "Build" job into GCC and Clang specific jobs. This way one can run only a subset of tests with Clang or GCC. Signed-off-by: Matias Elo Reviewed-by: Janne Peltonen --- .github/workflows/ci-pipeline-arm64.yml | 42 +++++++++++++++++++++++++-------- .github/workflows/ci-pipeline.yml | 40 +++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci-pipeline-arm64.yml b/.github/workflows/ci-pipeline-arm64.yml index f152e9305..f798bf38d 100644 --- a/.github/workflows/ci-pipeline-arm64.yml +++ b/.github/workflows/ci-pipeline-arm64.yml @@ -11,28 +11,50 @@ env: OS: ubuntu_20.04 jobs: - Build: + Build_gcc: if: ${{ github.repository == 'OpenDataPlane/odp' }} runs-on: [self-hosted, ARM64] strategy: fail-fast: false matrix: - cc: [gcc, clang] - conf: ['', 'CFLAGS=-O3', 'CFLAGS=-O1', 'CFLAGS=-O0 --enable-debug=full', 'CFLAGS=-Os', 'CFLAGS=-pedantic', - '--enable-lto', '--enable-lto --enable-abi-compat', '--enable-pcapng-support'] - exclude: - - cc: clang - conf: '--enable-lto' - - cc: clang - conf: '--enable-lto --enable-abi-compat' + conf: ['', + 'CFLAGS=-O3', + 'CFLAGS=-O1', + 'CFLAGS=-O0 --enable-debug=full', + 'CFLAGS=-Os', + 'CFLAGS=-pedantic', + '--enable-lto', + '--enable-lto --enable-abi-compat', + '--enable-pcapng-support'] steps: - uses: OpenDataPlane/action-clean-up@main - uses: actions/checkout@v3 - - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" + - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=gcc -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/build_${ARCH}.sh - if: ${{ failure() }} uses: ./.github/actions/build-failure-log + Build_clang: + if: ${{ github.repository == 'OpenDataPlane/odp' }} + runs-on: [self-hosted, ARM64] + strategy: + fail-fast: false + matrix: + conf: ['', + 'CFLAGS=-O3', + 'CFLAGS=-O1', + 'CFLAGS=-O0 --enable-debug=full', + 'CFLAGS=-Os', + 'CFLAGS=-pedantic', + '--enable-pcapng-support'] + steps: + - uses: OpenDataPlane/action-clean-up@main + - uses: actions/checkout@v3 + - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=clang + -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/build_${ARCH}.sh + - if: ${{ failure() }} + uses: ./.github/actions/build-failure-log + Build_static_u22: if: ${{ github.repository == 'OpenDataPlane/odp' }} runs-on: [self-hosted, ARM64] diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index 2cef615eb..d9fb27d82 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -57,26 +57,46 @@ jobs: make doxygen-doc 2>&1 | tee ./doxygen.log ! fgrep -rq warning ./doxygen.log - Build: + Build_gcc: runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: - cc: [gcc, clang] - conf: ['', 'CFLAGS=-O3', 'CFLAGS=-O1', 'CFLAGS=-O0 --enable-debug=full', 'CFLAGS=-Os', 'CFLAGS=-pedantic', - '--enable-lto', '--enable-lto --enable-abi-compat', '--enable-pcapng-support'] - exclude: - - cc: clang - conf: '--enable-lto' - - cc: clang - conf: '--enable-lto --enable-abi-compat' + conf: ['', + 'CFLAGS=-O3', + 'CFLAGS=-O1', + 'CFLAGS=-O0 --enable-debug=full', + 'CFLAGS=-Os', + 'CFLAGS=-pedantic', + '--enable-lto', + '--enable-lto --enable-abi-compat', + '--enable-pcapng-support'] steps: - uses: actions/checkout@v3 - - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" + - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=gcc -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/build_${ARCH}.sh - if: ${{ failure() }} uses: ./.github/actions/build-failure-log + Build_clang: + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + conf: ['', + 'CFLAGS=-O3', + 'CFLAGS=-O1', + 'CFLAGS=-O0 --enable-debug=full', + 'CFLAGS=-Os', + 'CFLAGS=-pedantic', + '--enable-pcapng-support'] + steps: + - uses: actions/checkout@v3 + - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=clang + -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/build_${ARCH}.sh + - if: ${{ failure() }} + uses: ./.github/actions/build-failure-log + Build_static_u20: runs-on: ubuntu-20.04 env: -- cgit v1.2.3 From 9acedf6d9fff2b5318cf257e88ace7a5e52b88de Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 4 Dec 2023 16:33:13 +0200 Subject: github_ci: split run job into gcc and clang specific jobs Split previous "Run" job into GCC and Clang specific jobs. This way one can run only a subset of tests with Clang or GCC. The old "Run" job set C++ compiler always to g++-10. This has been removed and default C++ compiler version is used instead. g++-10 is tested in "Build_gcc_u22" job. Signed-off-by: Matias Elo Reviewed-by: Janne Peltonen --- .github/workflows/ci-pipeline-arm64.yml | 38 +++++++++++++++++++++++++++------ .github/workflows/ci-pipeline.yml | 30 +++++++++++++++++++++----- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-pipeline-arm64.yml b/.github/workflows/ci-pipeline-arm64.yml index f798bf38d..37ae608fb 100644 --- a/.github/workflows/ci-pipeline-arm64.yml +++ b/.github/workflows/ci-pipeline-arm64.yml @@ -152,28 +152,54 @@ jobs: - if: ${{ failure() }} uses: ./.github/actions/run-failure-log - Run: + Run_gcc: if: ${{ github.repository == 'OpenDataPlane/odp' }} runs-on: [self-hosted, ARM64] strategy: fail-fast: false matrix: - cc: [gcc, clang] - conf: ['', '--enable-abi-compat', '--enable-deprecated --enable-helper-deprecated --enable-debug=full', + conf: ['', + '--enable-abi-compat', + '--enable-deprecated --enable-helper-deprecated --enable-debug=full', '--enable-dpdk-zero-copy --disable-static-applications', '--disable-host-optimization --enable-event-validation=warn', '--disable-host-optimization --enable-abi-compat', - '--without-openssl --without-pcap', '--with-crypto=armv8crypto', '--with-crypto=ipsecmb'] + '--without-openssl --without-pcap', + '--with-crypto=armv8crypto', + '--with-crypto=ipsecmb'] steps: - uses: OpenDataPlane/action-clean-up@main - uses: actions/checkout@v3 - - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e ARCH="${ARCH}" - -e CXX=g++-10 -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/check.sh + - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=gcc -e ARCH="${ARCH}" + -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/check.sh - if: ${{ failure() }} uses: ./.github/actions/run-failure-log - if: ${{ success() }} uses: ./.github/actions/dump-log + Run_clang: + if: ${{ github.repository == 'OpenDataPlane/odp' }} + runs-on: [self-hosted, ARM64] + strategy: + fail-fast: false + matrix: + conf: ['', + '--enable-abi-compat', + '--enable-deprecated --enable-helper-deprecated --enable-debug=full', + '--enable-dpdk-zero-copy --disable-static-applications', + '--disable-host-optimization --enable-event-validation=warn', + '--disable-host-optimization --enable-abi-compat', + '--without-openssl --without-pcap', + '--with-crypto=armv8crypto', + '--with-crypto=ipsecmb'] + steps: + - uses: OpenDataPlane/action-clean-up@main + - uses: actions/checkout@v3 + - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=clang -e ARCH="${ARCH}" + -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/check.sh + - if: ${{ failure() }} + uses: ./.github/actions/run-failure-log + Run_CFLAGS: if: ${{ github.repository == 'OpenDataPlane/odp' }} runs-on: [self-hosted, ARM64] diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index d9fb27d82..507baad21 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -299,26 +299,46 @@ jobs: - if: ${{ failure() }} uses: ./.github/actions/run-failure-log - Run: + Run_gcc: runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: - cc: [gcc, clang] - conf: ['', '--enable-abi-compat', '--enable-deprecated --enable-helper-deprecated --enable-debug=full', + conf: ['', + '--enable-abi-compat', + '--enable-deprecated --enable-helper-deprecated --enable-debug=full', '--enable-dpdk-zero-copy --disable-static-applications', '--disable-host-optimization --enable-event-validation=warn', '--disable-host-optimization --enable-abi-compat', '--without-openssl --without-pcap'] steps: - uses: actions/checkout@v3 - - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e ARCH="${ARCH}" - -e CXX=g++-10 -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/check.sh + - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=gcc -e ARCH="${ARCH}" + -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/check.sh - if: ${{ failure() }} uses: ./.github/actions/run-failure-log - if: ${{ success() }} uses: ./.github/actions/dump-log + Run_clang: + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + conf: ['', + '--enable-abi-compat', + '--enable-deprecated --enable-helper-deprecated --enable-debug=full', + '--enable-dpdk-zero-copy --disable-static-applications', + '--disable-host-optimization --enable-event-validation=warn', + '--disable-host-optimization --enable-abi-compat', + '--without-openssl --without-pcap'] + steps: + - uses: actions/checkout@v3 + - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=clang -e ARCH="${ARCH}" + -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/check.sh + - if: ${{ failure() }} + uses: ./.github/actions/run-failure-log + Run_OS: runs-on: ubuntu-20.04 strategy: -- cgit v1.2.3 From b3e5768d2efc6517b5e411ee9c1644e9f79688cc Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 11 Dec 2023 09:24:13 +0200 Subject: github_ci: run part of tests only with gcc Reduce CI runtime by running a number of test jobs only using GCC. New build only Clang jobs have been added for these tests. Signed-off-by: Matias Elo Reviewed-by: Janne Peltonen --- .github/workflows/ci-pipeline-arm64.yml | 10 +++++----- .github/workflows/ci-pipeline.yml | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci-pipeline-arm64.yml b/.github/workflows/ci-pipeline-arm64.yml index 37ae608fb..ffafea5a7 100644 --- a/.github/workflows/ci-pipeline-arm64.yml +++ b/.github/workflows/ci-pipeline-arm64.yml @@ -46,7 +46,10 @@ jobs: 'CFLAGS=-O0 --enable-debug=full', 'CFLAGS=-Os', 'CFLAGS=-pedantic', - '--enable-pcapng-support'] + '--enable-pcapng-support', + '--without-openssl --without-pcap', + '--with-crypto=armv8crypto', + '--with-crypto=ipsecmb'] steps: - uses: OpenDataPlane/action-clean-up@main - uses: actions/checkout@v3 @@ -188,10 +191,7 @@ jobs: '--enable-deprecated --enable-helper-deprecated --enable-debug=full', '--enable-dpdk-zero-copy --disable-static-applications', '--disable-host-optimization --enable-event-validation=warn', - '--disable-host-optimization --enable-abi-compat', - '--without-openssl --without-pcap', - '--with-crypto=armv8crypto', - '--with-crypto=ipsecmb'] + '--disable-host-optimization --enable-abi-compat'] steps: - uses: OpenDataPlane/action-clean-up@main - uses: actions/checkout@v3 diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index 507baad21..189c380f6 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -89,7 +89,8 @@ jobs: 'CFLAGS=-O0 --enable-debug=full', 'CFLAGS=-Os', 'CFLAGS=-pedantic', - '--enable-pcapng-support'] + '--enable-pcapng-support', + '--without-openssl --without-pcap'] steps: - uses: actions/checkout@v3 - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=clang @@ -330,8 +331,7 @@ jobs: '--enable-deprecated --enable-helper-deprecated --enable-debug=full', '--enable-dpdk-zero-copy --disable-static-applications', '--disable-host-optimization --enable-event-validation=warn', - '--disable-host-optimization --enable-abi-compat', - '--without-openssl --without-pcap'] + '--disable-host-optimization --enable-abi-compat'] steps: - uses: actions/checkout@v3 - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC=clang -e ARCH="${ARCH}" -- cgit v1.2.3 From 26bae362b66e113f4e7dc8e5c18cecab4a6da1dc Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 11 Dec 2023 09:50:39 +0200 Subject: github_ci: add tests for aarch64 WFE locks Add CI tests for aarch64 WFE based lock implementations. Signed-off-by: Matias Elo Reviewed-by: Janne Peltonen --- .github/workflows/ci-pipeline-arm64.yml | 6 ++++-- .github/workflows/ci-pipeline.yml | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-pipeline-arm64.yml b/.github/workflows/ci-pipeline-arm64.yml index ffafea5a7..5cff6439b 100644 --- a/.github/workflows/ci-pipeline-arm64.yml +++ b/.github/workflows/ci-pipeline-arm64.yml @@ -49,7 +49,8 @@ jobs: '--enable-pcapng-support', '--without-openssl --without-pcap', '--with-crypto=armv8crypto', - '--with-crypto=ipsecmb'] + '--with-crypto=ipsecmb', + '--enable-wfe-locks'] steps: - uses: OpenDataPlane/action-clean-up@main - uses: actions/checkout@v3 @@ -169,7 +170,8 @@ jobs: '--disable-host-optimization --enable-abi-compat', '--without-openssl --without-pcap', '--with-crypto=armv8crypto', - '--with-crypto=ipsecmb'] + '--with-crypto=ipsecmb', + '--enable-wfe-locks'] steps: - uses: OpenDataPlane/action-clean-up@main - uses: actions/checkout@v3 diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index 189c380f6..60d126d3f 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -141,7 +141,7 @@ jobs: matrix: cc: [gcc, clang] conf: ['', '--enable-abi-compat', 'CFLAGS=-march=armv8.2-a', 'CFLAGS=-march=armv8-a+lse', - '--with-crypto=armv8crypto'] + '--with-crypto=armv8crypto', '--enable-wfe-locks'] steps: - uses: actions/checkout@v3 - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -- cgit v1.2.3 From 47fb70725fcaa0cd45d4d4cecce600f6f44a3e15 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 13 Dec 2023 11:18:26 +0200 Subject: test: timer_perf: fix thread activity check To avoid division by zero in result print, check the value used in division instead of number of rounds. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo --- test/performance/odp_timer_perf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/performance/odp_timer_perf.c b/test/performance/odp_timer_perf.c index 11a3c7864..5abee1988 100644 --- a/test/performance/odp_timer_perf.c +++ b/test/performance/odp_timer_perf.c @@ -1095,7 +1095,7 @@ static void print_stat_set_cancel_mode(test_global_t *global) printf(" 1 2 3 4 5 6 7 8 9 10"); for (i = 0; i < ODP_THREAD_COUNT_MAX; i++) { - if (global->stat[i].rounds) { + if (global->stat[i].sets) { if ((num % 10) == 0) printf("\n "); @@ -1152,7 +1152,7 @@ static void print_stat_expire_mode(test_global_t *global) printf(" 1 2 3 4 5 6 7 8 9 10"); for (i = 0; i < ODP_THREAD_COUNT_MAX; i++) { - if (global->stat[i].rounds) { + if (global->stat[i].events) { if ((num % 10) == 0) printf("\n "); -- cgit v1.2.3 From 17b9c31cc5317e40ea52fd86c683ecd233094fec Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 13 Dec 2023 13:52:00 +0200 Subject: example: debug: call odp_pktio_extra_stats_print() In pktio case, call extra statistics print in addition to pktio print. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo --- example/debug/odp_debug.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/example/debug/odp_debug.c b/example/debug/odp_debug.c index 6683e46b4..06d10f34d 100644 --- a/example/debug/odp_debug.c +++ b/example/debug/odp_debug.c @@ -39,7 +39,8 @@ static void print_usage(void) " -s, --shm Create a SHM and call odp_shm_print()\n" " -p, --pool Create various types of pools and call odp_pool_print()\n" " -q, --queue Create various types of queues and call odp_queue_print()\n" - " -i, --interface Create packet IO interface (loop) and call odp_pktio_print()\n" + " -i, --interface Create packet IO interface (loop), and call both odp_pktio_print()\n" + " and odp_pktio_extra_stats_print()\n" " -I, --ipsec Call odp_ipsec_print()\n" " -t, --timer Call timer pool, timer and timeout print functions\n" " -a, --stash Create stash and call odp_stash_print()\n" @@ -342,6 +343,9 @@ static int pktio_debug(void) printf("\n"); odp_pktio_print(pktio); + printf("\n"); + odp_pktio_extra_stats_print(pktio); + if (odp_pktio_close(pktio)) { ODPH_ERR("Pktio close failed\n"); return -1; -- cgit v1.2.3 From 0e855deb8056b6285b6e5488d92db5177dbb2133 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Sun, 3 Dec 2023 08:34:58 +0000 Subject: test: dma_perf: fix SHM size with address transfers Use destination segment size and count when calculating memory chunk sizes for address transfers. Otherwise the destination memory size might end up too small resulting in segmentation faults. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index 7e9d489df..c057e4823 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -717,12 +717,11 @@ static void free_packets(const sd_t *sd) static odp_bool_t allocate_memory(sd_t *sd) { - const uint64_t num_segs = (uint64_t)sd->dma.num_in_segs * sd->dma.num_inflight; + const uint64_t shm_size = (uint64_t)sd->dma.dst_seg_len * sd->dma.num_out_segs * + sd->dma.num_inflight; - sd->seg.src_shm = odp_shm_reserve(PROG_NAME "_src_shm", sd->dma.src_seg_len * num_segs, - ODP_CACHE_LINE_SIZE, 0U); - sd->seg.dst_shm = odp_shm_reserve(PROG_NAME "_dst_shm", sd->dma.dst_seg_len * num_segs, - ODP_CACHE_LINE_SIZE, 0U); + sd->seg.src_shm = odp_shm_reserve(PROG_NAME "_src_shm", shm_size, ODP_CACHE_LINE_SIZE, 0U); + sd->seg.dst_shm = odp_shm_reserve(PROG_NAME "_dst_shm", shm_size, ODP_CACHE_LINE_SIZE, 0U); if (sd->seg.src_shm == ODP_SHM_INVALID || sd->seg.dst_shm == ODP_SHM_INVALID) { ODPH_ERR("Error allocating SHM block\n"); -- cgit v1.2.3 From f4a012a2bd97d46297c4d162e973ea06fb719644 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Wed, 29 Nov 2023 07:18:38 +0000 Subject: test: dma_perf: add short description Add short description about the purpose and workflow of the tester. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index c057e4823..ec3401467 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -1,8 +1,14 @@ -/* Copyright (c) 2021-2023, Nokia - * - * All rights reserved. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021-2023 Nokia + */ + +/** + * DMA performance tester * - * SPDX-License-Identifier: BSD-3-Clause + * This tester application can be used to profile the performance of an ODP DMA implementation. + * Tester workflow is simple and consists of issuing as many back-to-back DMA transfers as the + * implementation allows and then recording key performance statistics (such as function overhead, + * latencies etc.). */ #ifndef _GNU_SOURCE -- cgit v1.2.3 From 4c8733c06bb6e128c38106af6cfdd45b155d8a73 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Wed, 29 Nov 2023 09:11:33 +0000 Subject: test: dma_perf: add software memory copy option Add option for using software memory copy in addition to DMA transfers. This is useful for comparing the performance of DMA subsystem and copying on CPU. Only the command line option is added here, implementation will be added later. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index ec3401467..26da793be 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -28,8 +28,9 @@ #define PROG_NAME "odp_dma_perf" enum { - SYNC = 0U, - ASYNC + SYNC_DMA = 0U, + ASYNC_DMA, + SW_COPY }; enum { @@ -47,7 +48,7 @@ enum { MANY }; -#define DEF_TRS_TYPE SYNC +#define DEF_TRS_TYPE SYNC_DMA #define DEF_SEG_CNT 1U #define DEF_LEN 1024U #define DEF_SEG_TYPE PACKET @@ -264,8 +265,9 @@ static void print_usage(void) "\n" " -t, --trs_type Transfer type for test data. %u by default.\n" " Types:\n" - " 0: synchronous\n" - " 1: asynchronous\n" + " 0: synchronous DMA\n" + " 1: asynchronous DMA\n" + " 2: SW memory copy\n" " -i, --num_in_seg Number of input segments to transfer. 0 means the maximum\n" " count supported by the implementation. %u by default.\n" " -o, --num_out_seg Number of output segments to transfer to. 0 means the\n" @@ -307,11 +309,17 @@ static parse_result_t check_options(prog_config_t *config) odp_shm_capability_t shm_capa; uint64_t shm_size = 0U; - if (config->trs_type != SYNC && config->trs_type != ASYNC) { + if (config->trs_type != SYNC_DMA && config->trs_type != ASYNC_DMA && + config->trs_type != SW_COPY) { ODPH_ERR("Invalid transfer type: %u\n", config->trs_type); return PRS_NOK; } + if (config->trs_type == SW_COPY) { + ODPH_ERR("SW memory copy transfer type not yet implemented\n"); + return PRS_NOT_SUP; + } + if (config->seg_type != PACKET && config->seg_type != MEMORY) { ODPH_ERR("Invalid segment type: %u\n", config->seg_type); return PRS_NOK; @@ -375,7 +383,7 @@ static parse_result_t check_options(prog_config_t *config) return PRS_NOT_SUP; } - if (config->trs_type == ASYNC) { + if (config->trs_type == ASYNC_DMA) { if (config->compl_mode != POLL && config->compl_mode != EVENT) { ODPH_ERR("Invalid completion mode: %u\n", config->compl_mode); return PRS_NOK; @@ -1156,8 +1164,10 @@ static void setup_api(prog_config_t *config) config->api.free_fn = free_memory; } - if (config->trs_type == SYNC) { + if (config->trs_type == SYNC_DMA) { + config->api.session_cfg_fn = NULL; config->api.compl_fn = NULL; + config->api.bootstrap_fn = NULL; config->api.wait_fn = config->num_workers == 1 || config->policy == MANY ? run_transfers_mt_unsafe : run_transfers_mt_safe; config->api.drain_fn = NULL; @@ -1407,7 +1417,7 @@ static void print_stats(const prog_config_t *config) " segment type: %s\n" " inflight count: %u\n" " session policy: %s\n\n", - config->trs_type == SYNC ? "synchronous" : config->compl_mode == POLL ? + config->trs_type == SYNC_DMA ? "synchronous" : config->compl_mode == POLL ? "asynchronous-poll" : "asynchronous-event", config->num_in_segs, config->num_out_segs, config->src_seg_len, config->seg_type == PACKET ? "packet" : "memory", config->num_inflight, @@ -1430,7 +1440,7 @@ static void print_stats(const prog_config_t *config) " start errors: %" PRIu64 "\n", stats->completed, stats->start_errs); - if (config->trs_type == ASYNC) { + if (config->trs_type == ASYNC_DMA) { if (config->compl_mode == POLL) printf(" poll errors: %" PRIu64 "\n", stats->poll_errs); @@ -1466,7 +1476,7 @@ static void print_stats(const prog_config_t *config) avg_start_cc = stats->start_cnt > 0U ? stats->start_cc / stats->start_cnt : 0U; printf(" average cycles breakdown:\n"); - if (config->trs_type == SYNC) { + if (config->trs_type == SYNC_DMA) { printf(" odp_dma_transfer(): %" PRIu64 " " "(min: %" PRIu64 ", max: %" PRIu64 ")\n", avg_start_cc, avg_start_cc > 0U ? stats->min_start_cc : 0U, -- cgit v1.2.3 From 6b32abade29d539ca46516a19cbe15e620c1daf9 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Wed, 29 Nov 2023 09:18:31 +0000 Subject: test: dma_perf: rename packet and address configuration functions In preparation for new software memory copy option implementation, rename `configure_packet_dma_transfer()` and `configure_address_dma_transfer()` to be more generic. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index 26da793be..f259078a3 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -675,7 +675,7 @@ static odp_bool_t setup_packet_segments(sd_t *sd) return configure_packets(sd) && allocate_packets(sd); } -static void configure_packet_dma_transfer(sd_t *sd) +static void configure_packet_transfer(sd_t *sd) { odp_dma_seg_t *start_src_seg, *start_dst_seg, *seg; uint32_t k = 0U, z = 0U, len; @@ -758,7 +758,7 @@ static odp_bool_t setup_memory_segments(sd_t *sd) return allocate_memory(sd); } -static void configure_address_dma_transfer(sd_t *sd) +static void configure_address_transfer(sd_t *sd) { odp_dma_seg_t *start_src_seg, *start_dst_seg, *seg; uint32_t k = 0U, z = 0U, len; @@ -1156,11 +1156,11 @@ static void setup_api(prog_config_t *config) { if (config->seg_type == PACKET) { config->api.setup_fn = setup_packet_segments; - config->api.trs_fn = configure_packet_dma_transfer; + config->api.trs_fn = configure_packet_transfer; config->api.free_fn = free_packets; } else { config->api.setup_fn = setup_memory_segments; - config->api.trs_fn = configure_address_dma_transfer; + config->api.trs_fn = configure_address_transfer; config->api.free_fn = free_memory; } -- cgit v1.2.3 From aa77a62dcb0e32e3d68f105fb12f8b1a4cecf8d2 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Wed, 29 Nov 2023 11:40:43 +0000 Subject: test: dma_perf: implement software memory copy mode Use plain `memcpy()` to copy data between packets and memory. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 114 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 9 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index f259078a3..ad767dae4 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -977,6 +977,25 @@ static void poll_transfers_mt_safe(sd_t *sd, stats_t *stats) } } +static void drain_poll_transfers(sd_t *sd) +{ + const uint32_t count = sd->dma.num_inflight; + trs_info_t *infos = sd->dma.infos, *info; + odp_dma_t handle = sd->dma.handle; + int rc; + + for (uint32_t i = 0U; i < count; ++i) { + info = &infos[i]; + + if (info->is_running) { + do { + rc = odp_dma_transfer_done(handle, info->compl_param.transfer_id, + NULL); + } while (rc == 0); + } + } +} + static odp_bool_t configure_event_compl_session(sd_t *sd) { odp_thrmask_t zero; @@ -1133,21 +1152,91 @@ static void drain_compl_events(ODP_UNUSED sd_t *sd) } } -static void drain_poll_transfers(sd_t *sd) +static void run_memcpy(trs_info_t *info, stats_t *stats) +{ + uint64_t start_tm, end_tm, start_cc, end_cc, trs_tm, trs_cc, start_cc_diff; + const odp_dma_transfer_param_t *param = &info->trs_param; + uint32_t tot_len, src_len, dst_len, min_len, len, i = 0U, j = 0U, src_off = 0U, + dst_off = 0U, src_rem, dst_rem; + const odp_bool_t is_addr = param->src_format == ODP_DMA_FORMAT_ADDR; + uint8_t *src_data, *dst_data; + + /* Test data is configured so that total source and total destination sizes always match, + * all source and all destination segments have the same size and in case of packets, + * there's always just a single segment. */ + tot_len = param->num_src * param->src_seg->len; + src_len = param->src_seg->len; + dst_len = param->dst_seg->len; + min_len = ODPH_MIN(src_len, dst_len); + len = min_len; + start_tm = odp_time_local_strict_ns(); + start_cc = odp_cpu_cycles(); + + while (tot_len > 0U) { + if (is_addr) { + src_data = param->src_seg[i].addr; + dst_data = param->dst_seg[j].addr; + } else { + src_data = odp_packet_data(param->src_seg[i].packet); + dst_data = odp_packet_data(param->dst_seg[j].packet); + } + + memcpy(dst_data + dst_off, src_data + src_off, len); + dst_off += len; + src_off += len; + src_rem = src_len - src_off; + dst_rem = dst_len - dst_off; + tot_len -= len; + len = ODPH_MIN(ODPH_MAX(src_rem, dst_rem), min_len); + + if (dst_rem > 0U) { + ++i; + src_off = 0U; + } else { + ++j; + dst_off = 0U; + } + } + + end_cc = odp_cpu_cycles(); + end_tm = odp_time_local_strict_ns(); + trs_tm = end_tm - start_tm; + stats->max_trs_tm = ODPH_MAX(trs_tm, stats->max_trs_tm); + stats->min_trs_tm = ODPH_MIN(trs_tm, stats->min_trs_tm); + stats->trs_tm += trs_tm; + trs_cc = odp_cpu_cycles_diff(end_cc, start_cc); + stats->max_trs_cc = ODPH_MAX(trs_cc, stats->max_trs_cc); + stats->min_trs_cc = ODPH_MIN(trs_cc, stats->min_trs_cc); + stats->trs_cc += trs_cc; + ++stats->trs_cnt; + start_cc_diff = odp_cpu_cycles_diff(end_cc, start_cc); + stats->max_start_cc = ODPH_MAX(start_cc_diff, stats->max_start_cc); + stats->min_start_cc = ODPH_MIN(start_cc_diff, stats->min_start_cc); + stats->start_cc += start_cc_diff; + ++stats->start_cnt; + ++stats->completed; +} + +static void run_memcpy_mt_unsafe(sd_t *sd, stats_t *stats) +{ + const uint32_t count = sd->dma.num_inflight; + trs_info_t *infos = sd->dma.infos; + + for (uint32_t i = 0U; i < count; ++i) + run_memcpy(&infos[i], stats); +} + +static void run_memcpy_mt_safe(sd_t *sd, stats_t *stats) { const uint32_t count = sd->dma.num_inflight; trs_info_t *infos = sd->dma.infos, *info; - odp_dma_t handle = sd->dma.handle; - int rc; for (uint32_t i = 0U; i < count; ++i) { info = &infos[i]; - if (info->is_running) { - do { - rc = odp_dma_transfer_done(handle, info->compl_param.transfer_id, - NULL); - } while (rc == 0); + if (odp_ticketlock_trylock(&info->lock)) { + run_memcpy(info, stats); + odp_ticketlock_unlock(&info->lock); } } } @@ -1171,7 +1260,7 @@ static void setup_api(prog_config_t *config) config->api.wait_fn = config->num_workers == 1 || config->policy == MANY ? run_transfers_mt_unsafe : run_transfers_mt_safe; config->api.drain_fn = NULL; - } else { + } else if (config->trs_type == ASYNC_DMA) { if (config->compl_mode == POLL) { config->api.session_cfg_fn = NULL; config->api.compl_fn = configure_poll_compl; @@ -1186,6 +1275,13 @@ static void setup_api(prog_config_t *config) config->api.wait_fn = wait_compl_event; config->api.drain_fn = drain_compl_events; } + } else { + config->api.session_cfg_fn = NULL; + config->api.compl_fn = NULL; + config->api.bootstrap_fn = NULL; + config->api.wait_fn = config->num_workers == 1 || config->policy == MANY ? + run_memcpy_mt_unsafe : run_memcpy_mt_safe; + config->api.drain_fn = NULL; } } -- cgit v1.2.3 From 676fba59977113a3ea069f762ff6a0de072e7eef Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Wed, 29 Nov 2023 12:23:12 +0000 Subject: test: dma_perf: refactor statistics output Refactor final statistics output to take into consideration the new software memory copy mode. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index ad767dae4..8ff10a338 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -1513,8 +1513,11 @@ static void print_stats(const prog_config_t *config) " segment type: %s\n" " inflight count: %u\n" " session policy: %s\n\n", - config->trs_type == SYNC_DMA ? "synchronous" : config->compl_mode == POLL ? - "asynchronous-poll" : "asynchronous-event", config->num_in_segs, + config->trs_type == SYNC_DMA ? "DMA synchronous" : + config->trs_type == ASYNC_DMA && config->compl_mode == POLL ? + "DMA asynchronous-poll" : + config->trs_type == ASYNC_DMA && config->compl_mode == EVENT ? + "DMA asynchronous-event" : "SW", config->num_in_segs, config->num_out_segs, config->src_seg_len, config->seg_type == PACKET ? "packet" : "memory", config->num_inflight, config->policy == SINGLE ? "shared" : "per-worker"); @@ -1550,7 +1553,7 @@ static void print_stats(const prog_config_t *config) stats->transfer_errs, stats->tot_tm); if (config->policy == MANY) { - printf(" DMA session:\n" + printf(" session:\n" " average time per transfer: %" PRIu64 " " "(min: %" PRIu64 ", max: %" PRIu64 ") ns\n" " average cycles per transfer: %" PRIu64 " " @@ -1577,6 +1580,11 @@ static void print_stats(const prog_config_t *config) "(min: %" PRIu64 ", max: %" PRIu64 ")\n", avg_start_cc, avg_start_cc > 0U ? stats->min_start_cc : 0U, avg_start_cc > 0U ? stats->max_start_cc : 0U); + } else if (config->trs_type == SW_COPY) { + printf(" memcpy(): %" PRIu64 " " + "(min: %" PRIu64 ", max: %" PRIu64 ")\n", avg_start_cc, + avg_start_cc > 0U ? stats->min_start_cc : 0U, + avg_start_cc > 0U ? stats->max_start_cc : 0U); } else { printf(" odp_dma_transfer_start(): %" PRIu64 " " "(min: %" PRIu64 ", max: %" PRIu64 ")\n", avg_start_cc, @@ -1587,7 +1595,7 @@ static void print_stats(const prog_config_t *config) if (config->compl_mode == POLL) { printf(" odp_dma_transfer_done(): %" PRIu64 "" - " (min: %" PRIu64 ", max: %" PRIu64 ", x %" PRIu64 "" + " (min: %" PRIu64 ", max: %" PRIu64 ", x%" PRIu64 "" " per transfer)\n", avg_wait_cc, avg_wait_cc > 0U ? stats->min_wait_cc : 0U, avg_wait_cc > 0U ? stats->max_wait_cc : 0U, -- cgit v1.2.3 From 925a3953831b29cf103ddba4093822f90dc4435b Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Wed, 29 Nov 2023 12:27:11 +0000 Subject: test: dma_perf: enable software memory copy mode The new software memory copy mode is now fully implemented and enabled. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index 8ff10a338..91ba64299 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -315,11 +315,6 @@ static parse_result_t check_options(prog_config_t *config) return PRS_NOK; } - if (config->trs_type == SW_COPY) { - ODPH_ERR("SW memory copy transfer type not yet implemented\n"); - return PRS_NOT_SUP; - } - if (config->seg_type != PACKET && config->seg_type != MEMORY) { ODPH_ERR("Invalid segment type: %u\n", config->seg_type); return PRS_NOK; -- cgit v1.2.3 From 100c91e0b0cf46f650d2f126ee2742023ce240de Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Sun, 3 Dec 2023 07:36:51 +0000 Subject: test: dma_perf: add sparse packet and memory segment type options Add options for using sparse packets and memory as the transfer segment type. The new sparse packet option skips packet preallocation and defers it to runtime. The new sparse memory option attempts to allocate a large memory pool, much larger than CPU cache size, and memory chunks for transfers are then configured in runtime. These new options configure scenarios which might be a more realistic usecase for some applications due to potentially incurred cache misses and allocation overheads. The old existing segment type options are renamed to 'dense packet' and 'dense memory'. Only the command line option is added here, implementation will be added later. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index 91ba64299..2e44043b6 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -34,8 +34,10 @@ enum { }; enum { - PACKET = 0U, - MEMORY + DENSE_PACKET = 0U, + SPARSE_PACKET, + DENSE_MEMORY, + SPARSE_MEMORY }; enum { @@ -51,7 +53,7 @@ enum { #define DEF_TRS_TYPE SYNC_DMA #define DEF_SEG_CNT 1U #define DEF_LEN 1024U -#define DEF_SEG_TYPE PACKET +#define DEF_SEG_TYPE DENSE_PACKET #define DEF_MODE POLL #define DEF_INFLIGHT 1U #define DEF_TIME 10U @@ -258,8 +260,9 @@ static void print_usage(void) "\n" " E.g. " PROG_NAME "\n" " " PROG_NAME " -s 10240\n" - " " PROG_NAME " -t 0 -i 1 -o 1 -s 51200 -S 1 -f 64 -T 10\n" + " " PROG_NAME " -t 0 -i 1 -o 1 -s 51200 -S 2 -f 64 -T 10\n" " " PROG_NAME " -t 1 -i 10 -o 10 -s 4096 -S 0 -m 1 -f 10 -c 4 -p 1\n" + " " PROG_NAME " -t 2 -i 10 -o 1 -s 1024 -S 3 -m 1 -f 10 -c 4 -p 1\n" "\n" "Optional OPTIONS:\n" "\n" @@ -277,10 +280,16 @@ static void print_usage(void) " segment length supported by the implementation. The actual\n" " maximum might be limited by what type of data is\n" " transferred (packet/memory). %u by default.\n" - " -S, --in_seg_type Input segment data type. %u by default.\n" + " -S, --in_seg_type Input segment data type. Dense types can load the DMA\n" + " subsystem more heavily as transfer resources are\n" + " pre-configured. Sparse types might on the other hand\n" + " reflect application usage more precisely as transfer\n" + " resources are configured in runtime. %u by default.\n" " Types:\n" - " 0: packet\n" - " 1: memory\n" + " 0: dense packet\n" + " 1: sparse packet\n" + " 2: dense memory\n" + " 3: sparse memory\n" " -m, --compl_mode Completion mode for transfers. %u by default.\n" " Modes:\n" " 0: poll\n" @@ -315,11 +324,17 @@ static parse_result_t check_options(prog_config_t *config) return PRS_NOK; } - if (config->seg_type != PACKET && config->seg_type != MEMORY) { + if (config->seg_type != DENSE_PACKET && config->seg_type != SPARSE_PACKET && + config->seg_type != DENSE_MEMORY && config->seg_type != SPARSE_MEMORY) { ODPH_ERR("Invalid segment type: %u\n", config->seg_type); return PRS_NOK; } + if (config->seg_type == SPARSE_PACKET || config->seg_type == SPARSE_MEMORY) { + ODPH_ERR("Sparse segment types not yet implemented\n"); + return PRS_NOT_SUP; + } + max_workers = ODPH_MIN(odp_thread_count_max() - 1, MAX_WORKERS); if (config->num_workers <= 0 || config->num_workers > max_workers) { @@ -449,7 +464,7 @@ static parse_result_t check_options(prog_config_t *config) return PRS_NOT_SUP; } - if (config->seg_type == PACKET) { + if (config->seg_type == DENSE_PACKET) { if (odp_pool_capability(&pool_capa) < 0) { ODPH_ERR("Error querying pool capabilities\n"); return PRS_NOK; @@ -1238,7 +1253,7 @@ static void run_memcpy_mt_safe(sd_t *sd, stats_t *stats) static void setup_api(prog_config_t *config) { - if (config->seg_type == PACKET) { + if (config->seg_type == DENSE_PACKET) { config->api.setup_fn = setup_packet_segments; config->api.trs_fn = configure_packet_transfer; config->api.free_fn = free_packets; @@ -1514,7 +1529,7 @@ static void print_stats(const prog_config_t *config) config->trs_type == ASYNC_DMA && config->compl_mode == EVENT ? "DMA asynchronous-event" : "SW", config->num_in_segs, config->num_out_segs, config->src_seg_len, - config->seg_type == PACKET ? "packet" : "memory", config->num_inflight, + config->seg_type == DENSE_PACKET ? "packet" : "memory", config->num_inflight, config->policy == SINGLE ? "shared" : "per-worker"); for (int i = 0; i < config->num_workers; ++i) { -- cgit v1.2.3 From 793b2a3b6c1a774a31e41386277b78827b094de5 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Sun, 3 Dec 2023 08:59:14 +0000 Subject: test: dma_perf: refactor SHM size calculation In preparation for sparse memory segment type implementation, calculate required address transfer memory chunk size already at capability check level. This makes it more straightforward to resolve required memory chunk sizes for later reservation. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index 2e44043b6..f7c52d9ca 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -135,6 +135,7 @@ typedef struct ODP_ALIGNED_CACHE { odp_shm_t dst_shm; void *src; void *dst; + uint64_t shm_size; } seg; odp_schedule_group_t grp; @@ -179,6 +180,7 @@ typedef struct prog_config_s { odp_dma_compl_mode_t compl_mode_mask; odp_pool_t src_pool; odp_pool_t dst_pool; + uint64_t shm_size; uint32_t num_in_segs; uint32_t num_out_segs; uint32_t src_seg_len; @@ -512,6 +514,8 @@ static parse_result_t check_options(prog_config_t *config) " (max: %" PRIu64 ")\n", shm_size, shm_capa.max_size); return PRS_NOT_SUP; } + + config->shm_size = shm_size; } return PRS_OK; @@ -741,11 +745,10 @@ static void free_packets(const sd_t *sd) static odp_bool_t allocate_memory(sd_t *sd) { - const uint64_t shm_size = (uint64_t)sd->dma.dst_seg_len * sd->dma.num_out_segs * - sd->dma.num_inflight; - - sd->seg.src_shm = odp_shm_reserve(PROG_NAME "_src_shm", shm_size, ODP_CACHE_LINE_SIZE, 0U); - sd->seg.dst_shm = odp_shm_reserve(PROG_NAME "_dst_shm", shm_size, ODP_CACHE_LINE_SIZE, 0U); + sd->seg.src_shm = odp_shm_reserve(PROG_NAME "_src_shm", sd->seg.shm_size, + ODP_CACHE_LINE_SIZE, 0U); + sd->seg.dst_shm = odp_shm_reserve(PROG_NAME "_dst_shm", sd->seg.shm_size, + ODP_CACHE_LINE_SIZE, 0U); if (sd->seg.src_shm == ODP_SHM_INVALID || sd->seg.dst_shm == ODP_SHM_INVALID) { ODPH_ERR("Error allocating SHM block\n"); @@ -1327,6 +1330,8 @@ static odp_bool_t setup_session_descriptors(prog_config_t *config) if (config->api.session_cfg_fn != NULL && !config->api.session_cfg_fn(sd)) return false; + + sd->seg.shm_size = config->shm_size; } return true; -- cgit v1.2.3 From a3df9b1825f95bfd9d8cd3097fa1aa2ad125d930 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Mon, 4 Dec 2023 13:46:18 +0000 Subject: test: dma_perf: implement sparse segment type options With sparse segment types, transfer segments are not pre-configured, but deferred to be done just before the transfer. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 164 +++++++++++++++++++++++++++++++++++----- 1 file changed, 144 insertions(+), 20 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index f7c52d9ca..30807d038 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -62,6 +62,7 @@ enum { #define MAX_SEGS 1024U #define MAX_WORKERS 24 +#define MAX_MEMORY (256U * 1024U * 1024U) #define GIGAS 1000000000 #define MEGAS 1000000 @@ -109,7 +110,9 @@ typedef struct { odp_bool_t is_running; } trs_info_t; -typedef struct ODP_ALIGNED_CACHE { +typedef struct sd_s sd_t; + +typedef struct ODP_ALIGNED_CACHE sd_s { struct { trs_info_t infos[MAX_SEGS]; odp_dma_seg_t src_seg[MAX_SEGS]; @@ -135,10 +138,17 @@ typedef struct ODP_ALIGNED_CACHE { odp_shm_t dst_shm; void *src; void *dst; + void *src_high; + void *dst_high; + void *cur_src; + void *cur_dst; uint64_t shm_size; + uint8_t seg_type; } seg; odp_schedule_group_t grp; + /* Prepare single transfer. */ + void (*prep_trs_fn)(sd_t *sd, trs_info_t *info); } sd_t; typedef struct prog_config_s prog_config_t; @@ -188,6 +198,8 @@ typedef struct prog_config_s { uint32_t num_inflight; uint32_t time_sec; uint32_t num_sessions; + uint32_t src_cache_size; + uint32_t dst_cache_size; int num_workers; uint8_t trs_type; uint8_t seg_type; @@ -466,7 +478,7 @@ static parse_result_t check_options(prog_config_t *config) return PRS_NOT_SUP; } - if (config->seg_type == DENSE_PACKET) { + if (config->seg_type == DENSE_PACKET || config->seg_type == SPARSE_PACKET) { if (odp_pool_capability(&pool_capa) < 0) { ODPH_ERR("Error querying pool capabilities\n"); return PRS_NOK; @@ -490,6 +502,11 @@ static parse_result_t check_options(prog_config_t *config) max_segs * num_sessions, pool_capa.pkt.max_num); return PRS_NOT_SUP; } + + config->src_cache_size = ODPH_MIN(ODPH_MAX(max_in, pool_capa.pkt.min_cache_size), + pool_capa.pkt.max_cache_size); + config->dst_cache_size = ODPH_MIN(ODPH_MAX(max_out, pool_capa.pkt.min_cache_size), + pool_capa.pkt.max_cache_size); } else { /* If SHM implementation capabilities are very puny, program will have already * failed when reserving memory for global program configuration. */ @@ -515,6 +532,10 @@ static parse_result_t check_options(prog_config_t *config) return PRS_NOT_SUP; } + if (config->seg_type == SPARSE_MEMORY && shm_size < MAX_MEMORY) + shm_size = shm_capa.max_size != 0U ? + ODPH_MIN(shm_capa.max_size, MAX_MEMORY) : MAX_MEMORY; + config->shm_size = shm_size; } @@ -610,15 +631,18 @@ static parse_result_t setup_program(int argc, char **argv, prog_config_t *config static odp_pool_t get_src_packet_pool(void) { odp_pool_param_t param; + uint32_t num_pkts_per_worker = ODPH_MAX(prog_conf->num_inflight * prog_conf->num_in_segs, + prog_conf->src_cache_size); if (prog_conf->src_pool != ODP_POOL_INVALID) return prog_conf->src_pool; odp_pool_param_init(¶m); param.type = ODP_POOL_PACKET; - param.pkt.num = prog_conf->num_inflight * prog_conf->num_in_segs * prog_conf->num_sessions; + param.pkt.num = num_pkts_per_worker * prog_conf->num_workers; param.pkt.len = prog_conf->src_seg_len; param.pkt.seg_len = prog_conf->src_seg_len; + param.pkt.cache_size = prog_conf->src_cache_size; prog_conf->src_pool = odp_pool_create(PROG_NAME "_src_pkts", ¶m); return prog_conf->src_pool; @@ -627,16 +651,18 @@ static odp_pool_t get_src_packet_pool(void) static odp_pool_t get_dst_packet_pool(void) { odp_pool_param_t param; + uint32_t num_pkts_per_worker = ODPH_MAX(prog_conf->num_inflight * prog_conf->num_out_segs, + prog_conf->dst_cache_size); if (prog_conf->dst_pool != ODP_POOL_INVALID) return prog_conf->dst_pool; odp_pool_param_init(¶m); param.type = ODP_POOL_PACKET; - param.pkt.num = prog_conf->num_inflight * prog_conf->num_out_segs * - prog_conf->num_sessions; + param.pkt.num = num_pkts_per_worker * prog_conf->num_workers; param.pkt.len = prog_conf->dst_seg_len; param.pkt.seg_len = prog_conf->dst_seg_len; + param.pkt.cache_size = prog_conf->dst_cache_size; prog_conf->dst_pool = odp_pool_create(PROG_NAME "_dst_pkts", ¶m); return prog_conf->dst_pool; @@ -686,7 +712,8 @@ static odp_bool_t allocate_packets(sd_t *sd) static odp_bool_t setup_packet_segments(sd_t *sd) { - return configure_packets(sd) && allocate_packets(sd); + return configure_packets(sd) && + (sd->seg.seg_type == DENSE_PACKET ? allocate_packets(sd) : true); } static void configure_packet_transfer(sd_t *sd) @@ -763,6 +790,11 @@ static odp_bool_t allocate_memory(sd_t *sd) return false; } + sd->seg.src_high = (uint8_t *)sd->seg.src + sd->seg.shm_size - sd->dma.src_seg_len; + sd->seg.dst_high = (uint8_t *)sd->seg.dst + sd->seg.shm_size - sd->dma.dst_seg_len; + sd->seg.cur_src = sd->seg.src; + sd->seg.cur_dst = sd->seg.dst; + return true; } @@ -783,7 +815,8 @@ static void configure_address_transfer(sd_t *sd) for (uint32_t j = 0U; j < sd->dma.num_in_segs; ++j, ++k) { seg = &start_src_seg[j]; - seg->addr = (uint8_t *)sd->seg.src + k * sd->dma.src_seg_len; + seg->addr = sd->seg.seg_type == SPARSE_MEMORY ? + NULL : (uint8_t *)sd->seg.src + k * sd->dma.src_seg_len; seg->len = sd->dma.src_seg_len; } @@ -791,7 +824,8 @@ static void configure_address_transfer(sd_t *sd) for (uint32_t j = 0U; j < sd->dma.num_out_segs; ++j, ++z) { seg = &start_dst_seg[j]; - seg->addr = (uint8_t *)sd->seg.dst + z * sd->dma.dst_seg_len; + seg->addr = sd->seg.seg_type == SPARSE_MEMORY ? + NULL : (uint8_t *)sd->seg.dst + z * sd->dma.dst_seg_len; seg->len = ODPH_MIN(len, sd->dma.dst_seg_len); len -= sd->dma.dst_seg_len; } @@ -857,10 +891,16 @@ static void run_transfers_mt_unsafe(sd_t *sd, stats_t *stats) { const uint32_t count = sd->dma.num_inflight; odp_dma_t handle = sd->dma.handle; - trs_info_t *infos = sd->dma.infos; + trs_info_t *infos = sd->dma.infos, *info; - for (uint32_t i = 0U; i < count; ++i) - run_transfer(handle, &infos[i], stats); + for (uint32_t i = 0U; i < count; ++i) { + info = &infos[i]; + + if (sd->prep_trs_fn != NULL) + sd->prep_trs_fn(sd, info); + + run_transfer(handle, info, stats); + } } static void run_transfers_mt_safe(sd_t *sd, stats_t *stats) @@ -873,6 +913,9 @@ static void run_transfers_mt_safe(sd_t *sd, stats_t *stats) info = &infos[i]; if (odp_ticketlock_trylock(&info->lock)) { + if (sd->prep_trs_fn != NULL) + sd->prep_trs_fn(sd, info); + run_transfer(handle, info, stats); odp_ticketlock_unlock(&info->lock); } @@ -899,9 +942,10 @@ static odp_bool_t configure_poll_compl(sd_t *sd) return true; } -static void poll_transfer(odp_dma_t handle, trs_info_t *info, stats_t *stats) +static void poll_transfer(sd_t *sd, trs_info_t *info, stats_t *stats) { uint64_t start_cc, end_cc, trs_tm, trs_cc, wait_cc, start_tm, start_cc_diff; + odp_dma_t handle = sd->dma.handle; odp_dma_result_t res; int ret; @@ -943,6 +987,9 @@ static void poll_transfer(odp_dma_t handle, trs_info_t *info, stats_t *stats) info->is_running = false; } else { + if (sd->prep_trs_fn != NULL) + sd->prep_trs_fn(sd, info); + start_tm = odp_time_global_strict_ns(); start_cc = odp_cpu_cycles(); ret = odp_dma_transfer_start(handle, &info->trs_param, &info->compl_param); @@ -967,24 +1014,22 @@ static void poll_transfer(odp_dma_t handle, trs_info_t *info, stats_t *stats) static void poll_transfers_mt_unsafe(sd_t *sd, stats_t *stats) { const uint32_t count = sd->dma.num_inflight; - odp_dma_t handle = sd->dma.handle; trs_info_t *infos = sd->dma.infos; for (uint32_t i = 0U; i < count; ++i) - poll_transfer(handle, &infos[i], stats); + poll_transfer(sd, &infos[i], stats); } static void poll_transfers_mt_safe(sd_t *sd, stats_t *stats) { const uint32_t count = sd->dma.num_inflight; - odp_dma_t handle = sd->dma.handle; trs_info_t *infos = sd->dma.infos, *info; for (uint32_t i = 0U; i < count; ++i) { info = &infos[i]; if (odp_ticketlock_trylock(&info->lock)) { - poll_transfer(handle, info, stats); + poll_transfer(sd, info, stats); odp_ticketlock_unlock(&info->lock); } } @@ -1080,6 +1125,10 @@ static odp_bool_t start_initial_transfers(sd_t *sd) for (uint32_t i = 0U; i < sd->dma.num_inflight; ++i) { info = &sd->dma.infos[i]; + + if (sd->prep_trs_fn != NULL) + sd->prep_trs_fn(sd, info); + start_tm = odp_time_global_strict_ns(); start_cc = odp_cpu_cycles(); ret = odp_dma_transfer_start(sd->dma.handle, &info->trs_param, &info->compl_param); @@ -1135,6 +1184,9 @@ static void wait_compl_event(sd_t *sd, stats_t *stats) else ++stats->completed; + if (sd->prep_trs_fn != NULL) + sd->prep_trs_fn(sd, info); + start_tm = odp_time_global_strict_ns(); start_cc = odp_cpu_cycles(); ret = odp_dma_transfer_start(sd->dma.handle, &info->trs_param, &info->compl_param); @@ -1233,10 +1285,16 @@ static void run_memcpy(trs_info_t *info, stats_t *stats) static void run_memcpy_mt_unsafe(sd_t *sd, stats_t *stats) { const uint32_t count = sd->dma.num_inflight; - trs_info_t *infos = sd->dma.infos; + trs_info_t *infos = sd->dma.infos, *info; - for (uint32_t i = 0U; i < count; ++i) - run_memcpy(&infos[i], stats); + for (uint32_t i = 0U; i < count; ++i) { + info = &infos[i]; + + if (sd->prep_trs_fn != NULL) + sd->prep_trs_fn(sd, info); + + run_memcpy(info, stats); + } } static void run_memcpy_mt_safe(sd_t *sd, stats_t *stats) @@ -1248,6 +1306,9 @@ static void run_memcpy_mt_safe(sd_t *sd, stats_t *stats) info = &infos[i]; if (odp_ticketlock_trylock(&info->lock)) { + if (sd->prep_trs_fn != NULL) + sd->prep_trs_fn(sd, info); + run_memcpy(info, stats); odp_ticketlock_unlock(&info->lock); } @@ -1256,7 +1317,7 @@ static void run_memcpy_mt_safe(sd_t *sd, stats_t *stats) static void setup_api(prog_config_t *config) { - if (config->seg_type == DENSE_PACKET) { + if (config->seg_type == DENSE_PACKET || config->seg_type == SPARSE_PACKET) { config->api.setup_fn = setup_packet_segments; config->api.trs_fn = configure_packet_transfer; config->api.free_fn = free_packets; @@ -1298,6 +1359,65 @@ static void setup_api(prog_config_t *config) } } +static void prepare_packet_transfer(sd_t *sd, trs_info_t *info) +{ + odp_dma_transfer_param_t *param = &info->trs_param; + odp_dma_seg_t *seg; + + for (uint32_t i = 0U; i < param->num_src; ++i) { + seg = ¶m->src_seg[i]; + + if (odp_likely(seg->packet != ODP_PACKET_INVALID)) + odp_packet_free(seg->packet); + + seg->packet = odp_packet_alloc(sd->seg.src_pool, seg->len); + + if (odp_unlikely(seg->packet == ODP_PACKET_INVALID)) + /* There should always be enough packets. */ + ODPH_ABORT("Failed to allocate packet, aborting\n"); + } + + for (uint32_t i = 0U; i < param->num_dst; ++i) { + seg = ¶m->dst_seg[i]; + + if (odp_likely(seg->packet != ODP_PACKET_INVALID)) + odp_packet_free(seg->packet); + + seg->packet = odp_packet_alloc(sd->seg.dst_pool, seg->len); + + if (odp_unlikely(seg->packet == ODP_PACKET_INVALID)) + /* There should always be enough packets. */ + ODPH_ABORT("Failed to allocate packet, aborting\n"); + } +} + +static void prepare_address_transfer(sd_t *sd, trs_info_t *info) +{ + odp_dma_transfer_param_t *param = &info->trs_param; + uint8_t *addr = sd->seg.cur_src; + + for (uint32_t i = 0U; i < param->num_src; ++i) { + if (odp_unlikely(addr > (uint8_t *)sd->seg.src_high)) + addr = sd->seg.src; + + param->src_seg[i].addr = addr; + addr += sd->dma.src_seg_len; + } + + sd->seg.cur_src = addr + ODP_CACHE_LINE_SIZE; + addr = sd->seg.cur_dst; + + for (uint32_t i = 0U; i < param->num_dst; ++i) { + if (odp_unlikely(addr > (uint8_t *)sd->seg.dst_high)) + addr = sd->seg.dst; + + param->dst_seg[i].addr = addr; + addr += sd->dma.dst_seg_len; + } + + sd->seg.cur_dst = addr + ODP_CACHE_LINE_SIZE; +} + static odp_bool_t setup_session_descriptors(prog_config_t *config) { sd_t *sd; @@ -1332,6 +1452,10 @@ static odp_bool_t setup_session_descriptors(prog_config_t *config) return false; sd->seg.shm_size = config->shm_size; + sd->seg.seg_type = config->seg_type; + sd->prep_trs_fn = config->seg_type == SPARSE_PACKET ? prepare_packet_transfer : + config->seg_type == SPARSE_MEMORY ? + prepare_address_transfer : NULL; } return true; -- cgit v1.2.3 From f41dcbecddd42efac5261f3396dcabbaec6d23c1 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Mon, 4 Dec 2023 13:56:59 +0000 Subject: test: dma_perf: refactor statistics output Refactor final statistics output to take into consideration the new sparse segment types. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index 30807d038..30008f96b 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -1658,8 +1658,10 @@ static void print_stats(const prog_config_t *config) config->trs_type == ASYNC_DMA && config->compl_mode == EVENT ? "DMA asynchronous-event" : "SW", config->num_in_segs, config->num_out_segs, config->src_seg_len, - config->seg_type == DENSE_PACKET ? "packet" : "memory", config->num_inflight, - config->policy == SINGLE ? "shared" : "per-worker"); + config->seg_type == DENSE_PACKET ? "dense packet" : + config->seg_type == SPARSE_PACKET ? "sparse packet" : + config->seg_type == DENSE_MEMORY ? "dense memory" : "sparse memory", + config->num_inflight, config->policy == SINGLE ? "shared" : "per-worker"); for (int i = 0; i < config->num_workers; ++i) { stats = &config->thread_config[i].stats; -- cgit v1.2.3 From b9f88b3c32151c7aad5dacde6c2a929baf9b7eaf Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Mon, 4 Dec 2023 13:59:27 +0000 Subject: test: dma_perf: enable sparse segment types The new sparse segment types are now fully implemented and enabled. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index 30008f96b..09943a9d6 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -344,11 +344,6 @@ static parse_result_t check_options(prog_config_t *config) return PRS_NOK; } - if (config->seg_type == SPARSE_PACKET || config->seg_type == SPARSE_MEMORY) { - ODPH_ERR("Sparse segment types not yet implemented\n"); - return PRS_NOT_SUP; - } - max_workers = ODPH_MIN(odp_thread_count_max() - 1, MAX_WORKERS); if (config->num_workers <= 0 || config->num_workers > max_workers) { -- cgit v1.2.3 From 5ee2cb86974f8b6e593491f498b699c898ed0419 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 5 Dec 2023 12:52:37 +0000 Subject: test: dma_perf: run new mode and segment types Add tests for the new SW copy mode and new sparse segment types to be run in the runner script. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf_run.sh | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/test/performance/odp_dma_perf_run.sh b/test/performance/odp_dma_perf_run.sh index 37bc4382f..6f1280fd1 100755 --- a/test/performance/odp_dma_perf_run.sh +++ b/test/performance/odp_dma_perf_run.sh @@ -25,24 +25,45 @@ check_result() fi } -echo "odp_dma_perf: synchronous transfer" +echo "odp_dma_perf: synchronous DMA transfer 1" echo "====================================" ${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 0 -i $SEGC -o $SEGC -s $SEGS -S 0 -f $INFL -T $TIME check_result $? -echo "odp_dma_perf: asynchronous transfer 1" +echo "odp_dma_perf: synchronous DMA transfer 2" +echo "====================================" + +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 0 -i $SEGC -o $SEGC -s $SEGS -S 1 -f $INFL -T $TIME + +check_result $? + +echo "odp_dma_perf: asynchronous DMA transfer 1" +echo "=====================================" + +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 1 -i $SEGC -o $SEGC -s $SEGS -S 2 -m 0 -f $INFL -T $TIME + +check_result $? + +echo "odp_dma_perf: asynchronous DMA transfer 2" +echo "=====================================" + +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 1 -i $SEGC -o $SEGC -s $SEGS -S 3 -m 1 -f $INFL -T $TIME + +check_result $? + +echo "odp_dma_perf: SW transfer 1" echo "=====================================" -${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 1 -i $SEGC -o $SEGC -s $SEGS -S 1 -m 0 -f $INFL -T $TIME +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 2 -i $SEGC -o $SEGC -s $SEGS -S 0 -f $INFL -T $TIME check_result $? -echo "odp_dma_perf: asynchronous transfer 2" +echo "odp_dma_perf: SW transfer 2" echo "=====================================" -${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 1 -i $SEGC -o $SEGC -s $SEGS -S 1 -m 1 -f $INFL -T $TIME +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 2 -i $SEGC -o $SEGC -s $SEGS -S 2 -f $INFL -T $TIME check_result $? -- cgit v1.2.3 From 180bf8831fe58f8b41a389433fcfa119cd47a3e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jere=20Lepp=C3=A4nen?= Date: Thu, 14 Dec 2023 12:51:08 +0200 Subject: validation: timer: run tests with all supported clock sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run most of the tests with all clock sources that are supported according to capability. Also check that the default clock source is supported. Signed-off-by: Jere Leppänen Reviewed-by: Petri Savolainen --- test/validation/api/timer/timer.c | 307 ++++++++++++++++++++------------------ 1 file changed, 161 insertions(+), 146 deletions(-) diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c index 980372c35..09c3715d8 100644 --- a/test/validation/api/timer/timer.c +++ b/test/validation/api/timer/timer.c @@ -65,14 +65,8 @@ struct test_timer { }; typedef struct { - /* Clock source support flags */ - uint8_t clk_supported[ODP_CLOCK_NUM_SRC]; - - /* Periodic timer support per clock source*/ - uint8_t periodic_support[ODP_CLOCK_NUM_SRC]; - - /* Periodic timers not supported with any clock source */ - int no_periodic; + /* Periodic timer support */ + int periodic_support; /* Default resolution / timeout parameters */ struct { @@ -107,19 +101,21 @@ typedef struct { } global_shared_mem_t; +typedef struct { + odp_timer_clk_src_t clk_src; + global_shared_mem_t global_mem; + +} test_global_t; + static global_shared_mem_t *global_mem; +static test_global_t *test_global; +static odp_shm_t global_shm; +static odp_instance_t inst; -static int timer_global_init(odp_instance_t *inst) +static int global_init(void) { - odp_shm_t global_shm; odp_init_t init_param; odph_helper_options_t helper_options; - odp_timer_capability_t capa; - odp_timer_res_capability_t res_capa; - uint64_t res_ns, min_tmo, max_tmo; - unsigned int range; - int i; - int num_periodic = 0; if (odph_options(&helper_options)) { ODPH_ERR("odph_options() failed\n"); @@ -129,35 +125,73 @@ static int timer_global_init(odp_instance_t *inst) odp_init_param_init(&init_param); init_param.mem_model = helper_options.mem_model; - if (0 != odp_init_global(inst, &init_param, NULL)) { + if (0 != odp_init_global(&inst, &init_param, NULL)) { ODPH_ERR("odp_init_global() failed\n"); return -1; } - if (0 != odp_init_local(*inst, ODP_THREAD_CONTROL)) { + if (0 != odp_init_local(inst, ODP_THREAD_CONTROL)) { ODPH_ERR("odp_init_local() failed\n"); return -1; } global_shm = odp_shm_reserve(GLOBAL_SHM_NAME, - sizeof(global_shared_mem_t), + sizeof(test_global_t), ODP_CACHE_LINE_SIZE, 0); if (global_shm == ODP_SHM_INVALID) { ODPH_ERR("Unable to reserve memory for global_shm\n"); return -1; } - global_mem = odp_shm_addr(global_shm); - memset(global_mem, 0, sizeof(global_shared_mem_t)); + test_global = odp_shm_addr(global_shm); + memset(test_global, 0, sizeof(*test_global)); + global_mem = &test_global->global_mem; /* Configure scheduler */ odp_schedule_config(NULL); + return 0; +} + +static int global_term(void) +{ + if (0 != odp_shm_free(global_shm)) { + ODPH_ERR("odp_shm_free() failed\n"); + return -1; + } + + if (0 != odp_term_local()) { + ODPH_ERR("odp_term_local() failed\n"); + return -1; + } + + if (0 != odp_term_global(inst)) { + ODPH_ERR("odp_term_global() failed\n"); + return -1; + } + + return 0; +} + +static int timer_global_init(odp_instance_t *instance) +{ + odp_timer_capability_t capa; + odp_timer_res_capability_t res_capa; + uint64_t res_ns, min_tmo, max_tmo; + unsigned int range; + odp_timer_clk_src_t clk_src = test_global->clk_src; + + *instance = inst; + + memset(global_mem, 0, sizeof(global_shared_mem_t)); + memset(&capa, 0, sizeof(capa)); - if (odp_timer_capability(ODP_CLOCK_DEFAULT, &capa)) { + if (odp_timer_capability(clk_src, &capa)) { ODPH_ERR("Timer capability failed\n"); return -1; } + global_mem->periodic_support = capa.periodic.max_pools > 0; + /* By default 20 msec resolution */ res_ns = 20 * ODP_TIME_MSEC_IN_NS; if (res_ns < capa.max_res.res_ns) @@ -166,7 +200,7 @@ static int timer_global_init(odp_instance_t *inst) memset(&res_capa, 0, sizeof(res_capa)); res_capa.res_ns = res_ns; - if (odp_timer_res_capability(ODP_CLOCK_DEFAULT, &res_capa)) { + if (odp_timer_res_capability(clk_src, &res_capa)) { ODPH_ERR("Timer resolution capability failed\n"); return -1; } @@ -194,42 +228,12 @@ static int timer_global_init(odp_instance_t *inst) global_mem->param.queue_type_plain = capa.queue_type_plain; global_mem->param.queue_type_sched = capa.queue_type_sched; - /* Check which clock sources are supported */ - for (i = 0; i < ODP_CLOCK_NUM_SRC; i++) { - if (odp_timer_capability(ODP_CLOCK_SRC_0 + i, &capa) == 0) { - global_mem->clk_supported[i] = 1; - - if (capa.periodic.max_pools) { - global_mem->periodic_support[i] = 1; - num_periodic++; - } - } - } - - global_mem->no_periodic = !num_periodic; - return 0; } static int timer_global_term(odp_instance_t inst) { - odp_shm_t shm; - - shm = odp_shm_lookup(GLOBAL_SHM_NAME); - if (0 != odp_shm_free(shm)) { - ODPH_ERR("odp_shm_free() failed\n"); - return -1; - } - - if (0 != odp_term_local()) { - ODPH_ERR("odp_term_local() failed\n"); - return -1; - } - - if (0 != odp_term_global(inst)) { - ODPH_ERR("odp_term_global() failed\n"); - return -1; - } + (void)inst; return 0; } @@ -254,15 +258,15 @@ check_plain_queue_support(void) static int check_periodic_support(void) { - if (global_mem->no_periodic) - return ODP_TEST_INACTIVE; + if (global_mem->periodic_support) + return ODP_TEST_ACTIVE; - return ODP_TEST_ACTIVE; + return ODP_TEST_INACTIVE; } static int check_periodic_sched_support(void) { - if (global_mem->periodic_support[0] && global_mem->param.queue_type_sched) + if (global_mem->periodic_support && global_mem->param.queue_type_sched) return ODP_TEST_ACTIVE; return ODP_TEST_INACTIVE; @@ -270,17 +274,18 @@ static int check_periodic_sched_support(void) static int check_periodic_plain_support(void) { - if (global_mem->periodic_support[0] && global_mem->param.queue_type_plain) + if (global_mem->periodic_support && global_mem->param.queue_type_plain) return ODP_TEST_ACTIVE; return ODP_TEST_INACTIVE; } -static void timer_test_capa_run(odp_timer_clk_src_t clk_src) +static void timer_test_capa(void) { odp_timer_capability_t capa; odp_timer_res_capability_t res_capa; int ret; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&capa, 0, sizeof(capa)); ret = odp_timer_capability(clk_src, &capa); @@ -353,8 +358,9 @@ static void timer_test_capa_run(odp_timer_clk_src_t clk_src) } } -static void timer_test_capa(void) +static void timer_test_capa_allsrc(void) { + odp_timer_capability_t capa; odp_timer_clk_src_t clk_src; int i; @@ -371,20 +377,15 @@ static void timer_test_capa(void) CU_ASSERT_FATAL(ODP_CLOCK_EXT == ODP_CLOCK_SRC_1); #endif + CU_ASSERT(odp_timer_capability(ODP_CLOCK_DEFAULT, &capa) == 0); + for (i = 0; i < ODP_CLOCK_NUM_SRC; i++) { - odp_timer_capability_t capa; int ret; clk_src = ODP_CLOCK_SRC_0 + i; ret = odp_timer_capability(clk_src, &capa); CU_ASSERT(ret == 0 || ret == -1); - - if (global_mem->clk_supported[i]) { - ODPH_DBG("\nTesting clock source: %i\n", clk_src); - CU_ASSERT(ret == 0); - timer_test_capa_run(clk_src); - } } } @@ -676,9 +677,10 @@ static void timer_pool_create_destroy(void) odp_timer_t tim; odp_queue_t queue; int ret; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&capa, 0, sizeof(capa)); - ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &capa); + ret = odp_timer_capability(clk_src, &capa); CU_ASSERT_FATAL(ret == 0); odp_queue_param_init(&queue_param); @@ -697,7 +699,7 @@ static void timer_pool_create_destroy(void) tparam.max_tmo = global_mem->param.max_tmo; tparam.num_timers = 100; tparam.priv = 0; - tparam.clk_src = ODP_CLOCK_DEFAULT; + tparam.clk_src = clk_src; tp[0] = odp_timer_pool_create("timer_pool_a", &tparam); CU_ASSERT(tp[0] != ODP_TIMER_POOL_INVALID); @@ -757,9 +759,10 @@ static void timer_pool_create_max(void) int ret; uint64_t tmo_ns = ODP_TIME_SEC_IN_NS; uint64_t res_ns = ODP_TIME_SEC_IN_NS / 10; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&capa, 0, sizeof(capa)); - ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &capa); + ret = odp_timer_capability(clk_src, &capa); CU_ASSERT_FATAL(ret == 0); uint32_t num = capa.max_pools; @@ -789,6 +792,7 @@ static void timer_pool_create_max(void) tp_param.min_tmo = tmo_ns / 2; tp_param.max_tmo = tmo_ns; tp_param.num_timers = 1; + tp_param.clk_src = clk_src; for (i = 0; i < num; i++) { tp[i] = odp_timer_pool_create("test_max", &tp_param); @@ -836,9 +840,10 @@ static void timer_pool_max_res(void) odp_event_t ev; uint64_t tick; int ret, i; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&capa, 0, sizeof(capa)); - ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &capa); + ret = odp_timer_capability(clk_src, &capa); CU_ASSERT_FATAL(ret == 0); odp_pool_param_init(&pool_param); @@ -875,7 +880,7 @@ static void timer_pool_max_res(void) tp_param.max_tmo = capa.max_res.max_tmo; tp_param.num_timers = 100; tp_param.priv = 0; - tp_param.clk_src = ODP_CLOCK_DEFAULT; + tp_param.clk_src = clk_src; tp = odp_timer_pool_create("high_res_tp", &tp_param); CU_ASSERT_FATAL(tp != ODP_TIMER_POOL_INVALID); @@ -979,9 +984,10 @@ static void timer_single_shot(odp_queue_type_t queue_type, odp_timer_tick_type_t odp_time_t t1, t2; uint64_t tick, nsec, res_ns, min_tmo; int ret, i; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&capa, 0, sizeof(capa)); - ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &capa); + ret = odp_timer_capability(clk_src, &capa); CU_ASSERT_FATAL(ret == 0); CU_ASSERT_FATAL(capa.max_tmo.max_tmo > 0); @@ -992,7 +998,7 @@ static void timer_single_shot(odp_queue_type_t queue_type, odp_timer_tick_type_t memset(&res_capa, 0, sizeof(res_capa)); res_capa.max_tmo = tmo_ns; - ret = odp_timer_res_capability(ODP_CLOCK_DEFAULT, &res_capa); + ret = odp_timer_res_capability(clk_src, &res_capa); CU_ASSERT_FATAL(ret == 0); CU_ASSERT_FATAL(res_capa.res_ns > 0); @@ -1029,6 +1035,7 @@ static void timer_single_shot(odp_queue_type_t queue_type, odp_timer_tick_type_t tp_param.min_tmo = min_tmo; tp_param.max_tmo = tmo_ns; tp_param.num_timers = 1; + tp_param.clk_src = clk_src; tp = odp_timer_pool_create("test_single", &tp_param); CU_ASSERT_FATAL(tp != ODP_TIMER_POOL_INVALID); @@ -1213,13 +1220,14 @@ static void timer_sched_abs_wait_3sec(void) timer_single_shot(ODP_QUEUE_TYPE_SCHED, ABSOLUTE, START, TIMEOUT, 30, 110 * MSEC); } -static void timer_pool_current_tick_run(odp_timer_clk_src_t clk_src) +static void timer_pool_current_tick(void) { odp_timer_capability_t capa; odp_timer_pool_param_t tp_param; odp_timer_pool_t tp; uint64_t t1, t2, ticks, min, max, limit; uint64_t nsec = 100 * ODP_TIME_MSEC_IN_NS; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&capa, 0, sizeof(capa)); CU_ASSERT_FATAL(odp_timer_capability(clk_src, &capa) == 0); @@ -1268,21 +1276,7 @@ static void timer_pool_current_tick_run(odp_timer_clk_src_t clk_src) odp_timer_pool_destroy(tp); } -static void timer_pool_current_tick(void) -{ - odp_timer_clk_src_t clk_src; - int i; - - for (i = 0; i < ODP_CLOCK_NUM_SRC; i++) { - clk_src = ODP_CLOCK_SRC_0 + i; - if (global_mem->clk_supported[i]) { - ODPH_DBG("\nTesting clock source: %i\n", clk_src); - timer_pool_current_tick_run(clk_src); - } - } -} - -static void timer_pool_sample_ticks_run(odp_timer_clk_src_t clk_2) +static void timer_pool_sample_ticks(void) { odp_timer_capability_t capa; odp_timer_pool_param_t tp_param; @@ -1290,6 +1284,7 @@ static void timer_pool_sample_ticks_run(odp_timer_clk_src_t clk_2) uint64_t t1[2], t2[2], ticks[2], min[2], max[2]; uint64_t clk_count[2] = {0}; odp_timer_clk_src_t clk_1 = ODP_CLOCK_DEFAULT; + odp_timer_clk_src_t clk_2 = test_global->clk_src; uint64_t nsec = 100 * ODP_TIME_MSEC_IN_NS; /* Highest resolution */ @@ -1354,15 +1349,7 @@ static void timer_pool_sample_ticks_run(odp_timer_clk_src_t clk_2) odp_timer_pool_destroy(tp[1]); } -static void timer_pool_sample_ticks(void) -{ - for (int i = 0; i < ODP_CLOCK_NUM_SRC; i++) { - if (global_mem->clk_supported[i]) - timer_pool_sample_ticks_run(ODP_CLOCK_SRC_0 + i); - } -} - -static void timer_pool_tick_info_run(odp_timer_clk_src_t clk_src) +static void timer_pool_tick_info(void) { odp_timer_capability_t capa; odp_timer_pool_param_t tp_param; @@ -1370,6 +1357,7 @@ static void timer_pool_tick_info_run(odp_timer_clk_src_t clk_src) odp_timer_pool_info_t info; uint64_t ticks_per_sec; double tick_hz, tick_nsec, tick_to_nsec, tick_low; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&capa, 0, sizeof(capa)); CU_ASSERT_FATAL(odp_timer_capability(clk_src, &capa) == 0); @@ -1439,20 +1427,6 @@ static void timer_pool_tick_info_run(odp_timer_clk_src_t clk_src) odp_timer_pool_destroy(tp); } -static void timer_pool_tick_info(void) -{ - odp_timer_clk_src_t clk_src; - int i; - - for (i = 0; i < ODP_CLOCK_NUM_SRC; i++) { - clk_src = ODP_CLOCK_SRC_0 + i; - if (global_mem->clk_supported[i]) { - ODPH_DBG("\nTesting clock source: %i\n", clk_src); - timer_pool_tick_info_run(clk_src); - } - } -} - static void timer_test_event_type(odp_queue_type_t queue_type, odp_event_type_t event_type, int rounds) { @@ -1474,6 +1448,7 @@ static void timer_test_event_type(odp_queue_type_t queue_type, int test_print = 0; int num = 5; odp_timer_t timer[num]; + odp_timer_clk_src_t clk_src = test_global->clk_src; odp_timer_pool_param_init(&timer_param); timer_param.res_ns = global_mem->param.res_ns; @@ -1481,7 +1456,7 @@ static void timer_test_event_type(odp_queue_type_t queue_type, period_ns = 2 * global_mem->param.min_tmo; timer_param.max_tmo = global_mem->param.max_tmo; timer_param.num_timers = num; - timer_param.clk_src = ODP_CLOCK_DEFAULT; + timer_param.clk_src = clk_src; timer_pool = odp_timer_pool_create("timer_pool", &timer_param); if (timer_pool == ODP_TIMER_POOL_INVALID) @@ -1685,6 +1660,7 @@ static void timer_test_queue_type(odp_queue_type_t queue_type, int priv, int exp uint64_t target_tick[num]; uint64_t target_nsec[num]; void *user_ptr[num]; + odp_timer_clk_src_t clk_src = test_global->clk_src; odp_pool_param_init(¶ms); params.type = ODP_POOL_TIMEOUT; @@ -1701,7 +1677,7 @@ static void timer_test_queue_type(odp_queue_type_t queue_type, int priv, int exp tparam.max_tmo = global_mem->param.max_tmo; tparam.num_timers = num + 1; tparam.priv = priv; - tparam.clk_src = ODP_CLOCK_DEFAULT; + tparam.clk_src = clk_src; if (exp_relax) tparam.exp_mode = ODP_TIMER_EXP_RELAXED; @@ -1894,9 +1870,10 @@ static void timer_test_cancel(void) odp_timeout_t tmo; odp_timer_retval_t rc; int ret; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&capa, 0, sizeof(capa)); - ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &capa); + ret = odp_timer_capability(clk_src, &capa); CU_ASSERT_FATAL(ret == 0); odp_pool_param_init(¶ms); @@ -1914,7 +1891,7 @@ static void timer_test_cancel(void) tparam.max_tmo = global_mem->param.max_tmo; tparam.num_timers = 1; tparam.priv = 0; - tparam.clk_src = ODP_CLOCK_DEFAULT; + tparam.clk_src = clk_src; tp = odp_timer_pool_create(NULL, &tparam); if (tp == ODP_TIMER_POOL_INVALID) CU_FAIL_FATAL("Timer pool create failed"); @@ -2003,9 +1980,10 @@ static void timer_test_tmo_limit(odp_queue_type_t queue_type, int i, ret, num_tmo; int num = 5; odp_timer_t timer[num]; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&timer_capa, 0, sizeof(timer_capa)); - ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa); + ret = odp_timer_capability(clk_src, &timer_capa); CU_ASSERT_FATAL(ret == 0); if (max_res) { @@ -2025,7 +2003,7 @@ static void timer_test_tmo_limit(odp_queue_type_t queue_type, timer_param.min_tmo = min_tmo; timer_param.max_tmo = max_tmo; timer_param.num_timers = num; - timer_param.clk_src = ODP_CLOCK_DEFAULT; + timer_param.clk_src = clk_src; timer_pool = odp_timer_pool_create("timer_pool", &timer_param); if (timer_pool == ODP_TIMER_POOL_INVALID) @@ -2303,7 +2281,7 @@ static int worker_entrypoint(void *arg ODP_UNUSED) uint64_t min_tmo = global_mem->param.min_tmo; odp_queue_param_t queue_param; odp_thrmask_t thr_mask; - odp_schedule_group_t group; + odp_schedule_group_t group = ODP_SCHED_GROUP_INVALID; uint64_t sched_tmo; uint64_t res_ns = global_mem->param.res_ns; odp_queue_type_t queue_type = global_mem->test_queue_type; @@ -2540,6 +2518,9 @@ sleep: odp_event_free(tt[i].ev); } + if (queue_type == ODP_QUEUE_TYPE_SCHED) + CU_ASSERT(odp_schedule_group_destroy(group) == 0); + free(tt); ODPH_DBG("Thread %u: exiting\n", thr); return CU_get_number_of_failures(); @@ -2562,6 +2543,7 @@ static void timer_test_all(odp_queue_type_t queue_type) uint32_t num_timers; uint32_t num_workers; int timers_per_thread; + odp_timer_clk_src_t clk_src = test_global->clk_src; CU_ASSERT_FATAL(odp_schedule_capability(&sched_capa) == 0); /* Reserve at least one core for running other processes so the timer @@ -2582,7 +2564,7 @@ static void timer_test_all(odp_queue_type_t queue_type) num_workers = 1; num_timers = num_workers * NTIMERS; - CU_ASSERT_FATAL(!odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa)); + CU_ASSERT_FATAL(!odp_timer_capability(clk_src, &timer_capa)); if (timer_capa.max_timers && timer_capa.max_timers < num_timers) num_timers = timer_capa.max_timers; @@ -2615,7 +2597,7 @@ static void timer_test_all(odp_queue_type_t queue_type) tparam.max_tmo = max_tmo; tparam.num_timers = num_timers; tparam.priv = 0; - tparam.clk_src = ODP_CLOCK_DEFAULT; + tparam.clk_src = clk_src; global_mem->tp = odp_timer_pool_create(NAME, &tparam); if (global_mem->tp == ODP_TIMER_POOL_INVALID) CU_FAIL_FATAL("Timer pool create failed"); @@ -2711,7 +2693,7 @@ static void timer_test_sched_all(void) timer_test_all(ODP_QUEUE_TYPE_SCHED); } -static void timer_test_periodic_capa_run(odp_timer_clk_src_t clk_src) +static void timer_test_periodic_capa(void) { odp_timer_capability_t timer_capa; odp_timer_periodic_capability_t capa; @@ -2721,6 +2703,7 @@ static void timer_test_periodic_capa_run(odp_timer_clk_src_t clk_src) int ret; uint32_t i, j; uint32_t num = 100; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&timer_capa, 0, sizeof(odp_timer_capability_t)); CU_ASSERT_FATAL(odp_timer_capability(clk_src, &timer_capa) == 0); @@ -2851,20 +2834,6 @@ static void timer_test_periodic_capa_run(odp_timer_clk_src_t clk_src) } } -static void timer_test_periodic_capa(void) -{ - odp_timer_clk_src_t clk_src; - int i; - - for (i = 0; i < ODP_CLOCK_NUM_SRC; i++) { - clk_src = ODP_CLOCK_SRC_0 + i; - if (global_mem->periodic_support[i]) { - ODPH_DBG("\nTesting clock source: %i\n", clk_src); - timer_test_periodic_capa_run(clk_src); - } - } -} - static void timer_test_periodic(odp_queue_type_t queue_type, int use_first, int rounds, int reuse_event) { @@ -2891,9 +2860,10 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first, int /* Test frequency: 1x 100Hz, or 1x min/max_base_freq */ const uint64_t multiplier = 1; odp_fract_u64_t base_freq = {100, 0, 0}; + odp_timer_clk_src_t clk_src = test_global->clk_src; memset(&timer_capa, 0, sizeof(odp_timer_capability_t)); - CU_ASSERT_FATAL(odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa) == 0); + CU_ASSERT_FATAL(odp_timer_capability(clk_src, &timer_capa) == 0); CU_ASSERT_FATAL(timer_capa.periodic.max_pools); CU_ASSERT_FATAL(timer_capa.periodic.max_timers); @@ -2918,7 +2888,7 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first, int periodic_capa.base_freq_hz = base_freq; periodic_capa.max_multiplier = multiplier; - ret = odp_timer_periodic_capability(ODP_CLOCK_DEFAULT, &periodic_capa); + ret = odp_timer_periodic_capability(clk_src, &periodic_capa); CU_ASSERT(ret == 0 || ret == 1); if (ret < 0) { @@ -2954,7 +2924,7 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first, int timer_param.timer_type = ODP_TIMER_TYPE_PERIODIC; timer_param.res_ns = 2 * periodic_capa.res_ns; timer_param.num_timers = 1; - timer_param.clk_src = ODP_CLOCK_DEFAULT; + timer_param.clk_src = clk_src; timer_param.periodic.base_freq_hz = base_freq; timer_param.periodic.max_multiplier = multiplier; @@ -3167,14 +3137,24 @@ static void timer_test_periodic_event_reuse(void) timer_test_periodic(ODP_QUEUE_TYPE_SCHED, 0, 2, 1); } -odp_testinfo_t timer_suite[] = { - ODP_TEST_INFO(timer_test_capa), +odp_testinfo_t timer_general_suite[] = { ODP_TEST_INFO(timer_test_param_init), ODP_TEST_INFO(timer_test_timeout_pool_alloc), ODP_TEST_INFO(timer_test_timeout_pool_alloc_multi), ODP_TEST_INFO(timer_test_timeout_from_event), ODP_TEST_INFO(timer_test_timeout_pool_free), ODP_TEST_INFO(timer_test_timeout_user_area), + ODP_TEST_INFO(timer_test_capa_allsrc), + ODP_TEST_INFO_NULL, +}; + +odp_suiteinfo_t timer_general_suites[] = { + {"Timer general", NULL, NULL, timer_general_suite}, + ODP_SUITE_INFO_NULL, +}; + +odp_testinfo_t timer_suite[] = { + ODP_TEST_INFO(timer_test_capa), ODP_TEST_INFO(timer_pool_create_destroy), ODP_TEST_INFO(timer_pool_create_max), ODP_TEST_INFO(timer_pool_max_res), @@ -3274,17 +3254,52 @@ odp_suiteinfo_t timer_suites[] = { int main(int argc, char *argv[]) { + int ret = 0; + /* parse common options: */ if (odp_cunit_parse_options(argc, argv)) return -1; + if (global_init()) + return -1; + odp_cunit_register_global_init(timer_global_init); odp_cunit_register_global_term(timer_global_term); - int ret = odp_cunit_register(timer_suites); + if (odp_cunit_register(timer_general_suites)) + goto fail; + + if (odp_cunit_run()) + goto fail; + + for (int i = ODP_CLOCK_SRC_0; i < ODP_CLOCK_NUM_SRC; i++) { + odp_timer_capability_t capa; + + if (odp_timer_capability(i, &capa)) + continue; + + printf("\n\n" + "-------------------------------------------------------------------------------\n" + " Running tests with clock source %d\n" + "-------------------------------------------------------------------------------\n\n", + i); + + test_global->clk_src = i; - if (ret == 0) - ret = odp_cunit_run(); + odp_cunit_register_global_init(timer_global_init); + odp_cunit_register_global_term(timer_global_term); + if (odp_cunit_register(timer_suites)) + goto fail; + + if (odp_cunit_run()) + ret = -1; + } + + global_term(); return ret; + +fail: + global_term(); + return -1; } -- cgit v1.2.3 From 066c7e6a4a3c5365661decc42db0b48738b220bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jere=20Lepp=C3=A4nen?= Date: Fri, 15 Dec 2023 11:27:21 +0200 Subject: validation: timer: prevent timer_test_max_tmo_min_tmo_sched from taking too long MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The maximum timeout parameters in odp_timer_capability_t.max_tmo can be very long in some implementations. Prevent the timer_test_max_tmo_min_tmo_sched test, which waits for a timeout of length odp_timer_capability_t.max_tmo.min_tmo, from taking too long by asserting that the timeout is reasonably short (less than 5 seconds). Signed-off-by: Jere Leppänen Reviewed-by: Petri Savolainen --- test/validation/api/timer/timer.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c index 09c3715d8..d5af76c50 100644 --- a/test/validation/api/timer/timer.c +++ b/test/validation/api/timer/timer.c @@ -2044,6 +2044,14 @@ static void timer_test_tmo_limit(odp_queue_type_t queue_type, ODPH_DBG(" tmo_ns %" PRIu64 "\n", tmo_ns); ODPH_DBG(" tmo_tick %" PRIu64 "\n\n", tmo_tick); + if (min) { + /* + * Prevent the test from taking too long by asserting that the + * timeout is reasonably short. + */ + CU_ASSERT_FATAL(tmo_ns < 5 * ODP_TIME_SEC_IN_NS); + } + for (i = 0; i < num; i++) { timer[i] = odp_timer_alloc(timer_pool, queue, NULL); CU_ASSERT_FATAL(timer[i] != ODP_TIMER_INVALID); -- cgit v1.2.3 From 40ec75bce9a6e8e621ad584d8135b16951357480 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 12 Dec 2023 06:32:49 +0000 Subject: test: ipsecfwd: replace helper IP lookup table Replace IP lookup table provided by ODP helper library with a simpler structure. Signed-off-by: Tuomas Taipale Reviewed-by: Janne Peltonen --- test/performance/odp_ipsecfwd.c | 111 +++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/test/performance/odp_ipsecfwd.c b/test/performance/odp_ipsecfwd.c index 33525a4d2..5c35d67f7 100644 --- a/test/performance/odp_ipsecfwd.c +++ b/test/performance/odp_ipsecfwd.c @@ -33,6 +33,7 @@ #define PKT_CNT 32768U #define MAX_BURST 32U #define ORDERED 0U +#define IP_ADDR_LEN 32U #define ALG_ENTRY(_alg_name, _type) \ { \ @@ -77,11 +78,17 @@ typedef struct pktio_s { } pktio_t; typedef struct { + uint32_t prefix; + uint32_t mask; odph_ethaddr_t dst_mac; const pktio_t *pktio; - odph_iplookup_prefix_t prefix; } fwd_entry_t; +typedef struct { + fwd_entry_t entries[MAX_FWDS]; + uint32_t num; +} lookup_table_t; + typedef struct { uint64_t ipsec_in_pkts; uint64_t ipsec_out_pkts; @@ -113,7 +120,7 @@ typedef struct { } sa_config_t; typedef uint32_t (*rx_fn_t)(thread_config_t *config, odp_event_t evs[], int num); -typedef void (*ipsec_fn_t)(odp_packet_t pkts[], int num, odph_table_t fwd_tbl, stats_t *stats); +typedef void (*ipsec_fn_t)(odp_packet_t pkts[], int num, lookup_table_t *fwd_tbl, stats_t *stats); typedef void (*drain_fn_t)(prog_config_t *config); typedef struct { @@ -127,9 +134,9 @@ typedef struct prog_config_s { odph_thread_t thread_tbl[MAX_WORKERS]; thread_config_t thread_config[MAX_WORKERS]; odp_ipsec_sa_t sas[MAX_SAS]; - fwd_entry_t fwd_entries[MAX_FWDS]; odp_queue_t sa_qs[MAX_SA_QUEUES]; pktio_t pktios[MAX_IFS]; + lookup_table_t fwd_tbl; odp_atomic_u32_t is_running; sa_config_t default_cfg; ops_t ops; @@ -137,7 +144,6 @@ typedef struct prog_config_s { odp_instance_t odp_instance; odp_queue_t compl_q; odp_pool_t pktio_pool; - odph_table_t fwd_tbl; odp_barrier_t init_barrier; odp_barrier_t term_barrier; uint32_t num_input_qs; @@ -147,7 +153,6 @@ typedef struct prog_config_s { uint32_t pkt_len; uint32_t num_ifs; uint32_t num_sas; - uint32_t num_fwds; int num_thrs; odp_bool_t is_dir_rx; odp_bool_t is_hashed_tx; @@ -367,6 +372,11 @@ static void print_usage(void) " prefix: \"192.168.1.0/24\"\n" " if: \"ens9f1\"\n" " dst_mac: \"00:00:05:00:07:00\"\n" + " },\n" + " {\n" + " prefix: \"192.1.0.0/16\"\n" + " if: \"ens9f0\"\n" + " dst_mac: \"00:00:05:00:08:00\"\n" " }\n" " );\n" "\n" @@ -389,7 +399,8 @@ static void print_usage(void) " in 'fwd'-named list. With forwarding entries, every\n" " parameter is always required and interfaces present in\n" " forwarding entries should be one of the interfaces passed\n" - " with '--interfaces' option. See example above for\n" + " with '--interfaces' option. The entries are looked up\n" + " in the order they are in the list. See example above for\n" " potential SA and forwarding configuration.\n" "\n" " Supported cipher and authentication algorithms for SAs:\n", @@ -501,21 +512,36 @@ static inline int process_ipsec_out_enq(odp_packet_t pkts[], const odp_ipsec_sa_ return sent; } -static inline const pktio_t *lookup_and_apply(odp_packet_t pkt, odph_table_t fwd_tbl, +static inline const fwd_entry_t *get_fwd_entry(lookup_table_t *table, uint32_t ip) +{ + fwd_entry_t *entry; + + for (uint32_t i = 0U; i < table->num; ++i) { + entry = &table->entries[i]; + + if ((ip & entry->mask) == entry->prefix) + return entry; + } + + return NULL; +} + +static inline const pktio_t *lookup_and_apply(odp_packet_t pkt, lookup_table_t *fwd_tbl, uint8_t *q_idx) { const uint32_t l3_off = odp_packet_l3_offset(pkt); odph_ipv4hdr_t ipv4; uint32_t dst_ip, src_ip; - fwd_entry_t *fwd; + const fwd_entry_t *fwd; odph_ethhdr_t eth; if (odp_packet_copy_to_mem(pkt, l3_off, ODPH_IPV4HDR_LEN, &ipv4) < 0) return NULL; dst_ip = odp_be_to_cpu_32(ipv4.dst_addr); + fwd = get_fwd_entry(fwd_tbl, dst_ip); - if (odph_iplookup_table_get_value(fwd_tbl, &dst_ip, &fwd, 0U) < 0 || fwd == NULL) + if (fwd == NULL) return NULL; if (l3_off != ODPH_ETHHDR_LEN) { @@ -543,7 +569,7 @@ static inline const pktio_t *lookup_and_apply(odp_packet_t pkt, odph_table_t fwd return fwd->pktio; } -static inline uint32_t forward_packets(odp_packet_t pkts[], int num, odph_table_t fwd_tbl) +static inline uint32_t forward_packets(odp_packet_t pkts[], int num, lookup_table_t *fwd_tbl) { odp_packet_t pkt; odp_bool_t is_hashed_tx = ifs.is_hashed_tx; @@ -599,7 +625,7 @@ static inline uint32_t forward_packets(odp_packet_t pkts[], int num, odph_table_ return num_procd; } -static inline void process_packets_out_enq(odp_packet_t pkts[], int num, odph_table_t fwd_tbl, +static inline void process_packets_out_enq(odp_packet_t pkts[], int num, lookup_table_t *fwd_tbl, stats_t *stats) { odp_packet_t pkt, pkts_ips[MAX_BURST], pkts_fwd[MAX_BURST]; @@ -635,7 +661,7 @@ static inline void process_packets_out_enq(odp_packet_t pkts[], int num, odph_ta } } -static void process_packets_in_enq(odp_packet_t pkts[], int num, odph_table_t fwd_tbl, +static void process_packets_in_enq(odp_packet_t pkts[], int num, lookup_table_t *fwd_tbl, stats_t *stats) { odp_packet_t pkt, pkts_ips[MAX_BURST], pkts_out[MAX_BURST]; @@ -680,7 +706,8 @@ static inline odp_bool_t is_ipsec_in(odp_packet_t pkt) return odp_packet_user_ptr(pkt) == NULL; } -static void complete_ipsec_ops(odp_packet_t pkts[], int num, odph_table_t fwd_tbl, stats_t *stats) +static void complete_ipsec_ops(odp_packet_t pkts[], int num, lookup_table_t *fwd_tbl, + stats_t *stats) { odp_packet_t pkt, pkts_out[MAX_BURST], pkts_fwd[MAX_BURST]; odp_bool_t is_in; @@ -784,7 +811,7 @@ static inline int process_ipsec_out(odp_packet_t pkts[], const odp_ipsec_sa_t sa return sent; } -static inline void process_packets_out(odp_packet_t pkts[], int num, odph_table_t fwd_tbl, +static inline void process_packets_out(odp_packet_t pkts[], int num, lookup_table_t *fwd_tbl, stats_t *stats) { odp_packet_t pkt, pkts_ips[MAX_BURST], pkts_fwd[MAX_BURST], pkts_ips_out[MAX_BURST]; @@ -840,7 +867,8 @@ static inline void process_packets_out(odp_packet_t pkts[], int num, odph_table_ } } -static void process_packets_in(odp_packet_t pkts[], int num, odph_table_t fwd_tbl, stats_t *stats) +static void process_packets_in(odp_packet_t pkts[], int num, lookup_table_t *fwd_tbl, + stats_t *stats) { odp_packet_t pkt, pkts_ips[MAX_BURST], pkts_out[MAX_BURST], pkts_ips_out[MAX_BURST]; odp_ipsec_sa_t *sa, sas[MAX_BURST]; @@ -1297,9 +1325,8 @@ static void create_fwd_table_entry(config_setting_t *cfg, prog_config_t *config) odph_ethaddr_t dst_mac; const pktio_t *pktio = NULL; fwd_entry_t *entry; - odph_iplookup_prefix_t prefix; - if (config->num_fwds == MAX_FWDS) { + if (config->fwd_tbl.num == MAX_FWDS) { ODPH_ERR("Maximum number of forwarding entries parsed (%u), ignoring rest\n", MAX_FWDS); return; @@ -1315,6 +1342,11 @@ static void create_fwd_table_entry(config_setting_t *cfg, prog_config_t *config) ODPH_ERR("Syntax error in IP address for forwarding entry\n"); return; } + + if (mask > IP_ADDR_LEN) { + ODPH_ERR("Invalid subnet mask for forwarding entry: %u\n", mask); + return; + } } else { return; } @@ -1339,13 +1371,13 @@ static void create_fwd_table_entry(config_setting_t *cfg, prog_config_t *config) return; } - entry = &config->fwd_entries[config->num_fwds]; + mask = mask > 0U ? 0xFFFFFFFF << (IP_ADDR_LEN - mask) : 0U; + entry = &config->fwd_tbl.entries[config->fwd_tbl.num]; + entry->prefix = dst_ip & mask; + entry->mask = mask; entry->dst_mac = dst_mac; entry->pktio = pktio; - prefix.ip = dst_ip; - prefix.cidr = mask; - entry->prefix = prefix; - ++config->num_fwds; + ++config->fwd_tbl.num; } static void parse_fwd_table(config_t *cfg, prog_config_t *config) @@ -1385,9 +1417,9 @@ static parse_result_t check_options(prog_config_t *config) return PRS_NOK; } - if (config->num_fwds == 0U) { + if (config->fwd_tbl.num == 0U) { ODPH_ERR("Invalid number of forwarding entries: %u (min: 1, max: %u)\n", - config->num_fwds, MAX_FWDS); + config->fwd_tbl.num, MAX_FWDS); return PRS_NOK; } @@ -1710,30 +1742,6 @@ static odp_bool_t setup_pktios(prog_config_t *config) return true; } -static odp_bool_t setup_fwd_table(prog_config_t *config) -{ - fwd_entry_t *fwd_e; - - config->fwd_tbl = odph_iplookup_table_create(SHORT_PROG_NAME "_fwd_tbl", 0U, 0U, - sizeof(fwd_entry_t *)); - - if (config->fwd_tbl == NULL) { - ODPH_ERR("Error creating forwarding table\n"); - return false; - } - - for (uint32_t i = 0U; i < config->num_fwds; ++i) { - fwd_e = &config->fwd_entries[i]; - - if (odph_iplookup_table_put_value(config->fwd_tbl, &fwd_e->prefix, &fwd_e) < 0) { - ODPH_ERR("Error populating forwarding table\n"); - return false; - } - } - - return true; -} - static inline void check_ipsec_status_ev(odp_event_t ev, stats_t *stats) { odp_ipsec_status_t status; @@ -1755,7 +1763,7 @@ static int process_packets(void *args) odp_event_type_t type; odp_event_subtype_t subtype; odp_packet_t pkt, pkts_in[MAX_BURST], pkts_ips[MAX_BURST]; - odph_table_t fwd_tbl = config->prog_config->fwd_tbl; + lookup_table_t *fwd_tbl = &config->prog_config->fwd_tbl; stats_t *stats = &config->stats; ifs.is_hashed_tx = config->prog_config->is_hashed_tx; @@ -1844,9 +1852,6 @@ static odp_bool_t setup_test(prog_config_t *config) if (!setup_pktios(config)) return false; - if (!setup_fwd_table(config)) - return false; - if (!setup_workers(config)) return false; @@ -1930,8 +1935,6 @@ static void wait_sas_disabled(uint32_t num_sas) static void teardown_test(const prog_config_t *config) { - (void)odph_iplookup_table_destroy(config->fwd_tbl); - for (uint32_t i = 0U; i < config->num_ifs; ++i) { free(config->pktios[i].name); -- cgit v1.2.3 From 27a87a7810f2eb1255ecbc7cea6015b220267ee5 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 14 Nov 2023 13:42:12 +0000 Subject: api: cls: remove deprecated items Remove deprecated items: - `odp_cls_drop_t` type - `odp_cos_drop_set()`, `odp_cos_drop()`, `odp_cos_with_l2_priority()` and `odp_cos_with_l3_qos()` functions Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- doc/users-guide/users-guide-cls.adoc | 30 +--- include/odp/api/spec/classification.h | 82 --------- .../include/odp_classification_datamodel.h | 36 ---- platform/linux-generic/odp_classification.c | 188 --------------------- platform/linux-generic/odp_packet_io.c | 2 - .../api/classification/odp_classification_basic.c | 62 +------ .../classification/odp_classification_test_pmr.c | 27 --- .../api/classification/odp_classification_tests.c | 137 --------------- .../classification/odp_classification_testsuites.h | 3 - 9 files changed, 9 insertions(+), 558 deletions(-) diff --git a/doc/users-guide/users-guide-cls.adoc b/doc/users-guide/users-guide-cls.adoc index 59163a2da..41badebed 100644 --- a/doc/users-guide/users-guide-cls.adoc +++ b/doc/users-guide/users-guide-cls.adoc @@ -135,29 +135,13 @@ using ODP_POOL_INVALID or ODP_QUEUE_INVALID field then any packet assigned to th === Packet Classification For each odp_pktio port, the API allows the assignment of a class-of-service to -a packet using one of three methods: - -1. The packet may be assigned a specific class-of-service based on its Layer-2 -(802.1P/902.1Q VLAN tag) priority field. Since the standard field defines 8 -discrete priority levels, the API allows to assign an odp_cos to each of these -priority levels with the `odp_cos_with_l2_priority()` function. - -2. Similarly, a class-of-service may be assigned using the Layer-3 (IP DiffServ) -header field. The application supplies an array of odp_cos values that covers -the entire range of the standard protocol header field, where array elements do -not need to contain unique values. There is also a need to specify if Layer-3 -priority takes precedence over Layer-2 priority in a packet with both headers -present. - -3. Additionally, the application may also program a number of pattern matching -rules that assign a class-of-service for packets with header fields matching -specified values. The field-matching rules take precedence over the previously -described priority-based assignment of a class-of-service. Using these matching -rules the application should be able for example to identify all packets -containing VoIP traffic based on the protocol being UDP, and a specific -destination or source port numbers, and appropriately assign these packets a -class-of-service that maps to a higher priority queue, assuring voice packets a -lower and bound latency. +a packet. Application can program a number of pattern matching rules that +assign a class-of-service for packets with header fields matching specified +values. Using these matching rules the application should be able for example +to identify all packets containing VoIP traffic based on the protocol being +UDP, and a specific destination or source port numbers, and appropriately +assign these packets a class-of-service that maps to a higher priority queue, +assuring voice packets a lower and bound latency. === Packet meta data Elements diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index f513eea94..4005fad66 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -21,7 +21,6 @@ extern "C" { #include #include #include -#include /** @defgroup odp_classification ODP CLASSIFICATION * Packet input classification. @@ -578,21 +577,6 @@ typedef struct odp_cls_capability_t { } odp_cls_capability_t; -#if ODP_DEPRECATED_API - -/** - * class of service packet drop policies - * - * @deprecated Drop policy will be removed from the API. - */ -typedef enum { - ODP_COS_DROP_POOL, /**< Follow buffer pool drop policy */ - ODP_COS_DROP_NEVER, /**< Never drop, ignoring buffer pool policy */ - -} odp_cls_drop_t; - -#endif - /** * Enumeration of actions for CoS. */ @@ -682,11 +666,6 @@ typedef struct odp_cls_cos_param { */ odp_pool_t pool; -#if ODP_DEPRECATED_API - /** Drop policy associated with CoS */ - odp_cls_drop_t drop_policy; -#endif - /** Random Early Detection configuration */ odp_red_param_t red; @@ -856,67 +835,6 @@ uint32_t odp_cls_cos_num_queue(odp_cos_t cos); */ uint32_t odp_cls_cos_queues(odp_cos_t cos, odp_queue_t queue[], uint32_t num); -#if ODP_DEPRECATED_API - -/** - * Assign packet drop policy for specific class-of-service - * - * @param cos CoS handle - * @param drop_policy Desired packet drop policy for this class. - * - * @retval 0 on success - * @retval <0 on failure - * - * @note Optional. - */ -int odp_cos_drop_set(odp_cos_t cos, odp_cls_drop_t drop_policy); - -/** -* Get the drop policy configured for a specific class-of-service instance. -* -* @param cos CoS handle -* -* @retval Drop policy configured with the given class-of-service -*/ -odp_cls_drop_t odp_cos_drop(odp_cos_t cos); - -#endif - -/** - * Request to override per-port class of service based on Layer-2 priority field if present. - * - * @deprecated Use #ODP_PMR_VLAN_PCP_0 instead. - * - * @param pktio_in Ingress port identifier. - * @param num_qos Number of QoS levels, typically 8. - * @param qos_table Values of the Layer-2 QoS header field. - * @param cos_table Class-of-service assigned to each of the allowed - * Layer-2 QOS levels. - * - * @retval 0 on success - * @retval <0 on failure - */ -int ODP_DEPRECATE(odp_cos_with_l2_priority)(odp_pktio_t pktio_in, uint8_t num_qos, - uint8_t qos_table[], odp_cos_t cos_table[]); - -/** - * Request to override per-port class of service based on Layer-3 priority field if present. - * - * @deprecated Use #ODP_PMR_IP_DSCP instead. - * - * @param pktio_in Ingress port identifier. - * @param num_qos Number of allowed Layer-3 QoS levels. - * @param qos_table Values of the Layer-3 QoS header field. - * @param cos_table Class-of-service assigned to each of the allowed - * Layer-3 QOS levels. - * @param l3_preference when true, Layer-3 QoS overrides L2 QoS when present. - * - * @retval 0 on success - * @retval <0 on failure - */ -int ODP_DEPRECATE(odp_cos_with_l3_qos)(odp_pktio_t pktio_in, uint32_t num_qos, uint8_t qos_table[], - odp_cos_t cos_table[], odp_bool_t l3_preference); - /** * Get statistics for a CoS * diff --git a/platform/linux-generic/include/odp_classification_datamodel.h b/platform/linux-generic/include/odp_classification_datamodel.h index 376dbd1db..c042a5308 100644 --- a/platform/linux-generic/include/odp_classification_datamodel.h +++ b/platform/linux-generic/include/odp_classification_datamodel.h @@ -40,14 +40,6 @@ extern "C" { #define CLS_PMRTERM_MAX 8 /* Maximum PMRs attached in PKTIO Level */ #define CLS_PMR_PER_COS_MAX 8 -/* L2 Priority Bits */ -#define CLS_COS_L2_QOS_BITS 3 -/* Max L2 QoS value */ -#define CLS_COS_MAX_L2_QOS (1 << CLS_COS_L2_QOS_BITS) -/* L2 DSCP Bits */ -#define CLS_COS_L3_QOS_BITS 6 -/* Max L3 QoS Value */ -#define CLS_COS_MAX_L3_QOS (1 << CLS_COS_L3_QOS_BITS) /* Max PMR Term size */ #define MAX_PMR_TERM_SIZE 16 /* Max queue per Class of service */ @@ -145,9 +137,6 @@ typedef struct ODP_ALIGNED_CACHE cos_s { bool queue_group; odp_cls_hash_proto_t hash_proto; odp_pktin_vector_config_t vector; /* Packet vector config */ -#if ODP_DEPRECATED_API - odp_cls_drop_t drop_policy; /* Associated Drop Policy */ -#endif size_t headroom; /* Headroom for this CoS */ odp_spinlock_t lock; /* cos lock */ odp_queue_param_t queue_param; @@ -173,28 +162,6 @@ typedef struct ODP_ALIGNED_CACHE { odp_queue_t queue[CLS_QUEUE_GROUP_MAX]; } _cls_queue_grp_tbl_t; -/** -L2 QoS and CoS Map - -This structure holds the mapping between L2 QoS value and -corresponding cos_t object -**/ -typedef struct pmr_l2_cos { - odp_spinlock_t lock; /* pmr_l2_cos lock */ - cos_t *cos[CLS_COS_MAX_L2_QOS]; /* Array of CoS objects */ -} pmr_l2_cos_t; - -/** -L3 QoS and CoS Map - -This structure holds the mapping between L3 QoS value and -corresponding cos_t object -**/ -typedef struct pmr_l3_cos { - odp_spinlock_t lock; /* pmr_l3_cos lock */ - cos_t *cos[CLS_COS_MAX_L3_QOS]; /* Array of CoS objects */ -} pmr_l3_cos_t; - /** Linux Generic Classifier @@ -204,9 +171,6 @@ the classifier configuration value. typedef struct classifier { cos_t *error_cos; /* Associated Error CoS */ cos_t *default_cos; /* Associated Default CoS */ - uint32_t l3_precedence; /* L3 QoS precedence */ - pmr_l2_cos_t l2_cos_table; /* L2 QoS-CoS table map */ - pmr_l3_cos_t l3_cos_table; /* L3 Qos-CoS table map */ size_t headroom; /* Pktio Headroom */ size_t skip; /* Pktio Skip Offset */ } classifier_t; diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index eee64e78c..fe00384af 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -139,9 +139,6 @@ void odp_cls_cos_param_init(odp_cls_cos_param_t *param) param->queue = ODP_QUEUE_INVALID; param->pool = ODP_POOL_INVALID; -#if ODP_DEPRECATED_API - param->drop_policy = ODP_COS_DROP_NEVER; -#endif param->num_queue = 1; param->vector.enable = false; odp_queue_param_init(¶m->queue_param); @@ -238,9 +235,6 @@ static inline void _cls_queue_unwind(uint32_t tbl_index, uint32_t j) odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param_in) { -#if ODP_DEPRECATED_API - odp_cls_drop_t drop_policy; -#endif uint32_t i, j; odp_queue_t queue; cos_t *cos; @@ -284,10 +278,6 @@ odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param_ } } -#if ODP_DEPRECATED_API - drop_policy = param.drop_policy; -#endif - for (i = 0; i < CLS_COS_MAX_ENTRY; i++) { cos = &cos_tbl->cos_entry[i]; LOCK(&cos->lock); @@ -347,9 +337,6 @@ odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param_ cos->pool = param.pool; cos->headroom = 0; cos->valid = 1; -#if ODP_DEPRECATED_API - cos->drop_policy = drop_policy; -#endif odp_atomic_init_u32(&cos->num_rule, 0); cos->index = i; cos->vector = param.vector; @@ -548,36 +535,6 @@ uint32_t odp_cls_cos_queues(odp_cos_t cos_id, odp_queue_t queue[], return cos->num_queue; } -#if ODP_DEPRECATED_API - -int odp_cos_drop_set(odp_cos_t cos_id, odp_cls_drop_t drop_policy) -{ - cos_t *cos = get_cos_entry(cos_id); - - if (!cos) { - _ODP_ERR("Invalid odp_cos_t handle\n"); - return -1; - } - - /*Drop policy is not supported in v1.0*/ - cos->drop_policy = drop_policy; - return 0; -} - -odp_cls_drop_t odp_cos_drop(odp_cos_t cos_id) -{ - cos_t *cos = get_cos_entry(cos_id); - - if (!cos) { - _ODP_ERR("Invalid odp_cos_t handle\n"); - return -1; - } - - return cos->drop_policy; -} - -#endif - int odp_pktio_default_cos_set(odp_pktio_t pktio_in, odp_cos_t default_cos) { pktio_entry_t *entry; @@ -643,62 +600,6 @@ int odp_pktio_headroom_set(odp_pktio_t pktio_in, uint32_t headroom) return 0; } -int ODP_DEPRECATE(odp_cos_with_l2_priority)(odp_pktio_t pktio_in, uint8_t num_qos, - uint8_t qos_table[], odp_cos_t cos_table[]) -{ - pmr_l2_cos_t *l2_cos; - uint32_t i; - cos_t *cos; - pktio_entry_t *entry = get_pktio_entry(pktio_in); - - if (entry == NULL) { - _ODP_ERR("Invalid odp_pktio_t handle\n"); - return -1; - } - l2_cos = &entry->cls.l2_cos_table; - - LOCK(&l2_cos->lock); - /* Update the L2 QoS table*/ - for (i = 0; i < num_qos; i++) { - cos = get_cos_entry(cos_table[i]); - if (cos != NULL) { - if (CLS_COS_MAX_L2_QOS > qos_table[i]) - l2_cos->cos[qos_table[i]] = cos; - } - } - UNLOCK(&l2_cos->lock); - return 0; -} - -int ODP_DEPRECATE(odp_cos_with_l3_qos)(odp_pktio_t pktio_in, uint32_t num_qos, uint8_t qos_table[], - odp_cos_t cos_table[], odp_bool_t l3_preference) -{ - pmr_l3_cos_t *l3_cos; - uint32_t i; - pktio_entry_t *entry = get_pktio_entry(pktio_in); - cos_t *cos; - - if (entry == NULL) { - _ODP_ERR("Invalid odp_pktio_t handle\n"); - return -1; - } - - entry->cls.l3_precedence = l3_preference; - l3_cos = &entry->cls.l3_cos_table; - - LOCK(&l3_cos->lock); - /* Update the L3 QoS table*/ - for (i = 0; i < num_qos; i++) { - cos = get_cos_entry(cos_table[i]); - if (cos != NULL) { - if (CLS_COS_MAX_L3_QOS > qos_table[i]) - l3_cos->cos[qos_table[i]] = cos; - } - } - UNLOCK(&l3_cos->lock); - return 0; -} - static int pmr_create_term(pmr_term_value_t *value, const odp_pmr_param_t *param) { @@ -1714,17 +1615,11 @@ int _odp_pktio_classifier_init(pktio_entry_t *entry) return 0; } -static -cos_t *match_qos_cos(pktio_entry_t *entry, const uint8_t *pkt_addr, - odp_packet_hdr_t *hdr); - /** Select a CoS for the given Packet based on pktio This function will call all the PMRs associated with a pktio for a given packet and will return the matched COS object. -This function will check PMR, L2 and L3 QoS COS object associated -with the PKTIO interface. Returns the default cos if the packet does not match any PMR Returns the error_cos if the packet has an error @@ -1753,12 +1648,6 @@ static inline cos_t *cls_select_cos(pktio_entry_t *entry, return cos; } - cos = match_qos_cos(entry, pkt_addr, pkt_hdr); - if (cos) { - ODP_DBG_RAW(CLS_DBG, " QoS matched -> cos: %s(%u)\n", cos->name, cos->index); - goto done; - } - ODP_DBG_RAW(CLS_DBG, " No match -> default cos\n"); cos = cls->default_cos; @@ -1895,83 +1784,6 @@ static uint32_t packet_rss_hash(odp_packet_hdr_t *pkt_hdr, return hash; } -static -cos_t *match_qos_l3_cos(pmr_l3_cos_t *l3_cos, const uint8_t *pkt_addr, - odp_packet_hdr_t *hdr) -{ - uint8_t dscp; - cos_t *cos = NULL; - const _odp_ipv4hdr_t *ipv4; - const _odp_ipv6hdr_t *ipv6; - - if (hdr->p.input_flags.l3 && hdr->p.input_flags.ipv4) { - ipv4 = (const _odp_ipv4hdr_t *)(pkt_addr + hdr->p.l3_offset); - dscp = _ODP_IPV4HDR_DSCP(ipv4->tos); - cos = l3_cos->cos[dscp]; - } else if (hdr->p.input_flags.l3 && hdr->p.input_flags.ipv6) { - ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + hdr->p.l3_offset); - dscp = _ODP_IPV6HDR_DSCP(ipv6->ver_tc_flow); - cos = l3_cos->cos[dscp]; - } - - return cos; -} - -static -cos_t *match_qos_l2_cos(pmr_l2_cos_t *l2_cos, const uint8_t *pkt_addr, - odp_packet_hdr_t *hdr) -{ - cos_t *cos = NULL; - const _odp_ethhdr_t *eth; - const _odp_vlanhdr_t *vlan; - uint16_t qos; - - if (packet_hdr_has_l2(hdr) && hdr->p.input_flags.vlan && - packet_hdr_has_eth(hdr)) { - eth = (const _odp_ethhdr_t *)(pkt_addr + hdr->p.l2_offset); - vlan = (const _odp_vlanhdr_t *)(eth + 1); - qos = odp_be_to_cpu_16(vlan->tci); - qos = ((qos >> 13) & 0x07); - cos = l2_cos->cos[qos]; - } - return cos; -} - -/* - * Select a CoS for the given Packet based on QoS values - * This function returns the COS object matching the L2 and L3 QoS - * based on the l3_preference value of the pktio -*/ -static -cos_t *match_qos_cos(pktio_entry_t *entry, const uint8_t *pkt_addr, - odp_packet_hdr_t *hdr) -{ - classifier_t *cls = &entry->cls; - pmr_l2_cos_t *l2_cos; - pmr_l3_cos_t *l3_cos; - cos_t *cos; - - l2_cos = &cls->l2_cos_table; - l3_cos = &cls->l3_cos_table; - - if (cls->l3_precedence) { - cos = match_qos_l3_cos(l3_cos, pkt_addr, hdr); - if (cos) - return cos; - cos = match_qos_l2_cos(l2_cos, pkt_addr, hdr); - if (cos) - return cos; - } else { - cos = match_qos_l2_cos(l2_cos, pkt_addr, hdr); - if (cos) - return cos; - cos = match_qos_l3_cos(l3_cos, pkt_addr, hdr); - if (cos) - return cos; - } - return NULL; -} - uint64_t odp_cos_to_u64(odp_cos_t hdl) { return _odp_pri(hdl); diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index a328423ae..cef2158cb 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -151,8 +151,6 @@ int _odp_pktio_init_global(void) pktio_entry->handle = _odp_cast_scalar(odp_pktio_t, i + 1); odp_ticketlock_init(&pktio_entry->rxl); odp_ticketlock_init(&pktio_entry->txl); - odp_spinlock_init(&pktio_entry->cls.l2_cos_table.lock); - odp_spinlock_init(&pktio_entry->cls.l3_cos_table.lock); _odp_pktio_entry_ptr[i] = pktio_entry; } diff --git a/test/validation/api/classification/odp_classification_basic.c b/test/validation/api/classification/odp_classification_basic.c index 2eb5c86b1..9462dfde4 100644 --- a/test/validation/api/classification/odp_classification_basic.c +++ b/test/validation/api/classification/odp_classification_basic.c @@ -56,9 +56,6 @@ static void cls_create_cos(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create(NULL, &cls_param); CU_ASSERT(odp_cos_to_u64(cos) != odp_cos_to_u64(ODP_COS_INVALID)); @@ -203,9 +200,6 @@ static void cls_destroy_cos(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create(name, &cls_param); CU_ASSERT_FATAL(cos != ODP_COS_INVALID); @@ -253,9 +247,6 @@ static void cls_create_pmr_match(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create("pmr_match", &cls_param); CU_ASSERT(cos != ODP_COS_INVALID); @@ -561,9 +552,7 @@ static void cls_cos_set_queue(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif + cos_queue = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos_queue != ODP_COS_INVALID); @@ -605,9 +594,7 @@ static void cls_cos_set_pool(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif + cos = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos != ODP_COS_INVALID); @@ -625,45 +612,6 @@ static void cls_cos_set_pool(void) odp_pool_destroy(cos_pool); } -#if ODP_DEPRECATED_API - -static void cls_cos_set_drop(void) -{ - int retval; - char cosname[ODP_COS_NAME_LEN]; - odp_cos_t cos_drop; - odp_queue_t queue; - odp_pool_t pool; - odp_cls_cos_param_t cls_param; - - pool = pool_create("cls_basic_pool"); - CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); - - queue = queue_create("cls_basic_queue", true); - CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); - - sprintf(cosname, "CoSDrop"); - odp_cls_cos_param_init(&cls_param); - cls_param.pool = pool; - cls_param.queue = queue; - cls_param.drop_policy = ODP_COS_DROP_POOL; - cos_drop = odp_cls_cos_create(cosname, &cls_param); - CU_ASSERT_FATAL(cos_drop != ODP_COS_INVALID); - - retval = odp_cos_drop_set(cos_drop, ODP_COS_DROP_POOL); - CU_ASSERT(retval == 0); - CU_ASSERT(ODP_COS_DROP_POOL == odp_cos_drop(cos_drop)); - - retval = odp_cos_drop_set(cos_drop, ODP_COS_DROP_NEVER); - CU_ASSERT(retval == 0); - CU_ASSERT(ODP_COS_DROP_NEVER == odp_cos_drop(cos_drop)); - odp_cos_destroy(cos_drop); - odp_pool_destroy(pool); - odp_queue_destroy(queue); -} - -#endif - static void cls_pmr_composite_create(void) { odp_pmr_t pmr_composite; @@ -700,9 +648,6 @@ static void cls_pmr_composite_create(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create("pmr_match", &cls_param); CU_ASSERT(cos != ODP_COS_INVALID); @@ -793,9 +738,6 @@ odp_testinfo_t classification_suite_basic[] = { ODP_TEST_INFO(cls_max_pmr_from_default_drop), ODP_TEST_INFO(cls_max_pmr_from_default_enqueue), ODP_TEST_INFO(cls_cos_set_queue), -#if ODP_DEPRECATED_API - ODP_TEST_INFO(cls_cos_set_drop), -#endif ODP_TEST_INFO(cls_cos_set_pool), ODP_TEST_INFO(cls_pmr_composite_create), ODP_TEST_INFO_CONDITIONAL(cls_create_cos_with_hash_queues, check_capa_cos_hashing), diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index b88f7beca..7db0e1b5e 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -77,9 +77,6 @@ void configure_default_cos(odp_pktio_t pktio, odp_cos_t *cos, odp_cls_cos_param_init(&cls_param); cls_param.pool = default_pool; cls_param.queue = default_queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif default_cos = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT(default_cos != ODP_COS_INVALID); @@ -153,9 +150,6 @@ static void cls_pktin_classifier_flag(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT(cos != ODP_COS_INVALID); @@ -250,9 +244,6 @@ static void cls_pmr_term_tcp_dport_n(int num_pkt) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT(cos != ODP_COS_INVALID); @@ -426,9 +417,6 @@ static void test_pmr(const odp_pmr_param_t *pmr_param, odp_packet_t pkt, odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create("PMR test cos", &cls_param); CU_ASSERT_FATAL(cos != ODP_COS_INVALID); @@ -700,9 +688,6 @@ static void cls_pmr_term_dmac(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos != ODP_COS_INVALID); @@ -1041,9 +1026,6 @@ static void cls_pmr_pool_set(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos != ODP_COS_INVALID); @@ -1143,9 +1125,6 @@ static void cls_pmr_queue_set(void) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos = odp_cls_cos_create(cosname, &cls_param); CU_ASSERT_FATAL(cos != ODP_COS_INVALID); @@ -1447,9 +1426,6 @@ static void test_pmr_series(const int num_udp, int marking) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue_ip; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos_ip = odp_cls_cos_create("cos_ip", &cls_param); CU_ASSERT_FATAL(cos_ip != ODP_COS_INVALID); @@ -1491,9 +1467,6 @@ static void test_pmr_series(const int num_udp, int marking) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool; cls_param.queue = queue_udp[i]; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif cos_udp[i] = odp_cls_cos_create(name, &cls_param); CU_ASSERT_FATAL(cos_udp[i] != ODP_COS_INVALID); diff --git a/test/validation/api/classification/odp_classification_tests.c b/test/validation/api/classification/odp_classification_tests.c index 008034d9a..d81884006 100644 --- a/test/validation/api/classification/odp_classification_tests.c +++ b/test/validation/api/classification/odp_classification_tests.c @@ -20,10 +20,6 @@ static odp_pktio_t pktio_loop; static odp_pktio_capability_t pktio_capa; static odp_cls_testcase_u tc; -#ifdef ODP_DEPRECATED -static int global_num_l2_qos; -#endif - #define NUM_COS_PMR_CHAIN 2 #define NUM_COS_DEFAULT 1 #define NUM_COS_DROP 1 @@ -262,9 +258,6 @@ void configure_cls_pmr_chain(odp_bool_t enable_pktv) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool_list[CLS_PMR_CHAIN_SRC]; cls_param.queue = queue_list[CLS_PMR_CHAIN_SRC]; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif if (enable_pktv) { cls_param.vector.enable = true; @@ -294,9 +287,6 @@ void configure_cls_pmr_chain(odp_bool_t enable_pktv) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool_list[CLS_PMR_CHAIN_DST]; cls_param.queue = queue_list[CLS_PMR_CHAIN_DST]; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif if (enable_pktv) { cls_param.vector.enable = true; @@ -416,9 +406,6 @@ void configure_pktio_default_cos(odp_bool_t enable_pktv) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool_list[CLS_DEFAULT]; cls_param.queue = queue_list[CLS_DEFAULT]; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif if (enable_pktv) { cls_param.vector.enable = true; @@ -632,9 +619,6 @@ void configure_pktio_error_cos(odp_bool_t enable_pktv) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool_list[CLS_ERROR]; cls_param.queue = queue_list[CLS_ERROR]; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif if (enable_pktv) { cls_param.vector.enable = true; @@ -709,110 +693,6 @@ static void cls_pktio_set_headroom(void) CU_ASSERT(retval < 0); } -#ifdef ODP_DEPRECATED - -void configure_cos_with_l2_priority(odp_bool_t enable_pktv) -{ - uint8_t num_qos = CLS_L2_QOS_MAX; - odp_cos_t cos_tbl[CLS_L2_QOS_MAX]; - odp_queue_t queue_tbl[CLS_L2_QOS_MAX]; - odp_pool_t pool; - uint8_t qos_tbl[CLS_L2_QOS_MAX]; - char cosname[ODP_COS_NAME_LEN]; - char queuename[ODP_QUEUE_NAME_LEN]; - char poolname[ODP_POOL_NAME_LEN]; - int retval; - int i; - odp_queue_param_t qparam; - odp_cls_cos_param_t cls_param; - - /** Initialize scalar variable qos_tbl **/ - for (i = 0; i < CLS_L2_QOS_MAX; i++) - qos_tbl[i] = 0; - - if (odp_schedule_num_prio() < num_qos) - num_qos = odp_schedule_num_prio(); - - global_num_l2_qos = num_qos; - - odp_queue_param_init(&qparam); - qparam.type = ODP_QUEUE_TYPE_SCHED; - qparam.sched.sync = ODP_SCHED_SYNC_PARALLEL; - qparam.sched.group = ODP_SCHED_GROUP_ALL; - for (i = 0; i < num_qos; i++) { - qparam.sched.prio = odp_schedule_min_prio() + i; - sprintf(queuename, "%s_%d", "L2_Queue", i); - queue_tbl[i] = odp_queue_create(queuename, &qparam); - CU_ASSERT_FATAL(queue_tbl[i] != ODP_QUEUE_INVALID); - queue_list[CLS_L2_QOS_0 + i] = queue_tbl[i]; - - sprintf(poolname, "%s_%d", "L2_Pool", i); - pool = pool_create(poolname); - CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); - pool_list[CLS_L2_QOS_0 + i] = pool; - - sprintf(cosname, "%s_%d", "L2_Cos", i); - odp_cls_cos_param_init(&cls_param); - cls_param.pool = pool; - cls_param.queue = queue_tbl[i]; - cls_param.drop_policy = ODP_COS_DROP_POOL; - - if (enable_pktv) { - cls_param.vector.enable = true; - cls_param.vector.pool = pktv_config.pool; - cls_param.vector.max_size = pktv_config.max_size; - cls_param.vector.max_tmo_ns = pktv_config.max_tmo_ns; - } - - cos_tbl[i] = odp_cls_cos_create(cosname, &cls_param); - if (cos_tbl[i] == ODP_COS_INVALID) - break; - - cos_list[CLS_L2_QOS_0 + i] = cos_tbl[i]; - qos_tbl[i] = i; - } - /* count 'i' is passed instead of num_qos to handle the rare scenario - if the odp_cls_cos_create() failed in the middle*/ - retval = odp_cos_with_l2_priority(pktio_loop, i, qos_tbl, cos_tbl); - CU_ASSERT(retval == 0); -} - -void test_cos_with_l2_priority(odp_bool_t enable_pktv) -{ - odp_packet_t pkt; - odph_ethhdr_t *ethhdr; - odph_vlanhdr_t *vlan; - odp_queue_t queue; - odp_pool_t pool; - uint32_t seqno = 0; - cls_packet_info_t pkt_info; - uint8_t i; - - pkt_info = default_pkt_info; - pkt_info.l4_type = CLS_PKT_L4_UDP; - pkt_info.vlan = true; - - for (i = 0; i < global_num_l2_qos; i++) { - pkt = create_packet(pkt_info); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - seqno = cls_pkt_get_seq(pkt); - CU_ASSERT(seqno != TEST_SEQ_INVALID); - ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); - vlan = (odph_vlanhdr_t *)(ethhdr + 1); - vlan->tci = odp_cpu_to_be_16(i << 13); - enqueue_pktio_interface(pkt, pktio_loop); - pkt = receive_packet(&queue, ODP_TIME_SEC_IN_NS, enable_pktv); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(queue == queue_list[CLS_L2_QOS_0 + i]); - pool = odp_packet_pool(pkt); - CU_ASSERT(pool == pool_list[CLS_L2_QOS_0 + i]); - CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); - odp_packet_free(pkt); - } -} - -#endif - void configure_pmr_cos(odp_bool_t enable_pktv) { uint16_t val; @@ -842,9 +722,6 @@ void configure_pmr_cos(odp_bool_t enable_pktv) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool_list[CLS_PMR]; cls_param.queue = queue_list[CLS_PMR]; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif if (enable_pktv) { cls_param.vector.enable = true; @@ -927,9 +804,6 @@ void configure_pktio_pmr_composite(odp_bool_t enable_pktv) odp_cls_cos_param_init(&cls_param); cls_param.pool = pool_list[CLS_PMR_SET]; cls_param.queue = queue_list[CLS_PMR_SET]; -#if ODP_DEPRECATED_API - cls_param.drop_policy = ODP_COS_DROP_POOL; -#endif if (enable_pktv) { cls_param.vector.enable = true; @@ -1029,13 +903,6 @@ static void cls_pktio_configure_common(odp_bool_t enable_pktv) tc.pmr_chain = 1; num_cos -= NUM_COS_PMR_CHAIN; } -#ifdef ODP_DEPRECATED - if (num_cos >= NUM_COS_L2_PRIO && TEST_L2_QOS) { - configure_cos_with_l2_priority(enable_pktv); - tc.l2_priority = 1; - num_cos -= NUM_COS_L2_PRIO; - } -#endif if (num_cos >= NUM_COS_PMR && TEST_PMR) { configure_pmr_cos(enable_pktv); tc.pmr_cos = 1; @@ -1070,10 +937,6 @@ static void cls_pktio_test_common(odp_bool_t enable_pktv) test_pktio_error_cos(enable_pktv); if (tc.pmr_chain && TEST_PMR_CHAIN) test_cls_pmr_chain(enable_pktv); -#ifdef ODP_DEPRECATED - if (tc.l2_priority && TEST_L2_QOS) - test_cos_with_l2_priority(enable_pktv); -#endif if (tc.pmr_cos && TEST_PMR) test_pmr_cos(enable_pktv); if (tc.pmr_composite_cos && TEST_PMR_SET) diff --git a/test/validation/api/classification/odp_classification_testsuites.h b/test/validation/api/classification/odp_classification_testsuites.h index 06e98d4cb..888613b1f 100644 --- a/test/validation/api/classification/odp_classification_testsuites.h +++ b/test/validation/api/classification/odp_classification_testsuites.h @@ -40,9 +40,6 @@ typedef union odp_cls_testcase { uint32_t drop_cos:1; uint32_t error_cos:1; uint32_t pmr_chain:1; -#ifdef ODP_DEPRECATED - uint32_t l2_priority:1; -#endif uint32_t pmr_cos:1; uint32_t pmr_composite_cos:1; }; -- cgit v1.2.3 From ccfed00dfff1178b8958ea6a165491d25ba29a4a Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 14 Nov 2023 13:44:11 +0000 Subject: api: crypto: remove deprecated items Remove deprecated items: - `ODP_CRYPTO_SES_CREATE_ERR_NONE`, `ODP_CRYPTO_SES_CREATE_ERR_ENOMEM`, `ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER` and `ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH` session creation error constants - `odp_crypto_alg_err_t.ODP_CRYPTO_ALG_ERR_KEY_SIZE` and `odp_crypto_alg_err_t.ODP_CRYPTO_ALG_ERR_IV_INVALID` error constants - `odp_crypto_hw_err_t` type - `odp_crypto_packet_result_t.ok` field Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- include/odp/api/spec/crypto.h | 1 - include/odp/api/spec/crypto_types.h | 37 ---------------------- .../include/odp/api/plat/crypto_inlines.h | 8 +---- test/validation/api/crypto/crypto_op_test.c | 4 --- 4 files changed, 1 insertion(+), 49 deletions(-) diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index e0e232dbe..49bc29ee4 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -14,7 +14,6 @@ #include #include -#include #include #include diff --git a/include/odp/api/spec/crypto_types.h b/include/odp/api/spec/crypto_types.h index 7752f1957..31214c0e9 100644 --- a/include/odp/api/spec/crypto_types.h +++ b/include/odp/api/spec/crypto_types.h @@ -12,7 +12,6 @@ #define ODP_API_SPEC_CRYPTO_TYPES_H_ #include -#include #include #include #include @@ -880,17 +879,6 @@ typedef enum { ODP_CRYPTO_SES_ERR_PARAMS, } odp_crypto_ses_create_err_t; -#if ODP_DEPRECATED_API -/** This synonym for backward compatibility has been deprecated */ -#define ODP_CRYPTO_SES_CREATE_ERR_NONE ODP_CRYPTO_SES_ERR_NONE -/** This synonym for backward compatibility has been deprecated */ -#define ODP_CRYPTO_SES_CREATE_ERR_ENOMEM ODP_CRYPTO_SES_ERR_ENOMEM -/** This synonym for backward compatibility has been deprecated */ -#define ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER ODP_CRYPTO_SES_ERR_CIPHER -/** This synonym for backward compatibility has been deprecated */ -#define ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH ODP_CRYPTO_SES_ERR_AUTH -#endif - /** * Crypto API algorithm return code */ @@ -899,49 +887,24 @@ typedef enum { ODP_CRYPTO_ALG_ERR_NONE, /** Invalid range or packet size */ ODP_CRYPTO_ALG_ERR_DATA_SIZE, - /** Key size invalid for algorithm */ - ODP_DEPRECATE(ODP_CRYPTO_ALG_ERR_KEY_SIZE), /** Computed ICV value mismatch */ ODP_CRYPTO_ALG_ERR_ICV_CHECK, - /** IV value not specified */ - ODP_DEPRECATE(ODP_CRYPTO_ALG_ERR_IV_INVALID), /** Other error */ ODP_CRYPTO_ALG_ERR_OTHER, } odp_crypto_alg_err_t; -/** - * Crypto API hardware centric return code - */ -typedef enum { - /** Operation completed successfully */ - ODP_DEPRECATE(ODP_CRYPTO_HW_ERR_NONE), - /** Error detected during DMA of data */ - ODP_DEPRECATE(ODP_CRYPTO_HW_ERR_DMA), - /** Operation failed due to pool depletion */ - ODP_DEPRECATE(ODP_CRYPTO_HW_ERR_BP_DEPLETED), -} ODP_DEPRECATE(odp_crypto_hw_err_t); - /** * Crypto API per packet operation completion status */ typedef struct odp_crypto_op_status { /** Algorithm specific return code */ odp_crypto_alg_err_t alg_err; - - /** Hardware specific return code */ - ODP_DEPRECATE(odp_crypto_hw_err_t) ODP_DEPRECATE(hw_err); } odp_crypto_op_status_t; /** * Crypto packet API operation result */ typedef struct odp_crypto_packet_result_t { - /** Request completed successfully. - * - * @deprecated Check the return value of odp_crypto_result() instead. - */ - odp_bool_t ODP_DEPRECATE(ok); - /** Input packet passed to odp_crypo_op_enq() when the operation * type of the session is ODP_CRYPTO_OP_TYPE_OOP. In other cases * this field does not have a valid value. diff --git a/platform/linux-generic/include/odp/api/plat/crypto_inlines.h b/platform/linux-generic/include/odp/api/plat/crypto_inlines.h index ddf7debf4..f350edfea 100644 --- a/platform/linux-generic/include/odp/api/plat/crypto_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/crypto_inlines.h @@ -55,14 +55,8 @@ _ODP_INLINE int odp_crypto_result(odp_crypto_packet_result_t *result, odp_packet ok = op_result->cipher_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE && op_result->auth_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE; - if (result) { + if (result) *result = *op_result; -#if ODP_DEPRECATED_API - result->ok = ok; - result->cipher_status.hw_err = ODP_CRYPTO_HW_ERR_NONE; - result->auth_status.hw_err = ODP_CRYPTO_HW_ERR_NONE; -#endif - } return ok ? 0 : -1; } diff --git a/test/validation/api/crypto/crypto_op_test.c b/test/validation/api/crypto/crypto_op_test.c index 9e8ab0584..1c6944fdf 100644 --- a/test/validation/api/crypto/crypto_op_test.c +++ b/test/validation/api/crypto/crypto_op_test.c @@ -115,10 +115,6 @@ int crypto_op(odp_packet_t pkt_in, *ok = (rc == 0); -#if ODP_DEPRECATED_API - CU_ASSERT(*ok == result.ok); -#endif - return 0; fail: odp_packet_free(pkt_in); -- cgit v1.2.3 From 87ad6089ddc891eea5dfeaa8550d8c214353f422 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 14 Nov 2023 13:45:09 +0000 Subject: api: sched: remove deprecated items Remove deprecated `ODP_SCHED_PRIO_HIGHEST`, `ODP_SCHED_PRIO_NORMAL`, `ODP_SCHED_PRIO_LOWEST` and `ODP_SCHED_PRIO_DEFAULT` scheduling priority constants. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- include/odp/api/abi-default/schedule_types.h | 21 ------------------- include/odp/api/spec/schedule_types.h | 24 ---------------------- .../linux-generic/include/odp_schedule_scalable.h | 8 ++++---- 3 files changed, 4 insertions(+), 49 deletions(-) diff --git a/include/odp/api/abi-default/schedule_types.h b/include/odp/api/abi-default/schedule_types.h index 45366ffa6..eeb18771e 100644 --- a/include/odp/api/abi-default/schedule_types.h +++ b/include/odp/api/abi-default/schedule_types.h @@ -15,7 +15,6 @@ extern "C" { #endif -#include #include /** @addtogroup odp_scheduler @@ -27,26 +26,6 @@ extern "C" { #define ODP_SCHED_GROUP_NAME_LEN 32 -#if ODP_DEPRECATED_API -#define ODP_SCHED_PRIO_HIGHEST (odp_schedule_max_prio()) - -#define ODP_SCHED_PRIO_NORMAL (odp_schedule_default_prio()) - -#define ODP_SCHED_PRIO_LOWEST (odp_schedule_min_prio()) - -#define ODP_SCHED_PRIO_DEFAULT (odp_schedule_default_prio()) -#else -/* Required to prevent Doxygen warning */ -#define ODP_SCHED_PRIO_HIGHEST -#define ODP_SCHED_PRIO_NORMAL -#define ODP_SCHED_PRIO_LOWEST -#define ODP_SCHED_PRIO_DEFAULT -#undef ODP_SCHED_PRIO_HIGHEST -#undef ODP_SCHED_PRIO_NORMAL -#undef ODP_SCHED_PRIO_LOWEST -#undef ODP_SCHED_PRIO_DEFAULT -#endif - typedef int odp_schedule_sync_t; #define ODP_SCHED_SYNC_PARALLEL 0 diff --git a/include/odp/api/spec/schedule_types.h b/include/odp/api/spec/schedule_types.h index 5e2f5a2da..3cca665c1 100644 --- a/include/odp/api/spec/schedule_types.h +++ b/include/odp/api/spec/schedule_types.h @@ -38,30 +38,6 @@ extern "C" { * Maximum schedule group name length in chars including null char */ -/** - * @def ODP_SCHED_PRIO_HIGHEST - * @deprecated This macro is equivalent of calling odp_schedule_max_prio(). Use - * direct function call instead. - */ - -/** - * @def ODP_SCHED_PRIO_NORMAL - * @deprecated This macro is equivalent of calling odp_schedule_default_prio(). - * Use direct function call instead. - */ - -/** - * @def ODP_SCHED_PRIO_LOWEST - * @deprecated This macro is equivalent of calling odp_schedule_min_prio(). Use - * direct function call instead. - */ - -/** - * @def ODP_SCHED_PRIO_DEFAULT - * @deprecated This macro is equivalent of calling odp_schedule_default_prio(). - * Use direct function call instead. - */ - /** * @typedef odp_schedule_sync_t * Scheduler synchronization method diff --git a/platform/linux-generic/include/odp_schedule_scalable.h b/platform/linux-generic/include/odp_schedule_scalable.h index 207573f4c..28c0a9894 100644 --- a/platform/linux-generic/include/odp_schedule_scalable.h +++ b/platform/linux-generic/include/odp_schedule_scalable.h @@ -19,10 +19,10 @@ #include /* - * ODP_SCHED_PRIO_HIGHEST/NORMAL/LOWEST/DEFAULT are compile time - * constants, but not ODP_SCHED_PRIO_NUM. The current API for this - * is odp_schedule_num_prio(). The other schedulers also define - * this internally as NUM_PRIO. + * Define scalable scheduler internal maximum priority count + * ODP_SCHED_PRIO_NUM as it is not compile-time constant at API + * level. The current API for this is odp_schedule_num_prio(). + * The other schedulers also define this internally as NUM_PRIO. * * One additional priority level for idle pktin queues. * This is only for internal use and not visible to the user. -- cgit v1.2.3 From d6155899abd310f5ab8f3a35d3e1c6ba86e00614 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 14 Nov 2023 13:46:02 +0000 Subject: api: timer: remove deprecated items Remove deprecated items: - `ODP_CLOCK_CPU` and `ODP_CLOCK_EXT` clock source constants - `ODP_TIMER_TOOEARLY`, `ODP_TIMER_TOOLATE` and `ODP_TIMER_NOEVENT` error constants - `odp_timer_set_abs()` and `odp_timer_set_rel()` functions Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- include/odp/api/spec/timer.h | 66 -------------------------------------- include/odp/api/spec/timer_types.h | 40 ----------------------- platform/linux-generic/odp_timer.c | 34 -------------------- test/validation/api/timer/timer.c | 4 --- 4 files changed, 144 deletions(-) diff --git a/include/odp/api/spec/timer.h b/include/odp/api/spec/timer.h index c42c5cf5e..ad27b5ded 100644 --- a/include/odp/api/spec/timer.h +++ b/include/odp/api/spec/timer.h @@ -17,7 +17,6 @@ extern "C" { #endif -#include #include #include #include @@ -388,71 +387,6 @@ int odp_timer_periodic_ack(odp_timer_t timer, odp_event_t tmo_ev); */ int odp_timer_periodic_cancel(odp_timer_t timer); -/** - * Set (or reset) a timer with absolute expiration time - * - * This function sets a timer to expire at a specific time. If the timer is - * already running (set and not yet expired), the function updates (resets) it - * with a new expiration time and optionally with a new event. A successful - * reset operation with a new event outputs the old event. A failed reset - * operation does not modify the timer. - * - * The user provided event can be of any event type, but only ODP_EVENT_TIMEOUT - * type events (odp_timeout_t) carry timeout specific metadata. Furthermore, - * timer performance may have been optimized for that event type. When the timer - * expires, the event is enqueued to the destination queue of the timer. - * - * @param timer Timer - * @param abs_tick Absolute expiration time in timer ticks - * @param[in,out] tmo_ev Pointer to an event handle. The event is enqueued - * when the timer expires. Use NULL when resetting the - * timer without changing the event. When resetting the - * timer with a new event, a successful operation - * outputs the old event here. - * - * @retval ODP_TIMER_SUCCESS Success - * @retval ODP_TIMER_TOO_NEAR Failure. Expiration time is too near to - * the current time. - * @retval ODP_TIMER_TOO_FAR Failure. Expiration time is too far from - * the current time. - * @retval ODP_TIMER_FAIL Failure. Set operation: No event provided. - * Reset operation: Too late to reset the timer. - * - * @see odp_timer_set_rel(), odp_timer_alloc(), odp_timer_cancel() - * - * @deprecated Use odp_timer_start() or odp_timer_restart() instead - */ -int ODP_DEPRECATE(odp_timer_set_abs)(odp_timer_t timer, uint64_t abs_tick, odp_event_t *tmo_ev); - -/** - * Set (or reset) a timer with relative expiration time - * - * Like odp_timer_set_abs(), but the expiration time is relative to the current - * time: expiration tick = odp_timer_current_tick() + 'rel_tick'. - * - * @param timer Timer - * @param rel_tick Expiration time relative to current time of - * the timer pool in timer ticks - * @param[in,out] tmo_ev Pointer to an event handle. The event is enqueued - * when the timer expires. Use NULL when resetting the - * timer without changing the event. When resetting the - * timer with a new event, a successful operation - * outputs the old event here. - * - * @retval ODP_TIMER_SUCCESS Success - * @retval ODP_TIMER_TOO_NEAR Failure. Expiration time is too near to - * the current time. - * @retval ODP_TIMER_TOO_FAR Failure. Expiration time is too far from - * the current time. - * @retval ODP_TIMER_FAIL Failure. Set operation: No event provided. - * Reset operation: Too late to reset the timer. - * - * @see odp_timer_set_abs(), odp_timer_alloc(), odp_timer_cancel() - * - * @deprecated Use odp_timer_start() or odp_timer_restart() instead - */ -int ODP_DEPRECATE(odp_timer_set_rel)(odp_timer_t timer, uint64_t rel_tick, odp_event_t *tmo_ev); - /** * Cancel a timer * diff --git a/include/odp/api/spec/timer_types.h b/include/odp/api/spec/timer_types.h index 0fd5d4f70..3fb656aa5 100644 --- a/include/odp/api/spec/timer_types.h +++ b/include/odp/api/spec/timer_types.h @@ -17,7 +17,6 @@ extern "C" { #endif -#include #include #include @@ -251,22 +250,6 @@ typedef enum { /** The default clock source */ #define ODP_CLOCK_DEFAULT ODP_CLOCK_SRC_0 -#if ODP_DEPRECATED_API -/** - * For backwards compatibility, ODP_CLOCK_CPU is synonym of ODP_CLOCK_DEFAULT. - * - * @deprecated Use #ODP_CLOCK_DEFAULT instead. - */ -#define ODP_CLOCK_CPU ODP_CLOCK_DEFAULT - -/** - * For backwards compatibility, ODP_CLOCK_EXT is synonym of ODP_CLOCK_SRC_1. - * - * @deprecated Use #ODP_CLOCK_SRC_1 instead. - */ -#define ODP_CLOCK_EXT ODP_CLOCK_SRC_1 -#endif - /** * Timer expiration mode * @@ -555,29 +538,6 @@ typedef enum { */ typedef odp_timer_retval_t odp_timer_set_t; -#if ODP_DEPRECATED_API -/** - * For backwards compatibility, ODP_TIMER_TOOEARLY is synonym of ODP_TIMER_TOO_NEAR. - * - * @deprecated Use #ODP_TIMER_TOO_NEAR instead. - */ -#define ODP_TIMER_TOOEARLY ODP_TIMER_TOO_NEAR - -/** - * For backwards compatibility, ODP_TIMER_TOOLATE is synonym of ODP_TIMER_TOO_FAR. - * - * @deprecated Use #ODP_TIMER_TOO_FAR instead. - */ -#define ODP_TIMER_TOOLATE ODP_TIMER_TOO_FAR - -/** - * For backwards compatibility, ODP_TIMER_NOEVENT is synonym of ODP_TIMER_FAIL. - * - * @deprecated Use #ODP_TIMER_FAIL instead. - */ -#define ODP_TIMER_NOEVENT ODP_TIMER_FAIL -#endif - /** * Timer tick information */ diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 986875c6f..ccc716652 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -1537,39 +1536,6 @@ odp_event_t odp_timer_free(odp_timer_t hdl) return timer_free(tp, idx); } -int ODP_DEPRECATE(odp_timer_set_abs)(odp_timer_t hdl, uint64_t abs_tck, odp_event_t *tmo_ev) -{ - timer_pool_t *tp = handle_to_tp(hdl); - uint64_t cur_tick = odp_time_global_ns(); - uint32_t idx = handle_to_idx(hdl, tp); - - if (odp_unlikely(abs_tck < cur_tick + tp->min_rel_tck)) - return ODP_TIMER_TOO_NEAR; - if (odp_unlikely(abs_tck > cur_tick + tp->max_rel_tck)) - return ODP_TIMER_TOO_FAR; - if (timer_reset(idx, abs_tck, tmo_ev, tp)) - return ODP_TIMER_SUCCESS; - else - return ODP_TIMER_FAIL; -} - -int ODP_DEPRECATE(odp_timer_set_rel)(odp_timer_t hdl, uint64_t rel_tck, odp_event_t *tmo_ev) -{ - timer_pool_t *tp = handle_to_tp(hdl); - uint64_t cur_tick = odp_time_global_ns(); - uint64_t abs_tck = cur_tick + rel_tck; - uint32_t idx = handle_to_idx(hdl, tp); - - if (odp_unlikely(rel_tck < tp->min_rel_tck)) - return ODP_TIMER_TOO_NEAR; - if (odp_unlikely(rel_tck > tp->max_rel_tck)) - return ODP_TIMER_TOO_FAR; - if (timer_reset(idx, abs_tck, tmo_ev, tp)) - return ODP_TIMER_SUCCESS; - else - return ODP_TIMER_FAIL; -} - int odp_timer_start(odp_timer_t timer, const odp_timer_start_t *start_param) { uint64_t abs_tick, rel_tick; diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c index d5af76c50..a29fa2de8 100644 --- a/test/validation/api/timer/timer.c +++ b/test/validation/api/timer/timer.c @@ -372,10 +372,6 @@ static void timer_test_capa_allsrc(void) CU_ASSERT_FATAL(ODP_CLOCK_SRC_0 + 4 == ODP_CLOCK_SRC_4); CU_ASSERT_FATAL(ODP_CLOCK_SRC_0 + 5 == ODP_CLOCK_SRC_5); CU_ASSERT_FATAL(ODP_CLOCK_SRC_5 + 1 == ODP_CLOCK_NUM_SRC); -#if ODP_DEPRECATED_API - CU_ASSERT_FATAL(ODP_CLOCK_CPU == ODP_CLOCK_DEFAULT); - CU_ASSERT_FATAL(ODP_CLOCK_EXT == ODP_CLOCK_SRC_1); -#endif CU_ASSERT(odp_timer_capability(ODP_CLOCK_DEFAULT, &capa) == 0); -- cgit v1.2.3 From a2237d7c49d41388db5e343c4830f785a7c6cd52 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 14 Nov 2023 13:47:37 +0000 Subject: abi: event: remove unnecessary header Remove unnecessary `` include. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- include/odp/api/abi-default/event_types.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/odp/api/abi-default/event_types.h b/include/odp/api/abi-default/event_types.h index 7955e53b8..d6231a98f 100644 --- a/include/odp/api/abi-default/event_types.h +++ b/include/odp/api/abi-default/event_types.h @@ -11,7 +11,6 @@ extern "C" { #endif #include -#include /** @internal Dummy type for strong typing */ typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_event_t; -- cgit v1.2.3 From 2e3809b7d365e3f3e3fa69c514102d11d1668a0f Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 14 Nov 2023 13:48:15 +0000 Subject: helper: threads: remove deprecated items Remove deprecated items: - `odph_odpthread_t` and `odph_odpthread_params_t` types - `odph_thread_param_t.instance` field - `odph_odpthreads_create()` and `odph_odpthreads_join()` functions Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- helper/include/odp/helper/threads.h | 68 +++---------------- helper/threads.c | 127 +----------------------------------- 2 files changed, 11 insertions(+), 184 deletions(-) diff --git a/helper/include/odp/helper/threads.h b/helper/include/odp/helper/threads.h index 358543c85..c18a46e8a 100644 --- a/helper/include/odp/helper/threads.h +++ b/helper/include/odp/helper/threads.h @@ -21,7 +21,6 @@ extern "C" { #endif -#include #include #include @@ -70,13 +69,7 @@ typedef struct { /** ODP thread type */ odp_thread_type_t thr_type; - /** @deprecated ODP instance handle for odph_odpthreads_create(). */ - odp_instance_t ODPH_DEPRECATE(instance); - - /** - * Minimum stack size in bytes. 0 = use default. Ignored by - * odph_odpthreads_create(). - */ + /** Minimum stack size in bytes. 0 = use default. */ uint64_t stack_size; } odph_thread_param_t; @@ -134,12 +127,6 @@ typedef struct { odp_mem_model_t mem_model; /**< Process or thread */ } odph_helper_options_t; -/** @deprecated Legacy thread table entry */ -typedef odph_thread_t ODPH_DEPRECATE(odph_odpthread_t); - -/** @deprecated Legacy thread parameters */ -typedef odph_thread_param_t ODPH_DEPRECATE(odph_odpthread_params_t); - /** Common parameters for odph_thread_create() call */ typedef struct { /** @@ -226,12 +213,11 @@ void odph_thread_common_param_init(odph_thread_common_param_t *param); /** * Create and pin threads (as Linux pthreads or processes) * - * This is an updated version of odph_odpthreads_create() call. It may be called - * multiple times to create threads in steps. Each call launches 'num' threads - * and pins those to separate CPUs based on the cpumask. Use 'thread_model' - * parameter to select if Linux pthreads or processes are used. This selection - * may be overridden with ODP helper options. See e.g. --odph_proc under - * odph_options() documentation. + * Function may be called multiple times to create threads in steps. Each call + * launches 'num' threads and pins those to separate CPUs based on the cpumask. + * Use 'thread_model' parameter to select if Linux pthreads or processes are + * used. This selection may be overridden with ODP helper options. See e.g. + * --odph_proc under odph_options() documentation. * * Thread creation may be synchronized by setting 'sync' parameter. It * serializes thread start up (odp_init_local() calls), which helps to @@ -270,11 +256,10 @@ int odph_thread_create(odph_thread_t thread[], /** * Wait previously launched threads to exit * - * This is an updated version of odph_odpthreads_join() call. It waits for - * threads launched with odph_thread_create() to exit. Threads may be waited to - * exit in a different order than those were created. A function call may be - * used to wait any number of launched threads to exit. A particular thread - * may be waited only once. + * Function waits for threads launched with odph_thread_create() to exit. + * Threads may be waited to exit in a different order than those were created. + * A function call may be used to wait any number of launched threads to exit. + * A particular thread may be waited only once. * * @param thread Table of threads to exit * @param num Number of threads to exit @@ -286,39 +271,6 @@ int odph_thread_create(odph_thread_t thread[], */ int odph_thread_join(odph_thread_t thread[], int num); -/** - * Creates and launches odpthreads (as linux threads or processes) - * - * Creates, pins and launches threads to separate CPU's based on the cpumask. - * - * @param thread_tbl Thread table - * @param mask CPU mask - * @param thr_params ODP thread parameters - * - * @return Number of threads created - * - * @deprecated Use odph_thread_create() instead. - */ -int ODPH_DEPRECATE(odph_odpthreads_create)( - ODPH_DEPRECATE(odph_odpthread_t) *thread_tbl, - const odp_cpumask_t *mask, - const ODPH_DEPRECATE(odph_odpthread_params_t) *thr_params); - -/** - * Waits odpthreads (as linux threads or processes) to exit. - * - * Returns when all odpthreads have terminated. - * - * @param thread_tbl Thread table - * @return The number of joined threads or -1 on error. - * (error occurs if any of the start_routine return non-zero or if - * the thread join/process wait itself failed -e.g. as the result of a kill) - * - * @deprecated Use odph_thread_join() instead. - */ -int ODPH_DEPRECATE(odph_odpthreads_join)( - ODPH_DEPRECATE(odph_odpthread_t) *thread_tbl); - /** * Set CPU affinity of the current odp thread * diff --git a/helper/threads.c b/helper/threads.c index 63b4cc019..72003d0f4 100644 --- a/helper/threads.c +++ b/helper/threads.c @@ -42,8 +42,7 @@ static void *run_thread(void *arg) int status; int ret; odp_instance_t instance; - ODPH_DEPRECATE(odph_odpthread_params_t) *thr_params; - + odph_thread_param_t *thr_params; odph_thread_start_args_t *start_args = arg; thr_params = &start_args->thr_params; @@ -408,130 +407,6 @@ int odph_thread_join(odph_thread_t thread[], int num) return i; } -/* - * create an odpthread set (as linux processes or linux threads or both) - */ -int ODPH_DEPRECATE(odph_odpthreads_create)( - ODPH_DEPRECATE(odph_odpthread_t) *thread_tbl, - const odp_cpumask_t *mask, - const ODPH_DEPRECATE(odph_odpthread_params_t) *thr_params) -{ - int i; - int num; - int cpu_count; - int cpu; - - num = odp_cpumask_count(mask); - - memset(thread_tbl, 0, num * sizeof(*thread_tbl)); - - cpu_count = odp_cpu_count(); - - if (num < 1 || num > cpu_count) { - ODPH_ERR("Invalid number of odpthreads:%d" - " (%d cores available)\n", - num, cpu_count); - return -1; - } - - cpu = odp_cpumask_first(mask); - for (i = 0; i < num; i++) { - odph_thread_start_args_t *start_args; - - start_args = &thread_tbl[i].start_args; - - /* Copy thread parameters */ - start_args->thr_params = *thr_params; - start_args->instance = thr_params->ODPH_DEPRECATE(instance); - - if (helper_options.mem_model == ODP_MEM_MODEL_THREAD) { - if (create_pthread(&thread_tbl[i], cpu, 0)) - break; - } else { - if (create_process(&thread_tbl[i], cpu, 0)) - break; - } - - cpu = odp_cpumask_next(mask, cpu); - } - thread_tbl[num - 1].last = 1; - - return i; -} - -/* - * wait for the odpthreads termination (linux processes and threads) - */ -int ODPH_DEPRECATE(odph_odpthreads_join)( - ODPH_DEPRECATE(odph_odpthread_t) *thread_tbl) -{ - pid_t pid; - int i = 0; - int terminated = 0; - /* child process return code (!=0 is error) */ - int status = 0; - /* "child" thread return code (!NULL is error) */ - void *thread_ret = NULL; - int ret; - int retval = 0; - - /* joins linux threads or wait for processes */ - do { - if (thread_tbl[i].cpu == FAILED_CPU) { - ODPH_DBG("ODP thread %d not started.\n", i); - continue; - } - /* pthreads: */ - if (thread_tbl[i].start_args.mem_model == - ODP_MEM_MODEL_THREAD) { - /* Wait thread to exit */ - ret = pthread_join(thread_tbl[i].thread.thread_id, - &thread_ret); - if (ret != 0) { - ODPH_ERR("Failed to join thread from cpu #%d\n", - thread_tbl[i].cpu); - retval = -1; - } else { - terminated++; - if (thread_ret != NULL) { - ODPH_ERR("Bad exit status cpu #%d %p\n", - thread_tbl[i].cpu, thread_ret); - retval = -1; - } - } - pthread_attr_destroy(&thread_tbl[i].thread.attr); - } else { - /* processes: */ - pid = waitpid(thread_tbl[i].proc.pid, &status, 0); - - if (pid < 0) { - ODPH_ERR("waitpid() failed\n"); - retval = -1; - break; - } - - terminated++; - - /* Examine the child process' termination status */ - if (WIFEXITED(status) && - WEXITSTATUS(status) != EXIT_SUCCESS) { - ODPH_ERR("Child exit status:%d (pid:%d)\n", - WEXITSTATUS(status), (int)pid); - retval = -1; - } - if (WIFSIGNALED(status)) { - int signo = WTERMSIG(status); - - ODPH_ERR("Child term signo:%d - %s (pid:%d)\n", - signo, strsignal(signo), (int)pid); - retval = -1; - } - } - } while (!thread_tbl[i++].last); - - return (retval < 0) ? retval : terminated; -} - /* man gettid() notes: * Glibc does not provide a wrapper for this system call; */ -- cgit v1.2.3 From 8dd73b9d5ec35638b1d6b08e3cbf9842789d9429 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 14 Nov 2023 13:54:32 +0000 Subject: linux-gen: event: remove unnecessary header Remove unnecessary `` include. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- platform/linux-generic/include-abi/odp/api/abi/event_types.h | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/linux-generic/include-abi/odp/api/abi/event_types.h b/platform/linux-generic/include-abi/odp/api/abi/event_types.h index 7eb539827..8ff5acd6b 100644 --- a/platform/linux-generic/include-abi/odp/api/abi/event_types.h +++ b/platform/linux-generic/include-abi/odp/api/abi/event_types.h @@ -19,7 +19,6 @@ extern "C" { #endif #include -#include /** @ingroup odp_event * @{ -- cgit v1.2.3 From 988f0b5812d70a415d1c6fdd940c6414aec08272 Mon Sep 17 00:00:00 2001 From: Janne Peltonen Date: Mon, 11 Dec 2023 09:37:57 +0200 Subject: api: hints: fix type conversion problem in odp_unlikely() Convert the argument of odp_unlikely() to boolean before passing it to __builtin_expect() which takes a long int argument. This prevents implementation-defined behaviour when the argument of odp_unlikely() does not fit in a long int. In certain systems with 32-bit long, odp_unlikely() currently turns certain non-zero 64-bit values to zero, breaking the code that is using odp_unlikely(). Signed-off-by: Janne Peltonen Reviewed-by: Matias Elo --- include/odp/api/spec/hints.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/odp/api/spec/hints.h b/include/odp/api/spec/hints.h index 032b483df..fa5b1b9bb 100644 --- a/include/odp/api/spec/hints.h +++ b/include/odp/api/spec/hints.h @@ -61,7 +61,7 @@ extern "C" { /** * Branch unlikely taken */ -#define odp_unlikely(x) __builtin_expect((x), 0) +#define odp_unlikely(x) __builtin_expect(!!(x), 0) /* * __builtin_prefetch (const void *addr, rw, locality) -- cgit v1.2.3 From 66629a6516517936bac3f417bed2c4517268bbef Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Thu, 16 Nov 2023 12:23:10 +0000 Subject: api: timer: explicitly deprecate odp_timer_set_t Explicitly deprecate `odp_timer_set_t` with `ODP_DEPRECATE()` macro. Signed-off-by: Tuomas Taipale Reviewed-by: Petri Savolainen --- include/odp/api/spec/timer_types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/odp/api/spec/timer_types.h b/include/odp/api/spec/timer_types.h index 3fb656aa5..7db57c340 100644 --- a/include/odp/api/spec/timer_types.h +++ b/include/odp/api/spec/timer_types.h @@ -17,6 +17,7 @@ extern "C" { #endif +#include #include #include @@ -536,7 +537,7 @@ typedef enum { * * @deprecated Use odp_timer_retval_t instead. */ -typedef odp_timer_retval_t odp_timer_set_t; +typedef odp_timer_retval_t ODP_DEPRECATE(odp_timer_set_t); /** * Timer tick information -- cgit v1.2.3 From b600f956e1047702c13887db08ea2da529519041 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 8 Nov 2023 13:22:55 +0200 Subject: api: event: add odp_event_pool() function Add odp_event_pool() function, which returns a handle to the pool where the event was allocated from. If the underlying event type does not have API for returning pool handle (e.g. ODP_EVENT_IPSEC_STATUS), ODP_POOL_INVALID is returned. Signed-off-by: Matias Elo Acked-by: Ashwin Sekhar T K Reviewed-by: Tuomas Taipale --- include/odp/api/spec/event.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/odp/api/spec/event.h b/include/odp/api/spec/event.h index a8737d3a5..220c955c3 100644 --- a/include/odp/api/spec/event.h +++ b/include/odp/api/spec/event.h @@ -19,6 +19,7 @@ extern "C" { #include #include +#include /** @defgroup odp_event ODP EVENT * Generic event metadata and operations. @@ -93,6 +94,19 @@ void odp_event_types_multi(const odp_event_t event[], odp_event_type_t type[], int odp_event_type_multi(const odp_event_t event[], int num, odp_event_type_t *type); +/** + * Event pool + * + * Returns handle to the pool where the event was allocated from. If the + * underlying event type does not have an API for returning pool handle + * (e.g. ODP_EVENT_IPSEC_STATUS), ODP_POOL_INVALID is returned. + * + * @param event Event handle + * + * @return Pool handle or ODP_POOL_INVALID depending on event type + */ +odp_pool_t odp_event_pool(odp_event_t event); + /** * Event user area * -- cgit v1.2.3 From 695cccb682bab20d26ea3e358d1772fa17ce9a09 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 8 Nov 2023 14:03:08 +0200 Subject: linux-gen: event: implement odp_event_pool() Implement new odp_event_pool() function. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- .../linux-generic/include/odp/api/plat/event_inlines.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/platform/linux-generic/include/odp/api/plat/event_inlines.h b/platform/linux-generic/include/odp/api/plat/event_inlines.h index 2e7c7db5e..b68ced244 100644 --- a/platform/linux-generic/include/odp/api/plat/event_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/event_inlines.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,7 @@ #define _ODP_INLINE static inline #define odp_event_type __odp_event_type #define odp_event_type_multi __odp_event_type_multi + #define odp_event_pool __odp_event_pool #define odp_event_user_area __odp_event_user_area #define odp_event_user_area_and_flag __odp_event_user_area_and_flag #define odp_event_subtype __odp_event_subtype @@ -68,6 +70,20 @@ _ODP_INLINE int odp_event_type_multi(const odp_event_t event[], int num, return i; } +_ODP_INLINE odp_pool_t odp_event_pool(odp_event_t event) +{ + const odp_event_type_t type = __odp_event_type_get(event); + + switch (type) { + case ODP_EVENT_BUFFER: + case ODP_EVENT_PACKET: + case ODP_EVENT_PACKET_VECTOR: + return _odp_event_hdr_field(event, odp_pool_t, pool); + default: + return ODP_POOL_INVALID; + } +} + _ODP_INLINE void *odp_event_user_area(odp_event_t event) { const odp_event_type_t type = __odp_event_type_get(event); -- cgit v1.2.3 From 026f78ee88eeab2116fc1f9e97dea8119f5ae11c Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 10 Nov 2023 15:59:47 +0200 Subject: validation: event: add tests for odp_event_pool() Add validation tests for new odp_event_pool() API. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- test/validation/api/buffer/buffer.c | 2 ++ test/validation/api/dma/dma.c | 6 ++++++ test/validation/api/ipsec/ipsec.c | 4 +++- test/validation/api/packet/packet.c | 19 +++++++++++++------ test/validation/api/pktio/pktio.c | 8 ++++++-- test/validation/api/timer/timer.c | 3 +++ 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/test/validation/api/buffer/buffer.c b/test/validation/api/buffer/buffer.c index 909608ed8..91cfbfb5f 100644 --- a/test/validation/api/buffer/buffer.c +++ b/test/validation/api/buffer/buffer.c @@ -94,6 +94,8 @@ static void test_pool_alloc_free(const odp_pool_param_t *param) odp_buffer_from_event_multi(&buf, &ev, 1); CU_ASSERT(buf == buffer[i]); + CU_ASSERT(odp_event_pool(ev) == pool); + if (odp_event_type(ev) != ODP_EVENT_BUFFER) wrong_type = true; if (odp_event_subtype(ev) != ODP_EVENT_NO_SUBTYPE) diff --git a/test/validation/api/dma/dma.c b/test/validation/api/dma/dma.c index 787f719a7..4f454168d 100644 --- a/test/validation/api/dma/dma.c +++ b/test/validation/api/dma/dma.c @@ -330,6 +330,7 @@ static void test_dma_compl_pool(void) odp_pool_t pool; odp_pool_info_t pool_info; odp_dma_compl_t compl[global.dma_capa.max_transfers]; + odp_event_t ev; uint64_t u64; int ret; uint32_t i, j; @@ -359,6 +360,11 @@ static void test_dma_compl_pool(void) if (compl[i] == ODP_DMA_COMPL_INVALID) break; + /* No source pool for DMA completion events */ + ev = odp_dma_compl_to_event(compl[i]); + CU_ASSERT_FATAL(ev != ODP_EVENT_INVALID); + CU_ASSERT(odp_event_pool(ev) == ODP_POOL_INVALID); + printf("\n DMA compl handle: 0x%" PRIx64 "\n", u64); odp_dma_compl_print(compl[i]); } diff --git a/test/validation/api/ipsec/ipsec.c b/test/validation/api/ipsec/ipsec.c index da60c77b3..9849a44b5 100644 --- a/test/validation/api/ipsec/ipsec.c +++ b/test/validation/api/ipsec/ipsec.c @@ -459,11 +459,13 @@ static void ipsec_status_event_handle(odp_event_t ev_status, CU_ASSERT_EQUAL(1, odp_event_is_valid(ev_status)); CU_ASSERT_EQUAL_FATAL(ODP_EVENT_IPSEC_STATUS, odp_event_type(ev_status)); - /* No user area for IPsec status events */ + /* No user area or source pool for IPsec status events */ CU_ASSERT(odp_event_user_area(ev_status) == NULL); CU_ASSERT(odp_event_user_area_and_flag(ev_status, &flag) == NULL); CU_ASSERT(flag < 0); + CU_ASSERT(odp_event_pool(ev_status) == ODP_POOL_INVALID); + CU_ASSERT_EQUAL(0, odp_ipsec_status(&status, ev_status)); CU_ASSERT_EQUAL(ODP_IPSEC_STATUS_WARN, status.id); CU_ASSERT_EQUAL(sa, status.sa); diff --git a/test/validation/api/packet/packet.c b/test/validation/api/packet/packet.c index 40cfc1481..79b8fbe50 100644 --- a/test/validation/api/packet/packet.c +++ b/test/validation/api/packet/packet.c @@ -402,6 +402,7 @@ static void packet_test_alloc_free(void) odp_packet_t packet; odp_pool_param_t params; odp_event_subtype_t subtype; + odp_event_t ev; odp_pool_param_init(¶ms); @@ -418,13 +419,15 @@ static void packet_test_alloc_free(void) packet = odp_packet_alloc(pool, packet_len); CU_ASSERT_FATAL(packet != ODP_PACKET_INVALID); CU_ASSERT(odp_packet_len(packet) == packet_len); - CU_ASSERT(odp_event_type(odp_packet_to_event(packet)) == - ODP_EVENT_PACKET); - CU_ASSERT(odp_event_subtype(odp_packet_to_event(packet)) == - ODP_EVENT_PACKET_BASIC); - CU_ASSERT(odp_event_types(odp_packet_to_event(packet), &subtype) == - ODP_EVENT_PACKET); + + ev = odp_packet_to_event(packet); + CU_ASSERT_FATAL(ev != ODP_EVENT_INVALID); + CU_ASSERT(odp_event_type(ev) == ODP_EVENT_PACKET); + CU_ASSERT(odp_event_subtype(ev) == ODP_EVENT_PACKET_BASIC); + CU_ASSERT(odp_event_types(ev, &subtype) == ODP_EVENT_PACKET); CU_ASSERT(subtype == ODP_EVENT_PACKET_BASIC); + CU_ASSERT(odp_event_pool(ev) == pool); + CU_ASSERT(odp_packet_subtype(packet) == ODP_EVENT_PACKET_BASIC); CU_ASSERT(odp_packet_to_u64(packet) != odp_packet_to_u64(ODP_PACKET_INVALID)); @@ -3205,6 +3208,7 @@ static void packet_vector_basic_test(void) odp_pool_capability_t capa; uint32_t i, num; uint32_t max_size = PKT_VEC_PACKET_NUM; + odp_event_t ev; CU_ASSERT_FATAL(odp_pool_capability(&capa) == 0); if (capa.vector.max_size < max_size) @@ -3215,6 +3219,9 @@ static void packet_vector_basic_test(void) /* Making sure default vector packet is from default vector pool */ CU_ASSERT(odp_packet_vector_pool(pktv_default) == vector_default_pool) + ev = odp_packet_vector_to_event(pktv_default); + CU_ASSERT_FATAL(ev != ODP_EVENT_INVALID); + CU_ASSERT(odp_event_pool(ev) == vector_default_pool); /* Get packet vector table */ num = odp_packet_vector_tbl(pktv_default, &pkt_tbl); diff --git a/test/validation/api/pktio/pktio.c b/test/validation/api/pktio/pktio.c index 5feeea4c0..3abf2dd0e 100644 --- a/test/validation/api/pktio/pktio.c +++ b/test/validation/api/pktio/pktio.c @@ -3648,11 +3648,13 @@ static void pktio_test_pktout_compl_event(bool use_plain_queue) CU_ASSERT(odp_packet_tx_compl_user_ptr(tx_compl) == (const void *)&pkt_seq[i]); - /* No user area for TX completion events */ + /* No user area or source pool for TX completion events */ CU_ASSERT(odp_event_user_area(ev) == NULL); CU_ASSERT(odp_event_user_area_and_flag(ev, &flag) == NULL); CU_ASSERT(flag < 0); + CU_ASSERT(odp_event_pool(ev) == ODP_POOL_INVALID); + /* Alternatively call event free / compl free */ if (i % 2) odp_packet_tx_compl_free(tx_compl); @@ -3688,11 +3690,13 @@ static void pktio_test_pktout_compl_event(bool use_plain_queue) } } - /* No user area for TX completion events */ + /* No user area or source pool for TX completion events */ CU_ASSERT(odp_event_user_area(ev) == NULL); CU_ASSERT(odp_event_user_area_and_flag(ev, &flag) == NULL); CU_ASSERT(flag < 0); + CU_ASSERT(odp_event_pool(ev) == ODP_POOL_INVALID); + /* Check that sequence number is found */ CU_ASSERT(j < TX_BATCH_LEN); diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c index a29fa2de8..5436b9b42 100644 --- a/test/validation/api/timer/timer.c +++ b/test/validation/api/timer/timer.c @@ -447,6 +447,9 @@ static void timer_test_timeout_pool_alloc(void) wrong_type = true; if (subtype != ODP_EVENT_NO_SUBTYPE) wrong_subtype = true; + + /* No source pool for timeout events */ + CU_ASSERT(odp_event_pool(ev) == ODP_POOL_INVALID); } /* Check that the pool had at least num items */ -- cgit v1.2.3 From 369b5583321450c3c35fb15a581c8e3f2ec32b5f Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 15 Nov 2023 14:58:43 +0200 Subject: api: pool: clarify per thread statistics Clarify that disabled/unused per thread statistics counters will not necessarily be zeroed by odp_pool_stats(). Rationale is that depending on implementation the per thread counter array may be large. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo Acked-by: Ashwin Sekhar T K --- include/odp/api/spec/pool.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/include/odp/api/spec/pool.h b/include/odp/api/spec/pool.h index 4fade6470..b02c0d294 100644 --- a/include/odp/api/spec/pool.h +++ b/include/odp/api/spec/pool.h @@ -154,17 +154,21 @@ unsigned int odp_pool_max_index(void); int odp_pool_index(odp_pool_t pool); /** - * Get statistics for pool + * Read pool statistics * - * Read the statistics counters enabled using odp_pool_stats_opt_t during pool creation. The - * inactive counters are set to zero by the implementation. Depending on the implementation, there - * may be some delay until performed pool operations are visible in the statistics. + * Read statistics counters that were enabled in pool creation parameters (odp_pool_param_t.stats). + * The function writes all disabled counters to zero, except per thread counters + * (thread.cache_available[]) which have undefined values. * - * A single call may read statistics from one to ODP_POOL_MAX_THREAD_STATS - * threads. Set 'stats.thread.first' and 'stats.thread.last' to select the - * threads ('first' <= 'last'). Valid values range from 0 to odp_thread_count_max() - 1. - * A successful call fills the output array starting always from the first element - * 'stats.thread.cache_available[0]' (='stats.thread.first'). + * When per thread counters are enabled, application sets 'stats.thread.first' and + * 'stats.thread.last' to select the threads ('first' <= 'last'). A single call may read statistics + * from one to #ODP_POOL_MAX_THREAD_STATS threads. Valid thread ID values range from 0 to + * odp_thread_count_max() - 1. A successful call fills the output array starting always from the + * first element 'stats.thread.cache_available[0]' (='stats.thread.first'). Unused array elements + * have undefined values. + * + * Depending on the implementation, there may be some delay until performed pool operations are + * visible in the statistics. * * @param pool Pool handle * @param[in,out] stats Output buffer for counters -- cgit v1.2.3 From cd2216880c35d3ed7942221b08ac837561d783d6 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 15 Nov 2023 15:28:56 +0200 Subject: linux-gen: pool: remove per thread stats zeroing Simplify and speed up pool statistics function a bit by removing unnecessary zeroing of per thread statistics. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo Acked-by: Ashwin Sekhar T K --- platform/linux-generic/odp_pool.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index 59908644d..94461e6b1 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -1688,7 +1688,6 @@ unsigned int odp_pool_max_index(void) int odp_pool_stats(odp_pool_t pool_hdl, odp_pool_stats_t *stats) { pool_t *pool; - uint16_t first, last; if (odp_unlikely(pool_hdl == ODP_POOL_INVALID)) { _ODP_ERR("Invalid pool handle\n"); @@ -1700,14 +1699,9 @@ int odp_pool_stats(odp_pool_t pool_hdl, odp_pool_stats_t *stats) } pool = _odp_pool_entry(pool_hdl); - first = stats->thread.first; - last = stats->thread.last; - memset(stats, 0, sizeof(odp_pool_stats_t)); - - /* Restore input parameters */ - stats->thread.first = first; - stats->thread.last = last; + /* Zero everything else but per thread statistics */ + memset(stats, 0, offsetof(odp_pool_stats_t, thread)); if (pool->params.stats.bit.available) stats->available = ring_ptr_len(&pool->ring->hdr); -- cgit v1.2.3 From f3a36b8843a6473165f2d6c1d11aa976b28ee164 Mon Sep 17 00:00:00 2001 From: Janne Peltonen Date: Mon, 2 Oct 2023 11:29:15 +0300 Subject: api: sched: clarify event ordering in ordered contexts Describe event ordering in ordered scheduling contexts more accurately. In particular, events in a destination queue are not necessarily in the same order as they are in the source queue if odp_schedule_multi() returns multiple events (sharing single scheduling synchronization context) and if the ODP application enqueues the events in a different order. Also, other enqueued events than the scheduled ones have a well defined ordering. This API change is not intended to change any functionality but just tries to document more accurately what already is the expected behaviour. Signed-off-by: Janne Peltonen Reviewed-by: Petri Savolainen Acked-by: Pavan Nikhilesh --- include/odp/api/spec/schedule_types.h | 61 ++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/include/odp/api/spec/schedule_types.h b/include/odp/api/spec/schedule_types.h index 3cca665c1..b15397b96 100644 --- a/include/odp/api/spec/schedule_types.h +++ b/include/odp/api/spec/schedule_types.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright (c) 2015-2018 Linaro Limited + * Copyright (c) 2023 Nokia */ /** @@ -85,31 +86,53 @@ extern "C" { * enables the user to achieve high single flow throughput by avoiding * SW synchronization for ordering between threads. * - * The source queue (dequeue) ordering is maintained when - * events are enqueued to their destination queue(s) within the same ordered - * queue synchronization context. A thread holds the context until it - * requests another event from the scheduler, which implicitly releases the - * context. User may allow the scheduler to release the context earlier than - * that by calling odp_schedule_release_ordered(). However, this call is just - * a hint to the implementation and the context may be held until the next - * schedule call. + * When odp_schedule() returns an event, the calling thread is associated + * with an ordered scheduling synchronization context. The contexts arising + * from the same ordered queue have the same mutual ordering as the + * corresponding events had in the queue. + * + * When odp_schedule_multi() returns more than one event from an ordered + * queue, the events returned were consecutive in the queue and the calling + * thread is associated with single ordered scheduling synchronization + * context that is ordered with respect to other contexts as if just the + * first event was returned. + * + * When threads holding ordered scheduling synchronization contexts, which + * arise from the same ordered queue, enqueue events to destination queues, + * the order of events in each destination queue will be as follows: * - * Events from the same (source) queue appear in their original order - * when dequeued from a destination queue. The destination queue can have any - * queue type and synchronization method. Event ordering is based on the - * received event(s), but also other (newly allocated or stored) events are - * ordered when enqueued within the same ordered context. Events not enqueued - * (e.g. freed or stored) within the context are considered missing from - * reordering and are skipped at this time (but can be ordered again within - * another context). + * - Events enqueued by one thread have the order in which the enqueue + * calls were made. + * + * - Two events enqueued by different threads have the same mutual order + * as the scheduling synchronization contexts of the enqueuing threads. + * + * The ordering rules above apply to all events, not just those that were + * scheduled from the ordered queue. For instance, newly allocated events + * and previously stored events are ordered in the destination queue based + * on the scheduling synchronization context. The ordering rules apply + * regarless of the type (scheduled or plain) or schedule type (atomic, + * ordered, or parallel) of the destination queue. If the order type of + * the destination queue is ODP_QUEUE_ORDER_IGNORE, then the order between + * events enqueued by different threads is not guaranteed. + * + * An ordered scheduling synchronization context is implicitly released when + * the thread holding the context requests a new event from the scheduler. + * User may allow the scheduler to release the context earlier than that by + * calling odp_schedule_release_ordered(). However, this call is just a hint + * to the implementation and the context may be held until the next schedule + * call. + * + * Enqueue calls by different threads may return in a different order than + * the final order of the enqueued events in the destination queue. * * Unnecessary event re-ordering may be avoided for those destination queues - * that do not need to maintain the original event order by setting 'order' + * that do not need to maintain the specified event order by setting 'order' * queue parameter to ODP_QUEUE_ORDER_IGNORE. * * When scheduler is enabled as flow-aware, the event flow id value affects - * scheduling of the event and synchronization is maintained per flow within - * each queue. + * scheduling of the event and synchronization is maintained and order is + * defined per flow within each queue. */ /** -- cgit v1.2.3 From a6a6bdd8b373a65116d28c6a889d07fc2e2a63ef Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 15 Nov 2023 11:26:22 +0200 Subject: api: thread: move ODP_THREAD_COUNT_MAX to types header Move ODP_THREAD_COUNT_MAX specification and definition to thread_types headers where they belong to. No functional API changes. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale Reviewed-by: Jerin Jacob --- include/Makefile.am | 8 +++++++ include/odp/api/abi-default/thread.h | 16 +------------ include/odp/api/abi-default/thread_types.h | 26 ++++++++++++++++++++++ include/odp/api/spec/init.h | 2 +- include/odp/api/spec/thread.h | 9 ++------ include/odp/api/spec/thread_types.h | 7 ++++++ include/odp/api/thread.h | 2 -- include/odp/api/thread_types.h | 26 ++++++++++++++++++++++ .../arch/arm32-linux/odp/api/abi/thread_types.h | 5 +++++ .../arch/arm64-linux/odp/api/abi/thread_types.h | 5 +++++ .../arch/default-linux/odp/api/abi/thread_types.h | 5 +++++ .../arch/power64-linux/odp/api/abi/thread_types.h | 5 +++++ .../arch/x86_32-linux/odp/api/abi/thread_types.h | 5 +++++ .../arch/x86_64-linux/odp/api/abi/thread_types.h | 5 +++++ platform/linux-generic/Makefile.am | 1 + .../linux-generic/include-abi/odp/api/abi/thread.h | 3 +-- .../include-abi/odp/api/abi/thread_types.h | 5 +++++ .../include/odp/api/plat/thread_inline_types.h | 2 +- .../include/odp/api/plat/thread_inlines.h | 8 +++---- 19 files changed, 113 insertions(+), 32 deletions(-) create mode 100644 include/odp/api/abi-default/thread_types.h create mode 100644 include/odp/api/thread_types.h create mode 100644 include/odp/arch/arm32-linux/odp/api/abi/thread_types.h create mode 100644 include/odp/arch/arm64-linux/odp/api/abi/thread_types.h create mode 100644 include/odp/arch/default-linux/odp/api/abi/thread_types.h create mode 100644 include/odp/arch/power64-linux/odp/api/abi/thread_types.h create mode 100644 include/odp/arch/x86_32-linux/odp/api/abi/thread_types.h create mode 100644 include/odp/arch/x86_64-linux/odp/api/abi/thread_types.h create mode 100644 platform/linux-generic/include-abi/odp/api/abi/thread_types.h diff --git a/include/Makefile.am b/include/Makefile.am index ea3f17add..bc28a5cba 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -64,6 +64,7 @@ odpapiinclude_HEADERS = \ odp/api/sync.h \ odp/api/system_info.h \ odp/api/thread.h \ + odp/api/thread_types.h \ odp/api/threshold.h \ odp/api/thrmask.h \ odp/api/ticketlock.h \ @@ -193,6 +194,7 @@ odpapiabidefaultinclude_HEADERS = \ odp/api/abi-default/std_types.h \ odp/api/abi-default/sync.h \ odp/api/abi-default/thread.h \ + odp/api/abi-default/thread_types.h \ odp/api/abi-default/thrmask.h \ odp/api/abi-default/ticketlock.h \ odp/api/abi-default/time.h \ @@ -255,6 +257,7 @@ odpapiabiarchinclude_HEADERS = \ odp/arch/arm32-linux/odp/api/abi/std_types.h \ odp/arch/arm32-linux/odp/api/abi/sync.h \ odp/arch/arm32-linux/odp/api/abi/thread.h \ + odp/arch/arm32-linux/odp/api/abi/thread_types.h \ odp/arch/arm32-linux/odp/api/abi/thrmask.h \ odp/arch/arm32-linux/odp/api/abi/ticketlock.h \ odp/arch/arm32-linux/odp/api/abi/time.h \ @@ -313,6 +316,7 @@ odpapiabiarchinclude_HEADERS = \ odp/arch/arm64-linux/odp/api/abi/std_types.h \ odp/arch/arm64-linux/odp/api/abi/sync.h \ odp/arch/arm64-linux/odp/api/abi/thread.h \ + odp/arch/arm64-linux/odp/api/abi/thread_types.h \ odp/arch/arm64-linux/odp/api/abi/thrmask.h \ odp/arch/arm64-linux/odp/api/abi/ticketlock.h \ odp/arch/arm64-linux/odp/api/abi/time.h \ @@ -371,6 +375,7 @@ odpapiabiarchinclude_HEADERS = \ odp/arch/default-linux/odp/api/abi/std_types.h \ odp/arch/default-linux/odp/api/abi/sync.h \ odp/arch/default-linux/odp/api/abi/thread.h \ + odp/arch/default-linux/odp/api/abi/thread_types.h \ odp/arch/default-linux/odp/api/abi/thrmask.h \ odp/arch/default-linux/odp/api/abi/ticketlock.h \ odp/arch/default-linux/odp/api/abi/time.h \ @@ -429,6 +434,7 @@ odpapiabiarchinclude_HEADERS = \ odp/arch/power64-linux/odp/api/abi/std_types.h \ odp/arch/power64-linux/odp/api/abi/sync.h \ odp/arch/power64-linux/odp/api/abi/thread.h \ + odp/arch/power64-linux/odp/api/abi/thread_types.h \ odp/arch/power64-linux/odp/api/abi/thrmask.h \ odp/arch/power64-linux/odp/api/abi/ticketlock.h \ odp/arch/power64-linux/odp/api/abi/time.h \ @@ -487,6 +493,7 @@ odpapiabiarchinclude_HEADERS = \ odp/arch/x86_32-linux/odp/api/abi/std_types.h \ odp/arch/x86_32-linux/odp/api/abi/sync.h \ odp/arch/x86_32-linux/odp/api/abi/thread.h \ + odp/arch/x86_32-linux/odp/api/abi/thread_types.h \ odp/arch/x86_32-linux/odp/api/abi/thrmask.h \ odp/arch/x86_32-linux/odp/api/abi/ticketlock.h \ odp/arch/x86_32-linux/odp/api/abi/time.h \ @@ -545,6 +552,7 @@ odpapiabiarchinclude_HEADERS = \ odp/arch/x86_64-linux/odp/api/abi/std_types.h \ odp/arch/x86_64-linux/odp/api/abi/sync.h \ odp/arch/x86_64-linux/odp/api/abi/thread.h \ + odp/arch/x86_64-linux/odp/api/abi/thread_types.h \ odp/arch/x86_64-linux/odp/api/abi/thrmask.h \ odp/arch/x86_64-linux/odp/api/abi/ticketlock.h \ odp/arch/x86_64-linux/odp/api/abi/time.h \ diff --git a/include/odp/api/abi-default/thread.h b/include/odp/api/abi-default/thread.h index 3113278d3..3b7ce41dc 100644 --- a/include/odp/api/abi-default/thread.h +++ b/include/odp/api/abi-default/thread.h @@ -2,12 +2,6 @@ * Copyright (c) 2015-2018 Linaro Limited */ -/** - * @file - * - * ODP thread - */ - #ifndef ODP_ABI_THREAD_H_ #define ODP_ABI_THREAD_H_ @@ -15,15 +9,7 @@ extern "C" { #endif -/** @addtogroup odp_thread - * @{ - */ - -#define ODP_THREAD_COUNT_MAX 256 - -/** - * @} - */ +/* Empty header required due to the inline functions */ #ifdef __cplusplus } diff --git a/include/odp/api/abi-default/thread_types.h b/include/odp/api/abi-default/thread_types.h new file mode 100644 index 000000000..1511f488d --- /dev/null +++ b/include/odp/api/abi-default/thread_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#ifndef ODP_ABI_THREAD_TYPES_H_ +#define ODP_ABI_THREAD_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @ingroup odp_thread + * @{ + */ + +#define ODP_THREAD_COUNT_MAX 256 + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/spec/init.h b/include/odp/api/spec/init.h index f0491ad5b..ee787665f 100644 --- a/include/odp/api/spec/init.h +++ b/include/odp/api/spec/init.h @@ -17,7 +17,7 @@ extern "C" { #include #include -#include +#include #include /** @defgroup odp_initialization ODP INITIALIZATION diff --git a/include/odp/api/spec/thread.h b/include/odp/api/spec/thread.h index d595a9563..abe7a6eb4 100644 --- a/include/odp/api/spec/thread.h +++ b/include/odp/api/spec/thread.h @@ -17,18 +17,13 @@ extern "C" { #endif +#include + /** @defgroup odp_thread ODP THREAD * Thread types, masks and IDs. * @{ */ -/** - * @def ODP_THREAD_COUNT_MAX - * Maximum number of threads supported in build time. Use - * odp_thread_count_max() for maximum number of threads supported in run time, - * which depend on system configuration and may be lower than this number. - */ - /** * Get thread identifier * diff --git a/include/odp/api/spec/thread_types.h b/include/odp/api/spec/thread_types.h index 60cf4897b..204d28cad 100644 --- a/include/odp/api/spec/thread_types.h +++ b/include/odp/api/spec/thread_types.h @@ -19,6 +19,13 @@ extern "C" { * @{ */ +/** + * @def ODP_THREAD_COUNT_MAX + * Maximum number of threads supported in build time. Use odp_thread_count_max() + * for maximum number of threads supported in run time, which depends on system + * configuration and may be lower than this number. + */ + /** * Thread type */ diff --git a/include/odp/api/thread.h b/include/odp/api/thread.h index 2e0288886..24199a166 100644 --- a/include/odp/api/thread.h +++ b/include/odp/api/thread.h @@ -15,8 +15,6 @@ extern "C" { #endif -#include - #include #include diff --git a/include/odp/api/thread_types.h b/include/odp/api/thread_types.h new file mode 100644 index 000000000..54ea5b714 --- /dev/null +++ b/include/odp/api/thread_types.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +/** + * @file + * + * ODP thread + */ + +#ifndef ODP_API_THREAD_TYPES_H_ +#define ODP_API_THREAD_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/arch/arm32-linux/odp/api/abi/thread_types.h b/include/odp/arch/arm32-linux/odp/api/abi/thread_types.h new file mode 100644 index 000000000..e695c233b --- /dev/null +++ b/include/odp/arch/arm32-linux/odp/api/abi/thread_types.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#include diff --git a/include/odp/arch/arm64-linux/odp/api/abi/thread_types.h b/include/odp/arch/arm64-linux/odp/api/abi/thread_types.h new file mode 100644 index 000000000..e695c233b --- /dev/null +++ b/include/odp/arch/arm64-linux/odp/api/abi/thread_types.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#include diff --git a/include/odp/arch/default-linux/odp/api/abi/thread_types.h b/include/odp/arch/default-linux/odp/api/abi/thread_types.h new file mode 100644 index 000000000..e695c233b --- /dev/null +++ b/include/odp/arch/default-linux/odp/api/abi/thread_types.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#include diff --git a/include/odp/arch/power64-linux/odp/api/abi/thread_types.h b/include/odp/arch/power64-linux/odp/api/abi/thread_types.h new file mode 100644 index 000000000..e695c233b --- /dev/null +++ b/include/odp/arch/power64-linux/odp/api/abi/thread_types.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#include diff --git a/include/odp/arch/x86_32-linux/odp/api/abi/thread_types.h b/include/odp/arch/x86_32-linux/odp/api/abi/thread_types.h new file mode 100644 index 000000000..e695c233b --- /dev/null +++ b/include/odp/arch/x86_32-linux/odp/api/abi/thread_types.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#include diff --git a/include/odp/arch/x86_64-linux/odp/api/abi/thread_types.h b/include/odp/arch/x86_64-linux/odp/api/abi/thread_types.h new file mode 100644 index 000000000..e695c233b --- /dev/null +++ b/include/odp/arch/x86_64-linux/odp/api/abi/thread_types.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#include diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 3b645460b..f3707ab3a 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -115,6 +115,7 @@ odpapiabiarchinclude_HEADERS += \ include-abi/odp/api/abi/std_types.h \ include-abi/odp/api/abi/sync.h \ include-abi/odp/api/abi/thread.h \ + include-abi/odp/api/abi/thread_types.h \ include-abi/odp/api/abi/thrmask.h \ include-abi/odp/api/abi/ticketlock.h \ include-abi/odp/api/abi/time.h \ diff --git a/platform/linux-generic/include-abi/odp/api/abi/thread.h b/platform/linux-generic/include-abi/odp/api/abi/thread.h index d5628a740..14c074b95 100644 --- a/platform/linux-generic/include-abi/odp/api/abi/thread.h +++ b/platform/linux-generic/include-abi/odp/api/abi/thread.h @@ -4,6 +4,5 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include - +/* Inlined API functions */ #include diff --git a/platform/linux-generic/include-abi/odp/api/abi/thread_types.h b/platform/linux-generic/include-abi/odp/api/abi/thread_types.h new file mode 100644 index 000000000..e695c233b --- /dev/null +++ b/platform/linux-generic/include-abi/odp/api/abi/thread_types.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Nokia + */ + +#include diff --git a/platform/linux-generic/include/odp/api/plat/thread_inline_types.h b/platform/linux-generic/include/odp/api/plat/thread_inline_types.h index c9a15b06b..d24263fa7 100644 --- a/platform/linux-generic/include/odp/api/plat/thread_inline_types.h +++ b/platform/linux-generic/include/odp/api/plat/thread_inline_types.h @@ -9,7 +9,7 @@ #define ODP_PLAT_THREAD_INLINE_TYPES_H_ #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/platform/linux-generic/include/odp/api/plat/thread_inlines.h b/platform/linux-generic/include/odp/api/plat/thread_inlines.h index 2f2e50b06..2b6957064 100644 --- a/platform/linux-generic/include/odp/api/plat/thread_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/thread_inlines.h @@ -7,14 +7,14 @@ #ifndef ODP_PLAT_THREAD_INLINES_H_ #define ODP_PLAT_THREAD_INLINES_H_ -#include - -#include - #ifdef __cplusplus extern "C" { #endif +#include + +#include + /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ #ifndef _ODP_NO_INLINE -- cgit v1.2.3 From 34f525c6d23af062bfbb055cfda91d4f4f32d92b Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 15 Nov 2023 11:49:14 +0200 Subject: api: thread: add functions for reading maximum control/worker thread count Add new functions odp_thread_control_count_max() and odp_thread_worker_count_max() for reading the maximum number of control and worker threads. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale Reviewed-by: Jerin Jacob --- include/odp/api/spec/thread.h | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/include/odp/api/spec/thread.h b/include/odp/api/spec/thread.h index abe7a6eb4..29db89c47 100644 --- a/include/odp/api/spec/thread.h +++ b/include/odp/api/spec/thread.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright (c) 2013-2018 Linaro Limited - * Copyright (c) 2022 Nokia + * Copyright (c) 2022-2023 Nokia */ /** @@ -54,13 +54,36 @@ int odp_thread_count(void); /** * Maximum thread count * - * Returns the maximum thread count, which is a constant value and set in - * ODP initialization phase. This may be lower than ODP_THREAD_COUNT_MAX. + * Returns the maximum number of threads of any type. This is a constant value + * and set in ODP initialization phase. The value may be lower than + * #ODP_THREAD_COUNT_MAX. * * @return Maximum thread count */ int odp_thread_count_max(void); +/** + * Maximum control thread count + * + * Otherwise like odp_thread_count_max(), but returns the maximum number of + * control threads (#ODP_THREAD_CONTROL). The returned value is always <= + * odp_thread_count_max(). + * + * @return Maximum control thread count + */ +int odp_thread_control_count_max(void); + +/** + * Maximum worker thread count + * + * Otherwise like odp_thread_count_max(), but returns the maximum number of + * worker threads (#ODP_THREAD_WORKER). The returned value is always <= + * odp_thread_count_max(). + * + * @return Maximum worker thread count + */ +int odp_thread_worker_count_max(void); + /** * Thread type * -- cgit v1.2.3 From 585430047d3cf6dbe84b65b91af5459476644126 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 15 Nov 2023 12:28:38 +0200 Subject: api: thread: add functions for reading current control/worker thread count Add new functions odp_thread_control_count() and odp_thread_worker_count() for reading the current number of control and worker threads. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale Reviewed-by: Jerin Jacob --- include/odp/api/spec/thread.h | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/include/odp/api/spec/thread.h b/include/odp/api/spec/thread.h index 29db89c47..dbb033da1 100644 --- a/include/odp/api/spec/thread.h +++ b/include/odp/api/spec/thread.h @@ -43,14 +43,36 @@ int odp_thread_id(void); * Thread count * * Returns the current ODP thread count. This is the number of active threads - * running the ODP instance. Each odp_init_local() call increments and each - * odp_term_local() call decrements the count. The count is always between 1 and - * odp_thread_count_max(). + * of any type running in the ODP instance. Each odp_init_local() call + * increments and each odp_term_local() call decrements the count. The count is + * always between 1 and odp_thread_count_max(). * * @return Current thread count */ int odp_thread_count(void); +/** + * Control thread count + * + * Otherwise like odp_thread_count(), but returns the number of active threads + * of type #ODP_THREAD_CONTROL. The count is always between 0 and + * odp_thread_control_count_max(). + * + * @return Current control thread count + */ +int odp_thread_control_count(void); + +/** + * Worker thread count + * + * Otherwise like odp_thread_count(), but returns the number of active threads + * of type #ODP_THREAD_WORKER. The count is always between 0 and + * odp_thread_worker_count_max(). + * + * @return Current worker thread count + */ +int odp_thread_worker_count(void); + /** * Maximum thread count * -- cgit v1.2.3 From 9b3d483bf2169cfce2b8800563d8ab4c02f0488b Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 15 Nov 2023 13:26:30 +0200 Subject: linux-gen: thread: implement current control/worker thread count functions Implement new functions odp_thread_control_count() and odp_thread_worker_count() for reading the current number of control and worker threads. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-generic/odp_thread.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/linux-generic/odp_thread.c b/platform/linux-generic/odp_thread.c index bdfd758d7..2fa30f488 100644 --- a/platform/linux-generic/odp_thread.c +++ b/platform/linux-generic/odp_thread.c @@ -257,6 +257,16 @@ int odp_thread_count(void) return thread_globals->num; } +int odp_thread_control_count(void) +{ + return thread_globals->num_control; +} + +int odp_thread_worker_count(void) +{ + return thread_globals->num_worker; +} + int odp_thread_count_max(void) { return thread_globals->num_max; -- cgit v1.2.3 From a240b2231e548453ec49b30b830077c23d9505d2 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 15 Nov 2023 13:35:01 +0200 Subject: linux-gen: thread: implement max control/worker thread count functions Implement new functions odp_thread_control_count_max() and odp_thread_worker_count_max() for reading the maximum number of control and worker threads. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-generic/odp_thread.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/linux-generic/odp_thread.c b/platform/linux-generic/odp_thread.c index 2fa30f488..88aec8f06 100644 --- a/platform/linux-generic/odp_thread.c +++ b/platform/linux-generic/odp_thread.c @@ -272,6 +272,16 @@ int odp_thread_count_max(void) return thread_globals->num_max; } +int odp_thread_control_count_max(void) +{ + return thread_globals->num_max; +} + +int odp_thread_worker_count_max(void) +{ + return thread_globals->num_max; +} + int odp_thrmask_worker(odp_thrmask_t *mask) { odp_thrmask_copy(mask, &thread_globals->worker); -- cgit v1.2.3 From 05b146f8bb080f715c5bdba1417fbcfbdabd875e Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 15 Nov 2023 13:58:19 +0200 Subject: validation: thread: add tests for new control/worker thread count functions Add validation tests for the new control/worker thread count functions. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- test/validation/api/thread/thread.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/test/validation/api/thread/thread.c b/test/validation/api/thread/thread.c index 87c23e74e..840256fcf 100644 --- a/test/validation/api/thread/thread.c +++ b/test/validation/api/thread/thread.c @@ -104,13 +104,31 @@ static void thread_test_odp_thread_count(void) { int count = odp_thread_count(); - /* One thread running */ + /* One control thread running */ CU_ASSERT(count == 1); + CU_ASSERT(odp_thread_control_count() == 1); + CU_ASSERT(odp_thread_control_count() <= odp_thread_control_count_max()); + CU_ASSERT(odp_thread_worker_count() == 0); CU_ASSERT(count >= 1); CU_ASSERT(count <= odp_thread_count_max()); CU_ASSERT(count <= ODP_THREAD_COUNT_MAX); - CU_ASSERT(odp_thread_count_max() <= ODP_THREAD_COUNT_MAX); +} + +static void thread_test_odp_thread_count_max(void) +{ + int max_threads = odp_thread_count_max(); + int max_control = odp_thread_control_count_max(); + int max_worker = odp_thread_worker_count_max(); + + CU_ASSERT(max_threads > 0); + CU_ASSERT(max_threads <= ODP_THREAD_COUNT_MAX); + + CU_ASSERT(max_control >= 0); + CU_ASSERT(max_control <= max_threads); + + CU_ASSERT(max_worker >= 0); + CU_ASSERT(max_worker <= max_threads); } static int thread_func(void *arg) @@ -175,7 +193,9 @@ static void thread_test_odp_thrmask_worker(void) ret = odp_thrmask_worker(&mask); CU_ASSERT(ret == odp_thrmask_count(&mask)); CU_ASSERT(ret == num); + CU_ASSERT(ret == odp_thread_worker_count()); CU_ASSERT(ret <= odp_thread_count_max()); + CU_ASSERT(ret <= odp_thread_worker_count_max()); /* allow thread(s) to exit */ odp_barrier_wait(&global_mem->bar_exit); @@ -194,9 +214,10 @@ static void thread_test_odp_thrmask_control(void) CU_ASSERT(odp_thread_type() == ODP_THREAD_CONTROL); - /* should start out with 1 worker thread */ + /* Should start out with 1 control thread */ ret = odp_thrmask_control(&mask); CU_ASSERT(ret == odp_thrmask_count(&mask)); + CU_ASSERT(ret == odp_thread_control_count()); CU_ASSERT(ret == 1); } @@ -204,6 +225,7 @@ odp_testinfo_t thread_suite[] = { ODP_TEST_INFO(thread_test_odp_cpu_id), ODP_TEST_INFO(thread_test_odp_thread_id), ODP_TEST_INFO(thread_test_odp_thread_count), + ODP_TEST_INFO(thread_test_odp_thread_count_max), ODP_TEST_INFO(thread_test_odp_thrmask_to_from_str), ODP_TEST_INFO(thread_test_odp_thrmask_equal), ODP_TEST_INFO(thread_test_odp_thrmask_zero), -- cgit v1.2.3 From fda9ee7d2f7e0b43f8e188dc8c5be28958dbd1bc Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 24 Nov 2023 10:44:14 +0200 Subject: api: timer: only inactive timers can be freed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove possibility to free a timer that is running. When timer free call returns, the timer handle cannot be referenced any more. Expiration and event delivery of an already destroyed timer is an error prone corner case. Signed-off-by: Petri Savolainen Reviewed-by: Jere Leppänen Acked-by: Pavan Nikhilesh --- example/debug/odp_debug.c | 17 +++++++++++----- example/timer/odp_timer_accuracy.c | 9 ++++----- example/timer/odp_timer_simple.c | 18 +++++++++++------ include/odp/api/spec/timer.h | 20 ++++++++++--------- platform/linux-generic/odp_timer.c | 18 ++++++++--------- test/performance/odp_sched_pktio.c | 16 +++++++-------- test/performance/odp_stress.c | 24 ++++++++++++++-------- test/performance/odp_timer_perf.c | 41 ++++++++++++++++++++++++-------------- test/validation/api/timer/timer.c | 26 +++++++++++------------- 9 files changed, 109 insertions(+), 80 deletions(-) diff --git a/example/debug/odp_debug.c b/example/debug/odp_debug.c index 06d10f34d..cca6fa939 100644 --- a/example/debug/odp_debug.c +++ b/example/debug/odp_debug.c @@ -384,6 +384,7 @@ static int timer_debug(void) uint64_t tick; uint64_t max_tmo = ODP_TIME_SEC_IN_NS; uint64_t res = 100 * ODP_TIME_MSEC_IN_NS; + int started = 0; odp_pool_param_init(&pool_param); pool_param.type = ODP_POOL_TIMEOUT; @@ -462,16 +463,17 @@ static int timer_debug(void) start_param.tick = tick; start_param.tmo_ev = event; - if (odp_timer_start(timer, &start_param) != ODP_TIMER_SUCCESS) + if (odp_timer_start(timer, &start_param) == ODP_TIMER_SUCCESS) + started = 1; + else ODPH_ERR("Timer start failed.\n"); printf("\n"); odp_timer_print(timer); - event = odp_timer_free(timer); - - if (event == ODP_EVENT_INVALID) { - ODPH_ERR("Timer free failed.\n"); + if (started && odp_timer_cancel(timer, &event) != ODP_TIMER_SUCCESS) { + ODPH_ERR("Timer cancel failed\n"); + return -1; } else { timeout = odp_timeout_from_event(event); @@ -481,6 +483,11 @@ static int timer_debug(void) odp_timeout_free(timeout); } + if (odp_timer_free(timer)) { + ODPH_ERR("Timer free failed\n"); + return -1; + } + odp_timer_pool_destroy(timer_pool); if (odp_queue_destroy(queue)) { diff --git a/example/timer/odp_timer_accuracy.c b/example/timer/odp_timer_accuracy.c index 05e4e9181..83ca371d9 100644 --- a/example/timer/odp_timer_accuracy.c +++ b/example/timer/odp_timer_accuracy.c @@ -806,7 +806,6 @@ static int destroy_timers(test_global_t *test_global) { uint64_t i, alloc_timers; odp_timer_t timer; - odp_event_t ev; int ret = 0; alloc_timers = test_global->opt.alloc_timers; @@ -817,10 +816,10 @@ static int destroy_timers(test_global_t *test_global) if (timer == ODP_TIMER_INVALID) break; - ev = odp_timer_free(timer); - - if (ev != ODP_EVENT_INVALID) - odp_event_free(ev); + if (odp_timer_free(timer)) { + printf("Timer free failed: %" PRIu64 "\n", i); + ret = -1; + } } if (test_global->timer_pool != ODP_TIMER_POOL_INVALID) diff --git a/example/timer/odp_timer_simple.c b/example/timer/odp_timer_simple.c index fdf38c9d3..b1c818c76 100644 --- a/example/timer/odp_timer_simple.c +++ b/example/timer/odp_timer_simple.c @@ -159,18 +159,24 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) } /* Destroy created resources */ - rc += odp_timer_cancel(tim, &ev); - rc += -(odp_timer_free(tim) == ODP_EVENT_INVALID); odp_event_free(ev); - ret += odp_queue_destroy(queue); + if (odp_timer_free(tim)) + ret++; + + if (odp_queue_destroy(queue)) + ret++; err: odp_timer_pool_destroy(timer_pool); err_tp: - ret += odp_pool_destroy(timeout_pool); - ret += odp_term_local(); + if (odp_pool_destroy(timeout_pool)) + ret++; + + if (odp_term_local()) + ret++; err_local: - ret += odp_term_global(instance); + if (odp_term_global(instance)) + ret++; err_global: return ret; } diff --git a/include/odp/api/spec/timer.h b/include/odp/api/spec/timer.h index ad27b5ded..e8625236e 100644 --- a/include/odp/api/spec/timer.h +++ b/include/odp/api/spec/timer.h @@ -246,19 +246,21 @@ odp_timer_t odp_timer_alloc(odp_timer_pool_t timer_pool, odp_queue_t queue, cons /** * Free a timer * - * Free (destroy) a timer, reclaiming associated resources. - * The timeout event for an active timer will be returned. - * The timeout event for an expired timer will not be returned. It is the - * responsibility of the application to handle this timeout when it is received. + * Frees a previously allocated timer. The timer must be inactive when calling this function. + * In other words, the application must cancel an active single shot timer (odp_timer_cancel()) + * successfully or wait it to expire before freeing it. Similarly for an active periodic timer, the + * application must cancel it (odp_timer_periodic_cancel()) and receive the last event from + * the timer (odp_timer_periodic_ack()) before freeing it. * - * A periodic timer must be cancelled successfully before freeing it. + * The call returns failure only on non-recoverable errors. Application must not use the timer + * handle anymore after the call, regardless of the return value. * - * @param timer Timer + * @param timer Timer * - * @return Event handle of timeout event - * @retval ODP_EVENT_INVALID on failure + * @retval 0 on success + * @retval <0 on failure */ -odp_event_t odp_timer_free(odp_timer_t timer); +int odp_timer_free(odp_timer_t timer); /** * Start a timer diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index ccc716652..9fc247862 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -579,14 +579,20 @@ static odp_event_t timer_set_unused(timer_pool_t *tp, uint32_t idx) return old_event; } -static inline odp_event_t timer_free(timer_pool_t *tp, uint32_t idx) +int odp_timer_free(odp_timer_t hdl) { + timer_pool_t *tp = handle_to_tp(hdl); + uint32_t idx = handle_to_idx(hdl, tp); _odp_timer_t *tim = &tp->timers[idx]; tick_buf_t *tb = &tp->tick_buf[idx]; /* Free the timer by setting timer state to unused and * grab any timeout event */ odp_event_t old_event = timer_set_unused(tp, idx); + if (old_event != ODP_EVENT_INVALID) { + _ODP_ERR("Timer is active\n"); + return -1; + } /* Remove timer from queue */ _odp_queue_fn->timer_rem(tim->queue); @@ -605,7 +611,7 @@ static inline odp_event_t timer_free(timer_pool_t *tp, uint32_t idx) tp->num_alloc--; odp_spinlock_unlock(&tp->lock); - return old_event; + return 0; } static odp_event_t timer_cancel(timer_pool_t *tp, uint32_t idx) @@ -1528,14 +1534,6 @@ odp_timer_t odp_timer_alloc(odp_timer_pool_t tpid, odp_queue_t queue, const void return timer_alloc(tp, queue, user_ptr); } -odp_event_t odp_timer_free(odp_timer_t hdl) -{ - timer_pool_t *tp = handle_to_tp(hdl); - uint32_t idx = handle_to_idx(hdl, tp); - - return timer_free(tp, idx); -} - int odp_timer_start(odp_timer_t timer, const odp_timer_start_t *start_param) { uint64_t abs_tick, rel_tick; diff --git a/test/performance/odp_sched_pktio.c b/test/performance/odp_sched_pktio.c index 927d35cbd..ceaef0898 100644 --- a/test/performance/odp_sched_pktio.c +++ b/test/performance/odp_sched_pktio.c @@ -1081,10 +1081,10 @@ static int stop_pktios(test_global_t *test_global) return ret; } -static void empty_queues(void) +static void empty_queues(uint64_t wait_ns) { odp_event_t ev; - uint64_t wait_time = odp_schedule_wait_time(ODP_TIME_SEC_IN_NS / 2); + uint64_t wait_time = odp_schedule_wait_time(wait_ns); /* Drop all events from all queues */ while (1) { @@ -1365,7 +1365,6 @@ static int start_timers(test_global_t *test_global) static void destroy_timers(test_global_t *test_global) { int i, j; - odp_event_t event; odp_timer_t timer; int num_pktio = test_global->opt.num_pktio; int num_queue = test_global->opt.num_pktio_queue; @@ -1375,6 +1374,9 @@ static void destroy_timers(test_global_t *test_global) if (timer_pool == ODP_TIMER_POOL_INVALID) return; + /* Wait any remaining timers to expire */ + empty_queues(2000 * test_global->opt.timeout_us); + for (i = 0; i < num_pktio; i++) { for (j = 0; j < num_queue; j++) { timer = test_global->timer.timer[i][j]; @@ -1382,10 +1384,8 @@ static void destroy_timers(test_global_t *test_global) if (timer == ODP_TIMER_INVALID) break; - event = odp_timer_free(timer); - - if (event != ODP_EVENT_INVALID) - odp_event_free(event); + if (odp_timer_free(timer)) + printf("Timer free failed: %i, %i\n", i, j); } } @@ -1552,7 +1552,7 @@ int main(int argc, char *argv[]) quit: stop_pktios(test_global); - empty_queues(); + empty_queues(ODP_TIME_SEC_IN_NS / 2); close_pktios(test_global); destroy_pipeline_queues(test_global); destroy_timers(test_global); diff --git a/test/performance/odp_stress.c b/test/performance/odp_stress.c index d5e3142f6..f18d85c89 100644 --- a/test/performance/odp_stress.c +++ b/test/performance/odp_stress.c @@ -61,6 +61,7 @@ typedef struct test_global_t { test_stat_t stat[ODP_THREAD_COUNT_MAX]; thread_arg_t thread_arg[ODP_THREAD_COUNT_MAX]; test_stat_sum_t stat_sum; + odp_atomic_u64_t tot_rounds; } test_global_t; @@ -219,19 +220,21 @@ static int worker_thread(void *arg) test_global_t *global = thread_arg->global; test_options_t *test_options = &global->test_options; int mode = test_options->mode; + int group_mode = test_options->group_mode; uint64_t mem_size = test_options->mem_size; uint64_t copy_size = mem_size / 2; uint64_t rounds = 0; int ret = 0; uint32_t done = 0; uint64_t wait = ODP_SCHED_WAIT; + uint64_t tot_rounds = test_options->rounds * test_options->num_cpu; thr = odp_thread_id(); max_nsec = 2 * test_options->rounds * test_options->period_ns; max_time = odp_time_local_from_ns(max_nsec); printf("Thread %i starting on CPU %i\n", thr, odp_cpu_id()); - if (test_options->group_mode == 0) { + if (group_mode == 0) { /* Timeout events are load balanced. Using this * period to poll exit status. */ wait = odp_schedule_wait_time(100 * ODP_TIME_MSEC_IN_NS); @@ -280,7 +283,15 @@ static int worker_thread(void *arg) rounds++; - if (rounds < test_options->rounds) { + if (group_mode) { + if (rounds >= test_options->rounds) + done = 1; + } else { + if (odp_atomic_fetch_inc_u64(&global->tot_rounds) >= (tot_rounds - 1)) + done = 1; + } + + if (done == 0) { tmo = odp_timeout_from_event(ev); timer = odp_timeout_timer(tmo); start_param.tmo_ev = ev; @@ -291,8 +302,6 @@ static int worker_thread(void *arg) ODPH_ERR("Timer start failed (%" PRIu64 ")\n", rounds); done = 1; } - } else { - done = 1; } /* Do work */ @@ -530,7 +539,6 @@ static int start_timers(test_global_t *global) static void destroy_timers(test_global_t *global) { uint32_t i; - odp_event_t ev; test_options_t *test_options = &global->test_options; uint32_t num_cpu = test_options->num_cpu; @@ -540,9 +548,8 @@ static void destroy_timers(test_global_t *global) if (timer == ODP_TIMER_INVALID) continue; - ev = odp_timer_free(timer); - if (ev != ODP_EVENT_INVALID) - odp_event_free(ev); + if (odp_timer_free(timer)) + ODPH_ERR("Timer free failed (%u)\n", i); } if (global->timer_pool != ODP_TIMER_POOL_INVALID) @@ -744,6 +751,7 @@ int main(int argc, char **argv) memset(global, 0, sizeof(test_global_t)); odp_atomic_init_u32(&global->exit_test, 0); + odp_atomic_init_u64(&global->tot_rounds, 0); global->timer_pool = ODP_TIMER_POOL_INVALID; global->tmo_pool = ODP_POOL_INVALID; diff --git a/test/performance/odp_timer_perf.c b/test/performance/odp_timer_perf.c index 5abee1988..d5b2a6e03 100644 --- a/test/performance/odp_timer_perf.c +++ b/test/performance/odp_timer_perf.c @@ -514,7 +514,6 @@ static int destroy_timer_pool(test_global_t *global) odp_pool_t pool; odp_queue_t queue; odp_timer_t timer; - odp_event_t ev; uint32_t i, j; test_options_t *test_options = &global->test_options; uint32_t num_timer = test_options->num_timer; @@ -527,13 +526,8 @@ static int destroy_timer_pool(test_global_t *global) if (timer == ODP_TIMER_INVALID) break; - ev = odp_timer_free(timer); - - if (ev != ODP_EVENT_INVALID) { - if (test_options->mode == MODE_SCHED_OVERH) - printf("Event from timer free %i/%i\n", i, j); - odp_event_free(ev); - } + if (odp_timer_free(timer)) + printf("Timer free failed: %i/%i\n", i, j); } queue = global->queue[i]; @@ -649,15 +643,17 @@ static int sched_mode_worker(void *arg) return ret; } -static void cancel_timers(test_global_t *global, uint32_t worker_idx) +static int cancel_timers(test_global_t *global, uint32_t worker_idx) { uint32_t i, j; + int r; odp_timer_t timer; odp_event_t ev; test_options_t *test_options = &global->test_options; uint32_t num_tp = test_options->num_tp; uint32_t num_timer = test_options->num_timer; uint32_t num_worker = test_options->num_cpu; + int ret = 0; for (i = 0; i < num_tp; i++) { for (j = 0; j < num_timer; j++) { @@ -668,10 +664,20 @@ static void cancel_timers(test_global_t *global, uint32_t worker_idx) if (timer == ODP_TIMER_INVALID) continue; - if (odp_timer_cancel(timer, &ev) == ODP_TIMER_SUCCESS) + r = odp_timer_cancel(timer, &ev); + + if (r == ODP_TIMER_SUCCESS) { odp_event_free(ev); + } else if (r == ODP_TIMER_TOO_NEAR) { + ret = 1; + } else { + ret = -1; + break; + } } } + + return ret; } static int set_cancel_mode_worker(void *arg) @@ -815,7 +821,8 @@ static int set_cancel_mode_worker(void *arg) diff = odp_cpu_cycles_diff(c2, c1); /* Cancel all timers that belong to this thread */ - cancel_timers(global, worker_idx); + if (cancel_timers(global, worker_idx)) + ODPH_ERR("Timer cancel failed\n"); /* Update stats */ global->stat[thr].events = num_tmo; @@ -835,7 +842,7 @@ static int set_expire_mode_worker(void *arg) uint32_t i, j, exit_test; odp_event_t ev; odp_timeout_t tmo; - uint64_t c2, c3, c4, diff, nsec, time_ns, target_ns, period_tick; + uint64_t c2, c3, c4, diff, nsec, time_ns, target_ns, period_tick, wait; odp_timer_t timer; odp_timer_start_t start_param; odp_time_t t1, t2; @@ -937,11 +944,15 @@ static int set_expire_mode_worker(void *arg) nsec = odp_time_diff_ns(t2, t1); /* Cancel all timers that belong to this thread */ - cancel_timers(global, thread_arg->worker_idx); + status = cancel_timers(global, thread_arg->worker_idx); + + wait = ODP_SCHED_NO_WAIT; + if (status > 0) + wait = odp_schedule_wait_time(opt->period_ns); - /* Free already scheduled events */ + /* Wait and free remaining events */ while (1) { - ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT); + ev = odp_schedule(NULL, wait); if (ev == ODP_EVENT_INVALID) break; odp_event_free(ev); diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c index 5436b9b42..5fd5948b5 100644 --- a/test/validation/api/timer/timer.c +++ b/test/validation/api/timer/timer.c @@ -707,7 +707,7 @@ static void timer_pool_create_destroy(void) tim = odp_timer_alloc(tp[0], queue, USER_PTR); CU_ASSERT(tim != ODP_TIMER_INVALID); - CU_ASSERT(odp_timer_free(tim) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(tim) == 0); odp_timer_pool_destroy(tp[0]); @@ -731,7 +731,7 @@ static void timer_pool_create_destroy(void) tim = odp_timer_alloc(tp[1], queue, USER_PTR); CU_ASSERT(tim != ODP_TIMER_INVALID); - CU_ASSERT(odp_timer_free(tim) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(tim) == 0); odp_timer_pool_destroy(tp[1]); @@ -741,7 +741,7 @@ static void timer_pool_create_destroy(void) tim = odp_timer_alloc(tp[0], queue, USER_PTR); CU_ASSERT(tim != ODP_TIMER_INVALID); - CU_ASSERT(odp_timer_free(tim) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(tim) == 0); odp_timer_pool_destroy(tp[0]); @@ -816,7 +816,7 @@ static void timer_pool_create_max(void) } for (i = 0; i < num; i++) - CU_ASSERT(odp_timer_free(timer[i]) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(timer[i]) == 0); for (i = 0; i < num; i++) odp_timer_pool_destroy(tp[i]); @@ -912,7 +912,7 @@ static void timer_pool_max_res(void) odp_event_free(ev); } - CU_ASSERT(odp_timer_free(timer) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(timer) == 0); odp_timer_pool_destroy(tp); } @@ -1122,7 +1122,7 @@ static void timer_single_shot(odp_queue_type_t queue_type, odp_timer_tick_type_t free_schedule_context(queue_type); - CU_ASSERT(odp_timer_free(timer) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(timer) == 0); odp_timer_pool_destroy(tp); CU_ASSERT(odp_queue_destroy(queue) == 0); @@ -1585,7 +1585,7 @@ static void timer_test_event_type(odp_queue_type_t queue_type, } for (i = 0; i < num; i++) - CU_ASSERT(odp_timer_free(timer[i]) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(timer[i]) == 0); odp_timer_pool_destroy(timer_pool); CU_ASSERT(odp_queue_destroy(queue) == 0); @@ -1791,7 +1791,7 @@ static void timer_test_queue_type(odp_queue_type_t queue_type, int priv, int exp tick, nsec, target, (int64_t)(nsec - target)); odp_timeout_free(tmo); - CU_ASSERT(odp_timer_free(tim) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(tim) == 0); num_tmo++; } @@ -1947,9 +1947,7 @@ static void timer_test_cancel(void) odp_timeout_free(tmo); - ev = odp_timer_free(tim); - if (ev != ODP_EVENT_INVALID) - CU_FAIL_FATAL("Free returned event"); + CU_ASSERT_FATAL(odp_timer_free(tim) == 0); odp_timer_pool_destroy(tp); @@ -2135,7 +2133,7 @@ static void timer_test_tmo_limit(odp_queue_type_t queue_type, CU_ASSERT(num_tmo == num); for (i = 0; i < num; i++) - CU_ASSERT(odp_timer_free(timer[i]) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(timer[i]) == 0); odp_timer_pool_destroy(timer_pool); CU_ASSERT(odp_queue_destroy(queue) == 0); @@ -2507,7 +2505,7 @@ sleep: } for (i = 0; i < allocated; i++) { - if (odp_timer_free(tt[i].tim) != ODP_EVENT_INVALID) + if (odp_timer_free(tt[i].tim)) CU_FAIL("odp_timer_free"); } @@ -3108,7 +3106,7 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first, int CU_ASSERT(ret == 2); } - CU_ASSERT(odp_timer_free(timer) == ODP_EVENT_INVALID); + CU_ASSERT(odp_timer_free(timer) == 0); odp_timer_pool_destroy(timer_pool); CU_ASSERT(odp_queue_destroy(queue) == 0); CU_ASSERT(odp_pool_destroy(pool) == 0); -- cgit v1.2.3 From 26d99bf24fe9a70cb4796baf8a85e349b3d87e93 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 4 Dec 2023 09:43:00 +0200 Subject: api: timer: add odp_timer_pool_start_multi() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add odp_timer_pool_start_multi() function for starting timer pools, which takes the to-be-started pool handles as arguments. This can simplify implementations. A new limitation has been added to the spec, which states that timer pool handles must not be used by other APIs, except odp_timer_pool_to_u64() before being started. The old odp_timer_pool_start() function has been marked as deprecated in comments and will be properly deprecated in an upcoming release. Signed-off-by: Matias Elo Reviewed-by: Jere Leppänen Reviewed-by: Petri Savolainen Acked-by: Pavan Nikhilesh --- include/odp/api/spec/timer.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/odp/api/spec/timer.h b/include/odp/api/spec/timer.h index e8625236e..a55b8c2a2 100644 --- a/include/odp/api/spec/timer.h +++ b/include/odp/api/spec/timer.h @@ -113,6 +113,10 @@ void odp_timer_pool_param_init(odp_timer_pool_param_t *param); * The use of pool name is optional. Unique names are not required. Use odp_timer_pool_param_init() * to initialize timer pool parameters into their default values. * + * After creation a timer pool can be either started (see odp_timer_pool_start_multi()) or + * destroyed. The returned pool handle cannot be used with any other APIs, except + * odp_timer_pool_to_u64(), before the pool is successfully started. + * * Periodic timer expiration frequency is a multiple of the timer pool base frequency * (odp_timer_pool_param_t::base_freq_hz). Depending on implementation, the base frequency may need * to be selected carefully with respect to the timer pool source clock frequency. Use @@ -136,9 +140,30 @@ odp_timer_pool_t odp_timer_pool_create(const char *name, const odp_timer_pool_pa * The purpose of this call is to coordinate the creation of multiple timer * pools that may use the same underlying HW resources. * This function may be called multiple times. + * + * @deprecated Use odp_timer_pool_start_multi() instead */ void odp_timer_pool_start(void); +/** + * Start timer pools + * + * Start given timer pools. After a pool has been successfully started the pool handle can be used + * with other APIs. Each timer pool can be started only once. + * + * Returns 'num' when all given timer pools have been successfully started. If the return value + * N < 'num', only the first N pools started successfully and at least some of the remaining ones + * failed to start. In case of a negative return value, none of the pools were started. The + * unstarted timer pools cannot be used anymore (can only be destroyed). + * + * @param timer_pool Array of timer pool handles + * @param num Number of pools to start + * + * @retval num on success + * @retval Date: Thu, 14 Dec 2023 12:25:59 +0200 Subject: doc: usersguide: update timer pool management chapter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update user's guide timer pool management chapter to use new odp_timer_pool_start_multi() API. Signed-off-by: Matias Elo Reviewed-by: Jere Leppänen Reviewed-by: Petri Savolainen --- doc/users-guide/users-guide-timer.adoc | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/doc/users-guide/users-guide-timer.adoc b/doc/users-guide/users-guide-timer.adoc index f644477a0..71c66cd93 100644 --- a/doc/users-guide/users-guide-timer.adoc +++ b/doc/users-guide/users-guide-timer.adoc @@ -61,16 +61,11 @@ expired. === Timer Pool Management To facilitate implementation of the ODP timer APIs, an additional timer API is provided. During initialization, applications are expected to create the timer -pools they need and then call `odp_timer_pool_start()`. ODP implementations -may or may not fail further attempts to create timer pools after this API is -called. For best portability, applications should not attempt to create -further timer pools after calling `odp_timer_pool_start()`. Note that no such -restrictions exist on timeout pools, as these are just ordinary ODP pools. - -Following start, applications may allocate, set, cancel, and free timers -from their associated timer pools. During termination processing, after all -timers allocated from a timer pool have been freed, the pool itself should be -released via a call to `odp_timer_pool_destroy()`. +pools they need and then call `odp_timer_pool_start_multi()`. Following start, +applications may allocate, set, cancel, and free timers from their associated +timer pools. During termination processing, after all timers allocated from a +timer pool have been freed, the pool itself should be released via a call to +`odp_timer_pool_destroy()`. === Timeout Event Management The purpose of ODP timers is to schedule their associated timeout events, which -- cgit v1.2.3 From 5dc9b47a7e4af96905a8f175821a4f7530262d72 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 4 Dec 2023 10:33:58 +0200 Subject: linux-gen: timer: implement odp_timer_pool_start_multi() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement new odp_timer_pool_start_multi() function. Signed-off-by: Matias Elo Reviewed-by: Jere Leppänen Reviewed-by: Petri Savolainen --- platform/linux-generic/odp_timer.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 9fc247862..ee58eef21 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -1451,6 +1451,19 @@ void odp_timer_pool_start(void) /* Nothing to do here, timer pools are started by the create call */ } +int odp_timer_pool_start_multi(odp_timer_pool_t timer_pool[], int num) +{ + _ODP_ASSERT(timer_pool != NULL); + _ODP_ASSERT(num > 0); + if (ODP_DEBUG) { + for (int i = 0; i < num; i++) + _ODP_ASSERT(timer_pool[i] != ODP_TIMER_POOL_INVALID); + } + + /* Nothing to do here, timer pools are started by the create call. */ + return num; +} + void odp_timer_pool_destroy(odp_timer_pool_t tpid) { odp_timer_pool_del(timer_pool_from_hdl(tpid)); -- cgit v1.2.3 From 0f45938e08ed3c013c9649a78084726488e04c1d Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 4 Dec 2023 10:48:51 +0200 Subject: validation: timer: add tests for odp_timer_pool_start_multi() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update validation tests to utilize the new odp_timer_pool_start_multi() function. Signed-off-by: Matias Elo Reviewed-by: Jere Leppänen Reviewed-by: Petri Savolainen --- test/validation/api/timer/timer.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c index 5fd5948b5..923676120 100644 --- a/test/validation/api/timer/timer.c +++ b/test/validation/api/timer/timer.c @@ -703,7 +703,7 @@ static void timer_pool_create_destroy(void) tp[0] = odp_timer_pool_create("timer_pool_a", &tparam); CU_ASSERT(tp[0] != ODP_TIMER_POOL_INVALID); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&tp[0], 1) == 1); tim = odp_timer_alloc(tp[0], queue, USER_PTR); CU_ASSERT(tim != ODP_TIMER_INVALID); @@ -716,14 +716,14 @@ static void timer_pool_create_destroy(void) tp[1] = odp_timer_pool_create("timer_pool_c", &tparam); CU_ASSERT(tp[1] != ODP_TIMER_POOL_INVALID); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(tp, 2) == 2); odp_timer_pool_destroy(tp[0]); tp[0] = odp_timer_pool_create("timer_pool_d", &tparam); CU_ASSERT(tp[0] != ODP_TIMER_POOL_INVALID); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&tp[0], 1) == 1); memset(&info, 0, sizeof(odp_timer_pool_info_t)); CU_ASSERT(odp_timer_pool_info(tp[1], &info) == 0); @@ -801,7 +801,7 @@ static void timer_pool_create_max(void) CU_ASSERT_FATAL(tp[i] != ODP_TIMER_POOL_INVALID); } - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(tp, num) == (int)num); for (i = 0; i < num; i++) { timer[i] = odp_timer_alloc(tp[i], queue, USER_PTR); @@ -884,7 +884,7 @@ static void timer_pool_max_res(void) tp = odp_timer_pool_create("high_res_tp", &tp_param); CU_ASSERT_FATAL(tp != ODP_TIMER_POOL_INVALID); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&tp, 1) == 1); /* Maximum timeout length with maximum resolution */ tick = odp_timer_ns_to_tick(tp, capa.max_res.max_tmo); @@ -1039,7 +1039,7 @@ static void timer_single_shot(odp_queue_type_t queue_type, odp_timer_tick_type_t tp = odp_timer_pool_create("test_single", &tp_param); CU_ASSERT_FATAL(tp != ODP_TIMER_POOL_INVALID); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&tp, 1) == 1); timer = odp_timer_alloc(tp, queue, USER_PTR); CU_ASSERT_FATAL(timer != ODP_TIMER_INVALID); @@ -1242,6 +1242,7 @@ static void timer_pool_current_tick(void) tp = odp_timer_pool_create("cur_tick", &tp_param); CU_ASSERT_FATAL(tp != ODP_TIMER_POOL_INVALID); + /* API to be deprecated */ odp_timer_pool_start(); /* Allow +-10% error margin */ @@ -1312,7 +1313,7 @@ static void timer_pool_sample_ticks(void) tp[1] = odp_timer_pool_create("timer_pool_1", &tp_param); CU_ASSERT_FATAL(tp[1] != ODP_TIMER_POOL_INVALID); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(tp, 2) == 2); /* Allow +-10% error margin */ min[0] = odp_timer_ns_to_tick(tp[0], 0.9 * nsec); @@ -1373,7 +1374,7 @@ static void timer_pool_tick_info(void) tp = odp_timer_pool_create("tick_info_tp", &tp_param); CU_ASSERT_FATAL(tp != ODP_TIMER_POOL_INVALID); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&tp, 1) == 1); memset(&info, 0, sizeof(odp_timer_pool_info_t)); CU_ASSERT_FATAL(odp_timer_pool_info(tp, &info) == 0); @@ -1461,7 +1462,7 @@ static void timer_test_event_type(odp_queue_type_t queue_type, if (timer_pool == ODP_TIMER_POOL_INVALID) CU_FAIL_FATAL("Timer pool create failed"); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&timer_pool, 1) == 1); odp_pool_param_init(&pool_param); @@ -1690,7 +1691,7 @@ static void timer_test_queue_type(odp_queue_type_t queue_type, int priv, int exp if (tp == ODP_TIMER_POOL_INVALID) CU_FAIL_FATAL("Timer pool create failed"); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&tp, 1) == 1); odp_queue_param_init(&queue_param); if (queue_type == ODP_QUEUE_TYPE_SCHED) { @@ -1895,8 +1896,7 @@ static void timer_test_cancel(void) if (tp == ODP_TIMER_POOL_INVALID) CU_FAIL_FATAL("Timer pool create failed"); - /* Start all created timer pools */ - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&tp, 1) == 1); odp_queue_param_init(&queue_param); if (capa.queue_type_plain) { @@ -2006,7 +2006,7 @@ static void timer_test_tmo_limit(odp_queue_type_t queue_type, if (timer_pool == ODP_TIMER_POOL_INVALID) CU_FAIL_FATAL("Timer pool create failed"); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&timer_pool, 1) == 1); odp_pool_param_init(&pool_param); pool_param.type = ODP_POOL_TIMEOUT; @@ -2608,8 +2608,7 @@ static void timer_test_all(odp_queue_type_t queue_type) CU_FAIL_FATAL("Timer pool create failed"); tp = global_mem->tp; - /* Start all created timer pools */ - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&tp, 1) == 1); if (odp_timer_pool_info(tp, &tpinfo) != 0) CU_FAIL("odp_timer_pool_info"); @@ -2951,7 +2950,7 @@ static void timer_test_periodic(odp_queue_type_t queue_type, int use_first, int timer_pool = odp_timer_pool_create("periodic_timer", &timer_param); CU_ASSERT_FATAL(timer_pool != ODP_TIMER_POOL_INVALID); - odp_timer_pool_start(); + CU_ASSERT_FATAL(odp_timer_pool_start_multi(&timer_pool, 1) == 1); odp_pool_param_init(&pool_param); pool_param.type = ODP_POOL_TIMEOUT; -- cgit v1.2.3 From 2a2a53ffacf6e1103b6a689f174af8a1188a9842 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 13 Dec 2023 14:59:38 +0200 Subject: example: start using new odp_timer_pool_start_multi() call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update example applications to utilize new odp_timer_pool_start_multi() API. Signed-off-by: Matias Elo Reviewed-by: Jere Leppänen Reviewed-by: Petri Savolainen --- example/debug/odp_debug.c | 5 ++++- example/sysinfo/odp_sysinfo.c | 5 ++++- example/timer/odp_timer_accuracy.c | 6 +++++- example/timer/odp_timer_simple.c | 7 ++++++- example/timer/odp_timer_test.c | 6 +++++- test/performance/odp_bench_timer.c | 7 +++++-- test/performance/odp_sched_pktio.c | 7 +++++-- test/performance/odp_stress.c | 5 ++++- test/performance/odp_timer_perf.c | 7 +++++-- 9 files changed, 43 insertions(+), 12 deletions(-) diff --git a/example/debug/odp_debug.c b/example/debug/odp_debug.c index cca6fa939..a2f322e09 100644 --- a/example/debug/odp_debug.c +++ b/example/debug/odp_debug.c @@ -435,7 +435,10 @@ static int timer_debug(void) return -1; } - odp_timer_pool_start(); + if (odp_timer_pool_start_multi(&timer_pool, 1) != 1) { + ODPH_ERR("Timer pool start failed\n"); + return -1; + } odp_queue_param_init(&queue_param); if (timer_capa.queue_type_sched) diff --git a/example/sysinfo/odp_sysinfo.c b/example/sysinfo/odp_sysinfo.c index 0bebac4a2..3d95087a5 100644 --- a/example/sysinfo/odp_sysinfo.c +++ b/example/sysinfo/odp_sysinfo.c @@ -579,7 +579,10 @@ static int timer_capability(appl_args_t *appl_args) return -1; } - odp_timer_pool_start(); + if (odp_timer_pool_start_multi(&pool, 1) != 1) { + ODPH_ERR("odp_timer_pool_start_multi() failed for clock source: %d\n", i); + return -1; + } ret = odp_timer_pool_info(pool, info); if (ret) { diff --git a/example/timer/odp_timer_accuracy.c b/example/timer/odp_timer_accuracy.c index 83ca371d9..23c40e66f 100644 --- a/example/timer/odp_timer_accuracy.c +++ b/example/timer/odp_timer_accuracy.c @@ -671,7 +671,11 @@ static int create_timers(test_global_t *test_global) return -1; } - odp_timer_pool_start(); + if (odp_timer_pool_start_multi(&timer_pool, 1) != 1) { + ODPH_ERR("Timer pool start failed\n"); + return -1; + } + odp_timer_pool_print(timer_pool); /* Spend some time so that current tick would not be zero */ diff --git a/example/timer/odp_timer_simple.c b/example/timer/odp_timer_simple.c index b1c818c76..681f95714 100644 --- a/example/timer/odp_timer_simple.c +++ b/example/timer/odp_timer_simple.c @@ -82,7 +82,12 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) goto err; } - odp_timer_pool_start(); + if (odp_timer_pool_start_multi(&timer_pool, 1) != 1) { + ODPH_ERR("Timer pool start failed\n"); + ret += 1; + goto err; + } + /* Configure scheduler */ odp_schedule_config(NULL); diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 924ffe13f..8cda4043a 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -456,7 +456,11 @@ int main(int argc, char *argv[]) ODPH_ERR("Timer pool create failed.\n"); goto err; } - odp_timer_pool_start(); + + if (odp_timer_pool_start_multi(&gbls->tp, 1) != 1) { + ODPH_ERR("Timer pool start failed\n"); + return -1; + } odp_shm_print_all(); (void)odp_timer_pool_info(gbls->tp, &tpinfo); diff --git a/test/performance/odp_bench_timer.c b/test/performance/odp_bench_timer.c index b1c43c178..d4ac86adc 100644 --- a/test/performance/odp_bench_timer.c +++ b/test/performance/odp_bench_timer.c @@ -424,9 +424,12 @@ static int create_timer(void) return -1; } - gbl_args->timer_pool = tp; + if (odp_timer_pool_start_multi(&tp, 1) != 1) { + ODPH_ERR("Timer pool start failed\n"); + return -1; + } - odp_timer_pool_start(); + gbl_args->timer_pool = tp; gbl_args->timer_nsec = TIMER_NSEC; if (TIMER_NSEC < tp_param.min_tmo) diff --git a/test/performance/odp_sched_pktio.c b/test/performance/odp_sched_pktio.c index ceaef0898..3a85a91a5 100644 --- a/test/performance/odp_sched_pktio.c +++ b/test/performance/odp_sched_pktio.c @@ -1284,12 +1284,15 @@ static int create_timers(test_global_t *test_global) return -1; } + if (odp_timer_pool_start_multi(&timer_pool, 1) != 1) { + ODPH_ERR("Timer pool start failed\n"); + return -1; + } + test_global->timer.timer_pool = timer_pool; tick = odp_timer_ns_to_tick(timer_pool, timeout_ns); test_global->timer.timeout_tick = tick; - odp_timer_pool_start(); - for (i = 0; i < num_pktio; i++) { for (j = 0; j < num_queue; j++) { queue = test_global->pktio[i].input_queue[j]; diff --git a/test/performance/odp_stress.c b/test/performance/odp_stress.c index f18d85c89..84bc4fe6c 100644 --- a/test/performance/odp_stress.c +++ b/test/performance/odp_stress.c @@ -432,7 +432,10 @@ static int create_timers(test_global_t *global) return -1; } - odp_timer_pool_start(); + if (odp_timer_pool_start_multi(&tp, 1) != 1) { + ODPH_ERR("Timer pool start failed\n"); + return -1; + } global->period_ticks = odp_timer_ns_to_tick(tp, period_ns); diff --git a/test/performance/odp_timer_perf.c b/test/performance/odp_timer_perf.c index d5b2a6e03..8632fcb73 100644 --- a/test/performance/odp_timer_perf.c +++ b/test/performance/odp_timer_perf.c @@ -394,6 +394,11 @@ static int create_timer_pools(test_global_t *global) return -1; } + if (odp_timer_pool_start_multi(&tp, 1) != 1) { + ODPH_ERR("Timer pool start failed (%u)\n", i); + return -1; + } + pool = odp_pool_create(tp_name, &pool_param); global->pool[i] = pool; if (pool == ODP_POOL_INVALID) { @@ -413,8 +418,6 @@ static int create_timer_pools(test_global_t *global) global->timer_pool[i].start_tick = odp_timer_ns_to_tick(tp, START_NS); } - odp_timer_pool_start(); - printf(" start %" PRIu64 " tick\n", global->timer_pool[0].start_tick); printf(" period %" PRIu64 " ticks\n", global->timer_pool[0].period_tick); printf("\n"); -- cgit v1.2.3 From 9e8bed5058d9cfbd1147d1fc3b4807339ffc74d5 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 28 Nov 2023 16:07:26 +0200 Subject: api: timer: deprecate odp_timeout_fresh() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the function to check if a timeout is from a timer that was tried to be restarted or cancelled (the try failed), or from a timer that was freed. The feature is not very useful to applications, since freshness result depends on timing of those API calls vs the freshness check point. Also, an application should be able to maintain the same status information itself if needed. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo Reviewed-by: Jere Leppänen Acked-by: Pavan Nikhilesh --- example/timer/odp_timer_test.c | 8 +------- include/odp/api/spec/timer.h | 4 +++- platform/linux-generic/odp_timer.c | 2 +- test/performance/odp_bench_timer.c | 13 ------------- test/validation/api/timer/timer.c | 3 ++- 5 files changed, 7 insertions(+), 23 deletions(-) diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 8cda4043a..a397a6ac9 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -165,13 +165,7 @@ static void test_abs_timeouts(int thr, test_globals_t *gbls) tick = odp_timeout_tick(tmo); ttp = odp_timeout_user_ptr(tmo); ttp->ev = ev; - if (!odp_timeout_fresh(tmo)) { - /* Not the expected expiration tick, timer has - * been reset or cancelled or freed */ - ODPH_ABORT("Unexpected timeout received (timer " - "%" PRIu64 ", tick %" PRIu64 ")\n", - odp_timer_to_u64(ttp->tim), tick); - } + ODPH_DBG(" [%i] timeout, tick %" PRIu64 "\n", thr, tick); uint32_t rx_num = odp_atomic_fetch_dec_u32(&gbls->remain); diff --git a/include/odp/api/spec/timer.h b/include/odp/api/spec/timer.h index a55b8c2a2..6c9058520 100644 --- a/include/odp/api/spec/timer.h +++ b/include/odp/api/spec/timer.h @@ -474,8 +474,10 @@ odp_event_t odp_timeout_to_event(odp_timeout_t tmo); * @param tmo Timeout handle * @retval 1 Timeout is fresh * @retval 0 Timeout is stale + * + * @deprecated The function will be removed in a future API version. */ -int odp_timeout_fresh(odp_timeout_t tmo); +int ODP_DEPRECATE(odp_timeout_fresh)(odp_timeout_t tmo); /** * Return timer handle for the timeout diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index ee58eef21..daf187390 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -1799,7 +1799,7 @@ uint64_t odp_timeout_to_u64(odp_timeout_t tmo) return _odp_pri(tmo); } -int odp_timeout_fresh(odp_timeout_t tmo) +int ODP_DEPRECATE(odp_timeout_fresh)(odp_timeout_t tmo) { const odp_timeout_hdr_t *hdr = timeout_hdr(tmo); odp_timer_t hdl = hdr->timer; diff --git a/test/performance/odp_bench_timer.c b/test/performance/odp_bench_timer.c index d4ac86adc..a53671460 100644 --- a/test/performance/odp_bench_timer.c +++ b/test/performance/odp_bench_timer.c @@ -170,18 +170,6 @@ static int timeout_from_event(void) return i; } -static int timeout_fresh(void) -{ - int i; - odp_timeout_t timeout = gbl_args->timeout; - uint64_t *a1 = gbl_args->a1; - - for (i = 0; i < REPEAT_COUNT; i++) - a1[i] = odp_timeout_fresh(timeout); - - return i; -} - static int timeout_timer(void) { int i; @@ -274,7 +262,6 @@ bench_info_t test_suite[] = { BENCH_INFO(timer_ns_to_tick, 0, NULL), BENCH_INFO(timeout_to_event, 0, NULL), BENCH_INFO(timeout_from_event, 0, NULL), - BENCH_INFO(timeout_fresh, 0, NULL), BENCH_INFO(timeout_timer, 0, NULL), BENCH_INFO(timeout_tick, 0, NULL), BENCH_INFO(timeout_user_ptr, 0, NULL), diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c index 923676120..28b1399a2 100644 --- a/test/validation/api/timer/timer.c +++ b/test/validation/api/timer/timer.c @@ -2232,9 +2232,10 @@ static void handle_tmo(odp_event_t ev, bool stale, uint64_t prev_tick) CU_FAIL("odp_timeout_timer() wrong timer"); if (!stale) { +#if ODP_DEPRECATED_API if (!odp_timeout_fresh(tmo)) CU_FAIL("Wrong status (stale) for fresh timeout"); - +#endif /* tmo tick cannot be smaller than pre-calculated tick */ if (tick < ttp->tick) { ODPH_DBG("Too small tick: pre-calculated %" PRIu64 " " -- cgit v1.2.3 From 8892ab3b135f9213d6e2cb7c81f740a2556baf64 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 28 Nov 2023 16:51:05 +0200 Subject: doc: timer: remove timeout fresh text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed odp_timeout_fresh() references from user guide. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo Reviewed-by: Jere Leppänen --- doc/users-guide/users-guide-timer.adoc | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/doc/users-guide/users-guide-timer.adoc b/doc/users-guide/users-guide-timer.adoc index 71c66cd93..45507a872 100644 --- a/doc/users-guide/users-guide-timer.adoc +++ b/doc/users-guide/users-guide-timer.adoc @@ -113,11 +113,6 @@ while (1) { void *userptr = odp_timeout_user_ptr(timeout); uint64_t expiration = odp_timeout_tick(timeout); - if (!odp_timeout_fresh(timeout)) { - odp_timeout_free(timeout); - continue; - } - ...process the timeout event break; @@ -125,16 +120,3 @@ while (1) { } } ----- -When a worker thread receives a timeout event via `odp_schedule()`, it needs -to determine whether the event is still relevant. A timeout event that is still -relevant is said to be _fresh_ while one that is no longer relevant is said to -be _stale_. Timeouts may be stale for any number of reasons, most of which are -known only to the application itself. However, there are a few cases where the -ODP implementation may be able to assist in this determination and for those -cases the `odp_timeout_fresh()` API is provided. - -ODP defines a fresh timeout simply as one that has not been reset or -canceled since it expired. So if `odp_timeout_fresh()` returns 0 then it is -likely that the application should ignore this event, however if it returns 1 -then it remains an application responsibility to handle the event appropriate -to its needs. -- cgit v1.2.3 From 41f9792697fa6a64e831f695c53f47640b099890 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 21 Nov 2023 13:29:20 +0000 Subject: api: cls: add new packet matching rule capabilities Add new `max_pmr` and `max_pmr_per_cos` packet matching rule capabilities to `odp_cls_capability_t` to signal maximum amount of PMRs and maximum amount of PMRs per class of service, respectively, that an implementation is able to support. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo Reviewed-by: Kiran Kumar Kokkilagadda --- include/odp/api/spec/classification.h | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index 4005fad66..da4b0f6f7 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -529,11 +529,21 @@ typedef struct odp_cls_stats_capability_t { */ typedef struct odp_cls_capability_t { /** PMR terms supported by the classifier - * A bit mask of one bit for each of odp_pmr_term_t - */ + * + * A bit mask of one bit for each of odp_pmr_term_t. */ odp_cls_pmr_terms_t supported_terms; - /** Maximum number of PMR terms */ + /** Maximum number of single-term PMRs + * + * Depending on the implementation, using several/composite terms for a + * single PMR may end up incurring more than one PMR element from this + * total capacity. */ + uint32_t max_pmr; + + /** Maximum number of PMRs per CoS */ + uint32_t max_pmr_per_cos; + + /** Maximum number of terms per composite PMR */ uint32_t max_pmr_terms; /** Number of PMR terms available for use now */ @@ -542,13 +552,16 @@ typedef struct odp_cls_capability_t { /** Maximum number of CoS supported */ uint32_t max_cos; - /** Maximum number of CoSes that can have statistics enabled at the same + /** Maximum number of concurrent CoS stats + * + * Maximum number of CoSes that can have statistics enabled at the same * time. If this value is zero, then CoS level statistics are not * supported. */ uint32_t max_cos_stats; /** Maximum number of queues supported per CoS - * if the value is 1, then hashing is not supported*/ + * + * If the value is 1, then hashing is not supported. */ uint32_t max_hash_queues; /** Protocol header combination supported for Hashing */ @@ -906,7 +919,8 @@ void odp_cls_pmr_create_opt_init(odp_pmr_create_opt_t *opt); * considered to match only if a packet matches with all its terms. It is implementation specific * which term combinations are supported as composite PMRs. When creating a composite PMR, * application should check the return value and perform appropriate fallback actions if the create - * call returns failure. + * call returns failure. See odp_cls_capability_t::max_pmr and odp_cls_capability_t::max_pmr_terms + * for related capabilities. * * Use odp_cls_pmr_param_init() to initialize parameters into their default values. * -- cgit v1.2.3 From f39720f4538120466795d310878095b46ba9e309 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 21 Nov 2023 13:32:43 +0000 Subject: linux-gen: cls: fill new packet matching rule capabilities Fill new `max_pmr` and `max_pmr_per_cos` packet matching rule capabilities. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- example/sysinfo/odp_sysinfo.c | 2 ++ platform/linux-generic/odp_classification.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/example/sysinfo/odp_sysinfo.c b/example/sysinfo/odp_sysinfo.c index 3d95087a5..151701f11 100644 --- a/example/sysinfo/odp_sysinfo.c +++ b/example/sysinfo/odp_sysinfo.c @@ -987,6 +987,8 @@ int main(int argc, char **argv) printf("\n"); printf(" CLASSIFIER\n"); printf(" supported_terms: 0x%" PRIx64 "\n", cls_capa.supported_terms.all_bits); + printf(" max_pmr: %u\n", cls_capa.max_pmr); + printf(" max_pmr_per_cos: %u\n", cls_capa.max_pmr_per_cos); printf(" max_pmr_terms: %u\n", cls_capa.max_pmr_terms); printf(" available_pmr_terms: %u\n", cls_capa.available_pmr_terms); printf(" max_cos: %u\n", cls_capa.max_cos); diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index fe00384af..ef9227d4d 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -159,7 +159,9 @@ int odp_cls_capability(odp_cls_capability_t *capability) if (!pmr_tbl->pmr[i].valid) count++; - capability->max_pmr_terms = CLS_PMR_MAX_ENTRY; + capability->max_pmr = CLS_PMR_MAX_ENTRY; + capability->max_pmr_per_cos = CLS_PMR_PER_COS_MAX; + capability->max_pmr_terms = CLS_PMRTERM_MAX; capability->available_pmr_terms = count; capability->max_cos = CLS_COS_MAX_ENTRY; capability->max_cos_stats = capability->max_cos; -- cgit v1.2.3 From 45f98822433b88e67a7c70cd38d3b62703980fb9 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Wed, 22 Nov 2023 07:54:43 +0000 Subject: validation: cls: utilize new packet matching rule capabilities Utilize new `max_pmr` and `max_pmr_per_cos` packet matching rule capabilities as well as the existing `max_pmr_terms` capability. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- .../api/classification/odp_classification_basic.c | 26 ++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/test/validation/api/classification/odp_classification_basic.c b/test/validation/api/classification/odp_classification_basic.c index 9462dfde4..7131447ae 100644 --- a/test/validation/api/classification/odp_classification_basic.c +++ b/test/validation/api/classification/odp_classification_basic.c @@ -9,8 +9,6 @@ #include "odp_classification_testsuites.h" #include "classification.h" -#define PMR_SET_NUM 5 - /* Limit handle array allocation from stack to about 256kB */ #define MAX_HANDLES (32 * 1024) @@ -321,7 +319,7 @@ static void cls_max_pmr_from_default_action(int drop) CU_ASSERT_FATAL(num_cos > 1); - num_pmr = num_cos - 1; + num_pmr = capa.max_pmr_per_cos; odp_cos_t cos[num_cos]; odp_queue_t queue[num_cos]; @@ -379,8 +377,10 @@ static void cls_max_pmr_from_default_action(int drop) for (i = 0; i < num_pmr; i++) { pmr[i] = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos[i + 1]); - if (pmr[i] == ODP_PMR_INVALID) + if (pmr[i] == ODP_PMR_INVALID) { + ODPH_ERR("odp_cls_pmr_create() failed %u / %u\n", i + 1, num_pmr); break; + } val++; pmr_created++; @@ -389,6 +389,8 @@ static void cls_max_pmr_from_default_action(int drop) printf("\n Number of CoS created: %u\n Number of PMR created: %u\n", cos_created, pmr_created); + CU_ASSERT(pmr_created == num_pmr); + for (i = 0; i < pmr_created; i++) CU_ASSERT(odp_cls_pmr_destroy(pmr[i]) == 0); @@ -446,6 +448,8 @@ static void cls_create_pmr_multi(void) CU_ASSERT_FATAL(num_cos > 1); num_pmr = num_cos - 1; + if (num_pmr > capa.max_pmr) + num_pmr = capa.max_pmr; odp_cos_t src_cos[num_cos]; odp_cos_t cos[num_cos]; @@ -614,9 +618,9 @@ static void cls_cos_set_pool(void) static void cls_pmr_composite_create(void) { + odp_cls_capability_t capa; odp_pmr_t pmr_composite; int retval; - odp_pmr_param_t pmr_terms[PMR_SET_NUM]; odp_cos_t default_cos; odp_cos_t cos; odp_queue_t default_queue; @@ -626,9 +630,11 @@ static void cls_pmr_composite_create(void) odp_pool_t pkt_pool; odp_cls_cos_param_t cls_param; odp_pktio_t pktio; + uint32_t max_pmr_terms; uint16_t val = 1024; uint16_t mask = 0xffff; - int i; + + CU_ASSERT_FATAL(odp_cls_capability(&capa) == 0); pkt_pool = pool_create("pkt_pool"); CU_ASSERT_FATAL(pkt_pool != ODP_POOL_INVALID); @@ -652,7 +658,10 @@ static void cls_pmr_composite_create(void) cos = odp_cls_cos_create("pmr_match", &cls_param); CU_ASSERT(cos != ODP_COS_INVALID); - for (i = 0; i < PMR_SET_NUM; i++) { + max_pmr_terms = capa.max_pmr_terms; + odp_pmr_param_t pmr_terms[max_pmr_terms]; + + for (uint32_t i = 0; i < max_pmr_terms; i++) { odp_cls_pmr_param_init(&pmr_terms[i]); pmr_terms[i].term = ODP_PMR_TCP_DPORT; pmr_terms[i].match.value = &val; @@ -661,8 +670,7 @@ static void cls_pmr_composite_create(void) pmr_terms[i].val_sz = sizeof(val); } - pmr_composite = odp_cls_pmr_create(pmr_terms, PMR_SET_NUM, - default_cos, cos); + pmr_composite = odp_cls_pmr_create(pmr_terms, max_pmr_terms, default_cos, cos); CU_ASSERT(odp_pmr_to_u64(pmr_composite) != odp_pmr_to_u64(ODP_PMR_INVALID)); -- cgit v1.2.3 From f48906a85d070980bed63f8af533fa436aefdfd4 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 12 Dec 2023 11:30:05 +0000 Subject: api: cls: rename capability field Rename `max_pmr_terms` to `max_terms_per_pmr` to better match its intended purpose. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo Reviewed-by: Kiran Kumar Kokkilagadda --- example/sysinfo/odp_sysinfo.c | 2 +- include/odp/api/spec/classification.h | 6 +++--- platform/linux-generic/odp_classification.c | 2 +- test/validation/api/classification/odp_classification_basic.c | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/example/sysinfo/odp_sysinfo.c b/example/sysinfo/odp_sysinfo.c index 151701f11..25b308441 100644 --- a/example/sysinfo/odp_sysinfo.c +++ b/example/sysinfo/odp_sysinfo.c @@ -989,7 +989,7 @@ int main(int argc, char **argv) printf(" supported_terms: 0x%" PRIx64 "\n", cls_capa.supported_terms.all_bits); printf(" max_pmr: %u\n", cls_capa.max_pmr); printf(" max_pmr_per_cos: %u\n", cls_capa.max_pmr_per_cos); - printf(" max_pmr_terms: %u\n", cls_capa.max_pmr_terms); + printf(" max_terms_per_pmr: %u\n", cls_capa.max_terms_per_pmr); printf(" available_pmr_terms: %u\n", cls_capa.available_pmr_terms); printf(" max_cos: %u\n", cls_capa.max_cos); printf(" max_hash_queues: %u\n", cls_capa.max_hash_queues); diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index da4b0f6f7..95c6f138c 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -544,7 +544,7 @@ typedef struct odp_cls_capability_t { uint32_t max_pmr_per_cos; /** Maximum number of terms per composite PMR */ - uint32_t max_pmr_terms; + uint32_t max_terms_per_pmr; /** Number of PMR terms available for use now */ uint32_t available_pmr_terms; @@ -919,8 +919,8 @@ void odp_cls_pmr_create_opt_init(odp_pmr_create_opt_t *opt); * considered to match only if a packet matches with all its terms. It is implementation specific * which term combinations are supported as composite PMRs. When creating a composite PMR, * application should check the return value and perform appropriate fallback actions if the create - * call returns failure. See odp_cls_capability_t::max_pmr and odp_cls_capability_t::max_pmr_terms - * for related capabilities. + * call returns failure. See odp_cls_capability_t::max_pmr and + * odp_cls_capability_t::max_terms_per_pmr for related capabilities. * * Use odp_cls_pmr_param_init() to initialize parameters into their default values. * diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index ef9227d4d..0ce9d9dd6 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -161,7 +161,7 @@ int odp_cls_capability(odp_cls_capability_t *capability) capability->max_pmr = CLS_PMR_MAX_ENTRY; capability->max_pmr_per_cos = CLS_PMR_PER_COS_MAX; - capability->max_pmr_terms = CLS_PMRTERM_MAX; + capability->max_terms_per_pmr = CLS_PMRTERM_MAX; capability->available_pmr_terms = count; capability->max_cos = CLS_COS_MAX_ENTRY; capability->max_cos_stats = capability->max_cos; diff --git a/test/validation/api/classification/odp_classification_basic.c b/test/validation/api/classification/odp_classification_basic.c index 7131447ae..ca0b58ad5 100644 --- a/test/validation/api/classification/odp_classification_basic.c +++ b/test/validation/api/classification/odp_classification_basic.c @@ -630,7 +630,7 @@ static void cls_pmr_composite_create(void) odp_pool_t pkt_pool; odp_cls_cos_param_t cls_param; odp_pktio_t pktio; - uint32_t max_pmr_terms; + uint32_t max_terms_per_pmr; uint16_t val = 1024; uint16_t mask = 0xffff; @@ -658,10 +658,10 @@ static void cls_pmr_composite_create(void) cos = odp_cls_cos_create("pmr_match", &cls_param); CU_ASSERT(cos != ODP_COS_INVALID); - max_pmr_terms = capa.max_pmr_terms; - odp_pmr_param_t pmr_terms[max_pmr_terms]; + max_terms_per_pmr = capa.max_terms_per_pmr; + odp_pmr_param_t pmr_terms[max_terms_per_pmr]; - for (uint32_t i = 0; i < max_pmr_terms; i++) { + for (uint32_t i = 0; i < max_terms_per_pmr; i++) { odp_cls_pmr_param_init(&pmr_terms[i]); pmr_terms[i].term = ODP_PMR_TCP_DPORT; pmr_terms[i].match.value = &val; @@ -670,7 +670,7 @@ static void cls_pmr_composite_create(void) pmr_terms[i].val_sz = sizeof(val); } - pmr_composite = odp_cls_pmr_create(pmr_terms, max_pmr_terms, default_cos, cos); + pmr_composite = odp_cls_pmr_create(pmr_terms, max_terms_per_pmr, default_cos, cos); CU_ASSERT(odp_pmr_to_u64(pmr_composite) != odp_pmr_to_u64(ODP_PMR_INVALID)); -- cgit v1.2.3 From 47dc5d668b2406382d6a48a5d81042f442ade781 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Tue, 12 Dec 2023 11:37:56 +0000 Subject: api: cls: remove capability field Remove `available_pmr_terms` as obsolete and unused. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo Reviewed-by: Kiran Kumar Kokkilagadda --- example/sysinfo/odp_sysinfo.c | 1 - include/odp/api/spec/classification.h | 3 --- platform/linux-generic/odp_classification.c | 8 -------- 3 files changed, 12 deletions(-) diff --git a/example/sysinfo/odp_sysinfo.c b/example/sysinfo/odp_sysinfo.c index 25b308441..151388263 100644 --- a/example/sysinfo/odp_sysinfo.c +++ b/example/sysinfo/odp_sysinfo.c @@ -990,7 +990,6 @@ int main(int argc, char **argv) printf(" max_pmr: %u\n", cls_capa.max_pmr); printf(" max_pmr_per_cos: %u\n", cls_capa.max_pmr_per_cos); printf(" max_terms_per_pmr: %u\n", cls_capa.max_terms_per_pmr); - printf(" available_pmr_terms: %u\n", cls_capa.available_pmr_terms); printf(" max_cos: %u\n", cls_capa.max_cos); printf(" max_hash_queues: %u\n", cls_capa.max_hash_queues); printf(" hash_protocols: 0x%x\n", cls_capa.hash_protocols.all_bits); diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index 95c6f138c..518b2bd3c 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -546,9 +546,6 @@ typedef struct odp_cls_capability_t { /** Maximum number of terms per composite PMR */ uint32_t max_terms_per_pmr; - /** Number of PMR terms available for use now */ - uint32_t available_pmr_terms; - /** Maximum number of CoS supported */ uint32_t max_cos; diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 0ce9d9dd6..0e6eea3ae 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -151,18 +151,10 @@ void odp_cls_pmr_param_init(odp_pmr_param_t *param) int odp_cls_capability(odp_cls_capability_t *capability) { - uint32_t count = 0; - memset(capability, 0, sizeof(odp_cls_capability_t)); - - for (int i = 0; i < CLS_PMR_MAX_ENTRY; i++) - if (!pmr_tbl->pmr[i].valid) - count++; - capability->max_pmr = CLS_PMR_MAX_ENTRY; capability->max_pmr_per_cos = CLS_PMR_PER_COS_MAX; capability->max_terms_per_pmr = CLS_PMRTERM_MAX; - capability->available_pmr_terms = count; capability->max_cos = CLS_COS_MAX_ENTRY; capability->max_cos_stats = capability->max_cos; capability->pmr_range_supported = false; -- cgit v1.2.3 From 46c3d23a5314c177ce5182b32a5228c3ea3ca525 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Mon, 20 Nov 2023 16:39:18 +0200 Subject: api: time: add nanoseconds into time stamp Current time sum function (odp_time_sum()) is often used for adding nanoseconds into a time stamp. Added a new function which simplifies this use case. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen Reviewed-by: Jerin Jacob --- include/odp/api/spec/time.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/odp/api/spec/time.h b/include/odp/api/spec/time.h index 54ab5f19a..c4777fa90 100644 --- a/include/odp/api/spec/time.h +++ b/include/odp/api/spec/time.h @@ -127,6 +127,19 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1); */ uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1); +/** + * Add nanoseconds into time + * + * Adds 'ns' nanoseconds into the time stamp value. The resulting time may wrap around, if + * the sum of 'time' and 'ns' is more than 10 years from the ODP instance startup. + * + * @param time Time stamp + * @param ns Nanoseconds to be added + * + * @return Time stamp incremented by 'ns' nanoseconds + */ +odp_time_t odp_time_add_ns(odp_time_t time, uint64_t ns); + /** * Time sum * -- cgit v1.2.3 From ce3674603fe38d9a229f8faf73a1fe3acb6104b9 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Mon, 20 Nov 2023 16:58:18 +0200 Subject: linux-gen: time: implement odp_time_add_ns() Implemented the new add nanoseconds function. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen --- platform/linux-generic/include/odp/api/plat/time_inlines.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/linux-generic/include/odp/api/plat/time_inlines.h b/platform/linux-generic/include/odp/api/plat/time_inlines.h index 35a35c72e..76c9276d3 100644 --- a/platform/linux-generic/include/odp/api/plat/time_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/time_inlines.h @@ -35,6 +35,7 @@ #define odp_time_cmp __odp_time_cmp #define odp_time_diff __odp_time_diff #define odp_time_diff_ns __odp_time_diff_ns + #define odp_time_add_ns __odp_time_add_ns #define odp_time_sum __odp_time_sum #define odp_time_local_from_ns __odp_time_local_from_ns @@ -123,6 +124,15 @@ _ODP_INLINE uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1) return odp_time_to_ns(time); } +_ODP_INLINE odp_time_t odp_time_add_ns(odp_time_t time, uint64_t ns) +{ + odp_time_t t = _odp_time_from_ns(ns); + + t.u64 += time.u64; + + return t; +} + _ODP_INLINE odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2) { odp_time_t time; -- cgit v1.2.3 From 29f7e5aaba34df55ee92107ead4b7e303c254018 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Mon, 20 Nov 2023 17:12:41 +0200 Subject: linux-gen: use odp_time_add_ns() Simplify linux-gen implementation by using the new add nsec function instead of sum time stamps function. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen --- platform/linux-generic/odp_packet_io.c | 12 ++++-------- platform/linux-generic/odp_schedule_basic.c | 11 ++++------- platform/linux-generic/odp_schedule_scalable.c | 8 ++------ platform/linux-generic/odp_schedule_sp.c | 3 +-- platform/linux-generic/test/pktio_ipc/ipc_common.c | 4 +--- 5 files changed, 12 insertions(+), 26 deletions(-) diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index cef2158cb..236813e80 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -2566,14 +2566,12 @@ int odp_pktin_recv_tmo(odp_pktin_queue_t queue, odp_packet_t packets[], int num, /* Avoid unnecessary system calls. Record the start time * only when needed and after the first call to recv. */ if (odp_unlikely(!started)) { - odp_time_t t; - /* Avoid overflow issues for large wait times */ if (wait > MAX_WAIT_TIME) wait = MAX_WAIT_TIME; - t = odp_time_local_from_ns(wait * 1000); + started = 1; - t1 = odp_time_sum(odp_time_local(), t); + t1 = odp_time_add_ns(odp_time_local(), wait * 1000); } /* Check every SLEEP_CHECK rounds if total wait time @@ -2650,14 +2648,12 @@ int odp_pktin_recv_mq_tmo(const odp_pktin_queue_t queues[], uint32_t num_q, uint return 0; if (odp_unlikely(!started)) { - odp_time_t t; - /* Avoid overflow issues for large wait times */ if (wait > MAX_WAIT_TIME) wait = MAX_WAIT_TIME; - t = odp_time_local_from_ns(wait * 1000); + started = 1; - t1 = odp_time_sum(odp_time_local(), t); + t1 = odp_time_add_ns(odp_time_local(), wait * 1000); } /* Check every SLEEP_CHECK rounds if total wait time diff --git a/platform/linux-generic/odp_schedule_basic.c b/platform/linux-generic/odp_schedule_basic.c index 05eb6aa9f..7bd8cbfed 100644 --- a/platform/linux-generic/odp_schedule_basic.c +++ b/platform/linux-generic/odp_schedule_basic.c @@ -1628,7 +1628,7 @@ static inline int schedule_run(odp_queue_t *out_queue, odp_event_t out_ev[], uin static inline int schedule_loop(odp_queue_t *out_queue, uint64_t wait, odp_event_t out_ev[], uint32_t max_num) { - odp_time_t next, wtime; + odp_time_t next; int first = 1; int ret; @@ -1647,8 +1647,7 @@ static inline int schedule_loop(odp_queue_t *out_queue, uint64_t wait, break; if (first) { - wtime = odp_time_local_from_ns(wait); - next = odp_time_sum(odp_time_local(), wtime); + next = odp_time_add_ns(odp_time_local(), wait); first = 0; continue; } @@ -1677,11 +1676,9 @@ static inline int schedule_loop_sleep(odp_queue_t *out_queue, uint64_t wait, if (first) { start = odp_time_local(); - start_sleep = - odp_time_sum(start, - odp_time_local_from_ns(sched->powersave.poll_time)); + start_sleep = odp_time_add_ns(start, sched->powersave.poll_time); if (wait != ODP_SCHED_WAIT) - end = odp_time_sum(start, odp_time_local_from_ns(wait)); + end = odp_time_add_ns(start, wait); first = 0; continue; } diff --git a/platform/linux-generic/odp_schedule_scalable.c b/platform/linux-generic/odp_schedule_scalable.c index bb1549e9b..6d60c048f 100644 --- a/platform/linux-generic/odp_schedule_scalable.c +++ b/platform/linux-generic/odp_schedule_scalable.c @@ -1221,7 +1221,6 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t ev[], sched_scalable_thread_state_t *ts; int n; odp_time_t start; - odp_time_t delta; odp_time_t deadline; ts = _odp_sched_ts; @@ -1262,8 +1261,7 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t ev[], if (odp_likely(n > 0)) return n; - delta = odp_time_local_from_ns(wait); - deadline = odp_time_sum(start, delta); + deadline = odp_time_add_ns(start, wait); while (odp_time_cmp(deadline, odp_time_local()) > 0) { n = _schedule(from, ev, num); @@ -1281,7 +1279,6 @@ static odp_event_t schedule(odp_queue_t *from, uint64_t wait) sched_scalable_thread_state_t *ts; int n; odp_time_t start; - odp_time_t delta; odp_time_t deadline; ts = _odp_sched_ts; @@ -1324,8 +1321,7 @@ static odp_event_t schedule(odp_queue_t *from, uint64_t wait) if (odp_likely(n > 0)) return ev; - delta = odp_time_local_from_ns(wait); - deadline = odp_time_sum(start, delta); + deadline = odp_time_add_ns(start, wait); while (odp_time_cmp(deadline, odp_time_local()) > 0) { n = _schedule(from, &ev, num); diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c index a42955ee9..ada0677cc 100644 --- a/platform/linux-generic/odp_schedule_sp.c +++ b/platform/linux-generic/odp_schedule_sp.c @@ -683,8 +683,7 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, continue; if (update_t1) { - t1 = odp_time_sum(odp_time_local(), - odp_time_local_from_ns(wait)); + t1 = odp_time_add_ns(odp_time_local(), wait); update_t1 = 0; continue; } diff --git a/platform/linux-generic/test/pktio_ipc/ipc_common.c b/platform/linux-generic/test/pktio_ipc/ipc_common.c index d30aaf473..f693feeb2 100644 --- a/platform/linux-generic/test/pktio_ipc/ipc_common.c +++ b/platform/linux-generic/test/pktio_ipc/ipc_common.c @@ -18,14 +18,12 @@ int ipc_odp_packet_send_or_free(odp_pktio_t pktio, int sent = 0; odp_time_t start_time; odp_time_t end_time; - odp_time_t wait; odp_pktout_queue_t pktout; int i; memset(&pktout, 0, sizeof(pktout)); start_time = odp_time_local(); - wait = odp_time_local_from_ns(ODP_TIME_SEC_IN_NS); - end_time = odp_time_sum(start_time, wait); + end_time = odp_time_add_ns(start_time, ODP_TIME_SEC_IN_NS); if (odp_pktout_queue(pktio, &pktout, 1) != 1) { ODPH_ERR("no output queue\n"); -- cgit v1.2.3 From c512abdd56a790f164a3e417e3cc8f4ccc55b7d1 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 21 Nov 2023 15:48:12 +0200 Subject: validation: time: test new odp_time_add_ns() Added validation tests for the new odp_time_add_ns() function. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen --- test/validation/api/time/time.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/test/validation/api/time/time.c b/test/validation/api/time/time.c index 7664ec542..8f9cb9489 100644 --- a/test/validation/api/time/time.c +++ b/test/validation/api/time/time.c @@ -540,7 +540,7 @@ static void time_test_sum(time_cb time_cur, uint64_t res) { odp_time_t sum, t1, t2; - uint64_t nssum, ns1, ns2, ns; + uint64_t nssum, ns1, ns2, ns, diff; uint64_t upper_limit, lower_limit; /* sum timestamp and interval */ @@ -574,6 +574,27 @@ static void time_test_sum(time_cb time_cur, /* test on 0 */ sum = odp_time_sum(t2, ODP_TIME_NULL); CU_ASSERT(odp_time_cmp(t2, sum) == 0); + + /* test add nsec */ + ns = ODP_TIME_SEC_IN_NS; + upper_limit = ns + 2 * res; + lower_limit = ns - 2 * res; + + t1 = time_cur(); + t2 = odp_time_add_ns(t1, ns); + + CU_ASSERT(odp_time_cmp(t2, t1) > 0); + + diff = odp_time_diff_ns(t2, t1); + CU_ASSERT((diff <= upper_limit) && (diff >= lower_limit)); + + t1 = ODP_TIME_NULL; + t2 = odp_time_add_ns(t1, ns); + + CU_ASSERT(odp_time_cmp(t2, t1) > 0); + + diff = odp_time_diff_ns(t2, t1); + CU_ASSERT((diff <= upper_limit) && (diff >= lower_limit)); } static void time_test_local_sum(void) @@ -704,7 +725,7 @@ static void time_test_accuracy(time_cb time_cur, wait = odp_time_sum(t1[0], sec); for (i = 0; i < 5; i++) { odp_time_wait_until(wait); - wait = odp_time_sum(wait, sec); + wait = odp_time_add_ns(wait, ODP_TIME_SEC_IN_NS); } i = clock_gettime(CLOCK_MONOTONIC, &ts2); -- cgit v1.2.3 From 7ec1fd222fb3dcf9f507a98b99159fa12c4a9cb4 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 21 Nov 2023 16:00:25 +0200 Subject: test: bench_misc: test odp_time_add_ns() Added a test case for the new odp_time_add_ns() function. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen --- test/performance/odp_bench_misc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/performance/odp_bench_misc.c b/test/performance/odp_bench_misc.c index dd23c0c14..1d6b67f37 100644 --- a/test/performance/odp_bench_misc.c +++ b/test/performance/odp_bench_misc.c @@ -260,6 +260,19 @@ static int time_diff_ns(void) return i; } +static int time_add_ns(void) +{ + int i; + odp_time_t *t1 = gbl_args->t1; + odp_time_t *t3 = gbl_args->t3; + uint64_t *a1 = gbl_args->a1; + + for (i = 0; i < REPEAT_COUNT; i++) + t3[i] = odp_time_add_ns(t1[i], a1[i]); + + return i; +} + static int time_sum(void) { int i; @@ -718,6 +731,7 @@ bench_info_t test_suite[] = { BENCH_INFO(time_diff, init_time_global, 0, "time_diff (global)"), BENCH_INFO(time_diff, init_time_local, 0, "time_diff (local)"), BENCH_INFO(time_diff_ns, init_time_global, 0, NULL), + BENCH_INFO(time_add_ns, init_time_global, 0, NULL), BENCH_INFO(time_sum, init_time_global, 0, NULL), BENCH_INFO(time_to_ns_short, NULL, 0, "time_to_ns (short)"), BENCH_INFO(time_to_ns_long, NULL, 0, "time_to_ns (long)"), -- cgit v1.2.3 From fbc004659555563e58686712c999c507c985d545 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Mon, 4 Dec 2023 15:50:56 +0200 Subject: api: packet: clarify packet IO time Clarify that packet IO time is specific to the packet IO interface. This is already mentioned in odp_pktio_time() documentation. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo Acked-by: Pavan Nikhilesh --- include/odp/api/spec/packet.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index 187aedbb9..0744c5cf1 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -1847,17 +1847,18 @@ void odp_packet_flow_hash_set(odp_packet_t pkt, uint32_t flow_hash); /** * Packet timestamp * - * Returns packet timestamp value as odp_time_t type. Use time API for - * additional operations on packet timestamp values or conversion into - * nanoseconds. Use odp_packet_has_ts() to check if packet has a valid - * timestamp. Packet input interface timestamp resolution can be checked with - * odp_pktio_ts_res(). + * Returns timestamp value recorded into the packet. Use odp_packet_has_ts() to check if the packet + * has a valid timestamp. Packet input uses packet IO interface specific time source and thus + * timestamp (or nanosecond) values from one interface cannot be mixed with values from another + * interface (or time source in general). Packet IO interface timestamp resolution can be checked + * with odp_pktio_ts_res() and current time with odp_pktio_time(). + * + * Time API operations (e.g. odp_time_diff()) can be used with packet timestamp values or + * when converting those into nanoseconds (odp_time_to_ns()). * * @param pkt Packet handle * * @return Timestamp value - * - * @see odp_pktio_ts_res(), odp_packet_has_ts(), odp_time_to_ns() */ odp_time_t odp_packet_ts(odp_packet_t pkt); -- cgit v1.2.3 From 5844f7afa955693c85e33ef14f89f609e69bc39a Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Mon, 4 Dec 2023 16:51:56 +0200 Subject: api: timer: clarify timer tick Clarify that timer tick and related nanosecond values are specific to a timer pool. Also, state explicitly that those may not start from zero. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo Acked-by: Pavan Nikhilesh --- include/odp/api/spec/timer.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/odp/api/spec/timer.h b/include/odp/api/spec/timer.h index 6c9058520..1e7a06ad4 100644 --- a/include/odp/api/spec/timer.h +++ b/include/odp/api/spec/timer.h @@ -198,10 +198,14 @@ uint64_t odp_timer_ns_to_tick(odp_timer_pool_t timer_pool, uint64_t ns); * Current tick value * * Returns the current tick value of the timer pool. Timer tick is an implementation defined unit - * of time. Timer tick value increments with a constant, timer pool specific frequency. Tick - * frequency may be equal or higher than the requested timer pool resolution. The frequency can be - * checked with odp_timer_pool_info(). Tick value increments with implementation specific step - * sizes. The value will not wrap around in at least 10 years from the ODP instance startup. + * of time. Ticks and related nanosecond values are timer pool specific. Those may not start from + * zero, but are guaranteed not to wrap around in at least 10 years from the ODP instance startup. + * + * Timer tick value increments with a constant, timer pool specific frequency. Tick frequency may + * be equal or higher than the requested timer pool resolution. The frequency can be checked with + * odp_timer_pool_info(). Tick value increments with implementation specific step sizes. + * + * Use odp_timer_sample_ticks() to determine offset between tick values of two or more timer pools. * * @param timer_pool Timer pool * -- cgit v1.2.3 From 4e8e945620004c401a156aa9d7f029a9e05afdbe Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 22 Nov 2023 11:25:03 +0200 Subject: api: time: allow non-zero startup time Change local/global time specification to allow time stamp value to start from an implementation defined value. It is still guaranteed that time stamp values will not wrap around in at least 10 years. This allows implementation to return HW time counter value directly (when it won't wrap in 10 years). Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen Acked-by: Harman Kalra --- include/odp/api/spec/time.h | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/include/odp/api/spec/time.h b/include/odp/api/spec/time.h index c4777fa90..54cd147de 100644 --- a/include/odp/api/spec/time.h +++ b/include/odp/api/spec/time.h @@ -21,20 +21,24 @@ extern "C" { #include /** @defgroup odp_time ODP TIME - * Chip and CPU level wall clock time. + * SoC global and CPU local wall clock time + * * @{ */ /** * Current local time * - * Returns current local time stamp value. The local time source provides high - * resolution time, it is initialized to zero during ODP startup and will not - * wrap around in at least 10 years. - * Local time stamps are local to the calling thread and must not be shared - * with other threads. + * Returns current CPU local time stamp value. The used time source is specific to the calling + * thread and the CPU it is running on during the call. Time stamp values from different + * time sources cannot be compared or otherwise mixed. + * + * Local time stamp value advances with a constant rate defined by odp_time_local_res(). The rate + * remains constant even during dynamic CPU frequency scaling. Local time stamp and related + * nanosecond values may not start from zero, but are guaranteed not to wrap around in at least + * 10 years from the ODP instance startup. * - * @return Local time stamp. + * @return CPU local time stamp value */ odp_time_t odp_time_local(void); @@ -70,12 +74,15 @@ uint64_t odp_time_local_strict_ns(void); /** * Current global time * - * Returns current global time stamp value. The global time source provides high - * resolution time, it is initialized to zero during ODP startup and will not - * wrap around in at least 10 years. - * Global time stamps can be shared between threads. + * Returns current SoC global time stamp value. Global time stamp values read by different threads + * (or CPUs) may be compared or otherwise mixed as those come from the same time source. + * + * Global time stamp value advances with a constant rate defined by odp_time_global_res(). The rate + * remains constant even during dynamic CPU frequency scaling. Global time stamp and related + * nanosecond values may not start from zero, but are guaranteed not to wrap around in at least + * 10 years from the ODP instance startup. * - * @return Global time stamp. + * @return SoC global time stamp value */ odp_time_t odp_time_global(void); -- cgit v1.2.3 From c38d517f002f3880f003e74390b653dabd751aa0 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 22 Nov 2023 11:58:01 +0200 Subject: api: time: add ODP startup time request Added function to request startup time of the ODP instance. When time stamps may not start from zero anymore, this call can be used to calculate time stamps relative to ODP startup. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen Acked-by: Harman Kalra --- include/odp/api/spec/time.h | 10 ++++++++++ include/odp/api/spec/time_types.h | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/odp/api/spec/time.h b/include/odp/api/spec/time.h index 54cd147de..082df7bd6 100644 --- a/include/odp/api/spec/time.h +++ b/include/odp/api/spec/time.h @@ -228,6 +228,16 @@ void odp_time_wait_until(odp_time_t time); */ void odp_time_wait_ns(uint64_t ns); +/** + * Get ODP instance startup time + * + * Outputs time stamp values captured at ODP instance startup. Application may use those + * to calculate time stamp values relative to ODP startup time. + * + * @param[out] startup Startup time structure for output + */ +void odp_time_startup(odp_time_startup_t *startup); + /** * @} */ diff --git a/include/odp/api/spec/time_types.h b/include/odp/api/spec/time_types.h index 5f5685745..cf0393ef0 100644 --- a/include/odp/api/spec/time_types.h +++ b/include/odp/api/spec/time_types.h @@ -49,6 +49,18 @@ extern "C" { * Zero time stamp */ +/** + * Time stamp values at ODP startup + */ +typedef struct odp_time_startup_t { + /** Global time at ODP startup */ + odp_time_t global; + + /** Global time in nanoseconds at ODP startup */ + uint64_t global_ns; + +} odp_time_startup_t; + /** * @} */ -- cgit v1.2.3 From fe657362a2fea7b4c832b39c5e66a79ef3c75ecb Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 22 Nov 2023 12:14:10 +0200 Subject: api: time: clarify odp_time_sum() specification Add notification that resulting time stamp may wrap around if large time stamp values are summed up. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen Acked-by: Harman Kalra --- include/odp/api/spec/time.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/odp/api/spec/time.h b/include/odp/api/spec/time.h index 082df7bd6..c3571f7fa 100644 --- a/include/odp/api/spec/time.h +++ b/include/odp/api/spec/time.h @@ -150,6 +150,10 @@ odp_time_t odp_time_add_ns(odp_time_t time, uint64_t ns); /** * Time sum * + * Returns the sum of time stamp values. Time stamps must be from the same time source (global or + * local). The resulting time may wrap around, if the sum exceeds 10 years from the ODP instance + * startup. + * * @param t1 Time stamp * @param t2 Time stamp * -- cgit v1.2.3 From b45d04d31c7d97cfa950483da70c42b47209483a Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 22 Nov 2023 16:37:54 +0200 Subject: validation: time: do not require zero startup time Time does not have to start from zero anymore. Check that 64 bit nanosecond time has enough room not to wrap around in 10 years. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen --- test/validation/api/time/time.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/test/validation/api/time/time.c b/test/validation/api/time/time.c index 8f9cb9489..b783cad94 100644 --- a/test/validation/api/time/time.c +++ b/test/validation/api/time/time.c @@ -25,6 +25,7 @@ #define TIME_TOLERANCE_NS 1000000 #define TIME_TOLERANCE_CI_NS 40000000 #define GLOBAL_SHM_NAME "GlobalTimeTest" +#define YEAR_IN_NS (365 * 24 * ODP_TIME_HOUR_IN_NS) static uint64_t local_res; static uint64_t global_res; @@ -225,6 +226,7 @@ static void time_test_monotony(void) uint64_t gs_ns1, gs_ns2, gs_ns3; uint64_t ns1, ns2, ns3; uint64_t s_ns1, s_ns2, s_ns3; + uint64_t limit; l_t1 = odp_time_local(); ls_t1 = odp_time_local_strict(); @@ -276,12 +278,13 @@ static void time_test_monotony(void) s_ns2 = odp_time_to_ns(ls_t2); s_ns3 = odp_time_to_ns(ls_t3); - /* Time counting starts from zero. Assuming that the ODP instance has run - * less than 10 minutes before running this test case. */ - CU_ASSERT(ns1 < 10 * ODP_TIME_MIN_IN_NS); - CU_ASSERT(s_ns1 < 10 * ODP_TIME_MIN_IN_NS); - CU_ASSERT(l_ns1 < 10 * ODP_TIME_MIN_IN_NS); - CU_ASSERT(ls_ns1 < 10 * ODP_TIME_MIN_IN_NS); + /* Time should not wrap in at least 10 years from ODP start. Ignoring delay from start up + * and other test cases, which should be few seconds. */ + limit = 10 * YEAR_IN_NS; + CU_ASSERT(UINT64_MAX - ns1 > limit); + CU_ASSERT(UINT64_MAX - s_ns1 > limit); + CU_ASSERT(UINT64_MAX - l_ns1 > limit); + CU_ASSERT(UINT64_MAX - ls_ns1 > limit); /* Time stamp */ CU_ASSERT(ns2 > ns1); @@ -321,12 +324,13 @@ static void time_test_monotony(void) s_ns2 = odp_time_to_ns(gs_t2); s_ns3 = odp_time_to_ns(gs_t3); - /* Time counting starts from zero. Assuming that the ODP instance has run - * less than 10 minutes before running this test case. */ - CU_ASSERT(ns1 < 10 * ODP_TIME_MIN_IN_NS); - CU_ASSERT(s_ns1 < 10 * ODP_TIME_MIN_IN_NS); - CU_ASSERT(g_ns1 < 10 * ODP_TIME_MIN_IN_NS); - CU_ASSERT(gs_ns1 < 10 * ODP_TIME_MIN_IN_NS); + /* Time should not wrap in at least 10 years from ODP start. Ignoring delay from start up + * and other test cases, which should be few seconds. */ + limit = 10 * YEAR_IN_NS; + CU_ASSERT(UINT64_MAX - ns1 > limit); + CU_ASSERT(UINT64_MAX - s_ns1 > limit); + CU_ASSERT(UINT64_MAX - g_ns1 > limit); + CU_ASSERT(UINT64_MAX - gs_ns1 > limit); /* Time stamp */ CU_ASSERT(ns2 > ns1); -- cgit v1.2.3 From d2588efa504fa78a7670f2848e34c57abfebab93 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 22 Nov 2023 15:45:43 +0200 Subject: linux-gen: time: change to non-zero startup time Time does not have to start from zero anymore. Optimize time stamp performance by returning the counter value directly. Implemented the new startup time function. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen --- .../arch/common/odp/api/abi/time_cpu_inlines.h | 13 +++++-- platform/linux-generic/arch/common/odp_time_cpu.c | 28 ++++++++++++++- .../arch/default/odp/api/abi/time_inlines.h | 1 + platform/linux-generic/arch/default/odp_time.c | 40 ++++++++++++++-------- .../include/odp/api/plat/time_inlines.h | 6 ++++ 5 files changed, 69 insertions(+), 19 deletions(-) diff --git a/platform/linux-generic/arch/common/odp/api/abi/time_cpu_inlines.h b/platform/linux-generic/arch/common/odp/api/abi/time_cpu_inlines.h index c154c5f1a..553114666 100644 --- a/platform/linux-generic/arch/common/odp/api/abi/time_cpu_inlines.h +++ b/platform/linux-generic/arch/common/odp/api/abi/time_cpu_inlines.h @@ -21,8 +21,9 @@ extern "C" { #define _ODP_TIME_GIGA_HZ 1000000000ULL typedef struct _odp_time_global_t { - uint64_t start_time; uint64_t freq_hz; + uint64_t start_time; + uint64_t start_time_ns; } _odp_time_global_t; @@ -32,7 +33,7 @@ static inline odp_time_t _odp_time_cur(void) { odp_time_t time; - time.count = _odp_time_cpu_global() - _odp_time_glob.start_time; + time.count = _odp_time_cpu_global(); return time; } @@ -40,7 +41,7 @@ static inline odp_time_t _odp_time_cur_strict(void) { odp_time_t time; - time.count = _odp_time_cpu_global_strict() - _odp_time_glob.start_time; + time.count = _odp_time_cpu_global_strict(); return time; } @@ -86,6 +87,12 @@ static inline uint64_t _odp_time_res(void) return _odp_time_glob.freq_hz; } +static inline void _odp_time_startup(odp_time_startup_t *startup) +{ + startup->global.count = _odp_time_glob.start_time; + startup->global_ns = _odp_time_glob.start_time_ns; +} + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/arch/common/odp_time_cpu.c b/platform/linux-generic/arch/common/odp_time_cpu.c index bbfe82e21..3c392de0c 100644 --- a/platform/linux-generic/arch/common/odp_time_cpu.c +++ b/platform/linux-generic/arch/common/odp_time_cpu.c @@ -17,6 +17,8 @@ #include #include +#define YEAR_IN_SEC (365 * 24 * 3600) + #include _odp_time_global_t _odp_time_glob; @@ -25,6 +27,8 @@ _odp_time_global_t _odp_time_glob; int _odp_time_init_global(void) { + uint64_t count, diff, years; + odp_time_t time; _odp_time_global_t *global = &_odp_time_glob; memset(global, 0, sizeof(_odp_time_global_t)); @@ -38,7 +42,29 @@ int _odp_time_init_global(void) _ODP_PRINT("HW time counter freq: %" PRIu64 " hz\n\n", global->freq_hz); - global->start_time = _odp_time_cpu_global(); + count = _odp_time_cpu_global(); + time.count = count; + global->start_time = count; + global->start_time_ns = _odp_time_to_ns(time); + + /* Make sure that counters will not wrap */ + diff = UINT64_MAX - count; + years = (diff / global->freq_hz) / YEAR_IN_SEC; + + if (years < 10) { + _ODP_ERR("Time counter would wrap in 10 years: %" PRIu64 "\n", count); + return -1; + } + + diff = UINT64_MAX - global->start_time_ns; + years = (diff / ODP_TIME_SEC_IN_NS) / YEAR_IN_SEC; + + if (years < 10) { + _ODP_ERR("Time in nsec would wrap in 10 years: %" PRIu64 "\n", + global->start_time_ns); + return -1; + } + return 0; } diff --git a/platform/linux-generic/arch/default/odp/api/abi/time_inlines.h b/platform/linux-generic/arch/default/odp/api/abi/time_inlines.h index b38e52dac..ed0ffdb3f 100644 --- a/platform/linux-generic/arch/default/odp/api/abi/time_inlines.h +++ b/platform/linux-generic/arch/default/odp/api/abi/time_inlines.h @@ -18,6 +18,7 @@ extern "C" { odp_time_t _odp_time_cur(void); uint64_t _odp_time_res(void); +void _odp_time_startup(odp_time_startup_t *startup); static inline odp_time_t _odp_time_cur_strict(void) { diff --git a/platform/linux-generic/arch/default/odp_time.c b/platform/linux-generic/arch/default/odp_time.c index 919a3ba68..664a5deae 100644 --- a/platform/linux-generic/arch/default/odp_time.c +++ b/platform/linux-generic/arch/default/odp_time.c @@ -16,31 +16,24 @@ #include #include +#include #include #include #include +#define YEAR_IN_SEC (365 * 24 * 3600) + typedef struct _odp_time_global_t { struct timespec start_time; + uint64_t start_time_ns; } _odp_time_global_t; _odp_time_global_t _odp_time_glob; -static inline uint64_t time_diff_nsec(struct timespec *t2, struct timespec *t1) +static inline uint64_t time_nsec(struct timespec *t) { - struct timespec diff; - uint64_t nsec; - - diff.tv_sec = t2->tv_sec - t1->tv_sec; - diff.tv_nsec = t2->tv_nsec - t1->tv_nsec; - - if (diff.tv_nsec < 0) { - diff.tv_nsec += ODP_TIME_SEC_IN_NS; - diff.tv_sec -= 1; - } - - nsec = (diff.tv_sec * ODP_TIME_SEC_IN_NS) + diff.tv_nsec; + uint64_t nsec = (t->tv_sec * ODP_TIME_SEC_IN_NS) + t->tv_nsec; return nsec; } @@ -52,13 +45,12 @@ odp_time_t _odp_time_cur(void) int ret; odp_time_t time; struct timespec sys_time; - struct timespec *start_time = &_odp_time_glob.start_time; ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time); if (odp_unlikely(ret != 0)) _ODP_ABORT("clock_gettime() failed\n"); - time.nsec = time_diff_nsec(&sys_time, start_time); + time.nsec = time_nsec(&sys_time); return time; } @@ -75,11 +67,18 @@ uint64_t _odp_time_res(void) return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; } +void _odp_time_startup(odp_time_startup_t *startup) +{ + startup->global.nsec = _odp_time_glob.start_time_ns; + startup->global_ns = _odp_time_glob.start_time_ns; +} + #include int _odp_time_init_global(void) { struct timespec *start_time; + uint64_t diff, years; int ret = 0; _odp_time_global_t *global = &_odp_time_glob; @@ -93,6 +92,17 @@ int _odp_time_init_global(void) if (ret) _ODP_ERR("clock_gettime() failed: %d\n", ret); + global->start_time_ns = time_nsec(start_time); + + diff = UINT64_MAX - global->start_time_ns; + years = (diff / ODP_TIME_SEC_IN_NS) / YEAR_IN_SEC; + + if (years < 10) { + _ODP_ERR("Time in nsec would wrap in 10 years: %" PRIu64 "\n", + global->start_time_ns); + return -1; + } + return ret; } diff --git a/platform/linux-generic/include/odp/api/plat/time_inlines.h b/platform/linux-generic/include/odp/api/plat/time_inlines.h index 76c9276d3..8ead06f7b 100644 --- a/platform/linux-generic/include/odp/api/plat/time_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/time_inlines.h @@ -46,6 +46,7 @@ #define odp_time_wait_ns __odp_time_wait_ns #define odp_time_wait_until __odp_time_wait_until + #define odp_time_startup __odp_time_startup #else #define _ODP_INLINE #endif @@ -180,6 +181,11 @@ _ODP_INLINE void odp_time_wait_ns(uint64_t ns) odp_time_wait_until(end_time); } +_ODP_INLINE void odp_time_startup(odp_time_startup_t *startup) +{ + _odp_time_startup(startup); +} + /** @endcond */ #endif -- cgit v1.2.3 From 622150bcf2d2d6896bb3285a00f9661bc50afb4d Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 22 Nov 2023 17:13:04 +0200 Subject: validation: time: add startup time test Added a test case for the new odp_time_startup() function. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen --- test/validation/api/time/time.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/validation/api/time/time.c b/test/validation/api/time/time.c index b783cad94..8d3481e26 100644 --- a/test/validation/api/time/time.c +++ b/test/validation/api/time/time.c @@ -146,6 +146,35 @@ static void time_test_constants(void) CU_ASSERT(ns == ODP_TIME_USEC_IN_NS); } +static void time_test_startup_time(void) +{ + odp_time_startup_t startup; + uint64_t ns1, ns2, ns3; + odp_time_t time; + + memset(&startup, 0, sizeof(odp_time_startup_t)); + + odp_time_startup(&startup); + ns1 = startup.global_ns; + ns2 = odp_time_to_ns(startup.global); + + CU_ASSERT(UINT64_MAX - ns1 >= 10 * YEAR_IN_NS); + CU_ASSERT(UINT64_MAX - ns2 >= 10 * YEAR_IN_NS); + + time = odp_time_global(); + ns3 = odp_time_to_ns(time); + CU_ASSERT(odp_time_cmp(time, startup.global) > 0); + + time = odp_time_global_from_ns(10 * YEAR_IN_NS); + time = odp_time_sum(startup.global, time); + CU_ASSERT(odp_time_cmp(time, startup.global) > 0); + + printf("\n"); + printf(" Startup time in nsec: %" PRIu64 "\n", ns1); + printf(" Startup time to nsec: %" PRIu64 "\n", ns2); + printf(" Nsec since startup: %" PRIu64 "\n\n", ns3 - startup.global_ns); +} + static void time_test_res(time_res_cb time_res, uint64_t *res) { uint64_t rate; @@ -939,6 +968,7 @@ static void time_test_global_sync_control(void) odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_constants), + ODP_TEST_INFO(time_test_startup_time), ODP_TEST_INFO(time_test_local_res), ODP_TEST_INFO(time_test_local_conversion), ODP_TEST_INFO(time_test_local_cmp), -- cgit v1.2.3 From 12e96ee62b60031bd5e24c6df8687304aa86de03 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 23 Nov 2023 10:49:18 +0200 Subject: test: bench_misc: test odp_time_startup() Added a test case for the new odp_time_startup() function. Signed-off-by: Petri Savolainen Reviewed-by: Janne Peltonen --- test/performance/odp_bench_misc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/performance/odp_bench_misc.c b/test/performance/odp_bench_misc.c index 1d6b67f37..64318938a 100644 --- a/test/performance/odp_bench_misc.c +++ b/test/performance/odp_bench_misc.c @@ -375,6 +375,20 @@ static int time_global_res(void) return i; } +static int time_startup(void) +{ + int i; + uint64_t *a1 = gbl_args->a1; + odp_time_startup_t startup; + + for (i = 0; i < REPEAT_COUNT; i++) { + odp_time_startup(&startup); + a1[i] = startup.global_ns; + } + + return i; +} + static int cpu_id(void) { int i; @@ -740,6 +754,7 @@ bench_info_t test_suite[] = { BENCH_INFO(time_cmp, init_time_global, 0, NULL), BENCH_INFO(time_local_res, NULL, 0, NULL), BENCH_INFO(time_global_res, NULL, 0, NULL), + BENCH_INFO(time_startup, NULL, 0, NULL), BENCH_INFO(cpu_id, NULL, 0, NULL), BENCH_INFO(cpu_count, NULL, 0, NULL), BENCH_INFO(cpu_hz, NULL, 1, NULL), -- cgit v1.2.3 From 2e5df675b662f0a1fdcb5726acd5f317580c3e96 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 17 Nov 2023 17:13:08 +0200 Subject: api: packet: clarify don't free option Clarify that the option does not affect direct packet free calls. Signed-off-by: Petri Savolainen Reviewed-by: Tuomas Taipale Acked-by: Nithin Dabilpuram --- include/odp/api/spec/packet.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index 0744c5cf1..ca22280ec 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -2087,21 +2087,21 @@ int odp_packet_has_tx_compl_request(odp_packet_t pkt); /** * Set packet free control option * - * This option enables application to control which packets are freed/not freed back into pool - * after ODP implementation has finished processing those. The option affects only packets that - * are transmitted directly through a packet output interface (also with LSO), i.e. packets - * transmitted through inline IPsec or TM are not affected. - * - * When the option is set to #ODP_PACKET_FREE_CTRL_DONT_FREE, packet output interface will not free - * the packet after transmit and application may reuse the packet as soon as its transmit is - * complete (see e.g. odp_packet_tx_compl_done()). - * - * The option must not be enabled on packets that have multiple references. - * - * Check packet IO interface capability free_ctrl.dont_free (odp_pktio_capability_t::dont_free) for - * the option support. When an interface does not support the option, it ignores the value. - * - * The default value is #ODP_PACKET_FREE_CTRL_DISABLED. + * This option enables application to control if a packet is freed/not freed back into a pool + * after an ODP offload feature has finished processing it. The option does not have an effect on + * odp_packet_free() or other direct free calls. It affects only packets that are sent directly + * through a packet output interface queue (odp_pktout_queue_t or odp_queue_t), also when packets + * are LSO offloaded. Packets transmitted through inline IPsec or TM are not affected. + * + * Packet output interface frees transmitted packets by default. When the option is set to + * #ODP_PACKET_FREE_CTRL_DONT_FREE, packet output will not free the packet after transmit and + * application may reuse or free the packet as soon as its transmission is complete + * (see e.g. odp_packet_tx_compl_done()). Check packet IO interface capability free_ctrl.dont_free + * (odp_pktio_capability_t.free_ctrl) for the option support. When an interface does not support + * the option, it ignores the value. + * + * The option must not be enabled on packets that have multiple references. The default value is + * #ODP_PACKET_FREE_CTRL_DISABLED. * * @param pkt Packet handle * @param ctrl Packet free control option value -- cgit v1.2.3 From bedae84d86942adbf9b1a5ec7de20c5bdeba117a Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 19 Dec 2023 12:42:48 +0200 Subject: validation: pktio: add tx completion index checks Check that odp_packet_tx_compl_done() returns initially zero and that it does not clear completion status. Signed-off-by: Petri Savolainen Reviewed-by: Matias Elo --- test/validation/api/pktio/pktio.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/test/validation/api/pktio/pktio.c b/test/validation/api/pktio/pktio.c index 3abf2dd0e..780d83066 100644 --- a/test/validation/api/pktio/pktio.c +++ b/test/validation/api/pktio/pktio.c @@ -3776,6 +3776,11 @@ static void pktio_test_pktout_compl_poll(void) pktio_rx_info.inq = ODP_QUEUE_INVALID; pktio_rx_info.in_mode = ODP_PKTIN_MODE_DIRECT; + for (i = 0; i < TX_BATCH_LEN; i++) { + /* Completion status is initially zero */ + CU_ASSERT(odp_packet_tx_compl_done(pktio_tx, i) == 0); + } + ret = create_packets(pkt_tbl, pkt_seq, TX_BATCH_LEN, pktio_tx, pktio_rx); CU_ASSERT_FATAL(ret == TX_BATCH_LEN); @@ -3805,6 +3810,9 @@ static void pktio_test_pktout_compl_poll(void) CU_ASSERT(odp_packet_has_tx_compl_request(pkt_tbl[i]) != 0); /* Set pkt sequence number as its user ptr */ odp_packet_user_ptr_set(pkt_tbl[i], (const void *)&pkt_seq[i]); + + /* Completion status should be still zero after odp_packet_tx_compl_request() */ + CU_ASSERT(odp_packet_tx_compl_done(pktio_tx, i) == 0); } CU_ASSERT_FATAL(odp_pktout_send(pktout_queue, pkt_tbl, TX_BATCH_LEN) == TX_BATCH_LEN); @@ -3815,10 +3823,12 @@ static void pktio_test_pktout_compl_poll(void) for (i = 0; i < num_rx; i++) odp_packet_free(pkt_tbl[i]); - /* Transmits should be complete since we received the packets already */ for (i = 0; i < num_rx; i++) { - ret = odp_packet_tx_compl_done(pktio_tx, i); - CU_ASSERT(ret > 0); + /* Transmits should be complete since we received the packets already */ + CU_ASSERT(odp_packet_tx_compl_done(pktio_tx, i) > 0); + + /* Check that the previous call did not clear the status */ + CU_ASSERT(odp_packet_tx_compl_done(pktio_tx, i) > 0); } for (i = 0; i < num_ifaces; i++) { -- cgit v1.2.3 From 733d38dd110637dab0a74b990358f6c193930807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jere=20Lepp=C3=A4nen?= Date: Fri, 9 Jun 2023 10:56:53 +0300 Subject: quell false positive GCC 13.1 warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quell false positive GCC 13.1 -Warray-bounds and -Wstringop-overflow warnings. The warnings still appear during LTO linking, because GCC does not carry diagnostic pragmas to the linking stage. Signed-off-by: Jere Leppänen Reviewed-by: Janne Peltonen --- example/packet/odp_pktio.c | 3 +++ platform/linux-generic/odp_schedule_sp.c | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c index df4528d18..191d9fdb6 100644 --- a/example/packet/odp_pktio.c +++ b/example/packet/odp_pktio.c @@ -521,7 +521,10 @@ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len) odp_packet_free(pkt); /* Drop */ pkt_cnt--; } else if (odp_unlikely(i != j++)) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" pkt_tbl[j-1] = pkt; +#pragma GCC diagnostic pop } } diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c index ada0677cc..030e95171 100644 --- a/platform/linux-generic/odp_schedule_sp.c +++ b/platform/linux-generic/odp_schedule_sp.c @@ -799,6 +799,11 @@ static odp_schedule_group_t schedule_group_create(const char *name, if (!sched_group->s.group[i].allocated) { char *grp_name = sched_group->s.group[i].name; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#if __GNUC__ >= 13 +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif if (name == NULL) { grp_name[0] = 0; } else { @@ -806,6 +811,7 @@ static odp_schedule_group_t schedule_group_create(const char *name, ODP_SCHED_GROUP_NAME_LEN - 1); grp_name[ODP_SCHED_GROUP_NAME_LEN - 1] = 0; } +#pragma GCC diagnostic pop odp_thrmask_copy(&sched_group->s.group[i].mask, thrmask); sched_group->s.group[i].allocated = 1; -- cgit v1.2.3 From 2ecf3e3fd8064bafdbba8dfa8cd7c527241e492b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jere=20Lepp=C3=A4nen?= Date: Mon, 12 Jun 2023 13:55:49 +0300 Subject: linux-gen: pktio: fix flexible array member error in pedantic compilation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When compiling with GCC 13.1 and -Wpedantic, struct sset_info causes the error "invalid use of structure with flexible array member [-Werror=pedantic]". The flexible array member in this case is the data member of struct ethtool_sset_info. In order to reserve space for it, turn sset_info into a union, and make the next member in the union the size of struct ethtool_sset_info and the data. Signed-off-by: Jere Leppänen Reviewed-by: Janne Peltonen --- platform/linux-generic/pktio/stats/ethtool_stats.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/pktio/stats/ethtool_stats.c b/platform/linux-generic/pktio/stats/ethtool_stats.c index deb00bf59..bbf0729f1 100644 --- a/platform/linux-generic/pktio/stats/ethtool_stats.c +++ b/platform/linux-generic/pktio/stats/ethtool_stats.c @@ -29,9 +29,11 @@ static struct ethtool_gstrings *get_stringset(int fd, struct ifreq *ifr) { - struct { + union { struct ethtool_sset_info hdr; - uint32_t buf[1]; /* overlaps with hdr.data[] */ + /* Reserve space for hdr.data. */ + uint8_t buf[sizeof(struct ethtool_sset_info) + + sizeof(((struct ethtool_sset_info *)0)->data[0])]; } sset_info; struct ethtool_drvinfo drvinfo; uint32_t len; -- cgit v1.2.3 From bcc3a8c36f39b13d34e9de14e9962cbc67229dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jere=20Lepp=C3=A4nen?= Date: Mon, 12 Jun 2023 14:21:58 +0300 Subject: configure: add -Wno-error=stringop-overflow also to CXXFLAGS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also c++ programs need -Wno-error=stringop-overflow flag, in order to avoid errors during linking, when using LTO. Signed-off-by: Jere Leppänen Reviewed-by: Janne Peltonen --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 8459553b4..18b3861d9 100644 --- a/configure.ac +++ b/configure.ac @@ -120,6 +120,7 @@ AS_IF([test "$GCC" == yes], AS_IF([test `$CC -dumpversion | cut -d '.' -f 1` -ge 10], ODP_CHECK_CFLAG([-Wno-error=array-bounds]) ODP_CHECK_CFLAG([-Wno-error=stringop-overflow]) + ODP_CHECK_CXXFLAG([-Wno-error=stringop-overflow]) ) ) -- cgit v1.2.3 From 7f463e426c07b80f34990370870b09cd77de9187 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Fri, 15 Dec 2023 14:42:59 +0000 Subject: test: dma_perf: add new option Add new option to verify correctness of successfully transferred data. This can be useful in the unlikely occurrences of data corruption caused by a DMA subsystem. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf.c | 104 +++++++++++++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 18 deletions(-) diff --git a/test/performance/odp_dma_perf.c b/test/performance/odp_dma_perf.c index 09943a9d6..21c9c0558 100644 --- a/test/performance/odp_dma_perf.c +++ b/test/performance/odp_dma_perf.c @@ -68,6 +68,8 @@ enum { #define MEGAS 1000000 #define KILOS 1000 +#define DATA 0xAA + typedef enum { PRS_OK, PRS_NOK, @@ -81,6 +83,7 @@ typedef struct { uint64_t poll_errs; uint64_t scheduler_timeouts; uint64_t transfer_errs; + uint64_t data_errs; uint64_t tot_tm; uint64_t trs_tm; uint64_t max_trs_tm; @@ -111,6 +114,7 @@ typedef struct { } trs_info_t; typedef struct sd_s sd_t; +typedef void (*ver_fn_t)(trs_info_t *info, stats_t *stats); typedef struct ODP_ALIGNED_CACHE sd_s { struct { @@ -149,6 +153,8 @@ typedef struct ODP_ALIGNED_CACHE sd_s { odp_schedule_group_t grp; /* Prepare single transfer. */ void (*prep_trs_fn)(sd_t *sd, trs_info_t *info); + /* Verify single transfer. */ + ver_fn_t ver_fn; } sd_t; typedef struct prog_config_s prog_config_t; @@ -201,6 +207,7 @@ typedef struct prog_config_s { uint32_t src_cache_size; uint32_t dst_cache_size; int num_workers; + odp_bool_t is_verify; uint8_t trs_type; uint8_t seg_type; uint8_t compl_mode; @@ -276,7 +283,7 @@ static void print_usage(void) " " PROG_NAME " -s 10240\n" " " PROG_NAME " -t 0 -i 1 -o 1 -s 51200 -S 2 -f 64 -T 10\n" " " PROG_NAME " -t 1 -i 10 -o 10 -s 4096 -S 0 -m 1 -f 10 -c 4 -p 1\n" - " " PROG_NAME " -t 2 -i 10 -o 1 -s 1024 -S 3 -m 1 -f 10 -c 4 -p 1\n" + " " PROG_NAME " -t 2 -i 10 -o 1 -s 1024 -S 3 -f 10 -c 4 -p 1\n" "\n" "Optional OPTIONS:\n" "\n" @@ -317,6 +324,8 @@ static void print_usage(void) " Policies:\n" " 0: One session shared by workers\n" " 1: One session per worker\n" + " -v, --verify Verify transfers. Checks correctness of destination data\n" + " after successful transfers.\n" " -h, --help This help.\n" "\n", DEF_TRS_TYPE, DEF_SEG_CNT, DEF_SEG_CNT, DEF_LEN, DEF_SEG_TYPE, DEF_MODE, DEF_INFLIGHT, DEF_TIME, DEF_WORKERS, DEF_POLICY); @@ -551,10 +560,11 @@ static parse_result_t parse_options(int argc, char **argv, prog_config_t *config { "time_sec", required_argument, NULL, 'T' }, { "worker_count", required_argument, NULL, 'c' }, { "policy", required_argument, NULL, 'p' }, + { "verify", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; - static const char *shortopts = "t:i:o:s:S:m:f:T:c:p:h"; + static const char *shortopts = "t:i:o:s:S:m:f:T:c:p:vh"; init_config(config); @@ -595,6 +605,9 @@ static parse_result_t parse_options(int argc, char **argv, prog_config_t *config case 'p': config->policy = atoi(optarg); break; + case 'v': + config->is_verify = true; + break; case 'h': print_usage(); return PRS_TERM; @@ -711,6 +724,11 @@ static odp_bool_t setup_packet_segments(sd_t *sd) (sd->seg.seg_type == DENSE_PACKET ? allocate_packets(sd) : true); } +static inline void fill_data(uint8_t *data, uint32_t len) +{ + memset(data, DATA, len); +} + static void configure_packet_transfer(sd_t *sd) { odp_dma_seg_t *start_src_seg, *start_dst_seg, *seg; @@ -728,6 +746,9 @@ static void configure_packet_transfer(sd_t *sd) seg->packet = pkt; seg->offset = 0U; seg->len = sd->dma.src_seg_len; + + if (seg->packet != ODP_PACKET_INVALID) + fill_data(odp_packet_data(seg->packet), seg->len); } len = sd->dma.num_in_segs * sd->dma.src_seg_len; @@ -813,6 +834,9 @@ static void configure_address_transfer(sd_t *sd) seg->addr = sd->seg.seg_type == SPARSE_MEMORY ? NULL : (uint8_t *)sd->seg.src + k * sd->dma.src_seg_len; seg->len = sd->dma.src_seg_len; + + if (seg->addr != NULL) + fill_data(seg->addr, seg->len); } len = sd->dma.num_in_segs * sd->dma.src_seg_len; @@ -845,7 +869,7 @@ static void free_memory(const sd_t *sd) (void)odp_shm_free(sd->seg.dst_shm); } -static void run_transfer(odp_dma_t handle, trs_info_t *info, stats_t *stats) +static void run_transfer(odp_dma_t handle, trs_info_t *info, stats_t *stats, ver_fn_t ver_fn) { uint64_t start_tm, end_tm, start_cc, end_cc, trs_tm, trs_cc, start_cc_diff; odp_dma_result_t res; @@ -875,10 +899,14 @@ static void run_transfer(odp_dma_t handle, trs_info_t *info, stats_t *stats) stats->start_cc += start_cc_diff; ++stats->start_cnt; - if (odp_unlikely(!res.success)) + if (odp_unlikely(!res.success)) { ++stats->transfer_errs; - else + } else { ++stats->completed; + + if (ver_fn != NULL) + ver_fn(info, stats); + } } } @@ -894,7 +922,7 @@ static void run_transfers_mt_unsafe(sd_t *sd, stats_t *stats) if (sd->prep_trs_fn != NULL) sd->prep_trs_fn(sd, info); - run_transfer(handle, info, stats); + run_transfer(handle, info, stats, sd->ver_fn); } } @@ -911,7 +939,7 @@ static void run_transfers_mt_safe(sd_t *sd, stats_t *stats) if (sd->prep_trs_fn != NULL) sd->prep_trs_fn(sd, info); - run_transfer(handle, info, stats); + run_transfer(handle, info, stats, sd->ver_fn); odp_ticketlock_unlock(&info->lock); } } @@ -975,11 +1003,15 @@ static void poll_transfer(sd_t *sd, trs_info_t *info, stats_t *stats) stats->trs_poll_cnt += info->trs_poll_cnt; ++stats->trs_cnt; - if (odp_unlikely(!res.success)) + if (odp_unlikely(!res.success)) { ++stats->transfer_errs; - else + } else { ++stats->completed; + if (sd->ver_fn != NULL) + sd->ver_fn(info, stats); + } + info->is_running = false; } else { if (sd->prep_trs_fn != NULL) @@ -1174,11 +1206,15 @@ static void wait_compl_event(sd_t *sd, stats_t *stats) stats->wait_cc += wait_cc; ++stats->wait_cnt; - if (odp_unlikely(!res.success)) + if (odp_unlikely(!res.success)) { ++stats->transfer_errs; - else + } else { ++stats->completed; + if (sd->ver_fn != NULL) + sd->ver_fn(info, stats); + } + if (sd->prep_trs_fn != NULL) sd->prep_trs_fn(sd, info); @@ -1212,7 +1248,7 @@ static void drain_compl_events(ODP_UNUSED sd_t *sd) } } -static void run_memcpy(trs_info_t *info, stats_t *stats) +static void run_memcpy(trs_info_t *info, stats_t *stats, ver_fn_t ver_fn) { uint64_t start_tm, end_tm, start_cc, end_cc, trs_tm, trs_cc, start_cc_diff; const odp_dma_transfer_param_t *param = &info->trs_param; @@ -1275,6 +1311,9 @@ static void run_memcpy(trs_info_t *info, stats_t *stats) stats->start_cc += start_cc_diff; ++stats->start_cnt; ++stats->completed; + + if (ver_fn != NULL) + ver_fn(info, stats); } static void run_memcpy_mt_unsafe(sd_t *sd, stats_t *stats) @@ -1288,7 +1327,7 @@ static void run_memcpy_mt_unsafe(sd_t *sd, stats_t *stats) if (sd->prep_trs_fn != NULL) sd->prep_trs_fn(sd, info); - run_memcpy(info, stats); + run_memcpy(info, stats, sd->ver_fn); } } @@ -1304,7 +1343,7 @@ static void run_memcpy_mt_safe(sd_t *sd, stats_t *stats) if (sd->prep_trs_fn != NULL) sd->prep_trs_fn(sd, info); - run_memcpy(info, stats); + run_memcpy(info, stats, sd->ver_fn); odp_ticketlock_unlock(&info->lock); } } @@ -1370,6 +1409,8 @@ static void prepare_packet_transfer(sd_t *sd, trs_info_t *info) if (odp_unlikely(seg->packet == ODP_PACKET_INVALID)) /* There should always be enough packets. */ ODPH_ABORT("Failed to allocate packet, aborting\n"); + + fill_data(odp_packet_data(seg->packet), seg->len); } for (uint32_t i = 0U; i < param->num_dst; ++i) { @@ -1390,13 +1431,17 @@ static void prepare_address_transfer(sd_t *sd, trs_info_t *info) { odp_dma_transfer_param_t *param = &info->trs_param; uint8_t *addr = sd->seg.cur_src; + odp_dma_seg_t *seg; for (uint32_t i = 0U; i < param->num_src; ++i) { + seg = ¶m->src_seg[i]; + if (odp_unlikely(addr > (uint8_t *)sd->seg.src_high)) addr = sd->seg.src; - param->src_seg[i].addr = addr; + seg->addr = addr; addr += sd->dma.src_seg_len; + fill_data(seg->addr, seg->len); } sd->seg.cur_src = addr + ODP_CACHE_LINE_SIZE; @@ -1413,6 +1458,25 @@ static void prepare_address_transfer(sd_t *sd, trs_info_t *info) sd->seg.cur_dst = addr + ODP_CACHE_LINE_SIZE; } +static void verify_transfer(trs_info_t *info, stats_t *stats) +{ + odp_dma_transfer_param_t *param = &info->trs_param; + odp_dma_seg_t *seg; + const odp_bool_t is_addr = param->dst_format == ODP_DMA_FORMAT_ADDR; + uint8_t *data; + + for (uint32_t i = 0U; i < param->num_dst; ++i) { + seg = ¶m->dst_seg[i]; + data = is_addr ? seg->addr : odp_packet_data(seg->packet); + + for (uint32_t j = 0U; j < seg->len; ++j) + if (odp_unlikely(data[j] != DATA)) { + ++stats->data_errs; + return; + } + } +} + static odp_bool_t setup_session_descriptors(prog_config_t *config) { sd_t *sd; @@ -1451,6 +1515,7 @@ static odp_bool_t setup_session_descriptors(prog_config_t *config) sd->prep_trs_fn = config->seg_type == SPARSE_PACKET ? prepare_packet_transfer : config->seg_type == SPARSE_MEMORY ? prepare_address_transfer : NULL; + sd->ver_fn = config->is_verify ? verify_transfer : NULL; } return true; @@ -1684,9 +1749,12 @@ static void print_stats(const prog_config_t *config) stats->scheduler_timeouts); } - printf(" transfer errors: %" PRIu64 "\n" - " run time: %" PRIu64 " ns\n", - stats->transfer_errs, stats->tot_tm); + printf(" transfer errors: %" PRIu64 "\n", stats->transfer_errs); + + if (config->is_verify) + printf(" data errors: %" PRIu64 "\n", stats->data_errs); + + printf(" run time: %" PRIu64 " ns\n", stats->tot_tm); if (config->policy == MANY) { printf(" session:\n" -- cgit v1.2.3 From c0b7fb84bdfc57b7587c2299c01efb1c3a1933a9 Mon Sep 17 00:00:00 2001 From: Tuomas Taipale Date: Fri, 15 Dec 2023 14:50:53 +0000 Subject: test: dma_perf: run with new verify option Add new `-v` option to the runner script transfers. Signed-off-by: Tuomas Taipale Reviewed-by: Matias Elo --- test/performance/odp_dma_perf_run.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/performance/odp_dma_perf_run.sh b/test/performance/odp_dma_perf_run.sh index 6f1280fd1..f5d567740 100755 --- a/test/performance/odp_dma_perf_run.sh +++ b/test/performance/odp_dma_perf_run.sh @@ -28,42 +28,42 @@ check_result() echo "odp_dma_perf: synchronous DMA transfer 1" echo "====================================" -${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 0 -i $SEGC -o $SEGC -s $SEGS -S 0 -f $INFL -T $TIME +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 0 -i $SEGC -o $SEGC -s $SEGS -S 0 -f $INFL -T $TIME -v check_result $? echo "odp_dma_perf: synchronous DMA transfer 2" echo "====================================" -${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 0 -i $SEGC -o $SEGC -s $SEGS -S 1 -f $INFL -T $TIME +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 0 -i $SEGC -o $SEGC -s $SEGS -S 1 -f $INFL -T $TIME -v check_result $? echo "odp_dma_perf: asynchronous DMA transfer 1" echo "=====================================" -${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 1 -i $SEGC -o $SEGC -s $SEGS -S 2 -m 0 -f $INFL -T $TIME +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 1 -i $SEGC -o $SEGC -s $SEGS -S 2 -m 0 -f $INFL -T $TIME -v check_result $? echo "odp_dma_perf: asynchronous DMA transfer 2" echo "=====================================" -${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 1 -i $SEGC -o $SEGC -s $SEGS -S 3 -m 1 -f $INFL -T $TIME +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 1 -i $SEGC -o $SEGC -s $SEGS -S 3 -m 1 -f $INFL -T $TIME -v check_result $? echo "odp_dma_perf: SW transfer 1" echo "=====================================" -${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 2 -i $SEGC -o $SEGC -s $SEGS -S 0 -f $INFL -T $TIME +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 2 -i $SEGC -o $SEGC -s $SEGS -S 0 -f $INFL -T $TIME -v check_result $? echo "odp_dma_perf: SW transfer 2" echo "=====================================" -${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 2 -i $SEGC -o $SEGC -s $SEGS -S 2 -f $INFL -T $TIME +${TEST_DIR}/${BIN_NAME}${EXEEXT} -t 2 -i $SEGC -o $SEGC -s $SEGS -S 2 -f $INFL -T $TIME -v check_result $? -- cgit v1.2.3 From e6aa73088da2d937911888b80749e26fdeee0630 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 19 Dec 2023 12:16:20 +0200 Subject: api: increment ODP API version to 1.43.0 Increment API version number to reflect the following changes: Backward incompatible: - cls: add new odp_cls_capability_t.max_pmr and odp_cls_capability_t.max_pmr_per_cos capabilities - cls: rename odp_cls_capability_t.max_pmr_terms field to odp_cls_capability_t.max_terms_per_pmr - time: change local/global time specification to allow timestamp values to start from an implementation defined value - timer: deprecate odp_timer_set_t type - timer: deprecate odp_timer_pool_start() function - timer: deprecate odp_timeout_fresh() function - timer: change odp_timer_free() specification to remove the possibility to free a timer that is running - timer: change odp_timer_pool_create() specification to state that timer pool handles must not be used by other APIs before being started Backward compatible: - event: add odp_event_pool() function - hints: fix a type conversion issue in odp_unlikely() implementation - packet: clarify that ODP_PACKET_FREE_CTRL_DONT_FREE option does not affect direct packet free calls - packet: clarify that packet IO time is specific to the packet IO interface - pool: clarify that disabled/unused per thread statistics counters will not necessarily be zeroed by odp_pool_stats() - sched: clarify event ordering in ordered scheduling contexts - thread: add new functions odp_thread_control_count_max() and odp_thread_worker_count_max() - thread: add new functions odp_thread_control_count() and odp_thread_worker_count() - time: add odp_time_add_ns() function - time: add odp_time_startup() function - time: clarify odp_time_sum() specification by adding a notification that resulting timestamp may wrap around - timer: add odp_timer_pool_start_multi() function - timer: clarify that timer ticks and related nanosecond values are specific to a timer pool and may not start from zero Removed deprecated APIs: - cls: odp_cls_drop_t enum - cls: odp_cos_drop_set() function - cls: odp_cos_drop() function - cls: odp_cos_with_l2_priority() function - cls: odp_cos_with_l3_qos() function - crypto: ODP_CRYPTO_SES_CREATE_ERR_NONE, ODP_CRYPTO_SES_CREATE_ERR_ENOMEM, ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER, and ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH defines - crypto: odp_crypto_alg_err_t.ODP_CRYPTO_ALG_ERR_KEY_SIZE and odp_crypto_alg_err_t.ODP_CRYPTO_ALG_ERR_IV_INVALID enums - crypto: odp_crypto_hw_err_t enum - crypto: odp_crypto_packet_result_t.ok field - sched: ODP_SCHED_PRIO_HIGHEST, ODP_SCHED_PRIO_NORMAL, ODP_SCHED_PRIO_LOWEST, and ODP_SCHED_PRIO_DEFAULT defines - timer: ODP_CLOCK_CPU and ODP_CLOCK_EXT defines - timer: ODP_TIMER_TOOEARLY, ODP_TIMER_TOOLATE and ODP_TIMER_NOEVENT defines - timer: odp_timer_set_abs() function - timer: odp_timer_set_rel() function Helper library (1.5.0): Backward incompatible: - threads: remove deprecated odph_odpthread_t and odph_odpthread_params_t types - threads: remove deprecated odph_thread_param_t.instance field - threads: remove deprecated odph_odpthreads_create() and odph_odpthreads_join() functions Signed-off-by: Matias Elo Reviewed-by: Petri Savolainen --- CHANGELOG | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 6 ++-- 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4cb2a57cb..dd3d04048 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,111 @@ +== OpenDataPlane (1.43.0.0) + +=== Backward incompatible API changes +==== Classifier +* Add new `odp_cls_capability_t.max_pmr` and +`odp_cls_capability_t.max_pmr_per_cos` packet matching rule capabilities. +* Rename `odp_cls_capability_t.max_pmr_terms` field to +`odp_cls_capability_t.max_terms_per_pmr`. + +==== Time +* Change local/global time specification to allow timestamp values to start from +an implementation defined value, instead of always starting from zero. + +==== Timer +* Deprecate `odp_timer_set_t` type. Use `odp_timer_retval_t` instead. +* Deprecate `odp_timer_pool_start()` function in comments. Will be properly +deprecated in an upcoming release. Use `odp_timer_pool_start_multi()` instead. +* Deprecate `odp_timeout_fresh()` function. +* Change `odp_timer_free()` specification to remove the possibility to free a +timer that is running. +* Change `odp_timer_pool_create()` specification to state that timer pool +handles must not be used by other APIs, except `odp_timer_pool_to_u64()`, + before being started. + +=== Backward compatible API changes +==== Event +* Add `odp_event_pool()` function, which returns a handle to the pool where the +event was allocated from. + +==== Hints +* Fix a type conversion issue in `odp_unlikely()` implementation. + +==== Packet +* Clarify that `ODP_PACKET_FREE_CTRL_DONT_FREE` option does not affect direct +packet free calls. +* Clarify that packet IO time is specific to the packet IO interface. + +==== Pool +* Clarify that disabled/unused per thread statistics counters will not +necessarily be zeroed by `odp_pool_stats()`. + +==== Scheduler +* Clarify event ordering in ordered scheduling contexts. + +==== Thread +* Add new functions `odp_thread_control_count_max()` and +`odp_thread_worker_count_max()` for reading the maximum number of control and +worker threads. +* Add new functions `odp_thread_control_count()` and `odp_thread_worker_count()` +for reading the current number of control and worker threads. + +==== Time +* Add `odp_time_add_ns()` function for adding nanoseconds into a time value. +* Add `odp_time_startup()` function for requesting ODP instance startup time. +* Clarify `odp_time_sum()` specification by adding a notification that resulting +timestamp may wrap around if large timestamp values are summed up. + +==== Timer +* Add `odp_timer_pool_start_multi()` function for starting timer pools, which +takes the to-be-started pool handles as arguments. +* Clarify that timer ticks and related nanosecond values are specific to a timer +pool. Also, state explicitly that those may not start from zero. + +=== Remove deprecated APIs +==== Classifier +* Remove deprecated `odp_cls_drop_t` enum. +* Remove deprecated `odp_cos_drop_set()` function. +* Remove deprecated `odp_cos_drop()` function. +* Remove deprecated `odp_cos_with_l2_priority()` function. +* Remove deprecated `odp_cos_with_l3_qos()` function. + +==== Crypto +* Remove deprecated `ODP_CRYPTO_SES_CREATE_ERR_NONE`, +`ODP_CRYPTO_SES_CREATE_ERR_ENOMEM`, `ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER`, and +`ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH` defines. +* Remove deprecated `odp_crypto_alg_err_t.ODP_CRYPTO_ALG_ERR_KEY_SIZE` and +`odp_crypto_alg_err_t.ODP_CRYPTO_ALG_ERR_IV_INVALID` enums. +* Remove deprecated `odp_crypto_hw_err_t` enum. +* Remove deprecated `odp_crypto_packet_result_t.ok` field. + +==== Scheduler +* Remove deprecated `ODP_SCHED_PRIO_HIGHEST`, `ODP_SCHED_PRIO_NORMAL`, +`ODP_SCHED_PRIO_LOWEST`, and `ODP_SCHED_PRIO_DEFAULT` defines. + +==== Timer +* Remove deprecated `ODP_CLOCK_CPU` and `ODP_CLOCK_EXT` defines. +* Remove deprecated `ODP_TIMER_TOOEARLY`, `ODP_TIMER_TOOLATE` and +`ODP_TIMER_NOEVENT` defines. +* Remove deprecated `odp_timer_set_abs()` function. +* Remove deprecated `odp_timer_set_rel()` function. + +=== Helper (1.5.0) +==== Backward incompatible changes +* Remove deprecated `odph_odpthread_t` and `odph_odpthread_params_t` types. +* Remove deprecated `odph_thread_param_t.instance` field. +* Remove deprecated `odph_odpthreads_create()` and `odph_odpthreads_join()` +functions. + +=== Implementation +==== Ticketlock +* Add WFE based aarch64 ticketlock implementation (`--enable-wfe-locks`) for +power saving. + +=== Performance Tests +==== dma_perf +* Add option for using software memory copy in addition to DMA transfers. +* Add options for using sparse packets and memory as the transfer segment type. + == OpenDataPlane (1.42.1.0) === Backward compatible API changes diff --git a/configure.ac b/configure.ac index 18b3861d9..3184b85d2 100644 --- a/configure.ac +++ b/configure.ac @@ -3,8 +3,8 @@ AC_PREREQ([2.5]) # ODP API version ########################################################################## m4_define([odp_version_generation], [1]) -m4_define([odp_version_major], [42]) -m4_define([odp_version_minor], [1]) +m4_define([odp_version_major], [43]) +m4_define([odp_version_minor], [0]) m4_define([odp_version_patch], [0]) m4_define([odp_version_api], @@ -27,7 +27,7 @@ AC_SUBST(ODP_VERSION_API) # Helper library version ########################################################################## m4_define([odph_version_generation], [1]) -m4_define([odph_version_major], [4]) +m4_define([odph_version_major], [5]) m4_define([odph_version_minor], [0]) m4_define([odph_version], -- cgit v1.2.3 From cd737f15d128d600b254ae440dbdcd86db31ff28 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 4 Jan 2024 17:19:16 +0200 Subject: Port e928570b1 "linux-gen: config: remove ODP_ prefix from internal defines" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/include/odp_config_internal.h | 14 +++++----- .../linux-dpdk/include/odp_packet_io_internal.h | 6 ++-- platform/linux-dpdk/include/odp_pool_internal.h | 2 +- platform/linux-dpdk/odp_packet_dpdk.c | 2 +- platform/linux-dpdk/odp_pool.c | 32 +++++++++++----------- platform/linux-dpdk/odp_system_info.c | 8 +++--- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/platform/linux-dpdk/include/odp_config_internal.h b/platform/linux-dpdk/include/odp_config_internal.h index ec1d2c617..6593b613b 100644 --- a/platform/linux-dpdk/include/odp_config_internal.h +++ b/platform/linux-dpdk/include/odp_config_internal.h @@ -26,7 +26,7 @@ extern "C" { /* * Maximum number of packet IO resources */ -#define ODP_CONFIG_PKTIO_ENTRIES 64 +#define CONFIG_PKTIO_ENTRIES 64 /* * Maximum number of DMA sessions @@ -37,12 +37,12 @@ extern "C" { * Pools reserved for internal usage, 1 for IPsec status events, one per packet * I/O for TX completion and one per DMA session */ -#define CONFIG_INTERNAL_POOLS (1 + ODP_CONFIG_PKTIO_ENTRIES + CONFIG_MAX_DMA_SESSIONS) +#define CONFIG_INTERNAL_POOLS (1 + CONFIG_PKTIO_ENTRIES + CONFIG_MAX_DMA_SESSIONS) /* * Maximum number of pools */ -#define ODP_CONFIG_POOLS 256 +#define CONFIG_POOLS 256 /* * Queues reserved for ODP internal use @@ -89,7 +89,7 @@ extern "C" { * This defines the minimum supported buffer alignment. Requests for values * below this will be rounded up to this value. */ -#define ODP_CONFIG_BUFFER_ALIGN_MIN 16 +#define CONFIG_BUFFER_ALIGN_MIN 16 /* * Maximum buffer alignment @@ -97,7 +97,7 @@ extern "C" { * This defines the maximum supported buffer alignment. Requests for values * above this will fail. */ -#define ODP_CONFIG_BUFFER_ALIGN_MAX (4 * 1024) +#define CONFIG_BUFFER_ALIGN_MAX (4 * 1024) /* * Default packet tailroom @@ -134,7 +134,7 @@ extern "C" { #define CONFIG_PACKET_MAX_SEG_LEN (CONFIG_PACKET_SEG_SIZE - \ RTE_PKTMBUF_HEADROOM - \ CONFIG_PACKET_TAILROOM - \ - ODP_CONFIG_BUFFER_ALIGN_MIN) + CONFIG_BUFFER_ALIGN_MIN) /* * Number of shared memory blocks reserved for implementation internal use. @@ -143,7 +143,7 @@ extern "C" { * module global data, and one block per packet I/O is reserved for TX * completion usage. */ -#define CONFIG_INTERNAL_SHM_BLOCKS (ODP_CONFIG_POOLS + 20 + ODP_CONFIG_PKTIO_ENTRIES) +#define CONFIG_INTERNAL_SHM_BLOCKS (CONFIG_POOLS + 20 + CONFIG_PKTIO_ENTRIES) /* * Maximum number of shared memory blocks. diff --git a/platform/linux-dpdk/include/odp_packet_io_internal.h b/platform/linux-dpdk/include/odp_packet_io_internal.h index ece33b538..bab750a22 100644 --- a/platform/linux-dpdk/include/odp_packet_io_internal.h +++ b/platform/linux-dpdk/include/odp_packet_io_internal.h @@ -168,7 +168,7 @@ typedef struct { uint32_t tx_compl_pool_size; } config; - pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES]; + pktio_entry_t entries[CONFIG_PKTIO_ENTRIES]; lso_profile_t lso_profile[PKTIO_LSO_PROFILES]; int num_lso_profiles; @@ -241,9 +241,9 @@ static inline pktio_entry_t *get_pktio_entry(odp_pktio_t pktio) if (odp_unlikely(pktio == ODP_PKTIO_INVALID)) return NULL; - if (odp_unlikely(_odp_typeval(pktio) > ODP_CONFIG_PKTIO_ENTRIES)) { + if (odp_unlikely(_odp_typeval(pktio) > CONFIG_PKTIO_ENTRIES)) { _ODP_DBG("pktio limit %" PRIuPTR "/%d exceed\n", - _odp_typeval(pktio), ODP_CONFIG_PKTIO_ENTRIES); + _odp_typeval(pktio), CONFIG_PKTIO_ENTRIES); return NULL; } diff --git a/platform/linux-dpdk/include/odp_pool_internal.h b/platform/linux-dpdk/include/odp_pool_internal.h index 8512806f7..b8fd17314 100644 --- a/platform/linux-dpdk/include/odp_pool_internal.h +++ b/platform/linux-dpdk/include/odp_pool_internal.h @@ -92,7 +92,7 @@ typedef struct ODP_ALIGNED_CACHE { } pool_t; typedef struct pool_global_t { - pool_t pool[ODP_CONFIG_POOLS]; + pool_t pool[CONFIG_POOLS]; odp_shm_t shm; struct { diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c index 63e00d8e5..da76db06d 100644 --- a/platform/linux-dpdk/odp_packet_dpdk.c +++ b/platform/linux-dpdk/odp_packet_dpdk.c @@ -186,7 +186,7 @@ const pktio_if_ops_t * const _odp_pktio_if_ops[] = { NULL }; -extern void *pktio_entry_ptr[ODP_CONFIG_PKTIO_ENTRIES]; +extern void *pktio_entry_ptr[CONFIG_PKTIO_ENTRIES]; static uint32_t mtu_get_pkt_dpdk(pktio_entry_t *pktio_entry); diff --git a/platform/linux-dpdk/odp_pool.c b/platform/linux-dpdk/odp_pool.c index 541557f48..1748aa13e 100644 --- a/platform/linux-dpdk/odp_pool.c +++ b/platform/linux-dpdk/odp_pool.c @@ -58,14 +58,14 @@ #define POOL_NAME_FORMAT "%" PRIu64 "-%d-%s" /* Define a practical limit for contiguous memory allocations */ -#define MAX_SIZE (CONFIG_PACKET_SEG_SIZE - ODP_CONFIG_BUFFER_ALIGN_MIN) +#define MAX_SIZE (CONFIG_PACKET_SEG_SIZE - CONFIG_BUFFER_ALIGN_MIN) /* Maximum packet user area size */ #define MAX_UAREA_SIZE 2048 #define ROUNDUP_DIV(a, b) (((a) + ((b) - 1)) / (b)) -ODP_STATIC_ASSERT(CONFIG_INTERNAL_POOLS < ODP_CONFIG_POOLS, +ODP_STATIC_ASSERT(CONFIG_INTERNAL_POOLS < CONFIG_POOLS, "Internal pool count needs to be less than total configured pool count"); /* The pool table ptr - resides in shared memory */ @@ -116,7 +116,7 @@ static pool_t *find_pool(_odp_event_hdr_t *event_hdr) { int i; - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool_t *pool = _odp_pool_entry_from_idx(i); struct mem_cb_arg_t args; @@ -182,7 +182,7 @@ int _odp_pool_init_global(void) return -1; } - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool_t *pool = _odp_pool_entry_from_idx(i); LOCK_INIT(&pool->lock); @@ -251,7 +251,7 @@ int odp_pool_capability(odp_pool_capability_t *capa) { odp_pool_stats_opt_t supported_stats; /* Reserve pools for internal usage */ - unsigned int max_pools = ODP_CONFIG_POOLS - CONFIG_INTERNAL_POOLS; + unsigned int max_pools = CONFIG_POOLS - CONFIG_INTERNAL_POOLS; memset(capa, 0, sizeof(odp_pool_capability_t)); @@ -262,7 +262,7 @@ int odp_pool_capability(odp_pool_capability_t *capa) /* Buffer pools */ capa->buf.max_pools = max_pools; - capa->buf.max_align = ODP_CONFIG_BUFFER_ALIGN_MAX; + capa->buf.max_align = CONFIG_BUFFER_ALIGN_MAX; capa->buf.max_size = MAX_SIZE; capa->buf.max_num = CONFIG_POOL_MAX_NUM; capa->buf.max_uarea_size = MAX_UAREA_SIZE; @@ -272,7 +272,7 @@ int odp_pool_capability(odp_pool_capability_t *capa) capa->buf.stats.all = supported_stats.all; /* Packet pools */ - capa->pkt.max_align = ODP_CONFIG_BUFFER_ALIGN_MIN; + capa->pkt.max_align = CONFIG_BUFFER_ALIGN_MIN; capa->pkt.max_pools = max_pools; capa->pkt.max_len = CONFIG_PACKET_MAX_SEG_LEN; capa->pkt.max_num = _odp_pool_glb->config.pkt_max_num; @@ -586,7 +586,7 @@ static pool_t *get_unused_pool(void) { pool_t *pool; - for (int i = 0; i < ODP_CONFIG_POOLS; i++) { + for (int i = 0; i < CONFIG_POOLS; i++) { pool = _odp_pool_entry_from_idx(i); LOCK(&pool->lock); @@ -684,7 +684,7 @@ odp_pool_t _odp_pool_create(const char *name, const odp_pool_param_t *params, cache_size = params->buf.cache_size; priv_size = get_mbuf_priv_size(sizeof(odp_buffer_hdr_t)); align = params->buf.align > 0 ? params->buf.align : ODP_CACHE_LINE_SIZE; - align = _ODP_MAX(align, (uint32_t)ODP_CONFIG_BUFFER_ALIGN_MIN); + align = _ODP_MAX(align, (uint32_t)CONFIG_BUFFER_ALIGN_MIN); data_size = _ODP_ROUNDUP_ALIGN(params->buf.size + trailer, align); uarea_size = params->buf.uarea_size; priv_data.event_type = ODP_EVENT_BUFFER; @@ -693,8 +693,8 @@ odp_pool_t _odp_pool_create(const char *name, const odp_pool_param_t *params, num = params->pkt.num; cache_size = params->pkt.cache_size; priv_size = get_mbuf_priv_size(sizeof(odp_packet_hdr_t)); - align = params->pkt.align > 0 ? params->pkt.align : ODP_CONFIG_BUFFER_ALIGN_MIN; - align = _ODP_MAX(align, (uint32_t)ODP_CONFIG_BUFFER_ALIGN_MIN); + align = params->pkt.align > 0 ? params->pkt.align : CONFIG_BUFFER_ALIGN_MIN; + align = _ODP_MAX(align, (uint32_t)CONFIG_BUFFER_ALIGN_MIN); data_size = _ODP_MAX(params->pkt.seg_len, (uint32_t)CONFIG_PACKET_SEG_LEN_MIN); data_size = _ODP_MAX(data_size, params->pkt.len); @@ -793,7 +793,7 @@ odp_pool_t odp_pool_lookup(const char *name) uint32_t i; pool_t *pool; - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool = _odp_pool_entry_from_idx(i); LOCK(&pool->lock); @@ -877,7 +877,7 @@ void odp_pool_print_all(void) _ODP_PRINT("-----------------\n"); _ODP_PRINT(" idx %-*s type free tot cache elt_len ext\n", col_width, "name"); - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { pool_t *pool = _odp_pool_entry_from_idx(i); LOCK(&pool->lock); @@ -1002,7 +1002,7 @@ uint64_t odp_pool_to_u64(odp_pool_t hdl) unsigned int odp_pool_max_index(void) { - return ODP_CONFIG_POOLS - 1; + return CONFIG_POOLS - 1; } int odp_pool_stats(odp_pool_t pool_hdl, odp_pool_stats_t *stats) @@ -1109,7 +1109,7 @@ int odp_pool_ext_capability(odp_pool_type_t type, memset(capa, 0, sizeof(odp_pool_ext_capability_t)); capa->type = type; - capa->max_pools = ODP_CONFIG_POOLS - CONFIG_INTERNAL_POOLS; + capa->max_pools = CONFIG_POOLS - CONFIG_INTERNAL_POOLS; capa->min_cache_size = 0; capa->max_cache_size = RTE_MEMPOOL_CACHE_MAX_SIZE; capa->stats.all = supported_stats.all; @@ -1221,7 +1221,7 @@ odp_pool_t odp_pool_ext_create(const char *name, } /* Find an unused buffer pool slot and initialize it as requested */ - for (i = 0; i < ODP_CONFIG_POOLS; i++) { + for (i = 0; i < CONFIG_POOLS; i++) { uint32_t num; struct rte_mempool *mp; diff --git a/platform/linux-dpdk/odp_system_info.c b/platform/linux-dpdk/odp_system_info.c index 886f7f216..62db1064e 100644 --- a/platform/linux-dpdk/odp_system_info.c +++ b/platform/linux-dpdk/odp_system_info.c @@ -529,15 +529,15 @@ void odp_sys_config_print(void) _ODP_PRINT("\n\nodp_config_internal.h values:\n" "-----------------------------\n"); _ODP_PRINT("CONFIG_NUM_CPU_IDS: %i\n", CONFIG_NUM_CPU_IDS); - _ODP_PRINT("ODP_CONFIG_POOLS: %i\n", ODP_CONFIG_POOLS); + _ODP_PRINT("CONFIG_POOLS: %i\n", CONFIG_POOLS); _ODP_PRINT("CONFIG_INTERNAL_QUEUES: %i\n", CONFIG_INTERNAL_QUEUES); _ODP_PRINT("CONFIG_MAX_PLAIN_QUEUES: %i\n", CONFIG_MAX_PLAIN_QUEUES); _ODP_PRINT("CONFIG_MAX_SCHED_QUEUES: %i\n", CONFIG_MAX_SCHED_QUEUES); _ODP_PRINT("CONFIG_MAX_QUEUES: %i\n", CONFIG_MAX_QUEUES); _ODP_PRINT("CONFIG_QUEUE_MAX_ORD_LOCKS: %i\n", CONFIG_QUEUE_MAX_ORD_LOCKS); - _ODP_PRINT("ODP_CONFIG_PKTIO_ENTRIES: %i\n", ODP_CONFIG_PKTIO_ENTRIES); - _ODP_PRINT("ODP_CONFIG_BUFFER_ALIGN_MIN: %i\n", ODP_CONFIG_BUFFER_ALIGN_MIN); - _ODP_PRINT("ODP_CONFIG_BUFFER_ALIGN_MAX: %i\n", ODP_CONFIG_BUFFER_ALIGN_MAX); + _ODP_PRINT("CONFIG_PKTIO_ENTRIES: %i\n", CONFIG_PKTIO_ENTRIES); + _ODP_PRINT("CONFIG_BUFFER_ALIGN_MIN: %i\n", CONFIG_BUFFER_ALIGN_MIN); + _ODP_PRINT("CONFIG_BUFFER_ALIGN_MAX: %i\n", CONFIG_BUFFER_ALIGN_MAX); _ODP_PRINT("CONFIG_PACKET_TAILROOM: %i\n", CONFIG_PACKET_TAILROOM); _ODP_PRINT("CONFIG_PACKET_SEG_SIZE: %i\n", CONFIG_PACKET_SEG_SIZE); _ODP_PRINT("CONFIG_PACKET_SEG_LEN_MIN: %i\n", CONFIG_PACKET_SEG_LEN_MIN); -- cgit v1.2.3 From d1e9d0e1b7186b1ece092d565a491e50d1d951e9 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 4 Jan 2024 16:44:47 +0200 Subject: Port 84931a917 "linux-gen: m4: add configuration option for enabling wfe locks" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/m4/configure.m4 | 8 +++++--- platform/linux-dpdk/m4/odp_wfe.m4 | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) create mode 120000 platform/linux-dpdk/m4/odp_wfe.m4 diff --git a/platform/linux-dpdk/m4/configure.m4 b/platform/linux-dpdk/m4/configure.m4 index a7c58eb91..0fcd4a5b3 100644 --- a/platform/linux-dpdk/m4/configure.m4 +++ b/platform/linux-dpdk/m4/configure.m4 @@ -10,6 +10,7 @@ m4_include([platform/linux-dpdk/m4/odp_libconfig.m4]) m4_include([platform/linux-dpdk/m4/odp_openssl.m4]) m4_include([platform/linux-dpdk/m4/odp_pcapng.m4]) m4_include([platform/linux-dpdk/m4/odp_scheduler.m4]) +m4_include([platform/linux-dpdk/m4/odp_wfe.m4]) ODP_EVENT_VALIDATION ODP_PTHREAD @@ -73,9 +74,10 @@ AS_VAR_APPEND([PLAT_CFG_TEXT], [" event_validation: ${enable_event_validation} openssl: ${with_openssl} openssl_rand: ${openssl_rand} - pcap: ${have_pmd_pcap} - pcapng: ${have_pcapng} - default_config_path: ${default_config_path}"]) + pcap: ${have_pmd_pcap} + pcapng: ${have_pcapng} + wfe_locks: ${use_wfe_locks} + default_config_path: ${default_config_path}"]) ODP_CHECK_CFLAG([-Wno-error=cast-align]) diff --git a/platform/linux-dpdk/m4/odp_wfe.m4 b/platform/linux-dpdk/m4/odp_wfe.m4 new file mode 120000 index 000000000..2526a9c83 --- /dev/null +++ b/platform/linux-dpdk/m4/odp_wfe.m4 @@ -0,0 +1 @@ +../../linux-generic/m4/odp_wfe.m4 \ No newline at end of file -- cgit v1.2.3 From f0d7fccff02b8d84a1e3b2a30bf2cc0e64e9d4f4 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 4 Jan 2024 17:03:40 +0200 Subject: Port c20e1fe14 "linux-gen: ticketlock: enable WFE on aarch64" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/Makefile.am | 20 +++++++++++++++----- .../linux-dpdk/arch/aarch64/odp/api/abi/wait_until.h | 1 + .../linux-dpdk/arch/default/odp/api/abi/wait_until.h | 1 + .../arch/default/odp/api/abi/wait_until_generic.h | 1 + 4 files changed, 18 insertions(+), 5 deletions(-) create mode 120000 platform/linux-dpdk/arch/aarch64/odp/api/abi/wait_until.h create mode 120000 platform/linux-dpdk/arch/default/odp/api/abi/wait_until.h create mode 120000 platform/linux-dpdk/arch/default/odp/api/abi/wait_until_generic.h diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index 3eb6225af..e6b56b647 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -296,7 +296,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/default/odp/api/abi/cpu_generic.h \ arch/arm/odp/api/abi/cpu_inlines.h \ arch/arm/odp/api/abi/cpu.h \ - arch/default/odp/api/abi/sync_inlines.h + arch/default/odp/api/abi/sync_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/default/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/arm/odp_atomic.h \ arch/arm/odp_cpu.h \ @@ -324,7 +326,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/default/odp/api/abi/cpu_generic.h \ arch/aarch64/odp/api/abi/cpu_inlines.h \ arch/aarch64/odp/api/abi/cpu.h \ - arch/aarch64/odp/api/abi/sync_inlines.h + arch/aarch64/odp/api/abi/sync_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/aarch64/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/aarch64/odp_atomic.h \ arch/aarch64/odp_cpu.h \ @@ -346,7 +350,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/default/odp/api/abi/cpu_generic.h \ arch/default/odp/api/abi/cpu_inlines.h \ arch/default/odp/api/abi/cpu.h \ - arch/default/odp/api/abi/sync_inlines.h + arch/default/odp/api/abi/sync_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/default/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/default/odp_atomic.h \ arch/default/odp_cpu.h \ @@ -366,7 +372,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/default/odp/api/abi/cpu_generic.h \ arch/default/odp/api/abi/cpu_inlines.h \ arch/powerpc/odp/api/abi/cpu.h \ - arch/default/odp/api/abi/sync_inlines.h + arch/default/odp/api/abi/sync_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/default/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/default/odp_atomic.h \ arch/default/odp_cpu.h \ @@ -388,7 +396,9 @@ odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/default/odp/api/abi/atomic_inlines.h \ arch/x86/odp/api/abi/cpu_inlines.h \ arch/x86/odp/api/abi/cpu.h \ - arch/x86/odp/api/abi/sync_inlines.h + arch/x86/odp/api/abi/sync_inlines.h \ + arch/default/odp/api/abi/wait_until_generic.h \ + arch/default/odp/api/abi/wait_until.h endif noinst_HEADERS += arch/x86/cpu_flags.h \ arch/x86/odp_cpu.h \ diff --git a/platform/linux-dpdk/arch/aarch64/odp/api/abi/wait_until.h b/platform/linux-dpdk/arch/aarch64/odp/api/abi/wait_until.h new file mode 120000 index 000000000..65a5f4381 --- /dev/null +++ b/platform/linux-dpdk/arch/aarch64/odp/api/abi/wait_until.h @@ -0,0 +1 @@ +../../../../../../linux-generic/arch/aarch64/odp/api/abi/wait_until.h \ No newline at end of file diff --git a/platform/linux-dpdk/arch/default/odp/api/abi/wait_until.h b/platform/linux-dpdk/arch/default/odp/api/abi/wait_until.h new file mode 120000 index 000000000..ae06629ce --- /dev/null +++ b/platform/linux-dpdk/arch/default/odp/api/abi/wait_until.h @@ -0,0 +1 @@ +../../../../../../linux-generic/arch/default/odp/api/abi/wait_until.h \ No newline at end of file diff --git a/platform/linux-dpdk/arch/default/odp/api/abi/wait_until_generic.h b/platform/linux-dpdk/arch/default/odp/api/abi/wait_until_generic.h new file mode 120000 index 000000000..c43ede9ad --- /dev/null +++ b/platform/linux-dpdk/arch/default/odp/api/abi/wait_until_generic.h @@ -0,0 +1 @@ +../../../../../../linux-generic/arch/default/odp/api/abi/wait_until_generic.h \ No newline at end of file -- cgit v1.2.3 From 17a63adcc2ffe4db69161ebf3bf70cc02f7bbfc2 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 4 Jan 2024 17:28:44 +0200 Subject: Port d6155899a "api: timer: remove deprecated items" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_timer.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index aa841ae0f..02348a915 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -1066,18 +1066,6 @@ retry: return ODP_TIMER_SUCCESS; } -int ODP_DEPRECATE(odp_timer_set_abs)(odp_timer_t timer_hdl, uint64_t abs_tick, - odp_event_t *tmo_ev) -{ - return timer_set(timer_hdl, abs_tick, tmo_ev, 1); -} - -int ODP_DEPRECATE(odp_timer_set_rel)(odp_timer_t timer_hdl, uint64_t rel_tick, - odp_event_t *tmo_ev) -{ - return timer_set(timer_hdl, rel_tick, tmo_ev, 0); -} - int odp_timer_start(odp_timer_t timer, const odp_timer_start_t *start_param) { odp_event_t tmo_ev = start_param->tmo_ev; -- cgit v1.2.3 From 14eb09e073dfdbeb247e8693eb41eaad1e41f199 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 4 Jan 2024 16:38:06 +0200 Subject: Port a6a6bdd8b "api: thread: move ODP_THREAD_COUNT_MAX to types header" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/Makefile.am | 1 + platform/linux-dpdk/include-abi/odp/api/abi/thread_types.h | 1 + 2 files changed, 2 insertions(+) create mode 120000 platform/linux-dpdk/include-abi/odp/api/abi/thread_types.h diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index e6b56b647..886fe8f48 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -113,6 +113,7 @@ odpapiabiarchinclude_HEADERS += \ include-abi/odp/api/abi/std_types.h \ include-abi/odp/api/abi/sync.h \ include-abi/odp/api/abi/thread.h \ + include-abi/odp/api/abi/thread_types.h \ include-abi/odp/api/abi/thrmask.h \ include-abi/odp/api/abi/ticketlock.h \ include-abi/odp/api/abi/time.h \ diff --git a/platform/linux-dpdk/include-abi/odp/api/abi/thread_types.h b/platform/linux-dpdk/include-abi/odp/api/abi/thread_types.h new file mode 120000 index 000000000..b665090d0 --- /dev/null +++ b/platform/linux-dpdk/include-abi/odp/api/abi/thread_types.h @@ -0,0 +1 @@ +../../../../../linux-generic/include-abi/odp/api/abi/thread_types.h \ No newline at end of file -- cgit v1.2.3 From 2de154224a4861007d12d8630ab2bd6e6a292d3b Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 4 Jan 2024 17:26:51 +0200 Subject: Port fda9ee7d2 "api: timer: only inactive timers can be freed" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_timer.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index 02348a915..59feaa96d 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -918,30 +918,18 @@ odp_timer_t odp_timer_alloc(odp_timer_pool_t tp, return (odp_timer_t)timer; } -odp_event_t odp_timer_free(odp_timer_t timer_hdl) +int odp_timer_free(odp_timer_t timer_hdl) { - odp_event_t ev; timer_entry_t *timer = timer_from_hdl(timer_hdl); timer_pool_t *timer_pool = timer->timer_pool; uint32_t timer_idx = timer->timer_idx; -retry: odp_ticketlock_lock(&timer->lock); - if (timer->state == TICKING) { - _ODP_DBG("Freeing active timer.\n"); - - if (timer_global->ops.stop(&timer->rte_timer)) { - /* Another core runs timer callback function. */ - odp_ticketlock_unlock(&timer->lock); - goto retry; - } - - ev = timer->tmo_event; - timer->tmo_event = ODP_EVENT_INVALID; - timer->state = NOT_TICKING; - } else { - ev = ODP_EVENT_INVALID; + if (odp_unlikely(timer->state == TICKING)) { + odp_ticketlock_unlock(&timer->lock); + _ODP_ERR("Timer is active\n"); + return -1; } /* Remove timer from queue */ @@ -958,7 +946,7 @@ retry: ring_u32_enq(&timer_pool->free_timer.ring_hdr, timer_pool->free_timer.ring_mask, timer_idx); - return ev; + return 0; } static inline odp_timeout_hdr_t *timeout_to_hdr(odp_timeout_t tmo) -- cgit v1.2.3 From cb79785473f7f181f9c82ac2b6bf1f759e924ff0 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 4 Jan 2024 17:30:04 +0200 Subject: Port 9e8bed505 "api: timer: deprecate odp_timeout_fresh()" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index 59feaa96d..1b76fc912 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -1272,7 +1272,7 @@ uint64_t odp_timeout_to_u64(odp_timeout_t tmo) return (uint64_t)(uintptr_t)tmo; } -int odp_timeout_fresh(odp_timeout_t tmo) +int ODP_DEPRECATE(odp_timeout_fresh)(odp_timeout_t tmo) { timer_entry_t *timer; odp_timeout_hdr_t *timeout_hdr = timeout_to_hdr(tmo); -- cgit v1.2.3 From cb8bd350d5c9280b9889f1b614a703f09512a704 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 09:57:44 +0200 Subject: Port ce3674603 "linux-gen: time: implement odp_time_add_ns()" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/include/odp/api/plat/time_inlines.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/linux-dpdk/include/odp/api/plat/time_inlines.h b/platform/linux-dpdk/include/odp/api/plat/time_inlines.h index 8e4eec59c..b0d7ed012 100644 --- a/platform/linux-dpdk/include/odp/api/plat/time_inlines.h +++ b/platform/linux-dpdk/include/odp/api/plat/time_inlines.h @@ -104,6 +104,7 @@ static inline odp_time_t _odp_time_from_ns(uint64_t ns) #define odp_time_cmp __odp_time_cmp #define odp_time_diff __odp_time_diff #define odp_time_diff_ns __odp_time_diff_ns + #define odp_time_add_ns __odp_time_add_ns #define odp_time_sum __odp_time_sum #define odp_time_wait_ns __odp_time_wait_ns #define odp_time_wait_until __odp_time_wait_until @@ -206,6 +207,15 @@ _ODP_INLINE uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1) return odp_time_to_ns(time); } +_ODP_INLINE odp_time_t odp_time_add_ns(odp_time_t time, uint64_t ns) +{ + odp_time_t t = _odp_time_from_ns(ns); + + t.u64 += time.u64; + + return t; +} + _ODP_INLINE odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2) { odp_time_t time; -- cgit v1.2.3 From 540d8a3445d5e57837127af4e2acddeb72dab8b9 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 13:10:51 +0200 Subject: Port 29f7e5aab "linux-gen: use odp_time_add_ns()" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_schedule_eventdev.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/platform/linux-dpdk/odp_schedule_eventdev.c b/platform/linux-dpdk/odp_schedule_eventdev.c index 07cce4643..d6f3ba2f7 100644 --- a/platform/linux-dpdk/odp_schedule_eventdev.c +++ b/platform/linux-dpdk/odp_schedule_eventdev.c @@ -621,7 +621,7 @@ static inline uint16_t input_cached(odp_event_t out_ev[], unsigned int max_num, static inline int schedule_loop(odp_queue_t *out_queue, uint64_t wait, odp_event_t out_ev[], unsigned int max_num) { - odp_time_t next, wtime; + odp_time_t next; struct rte_event ev[max_num]; int first = 1; uint16_t num_deq; @@ -669,8 +669,7 @@ static inline int schedule_loop(odp_queue_t *out_queue, uint64_t wait, return 0; if (first) { - wtime = odp_time_local_from_ns(wait); - next = odp_time_sum(odp_time_local(), wtime); + next = odp_time_add_ns(odp_time_local(), wait); first = 0; continue; } -- cgit v1.2.3 From ce132da42dd2ff198236f14dd0c2491c61e73a49 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 10:02:15 +0200 Subject: Port 9b3d483bf "linux-gen: thread: implement current control/worker thread count functions" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_thread.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/linux-dpdk/odp_thread.c b/platform/linux-dpdk/odp_thread.c index 9f30aabb0..ed4cb3e0a 100644 --- a/platform/linux-dpdk/odp_thread.c +++ b/platform/linux-dpdk/odp_thread.c @@ -291,6 +291,16 @@ int odp_thread_count(void) return thread_globals->num; } +int odp_thread_control_count(void) +{ + return thread_globals->num_control; +} + +int odp_thread_worker_count(void) +{ + return thread_globals->num_worker; +} + int odp_thread_count_max(void) { return thread_globals->num_max; -- cgit v1.2.3 From d49671f07f2ad7db25107036abff5272798aece3 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 10:18:57 +0200 Subject: Port a240b2231 "linux-gen: thread: implement max control/worker thread count functions" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_thread.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/linux-dpdk/odp_thread.c b/platform/linux-dpdk/odp_thread.c index ed4cb3e0a..10b5de5e0 100644 --- a/platform/linux-dpdk/odp_thread.c +++ b/platform/linux-dpdk/odp_thread.c @@ -306,6 +306,16 @@ int odp_thread_count_max(void) return thread_globals->num_max; } +int odp_thread_control_count_max(void) +{ + return thread_globals->num_max; +} + +int odp_thread_worker_count_max(void) +{ + return thread_globals->num_max; +} + int odp_thrmask_worker(odp_thrmask_t *mask) { odp_thrmask_copy(mask, &thread_globals->worker); -- cgit v1.2.3 From 1d7598ec65e335bca2d4e6de49e73062f24c6207 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 10:48:28 +0200 Subject: Port d2588efa5 "linux-gen: time: change to non-zero startup time" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- .../linux-dpdk/include/odp/api/plat/time_inlines.h | 17 ++++++++---- platform/linux-dpdk/odp_time.c | 30 +++++++++++++++++++++- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/platform/linux-dpdk/include/odp/api/plat/time_inlines.h b/platform/linux-dpdk/include/odp/api/plat/time_inlines.h index b0d7ed012..f3d2a6947 100644 --- a/platform/linux-dpdk/include/odp/api/plat/time_inlines.h +++ b/platform/linux-dpdk/include/odp/api/plat/time_inlines.h @@ -1,5 +1,5 @@ /* Copyright (c) 2018, Linaro Limited - * Copyright (c) 2020-2023, Nokia + * Copyright (c) 2020-2024, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -21,8 +21,9 @@ /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ typedef struct _odp_time_global_t { - uint64_t start_cycles; uint64_t freq_hz; + uint64_t start_cycles; + uint64_t start_ns; } _odp_time_global_t; @@ -32,7 +33,7 @@ static inline odp_time_t _odp_time_cur(void) { odp_time_t time; - time.u64 = rte_get_timer_cycles() - _odp_time_glob.start_cycles; + time.u64 = rte_get_timer_cycles(); return time; } @@ -42,7 +43,7 @@ static inline odp_time_t _odp_time_cur_strict(void) odp_time_t time; rte_mb(); - time.u64 = rte_get_timer_cycles() - _odp_time_glob.start_cycles; + time.u64 = rte_get_timer_cycles(); return time; } @@ -108,7 +109,7 @@ static inline odp_time_t _odp_time_from_ns(uint64_t ns) #define odp_time_sum __odp_time_sum #define odp_time_wait_ns __odp_time_wait_ns #define odp_time_wait_until __odp_time_wait_until - + #define odp_time_startup __odp_time_startup #else #define _ODP_INLINE #endif @@ -248,6 +249,12 @@ _ODP_INLINE void odp_time_wait_until(odp_time_t time) _odp_time_wait_until(time); } +_ODP_INLINE void odp_time_startup(odp_time_startup_t *startup) +{ + startup->global.u64 = _odp_time_glob.start_cycles; + startup->global_ns = _odp_time_glob.start_ns; +} + /** @endcond */ #endif diff --git a/platform/linux-dpdk/odp_time.c b/platform/linux-dpdk/odp_time.c index 2fc25eb96..fbee02df1 100644 --- a/platform/linux-dpdk/odp_time.c +++ b/platform/linux-dpdk/odp_time.c @@ -1,5 +1,5 @@ /* Copyright (c) 2013-2018, Linaro Limited - * Copyright (c) 2021-2023, Nokia + * Copyright (c) 2021-2024, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -13,8 +13,11 @@ #include #include +#include #include +#define YEAR_IN_SEC (365 * 24 * 3600) + #include _odp_time_global_t _odp_time_glob; @@ -23,6 +26,9 @@ _odp_time_global_t _odp_time_glob; int _odp_time_init_global(void) { + uint64_t diff, years; + odp_time_t time; + memset(&_odp_time_glob, 0, sizeof(_odp_time_global_t)); #ifdef RTE_LIBEAL_USE_HPET @@ -37,6 +43,28 @@ int _odp_time_init_global(void) return -1; } + time.u64 = _odp_time_glob.start_cycles; + _odp_time_glob.start_ns = _odp_time_to_ns(time); + + /* Make sure that counters will not wrap */ + diff = UINT64_MAX - _odp_time_glob.start_cycles; + years = (diff / _odp_time_glob.freq_hz) / YEAR_IN_SEC; + + if (years < 10) { + _ODP_ERR("Time counter would wrap in 10 years: %" PRIu64 "\n", + _odp_time_glob.start_cycles); + return -1; + } + + diff = UINT64_MAX - _odp_time_glob.start_ns; + years = (diff / ODP_TIME_SEC_IN_NS) / YEAR_IN_SEC; + + if (years < 10) { + _ODP_ERR("Time in nsec would wrap in 10 years: %" PRIu64 "\n", + _odp_time_glob.start_ns); + return -1; + } + return 0; } -- cgit v1.2.3 From ebc40c4122c0e4326d579e263acc984b666162d6 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 10:55:04 +0200 Subject: Port 5dc9b47a7 "linux-gen: timer: implement odp_timer_pool_start_multi()" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_timer.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index 1b76fc912..4d66ac52a 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -1,5 +1,5 @@ /* Copyright (c) 2018, Linaro Limited - * Copyright (c) 2019-2023, Nokia + * Copyright (c) 2019-2024, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -750,6 +750,19 @@ void odp_timer_pool_start(void) /* Nothing to do */ } +int odp_timer_pool_start_multi(odp_timer_pool_t timer_pool[], int num) +{ + _ODP_ASSERT(timer_pool != NULL); + _ODP_ASSERT(num > 0); + if (ODP_DEBUG) { + for (int i = 0; i < num; i++) + _ODP_ASSERT(timer_pool[i] != ODP_TIMER_POOL_INVALID); + } + + /* Nothing to do here, timer pools are started by the create call. */ + return num; +} + void odp_timer_pool_destroy(odp_timer_pool_t tp) { timer_pool_t *timer_pool = timer_pool_from_hdl(tp); -- cgit v1.2.3 From 052d246a58081cf3cca9231dce162edec42f4d76 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 12:21:11 +0200 Subject: Port d51b28dd4 "linux-gen: system: add missing defines to odp_sys_config_print()" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_system_info.c | 43 ++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/platform/linux-dpdk/odp_system_info.c b/platform/linux-dpdk/odp_system_info.c index 62db1064e..0ebb3e09f 100644 --- a/platform/linux-dpdk/odp_system_info.c +++ b/platform/linux-dpdk/odp_system_info.c @@ -1,5 +1,5 @@ /* Copyright (c) 2013-2018, Linaro Limited - * Copyright (c) 2020-2022, Nokia + * Copyright (c) 2020-2024, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -528,22 +528,29 @@ void odp_sys_config_print(void) _ODP_PRINT("\n\nodp_config_internal.h values:\n" "-----------------------------\n"); - _ODP_PRINT("CONFIG_NUM_CPU_IDS: %i\n", CONFIG_NUM_CPU_IDS); - _ODP_PRINT("CONFIG_POOLS: %i\n", CONFIG_POOLS); - _ODP_PRINT("CONFIG_INTERNAL_QUEUES: %i\n", CONFIG_INTERNAL_QUEUES); - _ODP_PRINT("CONFIG_MAX_PLAIN_QUEUES: %i\n", CONFIG_MAX_PLAIN_QUEUES); - _ODP_PRINT("CONFIG_MAX_SCHED_QUEUES: %i\n", CONFIG_MAX_SCHED_QUEUES); - _ODP_PRINT("CONFIG_MAX_QUEUES: %i\n", CONFIG_MAX_QUEUES); - _ODP_PRINT("CONFIG_QUEUE_MAX_ORD_LOCKS: %i\n", CONFIG_QUEUE_MAX_ORD_LOCKS); - _ODP_PRINT("CONFIG_PKTIO_ENTRIES: %i\n", CONFIG_PKTIO_ENTRIES); - _ODP_PRINT("CONFIG_BUFFER_ALIGN_MIN: %i\n", CONFIG_BUFFER_ALIGN_MIN); - _ODP_PRINT("CONFIG_BUFFER_ALIGN_MAX: %i\n", CONFIG_BUFFER_ALIGN_MAX); - _ODP_PRINT("CONFIG_PACKET_TAILROOM: %i\n", CONFIG_PACKET_TAILROOM); - _ODP_PRINT("CONFIG_PACKET_SEG_SIZE: %i\n", CONFIG_PACKET_SEG_SIZE); - _ODP_PRINT("CONFIG_PACKET_SEG_LEN_MIN: %i\n", CONFIG_PACKET_SEG_LEN_MIN); - _ODP_PRINT("CONFIG_PACKET_MAX_SEG_LEN: %i\n", CONFIG_PACKET_MAX_SEG_LEN); - _ODP_PRINT("CONFIG_SHM_BLOCKS: %i\n", CONFIG_SHM_BLOCKS); - _ODP_PRINT("CONFIG_BURST_SIZE: %i\n", CONFIG_BURST_SIZE); - _ODP_PRINT("CONFIG_POOL_MAX_NUM: %i\n", CONFIG_POOL_MAX_NUM); + _ODP_PRINT("CONFIG_NUM_CPU_IDS: %i\n", CONFIG_NUM_CPU_IDS); + _ODP_PRINT("CONFIG_INTERNAL_QUEUES: %i\n", CONFIG_INTERNAL_QUEUES); + _ODP_PRINT("CONFIG_MAX_PLAIN_QUEUES: %i\n", CONFIG_MAX_PLAIN_QUEUES); + _ODP_PRINT("CONFIG_MAX_SCHED_QUEUES: %i\n", CONFIG_MAX_SCHED_QUEUES); + _ODP_PRINT("CONFIG_MAX_QUEUES: %i\n", CONFIG_MAX_QUEUES); + _ODP_PRINT("CONFIG_QUEUE_MAX_ORD_LOCKS: %i\n", CONFIG_QUEUE_MAX_ORD_LOCKS); + _ODP_PRINT("CONFIG_MAX_DMA_SESSIONS: %i\n", CONFIG_MAX_DMA_SESSIONS); + _ODP_PRINT("CONFIG_INTERNAL_STASHES: %i\n", CONFIG_INTERNAL_STASHES); + _ODP_PRINT("CONFIG_MAX_STASHES: %i\n", CONFIG_MAX_STASHES); + _ODP_PRINT("CONFIG_PKTIO_ENTRIES: %i\n", CONFIG_PKTIO_ENTRIES); + _ODP_PRINT("CONFIG_BUFFER_ALIGN_MIN: %i\n", CONFIG_BUFFER_ALIGN_MIN); + _ODP_PRINT("CONFIG_BUFFER_ALIGN_MAX: %i\n", CONFIG_BUFFER_ALIGN_MAX); + _ODP_PRINT("CONFIG_PACKET_TAILROOM: %i\n", CONFIG_PACKET_TAILROOM); + _ODP_PRINT("CONFIG_PACKET_SEG_SIZE: %i\n", CONFIG_PACKET_SEG_SIZE); + _ODP_PRINT("CONFIG_PACKET_MAX_SEG_LEN: %i\n", CONFIG_PACKET_MAX_SEG_LEN); + _ODP_PRINT("CONFIG_PACKET_SEG_LEN_MIN: %i\n", CONFIG_PACKET_SEG_LEN_MIN); + _ODP_PRINT("CONFIG_PACKET_VECTOR_MAX_SIZE: %i\n", CONFIG_PACKET_VECTOR_MAX_SIZE); + _ODP_PRINT("CONFIG_INTERNAL_SHM_BLOCKS: %i\n", CONFIG_INTERNAL_SHM_BLOCKS); + _ODP_PRINT("CONFIG_SHM_BLOCKS: %i\n", CONFIG_SHM_BLOCKS); + _ODP_PRINT("CONFIG_BURST_SIZE: %i\n", CONFIG_BURST_SIZE); + _ODP_PRINT("CONFIG_INTERNAL_POOLS: %i\n", CONFIG_INTERNAL_POOLS); + _ODP_PRINT("CONFIG_POOLS: %i\n", CONFIG_POOLS); + _ODP_PRINT("CONFIG_POOL_MAX_NUM: %i\n", CONFIG_POOL_MAX_NUM); + _ODP_PRINT("CONFIG_IPSEC_MAX_NUM_SA: %i\n", CONFIG_IPSEC_MAX_NUM_SA); _ODP_PRINT("\n"); } -- cgit v1.2.3 From 016946a13c33899b075d31e97169857c04c83614 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 12:40:58 +0200 Subject: Port 063e2f067 "linux-gen: timer: inline odp_timer_current_tick()" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/include/odp/api/plat/timer_inlines.h | 12 +++++++++++- platform/linux-dpdk/odp_timer.c | 7 ------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h b/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h index 66327acdb..d9403bb0e 100644 --- a/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h +++ b/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022-2023, Nokia +/* Copyright (c) 2022-2024, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -8,11 +8,15 @@ #define ODP_PLAT_TIMER_INLINES_H_ #include +#include #include #include #include +#include +#include + #include /** @cond _ODP_HIDE_FROM_DOXYGEN_ */ @@ -24,6 +28,7 @@ #define odp_timeout_tick __odp_timeout_tick #define odp_timeout_user_ptr __odp_timeout_user_ptr #define odp_timeout_user_area __odp_timeout_user_area + #define odp_timer_current_tick __odp_timer_current_tick #define odp_timeout_from_event __odp_timeout_from_event #define odp_timeout_from_event_multi __odp_timeout_from_event_multi #define odp_timeout_to_event __odp_timeout_to_event @@ -51,6 +56,11 @@ _ODP_INLINE void *odp_timeout_user_area(odp_timeout_t tmo) return _odp_timeout_hdr_field(tmo, void *, uarea_addr); } +_ODP_INLINE uint64_t odp_timer_current_tick(odp_timer_pool_t tp ODP_UNUSED) +{ + return rte_get_timer_cycles(); +} + _ODP_INLINE odp_timeout_t odp_timeout_from_event(odp_event_t ev) { _ODP_ASSERT(odp_event_type(ev) == ODP_EVENT_TIMEOUT); diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index 4d66ac52a..c04a4af1d 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -814,13 +814,6 @@ uint64_t odp_timer_ns_to_tick(odp_timer_pool_t tp, uint64_t ns) return ticks; } -uint64_t odp_timer_current_tick(odp_timer_pool_t tp) -{ - (void)tp; - - return rte_get_timer_cycles(); -} - int odp_timer_sample_ticks(odp_timer_pool_t tp[], uint64_t tick[], uint64_t clk_count[], int num) { uint64_t now; -- cgit v1.2.3 From fa734755ba7ada322b568bc63a4c3ccbbb815b8b Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 15:43:49 +0200 Subject: validation: pool: fix pool statistics test Values of per thread counters (odp_pool_stats_t.thread.cache_available[]) are undefined if these counters are not supported/enabled. Signed-off-by: Matias Elo Reviewed-by: Janne Peltonen --- test/validation/api/pool/pool.c | 65 +++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/test/validation/api/pool/pool.c b/test/validation/api/pool/pool.c index 6f9b054ac..ee8aa4b67 100644 --- a/test/validation/api/pool/pool.c +++ b/test/validation/api/pool/pool.c @@ -1446,8 +1446,10 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) CU_ASSERT(stats.thread.first == first); CU_ASSERT(stats.thread.last == last); - for (j = 0; j < num_thr; j++) - CU_ASSERT(stats.thread.cache_available[j] <= stats.cache_available); + if (supported.bit.thread_cache_available) { + for (j = 0; j < num_thr; j++) + CU_ASSERT(stats.thread.cache_available[j] <= stats.cache_available); + } /* Allocate the events */ for (j = 0; j < num_allocs; j++) { @@ -1493,29 +1495,31 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) if (supported.bit.cache_available) CU_ASSERT(selected.cache_available <= num_obj - num_events); - while (first_id < odp_thread_count_max()) { - memset(&stats, 0xff, sizeof(odp_pool_stats_t)); - - stats.thread.first = first_id; - stats.thread.last = last_id; - num_thr = last_id - first_id + 1; - CU_ASSERT_FATAL(odp_pool_stats(pool[i], &stats) == 0); - - for (uint32_t k = 0; k < num_thr; k++) { - uint64_t cached = stats.thread.cache_available[k]; - - CU_ASSERT(cached <= num_obj - num_events); - total_cached += cached; - } - first_id = last_id + 1; - last_id += ODP_POOL_MAX_THREAD_STATS; - if (last_id >= odp_thread_count_max()) - last_id = odp_thread_count_max() - 1; - }; - - if (supported.bit.cache_available && supported.bit.thread_cache_available && - ODP_POOL_MAX_THREAD_STATS >= odp_thread_count_max()) - CU_ASSERT(stats.cache_available == total_cached); + if (supported.bit.thread_cache_available) { + while (first_id < odp_thread_count_max()) { + memset(&stats, 0xff, sizeof(odp_pool_stats_t)); + + stats.thread.first = first_id; + stats.thread.last = last_id; + num_thr = last_id - first_id + 1; + CU_ASSERT_FATAL(odp_pool_stats(pool[i], &stats) == 0); + + for (uint32_t k = 0; k < num_thr; k++) { + uint64_t cached = stats.thread.cache_available[k]; + + CU_ASSERT(cached <= num_obj - num_events); + total_cached += cached; + } + first_id = last_id + 1; + last_id += ODP_POOL_MAX_THREAD_STATS; + if (last_id >= odp_thread_count_max()) + last_id = odp_thread_count_max() - 1; + }; + + if (supported.bit.cache_available && + ODP_POOL_MAX_THREAD_STATS >= odp_thread_count_max()) + CU_ASSERT(stats.cache_available == total_cached); + } } CU_ASSERT(num_events == num_obj); @@ -1541,8 +1545,10 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) CU_ASSERT(stats.cache_available == 0); if (supported.bit.cache_available) CU_ASSERT(selected.cache_available == 0); - for (j = 0; j < num_thr; j++) - CU_ASSERT(stats.thread.cache_available[j] == 0); + if (supported.bit.thread_cache_available) { + for (j = 0; j < num_thr; j++) + CU_ASSERT(stats.thread.cache_available[j] == 0); + } if (supported.bit.alloc_ops) { CU_ASSERT(stats.alloc_ops > 0 && stats.alloc_ops <= num_allocs); CU_ASSERT(selected.alloc_ops > 0 && selected.alloc_ops <= num_allocs); @@ -1600,8 +1606,9 @@ static void pool_test_pool_statistics(odp_pool_type_t pool_type) printf(" cache_available: %" PRIu64 "\n", stats.cache_available); printf(" cache_alloc_ops: %" PRIu64 "\n", stats.cache_alloc_ops); printf(" cache_free_ops: %" PRIu64 "\n", stats.cache_free_ops); - printf(" thread.cache_available[0]: %" PRIu64 "\n", - stats.thread.cache_available[0]); + if (supported.bit.thread_cache_available) + printf(" thread.cache_available[0]: %" PRIu64 "\n", + stats.thread.cache_available[0]); } CU_ASSERT_FATAL(odp_pool_stats_reset(pool[i]) == 0); -- cgit v1.2.3 From 4c0f0321c188a84eb62f70db9335fc1e347bc3a4 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 12:45:56 +0200 Subject: Port cd2216880 "linux-gen: pool: remove per thread stats zeroing" Port original commit from linux-generic. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_pool.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/platform/linux-dpdk/odp_pool.c b/platform/linux-dpdk/odp_pool.c index 1748aa13e..f7726f97b 100644 --- a/platform/linux-dpdk/odp_pool.c +++ b/platform/linux-dpdk/odp_pool.c @@ -1008,7 +1008,6 @@ unsigned int odp_pool_max_index(void) int odp_pool_stats(odp_pool_t pool_hdl, odp_pool_stats_t *stats) { pool_t *pool; - uint16_t first, last; if (odp_unlikely(pool_hdl == ODP_POOL_INVALID)) { _ODP_ERR("Invalid pool handle\n"); @@ -1020,14 +1019,9 @@ int odp_pool_stats(odp_pool_t pool_hdl, odp_pool_stats_t *stats) } pool = _odp_pool_entry(pool_hdl); - first = stats->thread.first; - last = stats->thread.last; - memset(stats, 0, sizeof(odp_pool_stats_t)); - - /* Restore input parameters */ - stats->thread.first = first; - stats->thread.last = last; + /* Zero everything else but per thread statistics */ + memset(stats, 0, offsetof(odp_pool_stats_t, thread)); if (pool->params.stats.bit.available) stats->available = rte_mempool_avail_count(pool->rte_mempool); -- cgit v1.2.3 From d99921f8eb9dc1fd1af4bee6c9fe67657b3737de Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 10 Jan 2024 13:18:56 +0200 Subject: linux-dpdk: remove support for eol dpdk versions Stop supporting EOL DPDK versions 19.11 and 20.11. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- .github/workflows/ci-pipeline-arm64.yml | 22 --------- .github/workflows/ci-pipeline.yml | 20 +------- platform/linux-dpdk/README | 85 +++++++-------------------------- 3 files changed, 18 insertions(+), 109 deletions(-) diff --git a/.github/workflows/ci-pipeline-arm64.yml b/.github/workflows/ci-pipeline-arm64.yml index c47bfc855..5b4f7e13c 100644 --- a/.github/workflows/ci-pipeline-arm64.yml +++ b/.github/workflows/ci-pipeline-arm64.yml @@ -257,28 +257,6 @@ jobs: - if: ${{ failure() }} uses: ./.github/actions/run-failure-log - Run_dpdk-19_11: - if: ${{ github.repository == 'OpenDataPlane/odp-dpdk' }} - runs-on: [self-hosted, ARM64] - steps: - - uses: OpenDataPlane/action-clean-up@main - - uses: actions/checkout@v3 - - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}" - -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native-dpdk_19.11 /odp/scripts/ci/check.sh - - if: ${{ failure() }} - uses: ./.github/actions/run-failure-log - - Run_dpdk-20_11: - if: ${{ github.repository == 'OpenDataPlane/odp-dpdk' }} - runs-on: [self-hosted, ARM64] - steps: - - uses: OpenDataPlane/action-clean-up@main - - uses: actions/checkout@v3 - - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}" - -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native-dpdk_20.11 /odp/scripts/ci/check.sh - - if: ${{ failure() }} - uses: ./.github/actions/run-failure-log - Run_dpdk-21_11: if: ${{ github.repository == 'OpenDataPlane/odp-dpdk' }} runs-on: [self-hosted, ARM64] diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index d0832a97f..d0b6a0647 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -36,7 +36,7 @@ jobs: ./scripts/ci-checkpatches.sh ${COMMIT_RANGE} Documentation: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - name: Install dependencies @@ -347,24 +347,6 @@ jobs: - if: ${{ failure() }} uses: ./.github/actions/run-failure-log - Run_dpdk-19_11: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v3 - - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}" - -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-dpdk_19.11 /odp/scripts/ci/check.sh - - if: ${{ failure() }} - uses: ./.github/actions/run-failure-log - - Run_dpdk-20_11: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v3 - - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}" - -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-dpdk_20.11 /odp/scripts/ci/check.sh - - if: ${{ failure() }} - uses: ./.github/actions/run-failure-log - Run_dpdk-21_11: runs-on: ubuntu-20.04 steps: diff --git a/platform/linux-dpdk/README b/platform/linux-dpdk/README index 55e723573..421d3f958 100644 --- a/platform/linux-dpdk/README +++ b/platform/linux-dpdk/README @@ -1,5 +1,5 @@ Copyright (c) 2018-2019, Linaro Limited -Copyright (c) 2019-2023, Nokia +Copyright (c) 2019-2024, Nokia All rights reserved. SPDX-License-Identifier: BSD-3-Clause @@ -19,8 +19,8 @@ Prerequisites and considerations: - it's also possible to use odp-dpdk for evaluation purposes without a DPDK compatible NIC, using the pcap poll mode driver - DPDK code must be downloaded, configured and compiled, details below -- ODP-DPDK has been compiled and tested on an x86 host with Ubuntu 18.04 LTS - (4.15.0 kernel). +- ODP-DPDK has been compiled and tested on an x86 host with Ubuntu 22.04 LTS + (5.15.0 kernel). - DPDK only works on a selected range of network cards. The list of known and supported devices can be found in the DPDK documentation: https://doc.dpdk.org/guides/nics/index.html @@ -36,44 +36,12 @@ cmds below for Ubuntu, where it has been compiled and tested. On Ubuntu install pcap development library: sudo apt-get install libpcap-dev -Right now ODP-DPDK supports DPDK v19.11, v20.11, v21.11, and v22.11 (recommended version). +Right now ODP-DPDK supports DPDK v21.11 and v22.11 (recommended version). -Compile DPDK 19.11 ------------------- -Fetch the DPDK code: - git clone https://dpdk.org/git/dpdk-stable --branch 19.11 --depth 1 ./ - -This has to be done only once: - cd - make config T=x86_64-native-linuxapp-gcc O=x86_64-native-linuxapp-gcc - -Enable pcap pmd to use ODP-DPDK without DPDK supported NIC's: - cd /x86_64-native-linuxapp-gcc - sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_PCAP=).*,\1y,' .config - -Enable openssl crypto pmd to use openssl with odp-dpdk: - sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_OPENSSL=).*,\1y,' .config - -Optionally, add more queues to eventdev: - sed -ri 's,(CONFIG_RTE_EVENT_MAX_QUEUES_PER_DEV=).*,\1255,' .config - -Now return to parent directory and build DPDK: - cd .. - -The last step depends on whether ODP shared libraries will be built with this -deployment of DPDK: -SHARED libraries: - make install T=x86_64-native-linuxapp-gcc DESTDIR=./install EXTRA_CFLAGS="-fPIC" - -STATIC libraries: - make install T=x86_64-native-linuxapp-gcc DESTDIR=./install - -This only ensures building DPDK, but traffic is not tested with this build yet. - -Compile DPDK from v20.11 onwards --------------------------------- +Compile DPDK +------------ Fetch the DPDK code: - git clone https://dpdk.org/git/dpdk-stable --branch 20.11 --depth 1 ./ + git clone https://dpdk.org/git/dpdk-stable --branch 22.11 --depth 1 ./ Prepare the build directory: cd @@ -98,14 +66,11 @@ path with the --with-dpdk-path option. ./bootstrap The following step depends on whether ODP shared libraries are to be built. -SHARED libraries (requires building DPDK with -fPIC, see above): - ./configure --with-dpdk-path=/install +SHARED libraries: + ./configure --enable-dpdk-shared STATIC libraries (better performance): - ./configure --with-dpdk-path=/install --disable-shared - -Starting from DPDK 20.11, --with-dpdk-path option is not used anymore: - ./configure + ./configure --disable-shared Or, if DPDK was not installed to the default location, set PKG_CONFIG_PATH: PKG_CONFIG_PATH=/install/lib/x86_64-linux-gnu/pkgconfig ./configure @@ -223,7 +188,7 @@ rte_eal_[mp_]remote_launch(), but not through ODP API's. Nevertheless, odp_local_init() makes sure for the rest of the DPDK libraries ODP threads look like proper DPDK threads. -Exaple how to run an ODP-DPDK L2 forwarding application: +Example how to run an ODP-DPDK L2 forwarding application: sudo ./odp_l2fwd -i 0,1 -c 2 @@ -298,27 +263,11 @@ Get the Intel Multi-Buffer Crypto library from https://github.com/intel/intel-ipsec-mb and follow the README from the repo on how to build the library. -Building DPDK 19.11 -------------------- -Follow the instructions from "Compile DPDK" section and make sure to enable the -necessary crypto PMDs: -E.g. -# Compile PMD for AESNI backed device -sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_AESNI_MB=).*,\1y,' .config - -# Compile PMD for AESNI GCM device -sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=).*,\1y,' .config - -# Compile PMD for SNOW 3G device -sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_SNOW3G=).*,\1y,' .config - -AESNI_MULTI_BUFFER_LIB_PATH=/path-to/Intel-multi-buffer-crypto/ \ - make install T=x86_64-native-linuxapp-gcc DESTDIR=./install EXTRA_CFLAGS="-fPIC" - -Building DPDK 20.11 -------------------- -If libIPSec_MB has been installed outside the normal search paths, -configure the compiler and linker options with +Building DPDK +------------- +Follow the instructions from "Compile DPDK" section. If libIPSec_MB has been +installed outside the normal search paths, configure the compiler and linker +options with: meson configure -Dc_args=-I/path-to/Intel-multi-buffer-crypto/include \ -Dc_link_args=-L/path-to/Intel-multi-buffer-crypto/lib @@ -341,7 +290,7 @@ yet tested in the ODP CI. To use eventdev one must set ODP_SCHEDULER environment variable to "eventdev" and provide the necessary platform parameters to DPDK. -Refer to DPDK event device driver documentation for platform defails: +Refer to DPDK event device driver documentation for platform details: https://doc.dpdk.org/guides/eventdevs/index.html In case of the standard software eventdev implementation one must enable a DPDK -- cgit v1.2.3 From 70c22bcfd0d2644826a8128147d8a5ce5d5d213e Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 13:46:23 +0200 Subject: linux-dpdk: timer: inline odp_timer_tick_to_ns() implementation Inline implementation of odp_timer_tick_to_ns() function. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- .../include/odp/api/plat/timer_inline_types.h | 8 +++++++ .../include/odp/api/plat/timer_inlines.h | 18 +++++++++++++++ platform/linux-dpdk/odp_timer.c | 27 ++++++++-------------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/platform/linux-dpdk/include/odp/api/plat/timer_inline_types.h b/platform/linux-dpdk/include/odp/api/plat/timer_inline_types.h index 330cbe4ce..6c997e80d 100644 --- a/platform/linux-dpdk/include/odp/api/plat/timer_inline_types.h +++ b/platform/linux-dpdk/include/odp/api/plat/timer_inline_types.h @@ -31,6 +31,14 @@ typedef struct _odp_timeout_inline_offset_t { extern const _odp_timeout_inline_offset_t _odp_timeout_inline_offset; +/* Timer global data */ +typedef struct _odp_timer_global_t { + uint64_t freq_hz; + +} _odp_timer_global_t; + +extern _odp_timer_global_t _odp_timer_glob; + /** @endcond */ #ifdef __cplusplus diff --git a/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h b/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h index d9403bb0e..217dce54d 100644 --- a/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h +++ b/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -32,6 +33,7 @@ #define odp_timeout_from_event __odp_timeout_from_event #define odp_timeout_from_event_multi __odp_timeout_from_event_multi #define odp_timeout_to_event __odp_timeout_to_event + #define odp_timer_tick_to_ns __odp_timer_tick_to_ns #else #define _ODP_INLINE #endif @@ -82,6 +84,22 @@ _ODP_INLINE odp_event_t odp_timeout_to_event(odp_timeout_t tmo) return (odp_event_t)tmo; } +_ODP_INLINE uint64_t odp_timer_tick_to_ns(odp_timer_pool_t tp ODP_UNUSED, uint64_t ticks) +{ + uint64_t nsec; + uint64_t sec = 0; + const uint64_t freq_hz = _odp_timer_glob.freq_hz; + + if (ticks >= freq_hz) { + sec = ticks / freq_hz; + ticks = ticks - sec * freq_hz; + } + + nsec = (ODP_TIME_SEC_IN_NS * ticks) / freq_hz; + + return (sec * ODP_TIME_SEC_IN_NS) + nsec; +} + /** @endcond */ #endif diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index c04a4af1d..e433fa471 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -198,6 +198,9 @@ _odp_timeout_inline_offset ODP_ALIGNED_CACHE = { .uarea_addr = offsetof(odp_timeout_hdr_t, uarea_addr) }; +/* Global data for inline functions */ +_odp_timer_global_t _odp_timer_glob; + #include static void timer_cb(struct rte_timer *rte_timer, void *arg ODP_UNUSED) @@ -395,6 +398,13 @@ int _odp_timer_init_global(const odp_init_t *params) timer_global->ops.reset = timer_reset; } + _odp_timer_glob.freq_hz = rte_get_timer_hz(); + if (_odp_timer_glob.freq_hz == 0) { + _ODP_ERR("Reading timer frequency failed\n"); + odp_shm_free(shm); + return -1; + } + return 0; } @@ -779,23 +789,6 @@ void odp_timer_pool_destroy(odp_timer_pool_t tp) odp_ticketlock_unlock(&timer_global->lock); } -uint64_t odp_timer_tick_to_ns(odp_timer_pool_t tp, uint64_t ticks) -{ - uint64_t nsec; - uint64_t freq_hz = rte_get_timer_hz(); - uint64_t sec = 0; - (void)tp; - - if (ticks >= freq_hz) { - sec = ticks / freq_hz; - ticks = ticks - sec * freq_hz; - } - - nsec = (SEC_IN_NS * ticks) / freq_hz; - - return (sec * SEC_IN_NS) + nsec; -} - uint64_t odp_timer_ns_to_tick(odp_timer_pool_t tp, uint64_t ns) { uint64_t ticks; -- cgit v1.2.3 From 35d2aa014a3c8368a54779c42f7c3a65e5dd06a4 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 Jan 2024 13:51:29 +0200 Subject: linux-dpdk: timer: inline odp_timer_ns_to_tick() implementation Inline implementation of odp_timer_ns_to_tick() function. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- .../include/odp/api/plat/timer_inlines.h | 18 ++++++++++++++ platform/linux-dpdk/odp_timer.c | 28 ++++------------------ 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h b/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h index 217dce54d..a85c7582d 100644 --- a/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h +++ b/platform/linux-dpdk/include/odp/api/plat/timer_inlines.h @@ -34,6 +34,7 @@ #define odp_timeout_from_event_multi __odp_timeout_from_event_multi #define odp_timeout_to_event __odp_timeout_to_event #define odp_timer_tick_to_ns __odp_timer_tick_to_ns + #define odp_timer_ns_to_tick __odp_timer_ns_to_tick #else #define _ODP_INLINE #endif @@ -100,6 +101,23 @@ _ODP_INLINE uint64_t odp_timer_tick_to_ns(odp_timer_pool_t tp ODP_UNUSED, uint64 return (sec * ODP_TIME_SEC_IN_NS) + nsec; } +_ODP_INLINE uint64_t odp_timer_ns_to_tick(odp_timer_pool_t tp ODP_UNUSED, uint64_t ns) +{ + uint64_t ticks; + uint64_t sec = 0; + const uint64_t freq_hz = _odp_timer_glob.freq_hz; + + if (ns >= ODP_TIME_SEC_IN_NS) { + sec = ns / ODP_TIME_SEC_IN_NS; + ns = ns - sec * ODP_TIME_SEC_IN_NS; + } + + ticks = sec * freq_hz; + ticks += (ns * freq_hz) / ODP_TIME_SEC_IN_NS; + + return ticks; +} + /** @endcond */ #endif diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index e433fa471..7e1ea4389 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -47,9 +47,6 @@ #define EXPIRED 1 #define TICKING 2 -/* One second in nanoseconds */ -#define SEC_IN_NS ((uint64_t)1000000000) - /* Maximum number of timer pools */ #define MAX_TIMER_POOLS 8 @@ -789,24 +786,6 @@ void odp_timer_pool_destroy(odp_timer_pool_t tp) odp_ticketlock_unlock(&timer_global->lock); } -uint64_t odp_timer_ns_to_tick(odp_timer_pool_t tp, uint64_t ns) -{ - uint64_t ticks; - uint64_t freq_hz = rte_get_timer_hz(); - uint64_t sec = 0; - (void)tp; - - if (ns >= SEC_IN_NS) { - sec = ns / SEC_IN_NS; - ns = ns - sec * SEC_IN_NS; - } - - ticks = sec * freq_hz; - ticks += (ns * freq_hz) / SEC_IN_NS; - - return ticks; -} - int odp_timer_sample_ticks(odp_timer_pool_t tp[], uint64_t tick[], uint64_t clk_count[], int num) { uint64_t now; @@ -856,9 +835,10 @@ int odp_timer_pool_info(odp_timer_pool_t tp, info->name = timer_pool->name; info->tick_info.freq.integer = freq_hz; - info->tick_info.nsec.integer = SEC_IN_NS / freq_hz; - if (SEC_IN_NS % freq_hz) { - info->tick_info.nsec.numer = SEC_IN_NS - (info->tick_info.nsec.integer * freq_hz); + info->tick_info.nsec.integer = ODP_TIME_SEC_IN_NS / freq_hz; + if (ODP_TIME_SEC_IN_NS % freq_hz) { + info->tick_info.nsec.numer = ODP_TIME_SEC_IN_NS - (info->tick_info.nsec.integer * + freq_hz); info->tick_info.nsec.denom = freq_hz; } /* Leave source clock information to zero as there is no direct link -- cgit v1.2.3 From 26e3fc76fe1f77e44e3534940ae41d40440e7ca7 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 12 Jan 2024 13:36:09 +0200 Subject: linux-dpdk: timer: fix warning from periodic timer reuse Initialize periodic timer timeout event after last ack to avoid warning from the following odp_timer_periodic_start() call if the same timer is reused. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_timer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index 7e1ea4389..eb4e31a57 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -1137,8 +1137,10 @@ int odp_timer_periodic_ack(odp_timer_t timer_hdl, odp_event_t tmo_ev) abs_tick = timer->periodic_ticks; - if (odp_unlikely(abs_tick == PERIODIC_CANCELLED)) + if (odp_unlikely(abs_tick == PERIODIC_CANCELLED)) { + timer->tmo_event = ODP_EVENT_INVALID; return 2; + } acc = (uint64_t)timer->periodic_ticks_frac_acc + (uint64_t)timer->periodic_ticks_frac; -- cgit v1.2.3 From 6434fc28a808b233a3e52fac98611ddd8e879dbe Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 12 Jan 2024 13:48:40 +0200 Subject: linux-dpdk: timer: fix odp_timer_periodic_cancel() failure return value Use failure return value in odp_timer_periodic_cancel() when enqueueing the final timeout event failed. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_timer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index eb4e31a57..689d30ad3 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -1232,9 +1232,12 @@ int odp_timer_periodic_cancel(odp_timer_t timer_hdl) /* Timer successfully cancelled, so send the final event manually. */ if (ret == 0 && timer->state == TICKING) { timer->state = NOT_TICKING; + timer->tmo_event = ODP_EVENT_INVALID; if (odp_unlikely(odp_queue_enq(timer->queue, event))) { _ODP_ERR("Failed to enqueue final timeout event\n"); _odp_event_free(event); + odp_ticketlock_unlock(&timer->lock); + return -1; } } -- cgit v1.2.3 From 219bf470229c42d77bf9cf6314b360ad9f233db1 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 12 Jan 2024 13:50:10 +0200 Subject: linux-dpdk: timer: optimize setting timers After removal of odp_timer_set_abs() and odp_timer_set_rel() functions timer_set() doesn't have to return the old timeout event anymore. Signed-off-by: Matias Elo Reviewed-by: Tuomas Taipale --- platform/linux-dpdk/odp_timer.c | 47 ++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c index 689d30ad3..e01a541ad 100644 --- a/platform/linux-dpdk/odp_timer.c +++ b/platform/linux-dpdk/odp_timer.c @@ -933,10 +933,9 @@ static inline odp_timeout_hdr_t *timeout_to_hdr(odp_timeout_t tmo) return (odp_timeout_hdr_t *)(uintptr_t)tmo; } -static inline int timer_set(odp_timer_t timer_hdl, uint64_t tick, - odp_event_t *event, int absolute) +static inline int timer_set(odp_timer_t timer_hdl, uint64_t tick, odp_event_t event, int absolute) { - odp_event_t old_ev, tmo_event; + odp_event_t tmo_event; uint64_t cur_tick, rel_tick, abs_tick; timer_entry_t *timer = timer_from_hdl(timer_hdl); int num_retry = 0; @@ -965,12 +964,20 @@ retry: odp_ticketlock_lock(&timer->lock); - if (timer->tmo_event == ODP_EVENT_INVALID) - if (event == NULL || (event && *event == ODP_EVENT_INVALID)) { + if (timer->tmo_event == ODP_EVENT_INVALID) { + if (odp_unlikely(event == ODP_EVENT_INVALID)) { odp_ticketlock_unlock(&timer->lock); /* Event missing, or timer already expired and * enqueued the event. */ return ODP_TIMER_FAIL; + } + } else { + /* Check that timer was not active */ + if (odp_unlikely(event != ODP_EVENT_INVALID)) { + _ODP_ERR("Timer was already active\n"); + odp_ticketlock_unlock(&timer->lock); + return ODP_TIMER_FAIL; + } } if (odp_unlikely(timer_global->ops.reset(&timer->rte_timer, rel_tick, @@ -1007,14 +1014,8 @@ retry: return ODP_TIMER_FAIL; } - if (event) { - old_ev = timer->tmo_event; - - if (*event != ODP_EVENT_INVALID) - timer->tmo_event = *event; - - *event = old_ev; - } + if (event != ODP_EVENT_INVALID) + timer->tmo_event = event; tmo_event = timer->tmo_event; timer->tick = abs_tick; @@ -1039,16 +1040,10 @@ int odp_timer_start(odp_timer_t timer, const odp_timer_start_t *start_param) int abs = start_param->tick_type == ODP_TIMER_TICK_ABS; int ret; - ret = timer_set(timer, start_param->tick, &tmo_ev, abs); + ret = timer_set(timer, start_param->tick, tmo_ev, abs); if (odp_unlikely(ret != ODP_TIMER_SUCCESS)) return ret; - /* Check that timer was not active */ - if (odp_unlikely(tmo_ev != ODP_EVENT_INVALID)) { - _ODP_ERR("Timer was active already\n"); - odp_event_free(tmo_ev); - } - return ODP_TIMER_SUCCESS; } @@ -1057,7 +1052,7 @@ int odp_timer_restart(odp_timer_t timer, const odp_timer_start_t *start_param) int abs = start_param->tick_type == ODP_TIMER_TICK_ABS; /* Reset timer without changing the event */ - return timer_set(timer, start_param->tick, NULL, abs); + return timer_set(timer, start_param->tick, ODP_EVENT_INVALID, abs); } int odp_timer_periodic_start(odp_timer_t timer_hdl, @@ -1109,16 +1104,10 @@ int odp_timer_periodic_start(odp_timer_t timer_hdl, absolute = 1; } - ret = timer_set(timer_hdl, first_tick, &tmo_ev, absolute); + ret = timer_set(timer_hdl, first_tick, tmo_ev, absolute); if (odp_unlikely(ret != ODP_TIMER_SUCCESS)) return ret; - /* Check that timer was not active */ - if (odp_unlikely(tmo_ev != ODP_EVENT_INVALID)) { - _ODP_ERR("Timer was active already\n"); - odp_event_free(tmo_ev); - } - return ODP_TIMER_SUCCESS; } @@ -1155,7 +1144,7 @@ int odp_timer_periodic_ack(odp_timer_t timer_hdl, odp_event_t tmo_ev) abs_tick += timeout_hdr->expiration; timeout_hdr->expiration = abs_tick; - ret = timer_set(timer_hdl, abs_tick, NULL, 1); + ret = timer_set(timer_hdl, abs_tick, ODP_EVENT_INVALID, 1); if (odp_likely(ret == ODP_TIMER_SUCCESS)) return 0; -- cgit v1.2.3