]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: show command to display metaq info
authorKrishnasamy <krishnasamyr@nvidia.com>
Tue, 25 Mar 2025 14:55:16 +0000 (14:55 +0000)
committerKrishnasamy <krishnasamyr@nvidia.com>
Tue, 1 Apr 2025 09:32:46 +0000 (09:32 +0000)
Display below info from metaq and sub queues
1. Current queue size
2. Max/Highwater size
3. Total number of events received fo so far

r1# sh zebra metaq
MetaQ Summary
Current Size    : 0
Max Size        : 9
Total           : 20
 |------------------------------------------------------------------|
 | SubQ                             | Current  | Max Size  | Total  |
 |----------------------------------+----------+-----------+--------|
 | NHG Objects                      | 0        | 0         | 0      |
 |----------------------------------+----------+-----------+--------|
 | EVPN/VxLan Objects               | 0        | 0         | 0      |
 |----------------------------------+----------+-----------+--------|
 | Early Route Processing           | 0        | 8         | 11     |
 |----------------------------------+----------+-----------+--------|
 | Early Label Handling             | 0        | 0         | 0      |
 |----------------------------------+----------+-----------+--------|
 | Connected Routes                 | 0        | 6         | 9      |
 |----------------------------------+----------+-----------+--------|
 | Kernel Routes                    | 0        | 0         | 0      |
 |----------------------------------+----------+-----------+--------|
 | Static Routes                    | 0        | 0         | 0      |
 |----------------------------------+----------+-----------+--------|
 | RIP/OSPF/ISIS/EIGRP/NHRP Routes  | 0        | 0         | 0      |
 |----------------------------------+----------+-----------+--------|
 | BGP Routes                       | 0        | 0         | 0      |
 |----------------------------------+----------+-----------+--------|
 | Other Routes                     | 0        | 0         | 0      |
 |----------------------------------+----------+-----------+--------|
 | Graceful Restart                 | 0        | 0         | 0      |
 |------------------------------------------------------------------|

Signed-off-by: Krishnasamy <krishnasamyr@nvidia.com>
zebra/rib.h
zebra/zebra_rib.c
zebra/zebra_vty.c

