diff options
author | Mark Stapp <mjs@voltanet.io> | 2018-09-27 21:10:54 +0200 |
---|---|---|
committer | Mark Stapp <mjs@voltanet.io> | 2018-11-21 16:38:08 +0100 |
commit | ad6aad4d0bc06f7711d05e1d05576ea25aac04c5 (patch) | |
tree | 93dbdea7ac22254f29aa95d89c92580314beb0e1 /zebra | |
parent | zebra: improve dataplane shutdown checks (diff) | |
download | frr-ad6aad4d0bc06f7711d05e1d05576ea25aac04c5.tar.xz frr-ad6aad4d0bc06f7711d05e1d05576ea25aac04c5.zip |
zebra: dplane lock and thread_master apis
Improve, simplify dataplane provider locking apis. Add accessor
for dataplane pthread's thread_master, for use by providers who
need to use the thread/event apis.
Signed-off-by: Mark Stapp <mjs@voltanet.io>
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/zebra_dplane.c | 58 | ||||
-rw-r--r-- | zebra/zebra_dplane.h | 11 |
2 files changed, 43 insertions, 26 deletions
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 5fd27dc83..95df24382 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -254,6 +254,12 @@ static int dplane_thread_loop(struct thread *event); * Public APIs */ +/* Obtain thread_master for dataplane thread */ +struct thread_master *dplane_get_thread_master(void) +{ + return zdplane_info.dg_master; +} + /* * Allocate a dataplane update context */ @@ -1069,6 +1075,21 @@ int dplane_provider_get_work_limit(const struct zebra_dplane_provider *prov) return zdplane_info.dg_updates_per_cycle; } +/* Lock/unlock a provider's mutex - iff the provider was registered with + * the THREADED flag. + */ +void dplane_provider_lock(struct zebra_dplane_provider *prov) +{ + if (dplane_provider_is_threaded(prov)) + DPLANE_PROV_LOCK(prov); +} + +void dplane_provider_unlock(struct zebra_dplane_provider *prov) +{ + if (dplane_provider_is_threaded(prov)) + DPLANE_PROV_UNLOCK(prov); +} + /* * Dequeue and maintain associated counter */ @@ -1077,8 +1098,7 @@ struct zebra_dplane_ctx *dplane_provider_dequeue_in_ctx( { struct zebra_dplane_ctx *ctx = NULL; - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_LOCK(prov); + dplane_provider_lock(prov); ctx = TAILQ_FIRST(&(prov->dp_ctx_in_q)); if (ctx) { @@ -1088,8 +1108,7 @@ struct zebra_dplane_ctx *dplane_provider_dequeue_in_ctx( memory_order_relaxed); } - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_UNLOCK(prov); + dplane_provider_unlock(prov); return ctx; } @@ -1105,8 +1124,7 @@ int dplane_provider_dequeue_in_list(struct zebra_dplane_provider *prov, limit = zdplane_info.dg_updates_per_cycle; - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_LOCK(prov); + dplane_provider_lock(prov); for (ret = 0; ret < limit; ret++) { ctx = TAILQ_FIRST(&(prov->dp_ctx_in_q)); @@ -1123,8 +1141,7 @@ int dplane_provider_dequeue_in_list(struct zebra_dplane_provider *prov, atomic_fetch_sub_explicit(&prov->dp_in_queued, ret, memory_order_relaxed); - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_UNLOCK(prov); + dplane_provider_unlock(prov); return ret; } @@ -1135,14 +1152,12 @@ int dplane_provider_dequeue_in_list(struct zebra_dplane_provider *prov, void dplane_provider_enqueue_out_ctx(struct zebra_dplane_provider *prov, struct zebra_dplane_ctx *ctx) { - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_LOCK(prov); + dplane_provider_lock(prov); TAILQ_INSERT_TAIL(&(prov->dp_ctx_out_q), ctx, zd_q_entries); - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_UNLOCK(prov); + dplane_provider_unlock(prov); atomic_fetch_add_explicit(&(prov->dp_out_counter), 1, memory_order_relaxed); @@ -1394,15 +1409,13 @@ static bool dplane_work_pending(void) while (prov) { - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_LOCK(prov); + dplane_provider_lock(prov); ctx = TAILQ_FIRST(&(prov->dp_ctx_in_q)); if (ctx == NULL) ctx = TAILQ_FIRST(&(prov->dp_ctx_out_q)); - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_UNLOCK(prov); + dplane_provider_unlock(prov); if (ctx != NULL) break; @@ -1542,7 +1555,6 @@ static int dplane_thread_loop(struct thread *event) /* At each iteration, the temporary work list has 'counter' * items. */ - if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug("dplane enqueues %d new work to provider '%s'", counter, dplane_provider_get_name(prov)); @@ -1572,8 +1584,7 @@ static int dplane_thread_loop(struct thread *event) } /* Enqueue new work to the provider */ - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_LOCK(prov); + dplane_provider_lock(prov); if (TAILQ_FIRST(&work_list)) TAILQ_CONCAT(&(prov->dp_ctx_in_q), &work_list, @@ -1591,8 +1602,7 @@ static int dplane_thread_loop(struct thread *event) atomic_store_explicit(&prov->dp_in_max, curr, memory_order_relaxed); - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_UNLOCK(prov); + dplane_provider_unlock(prov); /* Reset the temp list (though the 'concat' may have done this * already), and the counter @@ -1611,8 +1621,7 @@ static int dplane_thread_loop(struct thread *event) break; /* Dequeue completed work from the provider */ - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_LOCK(prov); + dplane_provider_lock(prov); while (counter < limit) { ctx = TAILQ_FIRST(&(prov->dp_ctx_out_q)); @@ -1627,8 +1636,7 @@ static int dplane_thread_loop(struct thread *event) break; } - if (dplane_provider_is_threaded(prov)) - DPLANE_PROV_UNLOCK(prov); + dplane_provider_unlock(prov); if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug("dplane dequeues %d completed work from provider %s", diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 2e64540d6..b6b2e6460 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -288,7 +288,16 @@ uint32_t dplane_provider_get_id(const struct zebra_dplane_provider *prov); void *dplane_provider_get_data(const struct zebra_dplane_provider *prov); bool dplane_provider_is_threaded(const struct zebra_dplane_provider *prov); -/* Providers should limit number of updates per work cycle */ +/* Lock/unlock a provider's mutex - iff the provider was registered with + * the THREADED flag. + */ +void dplane_provider_lock(struct zebra_dplane_provider *prov); +void dplane_provider_unlock(struct zebra_dplane_provider *prov); + +/* Obtain thread_master for dataplane thread */ +struct thread_master *dplane_get_thread_master(void); + +/* Providers should (generally) limit number of updates per work cycle */ int dplane_provider_get_work_limit(const struct zebra_dplane_provider *prov); /* Provider api to signal that work/events are available |