]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Converted simple table events to loop flags
authorMaria Matejka <mq@ucw.cz>
Mon, 12 Sep 2022 08:25:14 +0000 (10:25 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 18 Sep 2022 14:33:51 +0000 (16:33 +0200)
nest/rt-table.c
nest/rt.h

index f596e808f966b7d8227dd72c6482fda8a2b511a6..fbc41453a4eb16fd16f651ea6d1b830b575efaa3 100644 (file)
@@ -130,7 +130,7 @@ struct rt_export_block {
 
 static void rt_free_hostcache(struct rtable_private *tab);
 static void rt_update_hostcache(void *tab);
-static void rt_next_hop_update(void *tab);
+static void rt_next_hop_update(struct rtable_private *tab);
 static void rt_nhu_uncork(void *_tab);
 static inline void rt_next_hop_resolve_rte(rte *r);
 static inline void rt_flowspec_resolve_rte(rte *r, struct channel *c);
@@ -185,8 +185,12 @@ const char *rt_export_state_name(u8 state)
 
 static struct hostentry *rt_get_hostentry(struct rtable_private *tab, ip_addr a, ip_addr ll, rtable *dep);
 
+static inline rtable *rt_priv_to_pub(struct rtable_private *tab) { return RT_PUB(tab); }
+static inline rtable *rt_pub_to_pub(rtable *tab) { return tab; }
+#define RT_ANY_TO_PUB(tab)     _Generic((tab),rtable*:rt_pub_to_pub,struct rtable_private*:rt_priv_to_pub)((tab))
+
 #define rt_trace(tab, level, fmt, args...)  do {\
-  struct rtable_private *t = (tab);            \
+  rtable *t = RT_ANY_TO_PUB((tab));            \
   if (t->config->debug & (level))              \
     log(L_TRACE "%s: " fmt, t->name, ##args);  \
 } while (0)
@@ -1435,38 +1439,37 @@ rt_announce_exports(timer *tm)
 }
 
 static void
-rt_kick_announce_exports(void *_tab)
+rt_kick_announce_exports(struct rtable_private *tab)
 {
-  RT_LOCKED((rtable *) _tab, tab)
-    if (!tm_active(tab->export_timer))
-      tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop);
+  if (!tm_active(tab->export_timer))
+    tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop);
 }
 
 static void
 rt_import_announce_exports(void *_hook)
 {
   struct rt_import_hook *hook = _hook;
-  RT_LOCKED(hook->table, tab)
+  if (hook->import_state == TIS_CLEARED)
   {
-    if (hook->import_state == TIS_CLEARED)
+    void (*stopped)(struct rt_import_request *) = hook->stopped;
+    struct rt_import_request *req = hook->req;
+
+    RT_LOCKED(hook->table, tab)
     {
-      void (*stopped)(struct rt_import_request *) = hook->stopped;
-      struct rt_import_request *req = hook->req;
       req->hook = NULL;
 
       rt_trace(tab, D_EVENTS, "Hook %s stopped", req->name);
       rem_node(&hook->n);
       mb_free(hook);
       rt_unlock_table(tab);
-      RT_UNLOCK(tab);
-
-      stopped(req);
-      return;
     }
 
-    rt_trace(tab, D_EVENTS, "Announcing exports after imports from %s", hook->req->name);
-    ev_send_loop(tab->loop, tab->export_event);
+    stopped(req);
+    return;
   }
+
+  rt_trace(hook->table, D_EVENTS, "Announcing exports after imports from %s", hook->req->name);
+  birdloop_flag(hook->table->loop, RTF_EXPORT);
 }
 
 static struct rt_pending_export *
@@ -2399,22 +2402,18 @@ rt_schedule_nhu(struct rtable_private *tab)
   if (tab->nhu_corked)
   {
     if (!(tab->nhu_corked & NHU_SCHEDULED))
-    {
       tab->nhu_corked |= NHU_SCHEDULED;
-      rt_lock_table(tab);
-    }
   }
   else if (!(tab->nhu_state & NHU_SCHEDULED))
   {
     rt_trace(tab, D_EVENTS, "Scheduling NHU");
-    rt_lock_table(tab);
 
     /* state change:
      *   NHU_CLEAN   -> NHU_SCHEDULED
      *   NHU_RUNNING -> NHU_DIRTY
      */
     if ((tab->nhu_state |= NHU_SCHEDULED) == NHU_SCHEDULED)
-      ev_send_loop(tab->loop, tab->nhu_event);
+      birdloop_flag(tab->loop, RTF_NHU);
   }
 }
 