index 8484fe1291a28d9d6bb7b4de06c3d9aac72c2543..8f54453de17fbc3cdd00e5fac6e2751b829b0061 100644 (file)
@@ -192,6 +192,12 @@ struct route_entry {
 struct meta_queue {
        struct list *subq[MQ_SIZE];
        uint32_t size; /* sum of lengths of all subqueues */
+       _Atomic uint32_t max_subq[MQ_SIZE];    /* Max size of individual sub queue */
+       _Atomic uint32_t max_metaq;            /* Max size of the MetaQ */
+       _Atomic uint32_t total_subq[MQ_SIZE];  /* Total subq events */
+       _Atomic uint32_t total_metaq;          /* Total MetaQ events */
+       _Atomic uint32_t re_subq[MQ_SIZE];     /* current RE count sub queue */
+       _Atomic uint32_t max_re_subq[MQ_SIZE]; /* Max RE in sub queue */
 };
 
 /*
@@ -472,6 +478,7 @@ extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq,
                                           bool rt_delete);
 
 extern void rib_update_handle_vrf_all(enum rib_update_event event, int rtype);
+int zebra_show_metaq_counter(struct vty *vty, bool uj);
 
 /*
  * rib_find_rn_from_ctx
index 20ec25a431ed6ae3ca1d0eeb181b3d0a279855fc..a1975b8e675cb9bd6b88fdefb349d769a2bb901a 100644 (file)
@@ -30,6 +30,7 @@
 #include "printfrr.h"
 #include "frrscript.h"
 #include "frrdistance.h"
+#include "lib/termtable.h"
 
 #include "zebra/zebra_router.h"
 #include "zebra/connected.h"
@@ -273,6 +274,63 @@ static const char *subqueue2str(enum meta_queue_indexes index)
        return "Unknown";
 }
 
+/* Handler for 'show zebra metaq' */
+int zebra_show_metaq_counter(struct vty *vty, bool uj)
+{
+       struct meta_queue *mq = zrouter.mq;
+       struct ttable *tt = NULL;
+       char *table = NULL;
+       json_object *json = NULL;
+       json_object *json_table = NULL;
+
+       if (!mq)
+               return CMD_WARNING;
+
+       /* Create a table for subqueue details */
+       tt = ttable_new(&ttable_styles[TTSTYLE_ASCII]);
+       ttable_add_row(tt, "SubQ|Current|Max Size|Total");
+
+       /* Add rows for each subqueue */
+       for (uint8_t i = 0; i < MQ_SIZE; i++) {
+               ttable_add_row(tt, "%s|%u|%u|%u", subqueue2str(i), mq->subq[i]->count,
+                              mq->max_subq[i], mq->total_subq[i]);
+       }
+
+       /* For a better formatting between the content and separator */
+       tt->style.cell.rpad = 2;
+       tt->style.cell.lpad = 1;
+       ttable_restyle(tt);
+
+       if (uj) {
+               json = json_object_new_object();
+               /* Add MetaQ summary to the JSON object */
+               json_object_int_add(json, "currentSize", mq->size);
+               json_object_int_add(json, "maxSize", mq->max_metaq);
+               json_object_int_add(json, "total", mq->total_metaq);
+
+               /* Convert the table to JSON and add it to the main JSON object */
+               /* n = name/string, u = unsigned int */
+               json_table = ttable_json(tt, "sddd");
+               json_object_object_add(json, "subqueues", json_table);
+               vty_json(vty, json);
+       } else {
+               vty_out(vty, "MetaQ Summary\n");
+               vty_out(vty, "Current Size\t: %u\n", mq->size);
+               vty_out(vty, "Max Size\t: %u\n", mq->max_metaq);
+               vty_out(vty, "Total\t\t: %u\n", mq->total_metaq);
+
+               /* Dump the table */
+               table = ttable_dump(tt, "\n");
+               vty_out(vty, "%s\n", table);
+               XFREE(MTYPE_TMP_TTABLE, table);
+       }
+
+       /* Clean up the table */
+       ttable_del(tt);
+
+       return CMD_SUCCESS;
+}
+
 printfrr_ext_autoreg_p("ZN", printfrr_zebra_node);
 static ssize_t printfrr_zebra_node(struct fbuf *buf, struct printfrr_eargs *ea,
                                   const void *ptr)
@@ -3257,6 +3315,7 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
        struct route_node *rn = NULL;
        struct route_entry *re = NULL, *curr_re = NULL;
        uint8_t qindex = MQ_SIZE, curr_qindex = MQ_SIZE;
+       uint64_t curr, high;
 
        rn = (struct route_node *)data;
 
@@ -3300,6 +3359,15 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
        listnode_add(mq->subq[qindex], rn);
        route_lock_node(rn);
        mq->size++;
+       atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+       atomic_fetch_add_explicit(&mq->total_subq[qindex], 1, memory_order_relaxed);
+       curr = listcount(mq->subq[qindex]);
+       high = atomic_load_explicit(&mq->max_subq[qindex], memory_order_relaxed);
+       if (curr > high)
+               atomic_store_explicit(&mq->max_subq[qindex], curr, memory_order_relaxed);
+       high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+       if (mq->size > high)
+               atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED)
                rnode_debug(rn, re->vrf_id, "queued rn %p into sub-queue %s",
@@ -3310,8 +3378,21 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
 
 static int early_label_meta_queue_add(struct meta_queue *mq, void *data)
 {
+       uint64_t curr, high;
+
        listnode_add(mq->subq[META_QUEUE_EARLY_LABEL], data);
        mq->size++;
+       atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+       atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_EARLY_LABEL], 1, memory_order_relaxed);
+       curr = listcount(mq->subq[META_QUEUE_EARLY_LABEL]);
+       high = atomic_load_explicit(&mq->max_subq[META_QUEUE_EARLY_LABEL], memory_order_relaxed);
+       if (curr > high)
+               atomic_store_explicit(&mq->max_subq[META_QUEUE_EARLY_LABEL], curr,
+                                     memory_order_relaxed);
+       high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+       if (mq->size > high)
+               atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
+
        return 0;
 }
 
@@ -3320,6 +3401,7 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
        struct nhg_ctx *ctx = NULL;
        uint8_t qindex = META_QUEUE_NHG;
        struct wq_nhg_wrapper *w;
+       uint64_t curr, high;
 
        ctx = (struct nhg_ctx *)data;
 
@@ -3333,6 +3415,15 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
 
        listnode_add(mq->subq[qindex], w);
        mq->size++;
