From ABIĀ PoV, you are 100%. Is the agreed term 'callback'?, not 'notifier' for example rte_dev_event_callback_register, rte_mem_event_callback_register
I did wonder however, if all these cb's would be better handled through a EventDev event notification style approach. Ray K On 10/06/2020 15:45, David Marchand wrote: > Now that lcores can be dynamically allocated/freed, we will have to > notify DPDK components and applications of such events for cases where > per lcore context must be allocated/initialised. > > Signed-off-by: David Marchand <david.march...@redhat.com> > --- > lib/librte_eal/common/eal_common_lcore.c | 91 +++++++++++++++++++++++ > lib/librte_eal/common/eal_common_thread.c | 11 ++- > lib/librte_eal/common/eal_private.h | 26 +++++++ > lib/librte_eal/include/rte_lcore.h | 49 ++++++++++++ > lib/librte_eal/rte_eal_version.map | 2 + > 5 files changed, 178 insertions(+), 1 deletion(-) > > diff --git a/lib/librte_eal/common/eal_common_lcore.c > b/lib/librte_eal/common/eal_common_lcore.c > index 6aca1b2fee..3a997d8115 100644 > --- a/lib/librte_eal/common/eal_common_lcore.c > +++ b/lib/librte_eal/common/eal_common_lcore.c > @@ -212,6 +212,47 @@ rte_socket_id_by_idx(unsigned int idx) > return config->numa_nodes[idx]; > } > > +struct lcore_notifier { > + TAILQ_ENTRY(lcore_notifier) next; > + rte_lcore_notifier_cb cb; > + void *arg; > +}; > +static TAILQ_HEAD(lcore_notifiers_head, lcore_notifier) lcore_notifiers = > + TAILQ_HEAD_INITIALIZER(lcore_notifiers); > +static rte_spinlock_t lcore_notifiers_lock = RTE_SPINLOCK_INITIALIZER; > + > +void * > +rte_lcore_notifier_register(rte_lcore_notifier_cb cb, void *arg) > +{ > + struct lcore_notifier *notifier; > + > + if (cb == NULL) > + return NULL; > + > + notifier = calloc(1, sizeof(*notifier)); > + if (notifier == NULL) > + return NULL; > + > + notifier->cb = cb; > + notifier->arg = arg; > + rte_spinlock_lock(&lcore_notifiers_lock); > + TAILQ_INSERT_TAIL(&lcore_notifiers, notifier, next); > + rte_spinlock_unlock(&lcore_notifiers_lock); > + > + return notifier; > +} > + > +void > +rte_lcore_notifier_unregister(void *handle) > +{ > + struct lcore_notifier *notifier = handle; > + > + rte_spinlock_lock(&lcore_notifiers_lock); > + TAILQ_REMOVE(&lcore_notifiers, notifier, next); > + rte_spinlock_unlock(&lcore_notifiers_lock); > + free(notifier); > +} > + > rte_spinlock_t external_lcore_lock = RTE_SPINLOCK_INITIALIZER; > > unsigned int > @@ -277,3 +318,53 @@ rte_lcore_dump(FILE *f) > } > rte_spinlock_unlock(&external_lcore_lock); > } > + > +int > +eal_lcore_external_notify_allocated(unsigned int lcore_id) > +{ > + struct lcore_notifier *notifier; > + int ret = 0; > + > + RTE_LOG(DEBUG, EAL, "New lcore %u.\n", lcore_id); > + rte_spinlock_lock(&lcore_notifiers_lock); > + TAILQ_FOREACH(notifier, &lcore_notifiers, next) { > + if (notifier->cb(lcore_id, RTE_LCORE_EVENT_NEW_EXTERNAL, > + notifier->arg) == 0) > + continue; > + > + /* Some notifier refused the new lcore, inform all notifiers > + * that acked it. > + */ > + RTE_LOG(DEBUG, EAL, "A lcore notifier refused new lcore %u.\n", > + lcore_id); > + > + notifier = TAILQ_PREV(notifier, lcore_notifiers_head, next); > + while (notifier != NULL) { > + notifier->cb(lcore_id, > + RTE_LCORE_EVENT_RELEASE_EXTERNAL, > + notifier->arg); > + notifier = TAILQ_PREV(notifier, lcore_notifiers_head, > + next); > + } > + ret = -1; > + break; > + } > + rte_spinlock_unlock(&lcore_notifiers_lock); > + > + return ret; > +} > + > +void > +eal_lcore_external_notify_removed(unsigned int lcore_id) > +{ > + struct lcore_notifier *notifier; > + > + RTE_LOG(DEBUG, EAL, "Released lcore %u.\n", lcore_id); > + rte_spinlock_lock(&lcore_notifiers_lock); > + TAILQ_FOREACH_REVERSE(notifier, &lcore_notifiers, lcore_notifiers_head, > + next) { > + notifier->cb(lcore_id, RTE_LCORE_EVENT_RELEASE_EXTERNAL, > + notifier->arg); > + } > + rte_spinlock_unlock(&lcore_notifiers_lock); > +} > diff --git a/lib/librte_eal/common/eal_common_thread.c > b/lib/librte_eal/common/eal_common_thread.c > index a81b192ff3..f66d1ccaef 100644 > --- a/lib/librte_eal/common/eal_common_thread.c > +++ b/lib/librte_eal/common/eal_common_thread.c > @@ -285,6 +285,12 @@ rte_thread_register(void) > > rte_thread_init(lcore_id, &cpuset); > > + if (lcore_id != LCORE_ID_ANY && > + eal_lcore_external_notify_allocated(lcore_id) < 0) { > + eal_lcore_external_release(lcore_id); > + RTE_PER_LCORE(_lcore_id) = lcore_id = LCORE_ID_ANY; > + } > + > RTE_LOG(DEBUG, EAL, "Registered thread as lcore %u.\n", lcore_id); > RTE_PER_LCORE(thread_registered) = true; > } > @@ -298,8 +304,11 @@ rte_thread_unregister(void) > return; > > lcore_id = RTE_PER_LCORE(_lcore_id); > - if (lcore_id != LCORE_ID_ANY) > + if (lcore_id != LCORE_ID_ANY) { > + eal_lcore_external_notify_removed(lcore_id); > eal_lcore_external_release(lcore_id); > + RTE_PER_LCORE(_lcore_id) = LCORE_ID_ANY; > + } > > rte_thread_uninit(); > > diff --git a/lib/librte_eal/common/eal_private.h > b/lib/librte_eal/common/eal_private.h > index 8dd850f68a..649697c368 100644 > --- a/lib/librte_eal/common/eal_private.h > +++ b/lib/librte_eal/common/eal_private.h > @@ -283,6 +283,21 @@ uint64_t get_tsc_freq_arch(void); > */ > unsigned int eal_lcore_external_reserve(void); > > +/** > + * Evaluate all lcore notifiers with a RTE_LCORE_EVENT_NEW_EXTERNAL event for > + * the passed lcore. > + * If an error is returned by one of them, then this change is rolled back: > + * all previous lcore notifiers that had acked the > RTE_LCORE_EVENT_NEW_EXTERNAL > + * event receive a RTE_LCORE_EVENT_RELEASE_EXTERNAL event for the passed > lcore. > + * > + * @param lcore_id > + * The lcore to consider. > + * @return > + * - 0 if all notifiers agreed on the new lcore > + * - -1 if one of them refused > + */ > +int eal_lcore_external_notify_allocated(unsigned int lcore_id); > + > /** > * Release an external lcore. > * > @@ -291,6 +306,17 @@ unsigned int eal_lcore_external_reserve(void); > */ > void eal_lcore_external_release(unsigned int lcore_id); > > +/** > + * Evaluate all lcore notifiers with a RTE_LCORE_EVENT_RELEASE_EXTERNAL event > + * for the passed lcore. > + * This function must be called with a lcore that successfully passed > + * eal_lcore_external_notify_allocated(). > + * > + * @param lcore_id > + * The lcore with role ROLE_EXTERNAL to release. > + */ > +void eal_lcore_external_notify_removed(unsigned int lcore_id); > + > /** > * Prepare physical memory mapping > * i.e. hugepages on Linux and > diff --git a/lib/librte_eal/include/rte_lcore.h > b/lib/librte_eal/include/rte_lcore.h > index 9cf34efef4..e0fec33d5a 100644 > --- a/lib/librte_eal/include/rte_lcore.h > +++ b/lib/librte_eal/include/rte_lcore.h > @@ -238,6 +238,55 @@ __rte_experimental > void > rte_lcore_dump(FILE *f); > > +enum rte_lcore_event_type { > + RTE_LCORE_EVENT_NEW_EXTERNAL, > + RTE_LCORE_EVENT_RELEASE_EXTERNAL, > +}; > + > +/** > + * Callback prototype for getting lcore events. > + * > + * @param lcore_id > + * The lcore to consider for this event. > + * @param event > + * The type of event on the lcore. > + * @param arg > + * An opaque pointer passed at notifier registration. > + * @return > + * - -1 when refusing this event, > + * - 0 otherwise. > + */ > +typedef int (*rte_lcore_notifier_cb)(unsigned int lcore_id, > + enum rte_lcore_event_type event, void *arg); > + > +/** > + * Register a lcore notifier. > + * > + * @param cb > + * The callback invoked for each lcore event with the arg argument. > + * See rte_lcore_notifier_cb description. > + * @param arg > + * An optional argument that gets passed to the callback when it gets > + * invoked. > + * @return > + * On success, returns an opaque pointer for the created notifier. > + * NULL on failure. > + */ > +__rte_experimental > +void * > +rte_lcore_notifier_register(rte_lcore_notifier_cb cb, void *arg); > + > +/** > + * Unregister a lcore notifier. > + * > + * @param handle > + * The handle pointer returned by a former successful call to > + * rte_lcore_notifier_register. > + */ > +__rte_experimental > +void > +rte_lcore_notifier_unregister(void *handle); > + > /** > * Set core affinity of the current thread. > * Support both EAL and non-EAL thread and update TLS. > diff --git a/lib/librte_eal/rte_eal_version.map > b/lib/librte_eal/rte_eal_version.map > index 6754d52543..1e6f2aaacc 100644 > --- a/lib/librte_eal/rte_eal_version.map > +++ b/lib/librte_eal/rte_eal_version.map > @@ -396,6 +396,8 @@ EXPERIMENTAL { > > # added in 20.08 > rte_lcore_dump; > + rte_lcore_notifier_register; > + rte_lcore_notifier_unregister; > rte_thread_register; > rte_thread_unregister; > };