summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2018-09-27 21:10:54 +0200
committerMark Stapp <mjs@voltanet.io>2018-11-21 16:38:08 +0100
commitad6aad4d0bc06f7711d05e1d05576ea25aac04c5 (patch)
tree93dbdea7ac22254f29aa95d89c92580314beb0e1 /zebra
parentzebra: improve dataplane shutdown checks (diff)
downloadfrr-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.c58
-rw-r--r--zebra/zebra_dplane.h11
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