+       atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+       atomic_fetch_add_explicit(&mq->total_subq[qindex], 1, memory_order_relaxed);
+       curr = listcount(mq->subq[qindex]);
+       high = atomic_load_explicit(&mq->max_subq[qindex], memory_order_relaxed);
+       if (curr > high)
+               atomic_store_explicit(&mq->max_subq[qindex], curr, memory_order_relaxed);
+       high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+       if (mq->size > high)
+               atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED)
                zlog_debug("NHG Context id=%u queued into sub-queue %s",
@@ -3347,6 +3438,7 @@ static int rib_meta_queue_nhg_process(struct meta_queue *mq, void *data,
        struct nhg_hash_entry *nhe = NULL;
        uint8_t qindex = META_QUEUE_NHG;
        struct wq_nhg_wrapper *w;
+       uint64_t curr, high;
 
        nhe = (struct nhg_hash_entry *)data;
 
@@ -3361,6 +3453,15 @@ static int rib_meta_queue_nhg_process(struct meta_queue *mq, void *data,
 
        listnode_add(mq->subq[qindex], w);
        mq->size++;
+       atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+       atomic_fetch_add_explicit(&mq->total_subq[qindex], 1, memory_order_relaxed);
+       curr = listcount(mq->subq[qindex]);
+       high = atomic_load_explicit(&mq->max_subq[qindex], memory_order_relaxed);
+       if (curr > high)
+               atomic_store_explicit(&mq->max_subq[qindex], curr, memory_order_relaxed);
+       high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+       if (mq->size > high)
+               atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED)
                zlog_debug("NHG id=%u queued into sub-queue %s", nhe->id,
@@ -3381,8 +3482,19 @@ static int rib_meta_queue_nhg_del(struct meta_queue *mq, void *data)
 
 static int rib_meta_queue_evpn_add(struct meta_queue *mq, void *data)
 {
+       uint64_t curr, high;
+
        listnode_add(mq->subq[META_QUEUE_EVPN], data);
        mq->size++;
+       atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+       atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_EVPN], 1, memory_order_relaxed);
+       curr = listcount(mq->subq[META_QUEUE_EVPN]);
+       high = atomic_load_explicit(&mq->max_subq[META_QUEUE_EVPN], memory_order_relaxed);
+       if (curr > high)
+               atomic_store_explicit(&mq->max_subq[META_QUEUE_EVPN], curr, memory_order_relaxed);
+       high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+       if (mq->size > high)
+               atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
 
        return 0;
 }
@@ -4222,8 +4334,19 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
 
 static int rib_meta_queue_gr_run_add(struct meta_queue *mq, void *data)
 {
+       uint64_t curr, high;
+
        listnode_add(mq->subq[META_QUEUE_GR_RUN], data);
        mq->size++;
+       atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+       atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_GR_RUN], 1, memory_order_relaxed);
+       curr = listcount(mq->subq[META_QUEUE_GR_RUN]);
+       high = atomic_load_explicit(&mq->max_subq[META_QUEUE_GR_RUN], memory_order_relaxed);
+       if (curr > high)
+               atomic_store_explicit(&mq->max_subq[META_QUEUE_GR_RUN], curr, memory_order_relaxed);
+       high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+       if (mq->size > high)
+               atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED)
                zlog_debug("Graceful Run adding");
@@ -4234,9 +4357,20 @@ static int rib_meta_queue_gr_run_add(struct meta_queue *mq, void *data)
 static int rib_meta_queue_early_route_add(struct meta_queue *mq, void *data)
 {
        struct zebra_early_route *ere = data;
+       uint64_t curr, high;
 
        listnode_add(mq->subq[META_QUEUE_EARLY_ROUTE], data);
        mq->size++;
+       atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+       atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_EARLY_ROUTE], 1, memory_order_relaxed);
+       curr = listcount(mq->subq[META_QUEUE_EARLY_ROUTE]);
+       high = atomic_load_explicit(&mq->max_subq[META_QUEUE_EARLY_ROUTE], memory_order_relaxed);
+       if (curr > high)
+               atomic_store_explicit(&mq->max_subq[META_QUEUE_EARLY_ROUTE], curr,
+                                     memory_order_relaxed);
+       high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+       if (mq->size > high)
+               atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
                struct vrf *vrf = vrf_lookup_by_id(ere->re->vrf_id);
index a1731712d3dae3e07c7a823d07e3ed7effefb26f..e0d04f66258dd938ccb83b3ffb43d1ad4253c7b6 100644 (file)
@@ -4049,6 +4049,20 @@ DEFUN (zebra_show_routing_tables_summary,
        return CMD_SUCCESS;
 }
 
+/* Display Zebra MetaQ counters */
+DEFUN (show_zebra_metaq_counters,
+       show_zebra_metaq_counters_cmd,
+       "show zebra metaq [json]",
+       SHOW_STR
+       ZEBRA_STR
+       "Zebra MetaQ counters\n"
+       JSON_STR)
+{
+       bool uj = use_json(argc, argv);
+
+       return zebra_show_metaq_counter(vty, uj);
+}
+
 /* IPForwarding configuration write function. */
 static int config_write_forwarding(struct vty *vty)
 {
@@ -4338,6 +4352,7 @@ void zebra_vty_init(void)
        install_element(VIEW_NODE, &show_dataplane_providers_cmd);
        install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
        install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
+       install_element(VIEW_NODE, &show_zebra_metaq_counters_cmd);
 
 #ifdef HAVE_NETLINK
        install_element(CONFIG_NODE, &zebra_kernel_netlink_batch_tx_buf_cmd);