Signed-off-by: Remy Horton <remy.horton at intel.com> --- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 7 +++++ lib/librte_eal/common/include/rte_keepalive.h | 40 +++++++++++++++++++++++++ lib/librte_eal/common/rte_keepalive.c | 35 ++++++++++++++++++++-- lib/librte_eal/linuxapp/eal/rte_eal_version.map | 7 +++++ 4 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map index 58c2951..9a33441 100644 --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map @@ -151,3 +151,10 @@ DPDK_16.04 { rte_eal_primary_proc_alive; } DPDK_2.2; + +DPDK_16.7 { + global: + + rte_keepalive_register_alive_callback; + +} DPDK_16.04; diff --git a/lib/librte_eal/common/include/rte_keepalive.h b/lib/librte_eal/common/include/rte_keepalive.h index 10dac2e..3159730 100644 --- a/lib/librte_eal/common/include/rte_keepalive.h +++ b/lib/librte_eal/common/include/rte_keepalive.h @@ -59,6 +59,16 @@ typedef void (*rte_keepalive_failure_callback_t)( const int id_core); /** + * Keepalive 'alive' callback. + * + * Receives a data pointer passed to rte_keepalive_register_alive_callback() + * and the id of the failed core. + */ +typedef void (*rte_keepalive_alive_callback_t)( + void *data, + const int id_core); + +/** * Keepalive state structure. * @internal */ @@ -105,4 +115,34 @@ void rte_keepalive_register_core(struct rte_keepalive *keepcfg, void rte_keepalive_mark_alive(struct rte_keepalive *keepcfg); +/** + * Per-core sleep-time indication. + * @param *keepcfg + * Keepalive structure pointer + * + * This function needs to be called from within the main process loop of + * the LCore going to sleep. + */ +void +rte_keepalive_mark_sleep(struct rte_keepalive *keepcfg); + +/** + * Registers a 'live core' callback. + * + * The complement of the 'dead core' callback. This is called when a + * core is known to be alive, and is intended for cases when an app + * needs to know 'liveness' beyond just knowing when a core has died. + * + * @param *keepcfg + * Keepalive structure pointer + * @param callback + * Function called upon detection of a dead core. + * @param data + * Data pointer to be passed to function callback. + */ +void +rte_keepalive_register_alive_callback(struct rte_keepalive *keepcfg, + rte_keepalive_alive_callback_t callback, + void *data); + #endif /* _KEEPALIVE_H_ */ diff --git a/lib/librte_eal/common/rte_keepalive.c b/lib/librte_eal/common/rte_keepalive.c index 23363ec..7af3558 100644 --- a/lib/librte_eal/common/rte_keepalive.c +++ b/lib/librte_eal/common/rte_keepalive.c @@ -46,7 +46,8 @@ struct rte_keepalive { ALIVE = 1, MISSING = 0, DEAD = 2, - GONE = 3 + GONE = 3, + SLEEP = 4 } __rte_cache_aligned state_flags[RTE_KEEPALIVE_MAXCORES]; /** Last-seen-alive timestamps */ @@ -68,6 +69,15 @@ struct rte_keepalive { void *callback_data; uint64_t tsc_initial; uint64_t tsc_mhz; + + /** Live core handler. */ + rte_keepalive_failure_callback_t alive_callback; + + /** + * Live core handler app data. + * Pointer is passed to live core handler. + */ + void *alive_callback_data; }; static void @@ -95,6 +105,11 @@ rte_keepalive_dispatch_pings(__rte_unused void *ptr_timer, case ALIVE: /* Alive */ keepcfg->state_flags[idx_core] = MISSING; keepcfg->last_alive[idx_core] = rte_rdtsc(); + if (keepcfg->alive_callback) + keepcfg->alive_callback( + keepcfg->alive_callback_data, + idx_core + ); break; case MISSING: /* MIA */ print_trace("Core MIA. ", keepcfg, idx_core); @@ -111,6 +126,8 @@ rte_keepalive_dispatch_pings(__rte_unused void *ptr_timer, break; case GONE: /* Buried */ break; + case SLEEP: /* Idled core */ + break; } } } @@ -133,11 +150,19 @@ rte_keepalive_create(rte_keepalive_failure_callback_t callback, return keepcfg; } +void rte_keepalive_register_alive_callback(struct rte_keepalive *keepcfg, + rte_keepalive_failure_callback_t callback, + void *data) +{ + keepcfg->alive_callback = callback; + keepcfg->alive_callback_data = data; +} + void rte_keepalive_register_core(struct rte_keepalive *keepcfg, const int id_core) { if (id_core < RTE_KEEPALIVE_MAXCORES) { - keepcfg->active_cores[id_core] = 1; + keepcfg->active_cores[id_core] = ALIVE; keepcfg->last_alive[id_core] = rte_rdtsc(); } } @@ -147,3 +172,9 @@ rte_keepalive_mark_alive(struct rte_keepalive *keepcfg) { keepcfg->state_flags[rte_lcore_id()] = ALIVE; } + +void +rte_keepalive_mark_sleep(struct rte_keepalive *keepcfg) +{ + keepcfg->state_flags[rte_lcore_id()] = SLEEP; +} diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map index 12503ef..862bc92 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -154,3 +154,10 @@ DPDK_16.04 { rte_eal_primary_proc_alive; } DPDK_2.2; + +DPDK_16.7 { + global: + + rte_keepalive_register_alive_callback; + +} DPDK_16.04; -- 2.5.5