]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Refactoring of domains connected to pools
authorMaria Matejka <mq@ucw.cz>
Mon, 24 Apr 2023 14:10:59 +0000 (16:10 +0200)
committerMaria Matejka <mq@ucw.cz>
Tue, 25 Apr 2023 07:52:28 +0000 (09:52 +0200)
14 files changed:
lib/locking.h
lib/rcu.c
lib/resource.c
nest/iface.c
nest/locks.c
nest/proto.c
nest/rt-attr.c
nest/rt-table.c
proto/bfd/bfd.c
proto/bgp/bgp.c
sysdep/unix/alloc.c
sysdep/unix/domain.c
sysdep/unix/io-loop.c
sysdep/unix/io.c

index 751eecbd131de9fdce7341f02b43aeb959db08f5..fc3c59ffbca43d92bb192f6f3fbdd5f01acb0893 100644 (file)
@@ -10,6 +10,7 @@
 #define _BIRD_LOCKING_H_
 
 struct domain_generic;
+struct pool;
 
 /* Here define the global lock order; first to last. */
 struct lock_order {
@@ -30,8 +31,8 @@ extern _Thread_local struct domain_generic **last_locked;
 #define DEFINE_DOMAIN(type) DOMAIN(type) { struct domain_generic *type; }
 #define DOMAIN_ORDER(type)  OFFSETOF(struct lock_order, type)
 
-#define DOMAIN_NEW(type, name)  (DOMAIN(type)) { .type = domain_new(name, DOMAIN_ORDER(type)) }
-struct domain_generic *domain_new(const char *name, uint order);
+#define DOMAIN_NEW(type)  (DOMAIN(type)) { .type = domain_new(DOMAIN_ORDER(type)) }
+struct domain_generic *domain_new(uint order);
 
 #define DOMAIN_FREE(type, d)   domain_free((d).type)
 void domain_free(struct domain_generic *);
@@ -39,6 +40,9 @@ void domain_free(struct domain_generic *);
 #define DOMAIN_NAME(type, d)   domain_name((d).type)
 const char *domain_name(struct domain_generic *);
 
+#define DOMAIN_SETUP(type, d, n, p)    domain_setup((d).type, n, p)
+void domain_setup(struct domain_generic *, const char *name, struct pool *);
+
 #define DOMAIN_NULL(type)   (DOMAIN(type)) {}
 
 #define LOCK_DOMAIN(type, d)   do_lock(((d).type), &(locking_stack.type))
index 8ae4f2ab00794ef1299aac9bca5434e42e3478ba..7ea6ec9b8aa53a440171a06ded069c83326e086c 100644 (file)
--- a/lib/rcu.c
+++ b/lib/rcu.c
@@ -73,7 +73,8 @@ rcu_thread_stop(struct rcu_thread *rc)
 void
 rcu_init(void)
 {
-  rcu_domain = DOMAIN_NEW(resource, "Read-Copy-Update");
+  rcu_domain = DOMAIN_NEW(resource);
+  DOMAIN_SETUP(resource, rcu_domain, "Read-Copy-Update", NULL);
   init_list(&rcu_thread_list);
   rcu_thread_start(&main_rcu_thread);
 }
index 2071a4114ab0228a4371e095ff74088ebe297d21..e0aaac0a11c3325016f9ade6581e8f6090ef64b0 100644 (file)
@@ -51,6 +51,9 @@ rp_init(pool *z, struct domain_generic *dom, const char *name)
 {
   ASSERT_DIE(DG_IS_LOCKED(dom));
 
+  if (name && !domain_name(dom))
+    domain_setup(dom, name, z);
+
   z->name = name;
   z->domain = dom;
   z->inside = (TLIST_LIST(resource)) {};
@@ -87,7 +90,9 @@ pool *
 rp_vnewf(pool *p, struct domain_generic *dom, const char *fmt, va_list args)
 {
   pool *z = rp_new(p, dom, NULL);
-  z->name = mb_vsprintf(p, fmt, args);
+  z->name = mb_vsprintf(z, fmt, args);
+  if (!domain_name(dom))
+    domain_setup(dom, z->name, z);
   return z;
 }
 
index a024b943192c485ccb0c7f42503edf6bf0c0ce85..bbe38d3fabce5d0f04425d3bb45b818a1d1c6077 100644 (file)
@@ -1018,7 +1018,7 @@ if_choose_router_id(struct iface_patt *mask, u32 old_id)
 void
 if_init(void)
 {
-  iface_domain = DOMAIN_NEW(attrs, "Interfaces");
+  iface_domain = DOMAIN_NEW(attrs);
 
   IFACE_LOCK;
   if_pool = rp_new(&root_pool, iface_domain.attrs, "Interfaces");
index 247d0c569cd7b079ba043331a7021542ecb7b3a7..66409c6db38be68fa8fb4bbcc6a89e25a08b620a 100644 (file)
@@ -197,5 +197,6 @@ olock_init(void)
 {
   DBG("olock: init\n");
   init_list(&olock_list);
-  olock_domain = DOMAIN_NEW(attrs, "Object lock");
+  olock_domain = DOMAIN_NEW(attrs);
+  DOMAIN_SETUP(attrs, olock_domain, "Object lock", NULL);
 }
index 32183c9dc729ad027e2a9144a173dea8e8cbe462..647b7f4e517a7186798960616f1170c58890be94 100644 (file)
@@ -1859,9 +1859,9 @@ void protos_build_gen(void);
 void
 protos_build(void)
 {
-  protos_build_gen();
-
   proto_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Protocols");
+
+  protos_build_gen();
 }
 
 
index 38612a4ef3ad944f914fe285d7edf64b3b9da90b..c035a2dc09e5a62e88a5dc3d46b020085b92eeef 100644 (file)
@@ -1607,7 +1607,7 @@ ea_show_list(struct cli *c, ea_list *eal)
 void
 rta_init(void)
 {
-  attrs_domain = DOMAIN_NEW(attrs, "Attributes");
+  attrs_domain = DOMAIN_NEW(attrs);
 
   RTA_LOCK;
   rta_pool = rp_new(&root_pool, attrs_domain.attrs, "Attributes");
index f1e3c8f707e67020a260cb71e57784795eeea139..a934d3c3bc9c340e69e46f142d1f5cc5730ec820 100644 (file)
@@ -2850,7 +2850,7 @@ rt_setup(pool *pp, struct rtable_config *cf)
   pool *sp = birdloop_pool(loop);
 
   /* Create the table domain and pool */
-  DOMAIN(rtable) dom = DOMAIN_NEW(rtable, cf->name);
+  DOMAIN(rtable) dom = DOMAIN_NEW(rtable);
   LOCK_DOMAIN(rtable, dom);
 
   pool *p = rp_newf(sp, dom.rtable, "Routing table data %s", cf->name);
index f7d8f8d9f7760491b43cc14389b35ddcd3e8d490..e373e4dd0d70840660d0e26e7b0db36904e6186b 100644 (file)
@@ -1232,7 +1232,9 @@ bfd_build(void)
 {
   proto_build(&proto_bfd);
 
-  bfd_global.lock = DOMAIN_NEW(rtable, "BFD Global");
+  bfd_global.lock = DOMAIN_NEW(rtable);
+  DOMAIN_SETUP(rtable, bfd_global.lock, "BFD Global", NULL);
+
   init_list(&bfd_global.wait_list);
   init_list(&bfd_global.pickup_list);
   init_list(&bfd_global.proto_list);
index e60884bae9506c3334f3305e6b1b86afc1dac4ff..f4d80e8dfc92a1673683c599555328aa93cf90e7 100644 (file)
@@ -132,7 +132,8 @@ static list STATIC_LIST_INIT(bgp_sockets);          /* Global list of listening sockets
 static list STATIC_LIST_INIT(bgp_listen_pending);      /* Global list of listening socket open requests */
 static event bgp_listen_event = { .hook = bgp_listen_create };
 
-DOMAIN(rtable) bgp_listen_domain;
+static DOMAIN(rtable) bgp_listen_domain;
+static pool *bgp_listen_pool;
 
 static void bgp_connect(struct bgp_proto *p);
 static void bgp_active(struct bgp_proto *p);
@@ -276,7 +277,7 @@ bgp_listen_create(void *_ UNUSED)
     {
       /* Allocating new socket from global protocol pool.
        * We can do this in main_birdloop. */
-      sock *sk = sk_new(proto_pool);
+      sock *sk = sk_new(bgp_listen_pool);
       sk->type = SK_TCP_PASSIVE;
       sk->ttl = 255;
       sk->saddr = req->addr;
@@ -301,7 +302,7 @@ bgp_listen_create(void *_ UNUSED)
        continue;
       }
 
-      bs = mb_allocz(proto_pool, sizeof(struct bgp_socket));
+      bs = mb_allocz(bgp_listen_pool, sizeof(struct bgp_socket));
       bs->sk = sk;
       sk->data = bs;
 
@@ -1337,7 +1338,9 @@ bgp_incoming_connection(sock *sk, uint dummy UNUSED)
   {
     log(L_WARN "BGP: Unexpected connect from unknown address %I%J (port %d)",
        sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL, sk->dport);
+    LOCK_DOMAIN(rtable, bgp_listen_domain);
     sk_close(sk);
+    UNLOCK_DOMAIN(rtable, bgp_listen_domain);
     return 0;
   }
 
@@ -1365,6 +1368,8 @@ bgp_incoming_connection(sock *sk, uint dummy UNUSED)
       bgp_close_conn(&p->incoming_conn);
   }
 
+  LOCK_DOMAIN(rtable, bgp_listen_domain);
+
   BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
            sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL,
            sk->dport, acc ? "accepted" : "rejected");
@@ -1414,6 +1419,7 @@ err:
   sk_close(sk);
 
 leave:
+  UNLOCK_DOMAIN(rtable, bgp_listen_domain);
   birdloop_leave(p->p.loop);
   return 0;
 }
@@ -2843,5 +2849,8 @@ void bgp_build(void)
 {
   proto_build(&proto_bgp);
   bgp_register_attrs();
-  bgp_listen_domain = DOMAIN_NEW(rtable, "BGP Listen Sockets");
+  bgp_listen_domain = DOMAIN_NEW(rtable);
+  LOCK_DOMAIN(rtable, bgp_listen_domain);
+  bgp_listen_pool = rp_new(proto_pool, bgp_listen_domain.rtable, "BGP Listen Sockets");
+  UNLOCK_DOMAIN(rtable, bgp_listen_domain);
 }
index cafcc8dd4c7a9a5001faef10ff38d317d4ea9bb9..1b951da242ffe384ce189b65c44e55d533110595 100644 (file)
@@ -318,7 +318,8 @@ resource_sys_init(void)
     /* We assume that page size has only one bit and is between 1K and 256K (incl.).
      * Otherwise, the assumptions in lib/slab.c (sl_head's num_full range) aren't met. */
 
-    empty_pages_domain = DOMAIN_NEW(resource, "Empty Pages");
+    empty_pages_domain = DOMAIN_NEW(resource);
+    DOMAIN_SETUP(resource, empty_pages_domain, "Empty Pages", NULL);
     initialized = 1;
     return;
   }
index f4ee595df9dd12861de054af1f8a895a2bb23e51..c04e91eab609d20ebd54b2bc26d872822510b99c 100644 (file)
@@ -46,20 +46,21 @@ struct domain_generic {
   struct domain_generic **prev;
   struct lock_order *locked_by;
   const char *name;
+  pool *pool;
 };
 
-#define DOMAIN_INIT(_name, _order) { .mutex = PTHREAD_MUTEX_INITIALIZER, .name = _name, .order = _order }
+#define DOMAIN_INIT(_order) { .mutex = PTHREAD_MUTEX_INITIALIZER, .order = _order }
 
-static struct domain_generic the_bird_domain_gen = DOMAIN_INIT("The BIRD", OFFSETOF(struct lock_order, the_bird));
+static struct domain_generic the_bird_domain_gen = DOMAIN_INIT(OFFSETOF(struct lock_order, the_bird));
 
 DOMAIN(the_bird) the_bird_domain = { .the_bird = &the_bird_domain_gen };
 
 struct domain_generic *
-domain_new(const char *name, uint order)
+domain_new(uint order)
 {
   ASSERT_DIE(order < sizeof(struct lock_order));
   struct domain_generic *dg = xmalloc(sizeof(struct domain_generic));
-  *dg = (struct domain_generic) DOMAIN_INIT(name, order);
+  *dg = (struct domain_generic) DOMAIN_INIT(order);
   return dg;
 }
 
@@ -81,6 +82,14 @@ uint dg_order(struct domain_generic *dg)
   return dg->order;
 }
 
