From d4d82fc3ab9623b40a97e6d6d4624189ec7674bc Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Tue, 11 Oct 2016 11:20:49 -0700 Subject: [PATCH] event: directly add poller when adding to current core This is required since pollers are now directly removed (rather than scheduling an event) when the unregister call is made on the poller's lcore. Without this change, if a poller is registered then immediately unregistered, the unregistration will seg fault since the event adding the poller has not executed yet. Also add a test case that exhibits the sequence of events described in this commit message. Signed-off-by: Jim Harris Change-Id: I5c6ba0ee224ac1f8f3ebb8e7571714e718bd42db --- lib/event/reactor.c | 36 ++++++++++++++++++++++++-------- test/lib/event/reactor/reactor.c | 9 ++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/lib/event/reactor.c b/lib/event/reactor.c index 4864d9e84..80dcef23c 100644 --- a/lib/event/reactor.c +++ b/lib/event/reactor.c @@ -661,12 +661,9 @@ spdk_reactors_fini(void) } static void -_spdk_event_add_poller(spdk_event_t event) +_spdk_poller_register(struct spdk_reactor *reactor, struct spdk_poller *poller, + struct spdk_event *next) { - struct spdk_reactor *reactor = spdk_event_get_arg1(event); - struct spdk_poller *poller = spdk_event_get_arg2(event); - struct spdk_event *next = spdk_event_get_next(event); - if (poller->period_ticks) { spdk_poller_insert_timer(reactor, poller, spdk_get_ticks()); } else { @@ -678,13 +675,22 @@ _spdk_event_add_poller(spdk_event_t event) } } +static void +_spdk_event_add_poller(spdk_event_t event) +{ + struct spdk_reactor *reactor = spdk_event_get_arg1(event); + struct spdk_poller *poller = spdk_event_get_arg2(event); + struct spdk_event *next = spdk_event_get_next(event); + + _spdk_poller_register(reactor, poller, next); +} + void spdk_poller_register(struct spdk_poller **ppoller, spdk_poller_fn fn, void *arg, uint32_t lcore, struct spdk_event *complete, uint64_t period_microseconds) { struct spdk_poller *poller; struct spdk_reactor *reactor; - struct spdk_event *event; poller = calloc(1, sizeof(*poller)); if (poller == NULL) { @@ -709,10 +715,22 @@ spdk_poller_register(struct spdk_poller **ppoller, spdk_poller_fn fn, void *arg, } *ppoller = poller; - reactor = spdk_reactor_get(lcore); - event = spdk_event_allocate(lcore, _spdk_event_add_poller, reactor, poller, complete); - spdk_event_call(event); + + if (lcore == spdk_app_get_current_core()) { + /* + * The poller is registered to run on the current core, so call the add function + * directly. + */ + _spdk_poller_register(reactor, poller, complete); + } else { + /* + * The poller is registered to run on a different core. + * Schedule an event to run on the poller's core that will add the poller. + */ + spdk_event_call(spdk_event_allocate(lcore, _spdk_event_add_poller, reactor, poller, + complete)); + } } static void diff --git a/test/lib/event/reactor/reactor.c b/test/lib/event/reactor/reactor.c index a98837924..547896d32 100644 --- a/test/lib/event/reactor/reactor.c +++ b/test/lib/event/reactor/reactor.c @@ -44,6 +44,7 @@ static struct spdk_poller *poller_100ms; static struct spdk_poller *poller_250ms; static struct spdk_poller *poller_500ms; static struct spdk_poller *poller_oneshot; +static struct spdk_poller *poller_unregister; static void test_end(void *arg) @@ -67,6 +68,11 @@ oneshot(void *arg) spdk_poller_unregister(&poller_oneshot, NULL); } +static void +nop(void *arg) +{ +} + static void test_start(spdk_event_t evt) { @@ -79,6 +85,9 @@ test_start(spdk_event_t evt) spdk_poller_register(&poller_250ms, tick, (void *)250, 0, NULL, 250000); spdk_poller_register(&poller_500ms, tick, (void *)500, 0, NULL, 500000); spdk_poller_register(&poller_oneshot, oneshot, NULL, 0, NULL, 0); + + spdk_poller_register(&poller_unregister, nop, NULL, 0, NULL, 0); + spdk_poller_unregister(&poller_unregister, NULL); } static void