diff options
Diffstat (limited to 'zebra/zebra_dplane.c')
| -rw-r--r-- | zebra/zebra_dplane.c | 57 |
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. */ |
