]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Make the process_queue per bgp process
authorDonald Sharp <sharpd@nvidia.com>
Sat, 17 Oct 2020 13:43:14 +0000 (09:43 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Wed, 21 Oct 2020 19:34:47 +0000 (15:34 -0400)
We currently have a global process queue for handling route
updates in bgp.  This is fine, in general, except there are
places and times where we plug the queue for no new work
during certain peer states of bgp update delay.  If we
happen to be processing multiple bgp instances on startup
why do we want to stop processing in vrf A when vrf B
is in a bit of a pickle?

Also this separation will allow us to start forward thinking
about how to fully integrate pthreads into route processing
in bgp.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
bgpd/bgp_fsm.c
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgpd.c
bgpd/bgpd.h

index d7df707a36b85e01080da269c21ee3a64f664d4f..61119ced80779eb274093d9043765a9a7c277d63 100644 (file)
@@ -740,11 +740,12 @@ void bgp_update_delay_end(struct bgp *bgp)
        bgp->main_zebra_update_hold = 1;
        bgp->main_peers_update_hold = 1;
 
-       /* Resume the queue processing. This should trigger the event that would
-          take
-          care of processing any work that was queued during the read-only
-          mode. */
-       work_queue_unplug(bm->process_main_queue);
+       /*
+        * Resume the queue processing. This should trigger the event that would
+        * take care of processing any work that was queued during the read-only
+        * mode.
+        */
+       work_queue_unplug(bgp->process_queue);
 }
 
 /**
@@ -997,7 +998,7 @@ static void bgp_update_delay_begin(struct bgp *bgp)
        struct peer *peer;
 
        /* Stop the processing of queued work. Enqueue shall continue */
-       work_queue_plug(bm->process_main_queue);
+       work_queue_plug(bgp->process_queue);
 
        for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
                peer->update_delay_over = 0;
index 68ba73caa4ae72117fead5a66add00506982fd69..a1c99afc8de3b1dffe2568a098c9ac5c70712399 100644 (file)
@@ -2937,18 +2937,21 @@ static void bgp_processq_del(struct work_queue *wq, void *data)
        XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
 }
 
-void bgp_process_queue_init(void)
+void bgp_process_queue_init(struct bgp *bgp)
 {
-       if (!bm->process_main_queue)
-               bm->process_main_queue =
-                       work_queue_new(bm->master, "process_main_queue");
+       if (!bgp->process_queue) {
+               char name[BUFSIZ];
 
-       bm->process_main_queue->spec.workfunc = &bgp_process_wq;
-       bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
-       bm->process_main_queue->spec.max_retries = 0;
-       bm->process_main_queue->spec.hold = 50;
+               snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
+               bgp->process_queue = work_queue_new(bm->master, name);
+       }
+
+       bgp->process_queue->spec.workfunc = &bgp_process_wq;
+       bgp->process_queue->spec.del_item_data = &bgp_processq_del;
+       bgp->process_queue->spec.max_retries = 0;
+       bgp->process_queue->spec.hold = 50;
        /* Use a higher yield value of 50ms for main queue processing */
-       bm->process_main_queue->spec.yield = 50 * 1000L;
+       bgp->process_queue->spec.yield = 50 * 1000L;
 }
 
 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
@@ -2968,7 +2971,7 @@ static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
 {
 #define ARBITRARY_PROCESS_QLEN         10000
-       struct work_queue *wq = bm->process_main_queue;
+       struct work_queue *wq = bgp->process_queue;
        struct bgp_process_queue *pqnode;
        int pqnode_reuse = 0;
 
@@ -3025,13 +3028,13 @@ void bgp_add_eoiu_mark(struct bgp *bgp)
 {
        struct bgp_process_queue *pqnode;
 
-       if (bm->process_main_queue == NULL)
+       if (bgp->process_queue == NULL)
                return;
 
        pqnode = bgp_processq_alloc(bgp);
 
        SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
-       work_queue_add(bm->process_main_queue, pqnode);
+       work_queue_add(bgp->process_queue, pqnode);
 }
 
 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
@@ -4543,7 +4546,7 @@ static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
                                  struct bgp_table *table)
 {
        struct bgp_dest *dest;
-       int force = bm->process_main_queue ? 0 : 1;
+       int force = peer->bgp->process_queue ? 0 : 1;
 
        if (!table)
                table = peer->bgp->rib[afi][safi];
index 962a086081b3e26d4da6a198fb2345a2b75dfc57..09a04020999d15ad073dbc9aaf952e90f1fa755c 100644 (file)
@@ -527,7 +527,7 @@ DECLARE_HOOK(bgp_process,
 /* Prototypes. */
 extern void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
                           struct peer *peer, afi_t afi, safi_t safi);
-extern void bgp_process_queue_init(void);
+extern void bgp_process_queue_init(struct bgp *bgp);
 extern void bgp_route_init(void);
 extern void bgp_route_finish(void);
 extern void bgp_cleanup_routes(struct bgp *);
index 03a5854d07a652683973641bf76b3eb5ffa609fb..89ce9057ed3717e7fa83506393369d5a5382767e 100644 (file)
@@ -2981,6 +2981,8 @@ static struct bgp *bgp_create(as_t *as, const char *name,
        }
 
        bgp_lock(bgp);
+
+       bgp_process_queue_init(bgp);
        bgp->heuristic_coalesce = true;
        bgp->inst_type = inst_type;
        bgp->vrf_id = (inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? VRF_DEFAULT
@@ -3505,6 +3507,9 @@ int bgp_delete(struct bgp *bgp)
                        bgp_set_evpn(bgp_get_default());
        }
 
+       if (bgp->process_queue)
+               work_queue_free_and_null(&bgp->process_queue);
+
        thread_master_free_unused(bm->master);
        bgp_unlock(bgp); /* initial reference */
 
@@ -7085,8 +7090,6 @@ void bgp_master_init(struct thread_master *master, const int buffer_size)
        bm->terminating = false;
        bm->socket_buffer = buffer_size;
 
-       bgp_process_queue_init();
-
        bgp_mac_init();
        /* init the rd id space.
           assign 0th index in the bitfield,
@@ -7291,9 +7294,6 @@ void bgp_terminate(void)
                                bgp_notify_send(peer, BGP_NOTIFY_CEASE,
                                                BGP_NOTIFY_CEASE_PEER_UNCONFIG);
 
-       if (bm->process_main_queue)
-               work_queue_free_and_null(&bm->process_main_queue);
-
        if (bm->t_rmap_update)
                BGP_TIMER_OFF(bm->t_rmap_update);
 
index 00f1d5acc993563b4d1f89d292704a4f29173fad..eae3d97730864fb0b87b149bceeaaad50dd8c48e 100644 (file)
@@ -122,9 +122,6 @@ struct bgp_master {
        /* BGP thread master.  */
        struct thread_master *master;
 
-       /* work queues */
-       struct work_queue *process_main_queue;
-
        /* Listening sockets */
        struct list *listen_sockets;
 
@@ -682,6 +679,9 @@ struct bgp {
        /* Weighted ECMP related config. */
        enum bgp_link_bw_handling lb_handling;
 
+       /* Process Queue for handling routes */
+       struct work_queue *process_queue;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(bgp)