@@ -2422,7 +2421,7 @@ void
 rt_schedule_prune(struct rtable_private *tab)
 {
   if (tab->prune_state == 0)
-    ev_send_loop(tab->loop, tab->rt_event);
+    birdloop_flag(tab->loop, RTF_CLEANUP);
 
   /* state change 0->1, 2->3 */
   tab->prune_state |= 1;
@@ -2440,25 +2439,33 @@ rt_export_used(struct rt_table_exporter *e)
     return;
 
   tab->export_used = 1;
-  ev_send_loop(tab->loop, tab->rt_event);
+  birdloop_flag(tab->loop, RTF_CLEANUP);
 }
 
 static void
-rt_event(void *ptr)
+rt_flag_handler(struct birdloop_flag_handler *fh, u32 flags)
 {
-  RT_LOCKED((rtable *) ptr, tab)
+  RT_LOCKED(RT_PUB(SKIP_BACK(struct rtable_private, fh, fh)), tab)
   {
+    ASSERT_DIE(birdloop_inside(tab->loop));
+    rt_lock_table(tab);
 
-  ASSERT_DIE(birdloop_inside(tab->loop));
-  rt_lock_table(tab);
+    if (flags & RTF_NHU)
+      rt_next_hop_update(tab);
 
-  if (tab->export_used)
-    rt_export_cleanup(tab);
+    if (flags & RTF_EXPORT)
+      rt_kick_announce_exports(tab);
+
+    if (flags & RTF_CLEANUP)
+    {
+      if (tab->export_used)
+       rt_export_cleanup(tab);
 
-  if (tab->prune_state)
-    rt_prune_table(tab);
+      if (tab->prune_state)
+       rt_prune_table(tab);
+    }
 
-  rt_unlock_table(tab);
+    rt_unlock_table(tab);
   }
 }
 
@@ -2712,10 +2719,8 @@ rt_setup(pool *pp, struct rtable_config *cf)
   hmap_init(&t->id_map, p, 1024);
   hmap_set(&t->id_map, 0);
 
-  t->rt_event = ev_new_init(p, rt_event, t);
-  t->nhu_event = ev_new_init(p, rt_next_hop_update, t);
+  t->fh = (struct birdloop_flag_handler) { .hook = rt_flag_handler, };
   t->nhu_uncork_event = ev_new_init(p, rt_nhu_uncork, t);
-  t->export_event = ev_new_init(p, rt_kick_announce_exports, t);
   t->export_timer = tm_new_init(p, rt_announce_exports, t, 0, 0);
   t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0);
   t->last_rt_change = t->gc_time = current_time();
@@ -2745,6 +2750,9 @@ rt_setup(pool *pp, struct rtable_config *cf)
 
   /* Start the service thread */
   t->loop = birdloop_new(p, DOMAIN_ORDER(service), mb_sprintf(p, "Routing tahle %s", t->name));
+  birdloop_enter(t->loop);
+  birdloop_flag_set_handler(t->loop, &t->fh);
+  birdloop_leave(t->loop);
 
   return RT_PUB(t);
 }
@@ -2834,7 +2842,7 @@ again:
       if (limit <= 0)
       {
        FIB_ITERATE_PUT(fit);
-       ev_send_loop(tab->loop, tab->rt_event);
+       birdloop_flag(tab->loop, RTF_CLEANUP);
        return;
       }
 
@@ -3091,10 +3099,9 @@ done:;
     rt_kick_prune_timer(tab);
 
   if (tab->export_used)
-    ev_send_loop(tab->loop, tab->rt_event);
+    birdloop_flag(tab->loop, RTF_CLEANUP);
 
-
-  if (EMPTY_LIST(tab->exporter.pending) && tm_active(tab->export_timer))
+  if (EMPTY_LIST(tab->exporter.pending))
     tm_stop(tab->export_timer);
 }
 
