]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Protocol: better granularity of pool management
authorMaria Matejka <mq@ucw.cz>
Fri, 13 Oct 2023 08:22:09 +0000 (10:22 +0200)
committerMaria Matejka <mq@ucw.cz>
Fri, 13 Oct 2023 08:22:09 +0000 (10:22 +0200)
There are now 3 different pools with specific lifetime. All of these are
available since protocol start, anyway they get freed in different
moments.

First, pool_up gets freed immediately after announcing PS_STOP, to e.g.
stop all timers and events regularly updating the routing table when the
imports are already flushing.

Then, pool_inloop gets freed just before the protocol loop is finally
stopped, after all channels, imports and exports and other hooks are
cleaned up.

And finally, the pool itself is freed the last. Unless you explicitly
need the early free, use this pool.

nest/proto.c
nest/protocol.h
proto/bgp/bgp.c
proto/ospf/ospf.c
proto/rip/rip.c

index 9da594dcb3549fe1657cc716d4f323db7f29bbc9..cd887a48547e49f25789a1d6ebb0329977fd5eeb 100644 (file)
@@ -1306,10 +1306,10 @@ proto_event(void *ptr)
     p->do_stop = 0;
   }
 
-  if (proto_is_done(p) && p->pool_fragile)  /* perusing pool_fragile to do this once only */
+  if (proto_is_done(p) && p->pool_inloop)  /* perusing pool_inloop to do this once only */
   {
-    rp_free(p->pool_fragile);
-    p->pool_fragile = NULL;
+    rp_free(p->pool_inloop);
+    p->pool_inloop = NULL;
     if (p->loop != &main_birdloop)
       birdloop_stop_self(p->loop, proto_loop_stopped, p);
     else
@@ -1391,7 +1391,8 @@ proto_start(struct proto *p)
 
   PROTO_LOCKED_FROM_MAIN(p)
   {
-    p->pool_fragile = rp_newf(p->pool, birdloop_domain(p->loop), "Protocol %s fragile objects", p->cf->name);
+    p->pool_inloop = rp_newf(p->pool, birdloop_domain(p->loop), "Protocol %s early cleanup objects", p->cf->name);
+    p->pool_up = rp_newf(p->pool, birdloop_domain(p->loop), "Protocol %s stop-free objects", p->cf->name);
     proto_notify_state(p, (p->proto->start ? p->proto->start(p) : PS_UP));
   }
 }
@@ -2324,6 +2325,9 @@ proto_do_stop(struct proto *p)
     p->main_source = NULL;
   }
 
+  rp_free(p->pool_up);
+  p->pool_up = NULL;
+
   proto_stop_channels(p);
   rt_destroy_sources(&p->sources, p->event);
 
index 70b2022d3fee1770e6567d7f6f6012a2c8fec2e7..635f84b9be2849361a4db8f28b11299650a9aef1 100644 (file)
@@ -139,7 +139,9 @@ struct proto {
   struct proto_config *cf;             /* Configuration data */
   struct proto_config *cf_new;         /* Configuration we want to switch to after shutdown (NULL=delete) */
   pool *pool;                          /* Pool containing local objects */
-  pool *pool_fragile;                  /* Pool containing fragile local objects which need to be freed
+  pool *pool_up;                       /* Pool containing local objects which should be dropped as soon
+                                          as the protocol enters the STOP / DOWN state */
+  pool *pool_inloop;                   /* Pool containing local objects which need to be freed
                                           before the protocol's birdloop actually stops, like olocks */
   event *event;                                /* Protocol event */
   timer *restart_timer;                        /* Timer to restart the protocol from limits */
index 2257a8a9cfc45df5096452820b78f6d96fa5014f..d14facfd4cd9a83590e454ebdb6bd1482578c1c8 100644 (file)
@@ -1781,7 +1781,7 @@ bgp_start(struct proto *P)
    * so that we are the only instance attempting to talk with that neighbor.
    */
   struct object_lock *lock;
-  lock = p->lock = olock_new(P->pool_fragile);
+  lock = p->lock = olock_new(P->pool_inloop);
   lock->addr = p->remote_ip;
   lock->port = p->cf->remote_port;
   lock->iface = p->cf->iface;
index 896bf5a367fdf2101698adf6dafc1c2183991045..cd8396565f1c6dbc88c4b5abd62689891e350481 100644 (file)
@@ -295,7 +295,7 @@ ospf_start(struct proto *P)
   p->gr_mode = c->gr_mode;
   p->gr_time = c->gr_time;
   p->tick = c->tick;
-  p->disp_timer = tm_new_init(P->pool, ospf_disp, p, p->tick S, 0);
+  p->disp_timer = tm_new_init(P->pool_up, ospf_disp, p, p->tick S, 0);
   tm_start(p->disp_timer, 100 MS);
   p->lsab_size = 256;
   p->lsab_used = 0;
@@ -539,9 +539,6 @@ ospf_shutdown(struct proto *P)
   }
   FIB_WALK_END;
 
-  if (tm_active(p->disp_timer))
-    tm_stop(p->disp_timer);
-
   return PS_DOWN;
 }
 
index e09d082b7622453be12f766bd007eef64fb9c384..a8f9ffcd69a823163b1a4188a662e04c87e94ac7 100644 (file)
@@ -769,8 +769,8 @@ rip_add_iface(struct rip_proto *p, struct iface *iface, struct rip_iface_config
 
   add_tail(&p->iface_list, NODE ifa);
 
-  ifa->timer = tm_new_init(p->p.pool, rip_iface_timer, ifa, 0, 0);
-  ifa->rxmt_timer = tm_new_init(p->p.pool, rip_rxmt_timeout, ifa, 0, 0);
+  ifa->timer = tm_new_init(p->p.pool_up, rip_iface_timer, ifa, 0, 0);
+  ifa->rxmt_timer = tm_new_init(p->p.pool_up, rip_rxmt_timeout, ifa, 0, 0);
 
   struct object_lock *lock = olock_new(p->p.pool);
   lock->type = OBJLOCK_UDP;
@@ -1220,7 +1220,7 @@ rip_start(struct proto *P)
   fib_init(&p->rtable, P->pool, cf->rip2 ? NET_IP4 : NET_IP6,
           sizeof(struct rip_entry), OFFSETOF(struct rip_entry, n), 0, NULL);
   p->rte_slab = sl_new(P->pool, sizeof(struct rip_rte));
-  p->timer = tm_new_init(P->pool, rip_timer, p, 0, 0);
+  p->timer = tm_new_init(P->pool_up, rip_timer, p, 0, 0);
 
   p->rip2 = cf->rip2;
   p->ecmp = cf->ecmp;