]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Revert "BGP: Export uses common attribute cache"
authorMaria Matejka <mq@ucw.cz>
Tue, 25 Jun 2024 15:08:57 +0000 (17:08 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 26 Jun 2024 09:30:48 +0000 (11:30 +0200)
This reverts commit d01a7c2bdaf50aff23cf5e1b4e494328c5294960.

It seems that the performance penalty in global ea cache is actually
very high so returning back to local attribute caches in every BGP.

proto/bgp/attrs.c
proto/bgp/bgp.h
proto/bgp/packets.c

index bab8bb5e06f2d4e2766adf5329a3186c389f75e0..7ed898d238521b2cd17a01c673429d68923b0251 100644 (file)
@@ -1574,10 +1574,10 @@ bgp_finish_attrs(struct bgp_parse_state *s, ea_list **to)
  *     Route bucket hash table
  */
 
-#define RBH_KEY(b)             b->attrs
+#define RBH_KEY(b)             b->eattrs, b->hash
 #define RBH_NEXT(b)            b->next
-#define RBH_EQ(a1,a2)          a1 == a2
-#define RBH_FN(a)              ea_get_storage(a)->hash_key
+#define RBH_EQ(a1,h1,a2,h2)    h1 == h2 && ea_same(a1, a2)
+#define RBH_FN(a,h)            h
 
 #define RBH_REHASH             bgp_rbh_rehash
 #define RBH_PARAMS             /8, *2, 2, 2, 12, 20
@@ -1589,7 +1589,6 @@ static void
 bgp_init_bucket_table(struct bgp_ptx_private *c)
 {
   HASH_INIT(c->bucket_hash, c->pool, 8);
-  c->bucket_slab = sl_new(c->pool, sizeof(struct bgp_bucket));
 
   init_list(&c->bucket_queue);
   c->withdraw_bucket = NULL;
@@ -1599,21 +1598,24 @@ static struct bgp_bucket *
 bgp_get_bucket(struct bgp_ptx_private *c, ea_list *new)
 {
   /* Hash and lookup */
-  ea_list *ns = ea_lookup(new, 0, EALS_CUSTOM);
-  struct bgp_bucket *b = HASH_FIND(c->bucket_hash, RBH, ns);
+  u32 hash = ea_hash(new);
+  struct bgp_bucket *b = HASH_FIND(c->bucket_hash, RBH, new, hash);
 
   if (b)
-  {
-    ea_free(ns);
     return b;
-  }
+
+  /* Scan the list for total size */
+  uint ea_size = BIRD_CPU_ALIGN(ea_list_size(new));
+  uint size = sizeof(struct bgp_bucket) + ea_size;
 
   /* Allocate the bucket */
-  b = sl_alloc(c->bucket_slab);
-  *b = (struct bgp_bucket) {
-    .attrs = ns,
-  };
+  b = mb_alloc(c->pool, size);
+  *b = (struct bgp_bucket) { };
   init_list(&b->prefixes);
+  b->hash = hash;
+
+  /* Copy the ea_list */
+  ea_list_copy(b->eattrs, new, ea_size);
 
   /* Insert the bucket to bucket hash */
   HASH_INSERT2(c->bucket_hash, RBH, c->pool, b);
@@ -1637,8 +1639,7 @@ static void
 bgp_free_bucket(struct bgp_ptx_private *c, struct bgp_bucket *b)
 {
   HASH_REMOVE2(c->bucket_hash, RBH, c->pool, b);
-  ea_free(b->attrs);
-  sl_free(b);
+  mb_free(b);
 }
 
 int
@@ -1917,7 +1918,7 @@ bgp_out_feed_net(struct rt_exporter *e, struct rcu_unwinder *u, u32 index, _Bool
       {
        if (px->cur)
          feed->block[pos++] = (rte) {
-           .attrs = px->cur->attrs ? ea_ref_tmp(px->cur->attrs) : NULL,
+           .attrs = (px->cur == c->withdraw_bucket) ? NULL : ea_free_later(ea_lookup_slow(px->cur->eattrs, 0, EALS_CUSTOM)),
            .net = ni->addr,
            .src = px->src,
            .lastmod = px->lastmod,
@@ -1926,7 +1927,7 @@ bgp_out_feed_net(struct rt_exporter *e, struct rcu_unwinder *u, u32 index, _Bool
 
        if (px->last)
          feed->block[pos++] = (rte) {
-           .attrs = px->last->attrs ? ea_ref_tmp(px->last->attrs) : NULL,
+           .attrs = (px->last == c->withdraw_bucket) ? NULL : ea_free_later(ea_lookup_slow(px->last->eattrs, 0, EALS_CUSTOM)),
            .net = ni->addr,
            .src = px->src,
            .lastmod = px->lastmod,
index 00dbe496410e3d2b0027c5cb0ae1b1243e3816d8..a4fcc65bdec14925ed53da5c3c0fe8e3ca34d147 100644 (file)
@@ -467,9 +467,10 @@ struct bgp_bucket {
   node send_node;                      /* Node in send queue */
   struct bgp_bucket *next;             /* Node in bucket hash table */
   list prefixes;                       /* Prefixes to send in this bucket (struct bgp_prefix) */
-  ea_list *attrs;                      /* Attributes to encode */
+  u32 hash;                            /* Hash over extended attributes */
   u32 px_uc:31;                                /* How many prefixes are linking this bucket */
   u32 bmp:1;                           /* Temporary bucket for BMP encoding */
+  ea_list eattrs[0];                   /* Per-bucket extended attributes */
 };
 
 struct bgp_export_state {
index 0d1c05984298732425a39e6d0abd1ba07caecb0e..530b2d744ac684a73f5f9ca9142f8036c53ef8bc 100644 (file)
@@ -2313,7 +2313,7 @@ bgp_create_ip_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
 
   int lr, la;
 
-  la = bgp_encode_attrs(s, buck->attrs, buf+4, buf + MAX_ATTRS_LENGTH);
+  la = bgp_encode_attrs(s, buck->eattrs, buf+4, buf + MAX_ATTRS_LENGTH);
   if (la < 0)
   {
     /* Attribute list too long */
@@ -2362,7 +2362,7 @@ bgp_create_mp_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
 
   /* Encode attributes to temporary buffer */
   byte *abuf = alloca(MAX_ATTRS_LENGTH);
-  la = bgp_encode_attrs(s, buck->attrs, abuf, abuf + MAX_ATTRS_LENGTH);
+  la = bgp_encode_attrs(s, buck->eattrs, abuf, abuf + MAX_ATTRS_LENGTH);
   if (la < 0)
   {
     /* Attribute list too long */