@@ -3709,16 +3716,13 @@ rt_nhu_uncork(void *_tab)
     tab->nhu_corked = 0;
     rt_trace(tab, D_STATES, "Next hop updater uncorked");
 
-    ev_send_loop(tab->loop, tab->nhu_event);
+    birdloop_flag(tab->loop, RTF_NHU);
   }
 }
 
 static void
-rt_next_hop_update(void *_tab)
+rt_next_hop_update(struct rtable_private *tab)
 {
-  RT_LOCKED((rtable *) _tab, tab)
-  {
-
   ASSERT_DIE(birdloop_inside(tab->loop));
 
   if (tab->nhu_corked)
@@ -3738,7 +3742,7 @@ rt_next_hop_update(void *_tab)
 
     tab->nhu_corked = tab->nhu_state;
     tab->nhu_state = 0;
-    RT_RETURN(tab);
+    return;
   }
 
   struct fib_iterator *fit = &tab->nhu_fit;
@@ -3760,8 +3764,8 @@ rt_next_hop_update(void *_tab)
       if (max_feed <= 0)
        {
          FIB_ITERATE_PUT(fit);
-         ev_send_loop(tab->loop, tab->nhu_event);
-         RT_RETURN(tab);
+         birdloop_flag(tab->loop, RTF_NHU);
+         return;
        }
       lp_state lps;
       lp_save(tmp_linpool, &lps);
@@ -3781,11 +3785,7 @@ rt_next_hop_update(void *_tab)
    *   NHU_RUNNING -> NHU_CLEAN
    */
   if ((tab->nhu_state &= NHU_SCHEDULED) == NHU_SCHEDULED)
-    ev_send_loop(tab->loop, tab->nhu_event);
-
-  rt_unlock_table(tab);
-
-  }
+    birdloop_flag(tab->loop, RTF_NHU);
 }
 
 void
index cd3745d6d1ca3d350e5b2a83d044e14882100b78..649392b944620a4f6931a3fc5c6e7ff54e780b6b 100644 (file)
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -19,6 +19,7 @@
 #include "lib/route.h"
 #include "lib/event.h"
 #include "lib/rcu.h"
+#include "lib/io-loop.h"
 
 #include <stdatomic.h>
 
@@ -103,6 +104,7 @@ DEFINE_DOMAIN(rtable);
     uint id;                           /* Integer table ID for fast lookup */                  \
     DOMAIN(rtable) lock;               /* Lock to take to access the private parts */          \
     struct rtable_config *config;      /* Configuration of this table */                       \
+    struct birdloop *loop;             /* Service thread */                                    \
 
 /* The complete rtable structure */
 struct rtable_private {
@@ -111,7 +113,6 @@ struct rtable_private {
 
   /* Here the private items not to be accessed without locking */
   pool *rp;                            /* Resource pool to allocate everything from, including itself */
-  struct birdloop *loop;               /* Service thread */
   struct slab *rte_slab;               /* Slab to allocate route objects */
   struct fib fib;
   struct f_trie *trie;                 /* Trie of prefixes defined in fib */
@@ -127,12 +128,10 @@ struct rtable_private {
                                         * delete as soon as use_count becomes 0 and remove
                                         * obstacle from this routing table.
                                         */
-  struct event *rt_event;              /* Routing table event */
-  struct event *nhu_event;             /* Specific event for next hop update */
   struct event *nhu_uncork_event;      /* Helper event to schedule NHU on uncork */
-  struct event *export_event;          /* Event for export batching */
   struct timer *export_timer;          /* Timer for export batching */
   struct timer *prune_timer;           /* Timer for periodic pruning / GC */
+  struct birdloop_flag_handler fh;     /* Handler for simple events */
   btime last_rt_change;                        /* Last time when route changed */
   btime gc_time;                       /* Time of last GC */
   uint gc_counter;                     /* Number of operations since last GC */
@@ -174,6 +173,11 @@ typedef union rtable {
 
 #define RT_PRIV_SAME(tpriv, tpub)      (&(tpub)->priv == (tpriv))
 
+/* Flags for birdloop_flag() */
+#define RTF_CLEANUP    1
+#define RTF_NHU                2
+#define RTF_EXPORT     4
+
 extern struct rt_cork {
   _Atomic uint active;
   event_list queue;