]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Forbid locking altogether when RCU reader is active
authorMaria Matejka <mq@ucw.cz>
Thu, 27 Jun 2024 06:42:11 +0000 (08:42 +0200)
committerMaria Matejka <mq@ucw.cz>
Fri, 28 Jun 2024 20:03:45 +0000 (22:03 +0200)
lib/locking.h
lib/netindex.c
lib/rcu.c
lib/rcu.h
nest/rt-attr.c
nest/rt-table.c
proto/bgp/attrs.c
sysdep/unix/alloc.c
sysdep/unix/domain.c
sysdep/unix/io-loop.c

index 0251f87697cbb090b9fb4b658d7d78ee3f437041..60928ecc04954f146e83febdda23e0b4ae690722 100644 (file)
@@ -44,9 +44,8 @@ extern _Thread_local struct domain_generic **last_locked;
 #define DOMAIN(type) struct domain__##type
 #define DOMAIN_ORDER(type)  OFFSETOF(struct lock_order, type)
 
-#define DOMAIN_NEW(type)  (DOMAIN(type)) { .type = domain_new(DOMAIN_ORDER(type), 1) }
-#define DOMAIN_NEW_RCU_SYNC(type)  (DOMAIN(type)) { .type = domain_new(DOMAIN_ORDER(type), 0) }
-struct domain_generic *domain_new(uint order, bool allow_rcu);
+#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 *);
index 7596bffd5ba10d8add8b06f902068f1549025870..1bc43377e0cab514e75cff261b8ee36cea616747 100644 (file)
@@ -56,7 +56,7 @@ net_lock_revive_unlock(netindex_hash *h, struct netindex *i)
 netindex_hash *
 netindex_hash_new(pool *sp, event_list *cleanup_target, u8 type)
 {
-  DOMAIN(attrs) dom = DOMAIN_NEW_RCU_SYNC(attrs);
+  DOMAIN(attrs) dom = DOMAIN_NEW(attrs);
   LOCK_DOMAIN(attrs, dom);
 
   pool *p = rp_new(sp, dom.attrs, "Network index");
index 25c575f1f44897d9e0a85ca2d9579ad654bb691a..17101489e148997f497c27e1c3e989e66c909edb 100644 (file)
--- a/lib/rcu.c
+++ b/lib/rcu.c
@@ -18,7 +18,6 @@
 
 _Atomic u64 rcu_global_phase = RCU_GP_PHASE;
 _Thread_local struct rcu_thread this_rcu_thread;
-_Thread_local uint rcu_blocked;
 
 static struct rcu_thread * _Atomic rcu_thread_list = NULL;
 
@@ -36,9 +35,6 @@ rcu_critical(struct rcu_thread *t, u64 phase)
 void
 synchronize_rcu(void)
 {
-  if (!rcu_blocked && (last_locked > &locking_stack.meta))
-    bug("Forbidden to synchronize RCU unless an appropriate lock is taken");
-
   /* Increment phase */
   u64 phase = atomic_fetch_add_explicit(&rcu_global_phase, RCU_GP_PHASE, memory_order_acq_rel);
 
index a92440771d0b1d9bf50c7bb7357663216c230d9c..6a771a3a5e30c09b44c13f8372e0c5f9ed8def3a 100644 (file)
--- a/lib/rcu.h
+++ b/lib/rcu.h
@@ -28,7 +28,6 @@ struct rcu_thread {
 };
 
 extern _Thread_local struct rcu_thread this_rcu_thread;
-extern _Thread_local uint rcu_blocked;
 
 static inline void rcu_read_lock(void)
 {
index ff0d54fa6adc2bbdb0dcff22784a0924d0922558..978f423e98ab3e7a5190b87d5d9f0c5eb7fa8edf 100644 (file)
@@ -1843,7 +1843,7 @@ ea_show_list(struct cli *c, ea_list *eal)
 void
 rta_init(void)
 {
-  attrs_domain = DOMAIN_NEW_RCU_SYNC(attrs);
+  attrs_domain = DOMAIN_NEW(attrs);
 
   RTA_LOCK;
   rta_pool = rp_new(&root_pool, attrs_domain.attrs, "Attributes");
index 4f173815f3d4615eab24772e361bfe225ed1c0be..a401035f9d66ad8812a8ada562f4c92c364566b6 100644 (file)
@@ -3090,7 +3090,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_RCU_SYNC(rtable);
+  DOMAIN(rtable) dom = DOMAIN_NEW(rtable);
   LOCK_DOMAIN(rtable, dom);
 
   pool *p = rp_newf(sp, dom.rtable, "Routing table data %s", cf->name);
@@ -3256,7 +3256,7 @@ rt_init(void)
   init_list(&routing_tables);
   init_list(&deleted_routing_tables);
   ev_init_list(&rt_cork.queue, &main_birdloop, "Route cork release");
-  rt_cork.dom = DOMAIN_NEW_RCU_SYNC(resource);
+  rt_cork.dom = DOMAIN_NEW(resource);
   idm_init(&rtable_idm, rt_table_pool, 256);
 
   ea_register_init(&ea_roa_aggregated);
index d8d9d3cf35585253e99d417e5dc9129b17d085fe..7cc3e514259f3e361d940c22f74bd0ffabb8bc1e 100644 (file)
@@ -1948,7 +1948,7 @@ bgp_init_pending_tx(struct bgp_channel *c)
   ASSERT_DIE(c->c.out_table == NULL);
   ASSERT_DIE(c->tx == NULL);
 
-  DOMAIN(rtable) dom = DOMAIN_NEW_RCU_SYNC(rtable);
+  DOMAIN(rtable) dom = DOMAIN_NEW(rtable);
   LOCK_DOMAIN(rtable, dom);
   pool *p = rp_newf(c->pool, dom.rtable, "%s.%s TX", c->c.proto->name, c->c.name);
 
index 1cf41a5bb78e2f8919b9f6047d565bdf210feb5c..0432b9e265113546804ba6928cff41a9c69bada9 100644 (file)
@@ -215,6 +215,14 @@ alloc_page(void)
   /* Reinstate the stack with zero */
   PAGE_STACK_PUT(NULL);
 
+  if (rcu_read_active())
+  {
+    /* We can't lock and we actually shouldn't alloc either when rcu is active
+     * but that's a quest for another day. */
+  }
+  else
+  {
+
   /* If there is any free page kept cold, we use that. */
   LOCK_DOMAIN(resource, empty_pages_domain);
   if (empty_pages) {
@@ -244,6 +252,8 @@ alloc_page(void)
   if (fp)
     return fp;
 
+  }
+
   /* And in the worst case, allocate some new pages by mmap() */
   void *ptr = alloc_sys_page();
   ajlog(ptr, NULL, 0, AJT_ALLOC_MMAP);
index a3104b89883d3664b338892fdfb888bf2f79da8d..e76ac2fb0732821e56cb9d30724d68240795c9f9 100644 (file)
@@ -50,29 +50,27 @@ _Thread_local struct domain_generic **last_locked = NULL;
 struct domain_generic {
   pthread_mutex_t mutex;
   uint order;
-  bool forbidden_when_reading_rcu;
   struct domain_generic **prev;
   struct lock_order *locked_by;
   const char *name;
   pool *pool;
 };
 
-#define DOMAIN_INIT(_order, _allow_rcu) { \
+#define DOMAIN_INIT(_order) { \
   .mutex = PTHREAD_MUTEX_INITIALIZER, \
   .order = _order, \
-  .forbidden_when_reading_rcu = !_allow_rcu, \
 }
 
-static struct domain_generic the_bird_domain_gen = DOMAIN_INIT(OFFSETOF(struct lock_order, the_bird), 1);
+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(uint order, bool allow_rcu)
+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(order, allow_rcu);
+  *dg = (struct domain_generic) DOMAIN_INIT(order);
   return dg;
 }
 
@@ -108,11 +106,8 @@ void do_lock(struct domain_generic *dg, struct domain_generic **lsp)
   memcpy(&stack_copy, &locking_stack, sizeof(stack_copy));
   struct domain_generic **lll = last_locked;
 
-  if (dg->forbidden_when_reading_rcu)
-    if (rcu_read_active())
-      bug("Locking of this lock forbidden while RCU reader is active");
-    else
-      rcu_blocked++;
+  if (rcu_read_active())
+    bug("Locking forbidden while RCU reader is active");
 
   if ((char *) lsp - (char *) &locking_stack != dg->order)
     bug("Trying to lock on bad position: order=%u, lsp=%p, base=%p", dg->order, lsp, &locking_stack);
@@ -139,9 +134,6 @@ void do_lock(struct domain_generic *dg, struct domain_generic **lsp)
 
 void do_unlock(struct domain_generic *dg, struct domain_generic **lsp)
 {
-  if (dg->forbidden_when_reading_rcu)
-    ASSERT_DIE(rcu_blocked--);
-
   if ((char *) lsp - (char *) &locking_stack != dg->order)
     bug("Trying to unlock on bad position: order=%u, lsp=%p, base=%p", dg->order, lsp, &locking_stack);
 
index d2a60562e0bb0b494bb04c1726b8f5327a3e463d..7f45f541e9bcefd6cdbfd71b242ce10a6485ef5b 100644 (file)
@@ -1581,7 +1581,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(order, 1);
+  struct domain_generic *dg = domain_new(order);
   DG_LOCK(dg);
 
   pool *p = rp_vnewf(pp, dg, name, args);