+void
+domain_setup(struct domain_generic *dg, const char *name, pool *p)
+{
+  ASSERT_DIE(dg->pool == NULL);
+  dg->pool = p;
+  dg->name = name;
+}
+
 void do_lock(struct domain_generic *dg, struct domain_generic **lsp)
 {
   struct lock_order stack_copy;
index daa8656077a0c54b8a8ed2e63abd5cb1eca1fbf9..1a3333efacaea563ea057fe54716f0841bf32afd 100644 (file)
@@ -1029,7 +1029,7 @@ bird_thread_show_finish(void *data)
 void
 cmd_show_threads(int show_loops)
 {
-  DOMAIN(control) lock = DOMAIN_NEW(control, "Show Threads");
+  DOMAIN(control) lock = DOMAIN_NEW(control);
   LOCK_DOMAIN(control, lock);
   pool *p = rp_new(&root_pool, lock.control, "Show Threads");
 
@@ -1084,7 +1084,8 @@ birdloop_init(void)
   {
     struct birdloop_pickup_group *group = &pickup_groups[i];
 
-    group->domain = DOMAIN_NEW(resource, "Loop Pickup");
+    group->domain = DOMAIN_NEW(resource);
+    DOMAIN_SETUP(resource, group->domain, "Loop Pickup", NULL);
     init_list(&group->loops);
     init_list(&group->threads);
   }
@@ -1217,7 +1218,7 @@ birdloop_run_timer(timer *tm)
 static struct birdloop *
 birdloop_vnew_internal(pool *pp, uint order, struct birdloop_pickup_group *group, const char *name, va_list args)
 {
-  struct domain_generic *dg = domain_new(name, order);
+  struct domain_generic *dg = domain_new(order);
   DG_LOCK(dg);
 
   pool *p = rp_vnewf(pp, dg, name, args);
index 40a6f114e01b96b1f825b0fe6480837393435491..b21df0577b2ca0daad2e8835ef6a7203e3d84487 100644 (file)
@@ -1052,6 +1052,10 @@ sk_passive_connected(sock *s, int type)
     return 0;
   }
 
+  struct domain_generic *sock_lock = DG_IS_LOCKED(s->pool->domain) ? NULL : s->pool->domain;
+  if (sock_lock)
+    DG_LOCK(sock_lock);
+
   sock *t = sk_new(s->pool);
   t->type = type;
   t->data = s->data;
@@ -1082,13 +1086,20 @@ sk_passive_connected(sock *s, int type)
     close(t->fd);
     t->fd = -1;
     sk_close(t);
-    return 1;
+    t = NULL;
+  }
+  else
+  {
+    birdloop_add_socket(s->loop, t);
+    sk_alloc_bufs(t);
   }
 
-  birdloop_add_socket(s->loop, t);
+  if (sock_lock)
+    DG_UNLOCK(sock_lock);
+
+  if (t)
+    s->rx_hook(t, 0);
 
-  sk_alloc_bufs(t);
-  s->rx_hook(t, 0);
   return 1;
 }