summaryrefslogtreecommitdiff
path: root/zebra/zebra_dplane.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_dplane.c')
-rw-r--r--zebra/zebra_dplane.c57
1 files changed, 42 insertions, 15 deletions
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index fad3c16244..db2b9e002e 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -2014,16 +2014,6 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
for (ALL_NEXTHOPS(ctx->u.rinfo.zd_ng, nexthop)) {
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
- /* Check for available encapsulations. */
- if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
- continue;
-
- zl3vni = zl3vni_from_vrf(nexthop->vrf_id);
- if (zl3vni && is_l3vni_oper_up(zl3vni)) {
- nexthop->nh_encap_type = NET_VXLAN;
- nexthop->nh_encap.vni = zl3vni->vni;
- }
-
/* Optionally capture extra interface info while we're in the
* main zebra pthread - a plugin has to ask for this info.
*/
@@ -2044,6 +2034,16 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
if_extra, link);
}
}
+
+ /* Check for available evpn encapsulations. */
+ if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
+ continue;
+
+ zl3vni = zl3vni_from_vrf(nexthop->vrf_id);
+ if (zl3vni && is_l3vni_oper_up(zl3vni)) {
+ nexthop->nh_encap_type = NET_VXLAN;
+ nexthop->nh_encap.vni = zl3vni->vni;
+ }
}
/* Don't need some info when capturing a system notification */
@@ -3684,7 +3684,7 @@ int dplane_show_helper(struct vty *vty, bool detailed)
int dplane_show_provs_helper(struct vty *vty, bool detailed)
{
struct zebra_dplane_provider *prov;
- uint64_t in, in_max, out, out_max;
+ uint64_t in, in_q, in_max, out, out_q, out_max;
vty_out(vty, "Zebra dataplane providers:\n");
@@ -3697,17 +3697,20 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed)
in = atomic_load_explicit(&prov->dp_in_counter,
memory_order_relaxed);
+ in_q = atomic_load_explicit(&prov->dp_in_queued,
+ memory_order_relaxed);
in_max = atomic_load_explicit(&prov->dp_in_max,
memory_order_relaxed);
out = atomic_load_explicit(&prov->dp_out_counter,
memory_order_relaxed);
+ out_q = atomic_load_explicit(&prov->dp_out_queued,
+ memory_order_relaxed);
out_max = atomic_load_explicit(&prov->dp_out_max,
memory_order_relaxed);
- vty_out(vty,
- "%s (%u): in: %" PRIu64 ", q_max: %" PRIu64
- ", out: %" PRIu64 ", q_max: %" PRIu64 "\n",
- prov->dp_name, prov->dp_id, in, in_max, out, out_max);
+ vty_out(vty, "%s (%u): in: %"PRIu64", q: %"PRIu64", q_max: %"PRIu64", out: %"PRIu64", q: %"PRIu64", q_max: %"PRIu64"\n",
+ prov->dp_name, prov->dp_id, in, in_q, in_max,
+ out, out_q, out_max);
DPLANE_LOCK();
prov = TAILQ_NEXT(prov, dp_prov_link);
@@ -3912,11 +3915,24 @@ uint32_t dplane_provider_out_ctx_queue_len(struct zebra_dplane_provider *prov)
void dplane_provider_enqueue_out_ctx(struct zebra_dplane_provider *prov,
struct zebra_dplane_ctx *ctx)
{
+ uint64_t curr, high;
+
dplane_provider_lock(prov);
TAILQ_INSERT_TAIL(&(prov->dp_ctx_out_q), ctx,
zd_q_entries);
+ /* Maintain out-queue counters */
+ atomic_fetch_add_explicit(&(prov->dp_out_queued), 1,
+ memory_order_relaxed);
+ curr = atomic_load_explicit(&prov->dp_out_queued,
+ memory_order_relaxed);
+ high = atomic_load_explicit(&prov->dp_out_max,
+ memory_order_relaxed);
+ if (curr > high)
+ atomic_store_explicit(&prov->dp_out_max, curr,
+ memory_order_relaxed);
+
dplane_provider_unlock(prov);
atomic_fetch_add_explicit(&(prov->dp_out_counter), 1,
@@ -4537,6 +4553,7 @@ static int dplane_thread_loop(struct thread *event)
struct zebra_dplane_ctx *ctx, *tctx;
int limit, counter, error_counter;
uint64_t curr, high;
+ bool reschedule = false;
/* Capture work limit per cycle */
limit = zdplane_info.dg_updates_per_cycle;
@@ -4673,6 +4690,9 @@ static int dplane_thread_loop(struct thread *event)
dplane_provider_unlock(prov);
+ if (counter >= limit)
+ reschedule = true;
+
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug("dplane dequeues %d completed work from provider %s",
counter, dplane_provider_get_name(prov));
@@ -4683,6 +4703,13 @@ static int dplane_thread_loop(struct thread *event)
DPLANE_UNLOCK();
}
+ /*
+ * We hit the work limit while processing at least one provider's
+ * output queue - ensure we come back and finish it.
+ */
+ if (reschedule)
+ dplane_provider_work_ready();
+
/* After all providers have been serviced, enqueue any completed
* work and any errors back to zebra so it can process the results.
*/