]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Export uses common attribute cache
authorMaria Matejka <mq@ucw.cz>
Wed, 29 May 2024 06:18:31 +0000 (08:18 +0200)
committerMaria Matejka <mq@ucw.cz>
Tue, 4 Jun 2024 08:11:36 +0000 (10:11 +0200)
There is no real need for storing bucket attributes locally and we may
save some memory by caching the attributes in one central place.

If this becomes a contention problem, we should reduce the lock load
of the central attribute cache.

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

index 2b9f47178010809fcddbf32a1e217526fa8edbc6..58c76d5934d35ba045c21c09ffbc3e223b04410b 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->eattrs, b->hash
+#define RBH_KEY(b)             b->attrs
 #define RBH_NEXT(b)            b->next
-#define RBH_EQ(a1,h1,a2,h2)    h1 == h2 && ea_same(a1, a2)
-#define RBH_FN(a,h)            h
+#define RBH_EQ(a1,a2)          a1 == a2
+#define RBH_FN(a)              ea_get_storage(a)->hash_key
 
 #define RBH_REHASH             bgp_rbh_rehash
 #define RBH_PARAMS             /8, *2, 2, 2, 12, 20
@@ -1589,6 +1589,7 @@ static void
 bgp_init_bucket_table(struct bgp_channel *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;
@@ -1598,24 +1599,21 @@ static struct bgp_bucket *
 bgp_get_bucket(struct bgp_channel *c, ea_list *new)
 {
   /* Hash and lookup */
-  u32 hash = ea_hash(new);
-  struct bgp_bucket *b = HASH_FIND(c->bucket_hash, RBH, new, hash);
+  ea_list *ns = ea_lookup(new, 0, EALS_CUSTOM);
+  struct bgp_bucket *b = HASH_FIND(c->bucket_hash, RBH, ns);
 
   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 = mb_alloc(c->pool, size);
-  *b = (struct bgp_bucket) { };
+  b = sl_alloc(c->bucket_slab);
+  *b = (struct bgp_bucket) {
+    .attrs = ns,
+  };
   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);
@@ -1639,7 +1637,8 @@ static void
 bgp_free_bucket(struct bgp_channel *c, struct bgp_bucket *b)
 {
   HASH_REMOVE2(c->bucket_hash, RBH, c->pool, b);
-  mb_free(b);
+  ea_free(b->attrs);
+  sl_free(b);
 }
 
 int
index 9f0402f9b4284849920d2620217dd4d3abbe3e4a..74097cb87721faf9d66145db1a700f092638b307 100644 (file)
@@ -401,6 +401,7 @@ struct bgp_channel {
 
   HASH(struct bgp_prefix) prefix_hash; /* Prefixes to be sent */
   slab *prefix_slab;                   /* Slab holding prefix nodes */
+  slab *bucket_slab;                   /* Slab holding buckets to send */
 //  struct rt_exporter prefix_exporter;        /* Table-like exporter for ptx */
 
   ip_addr next_hop_addr;               /* Local address for NEXT_HOP attribute */
@@ -442,10 +443,9 @@ 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) */
-  u32 hash;                            /* Hash over extended attributes */
+  ea_list *attrs;                      /* Attributes to encode */
   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 78962c6251bba6c0142bd790398f89b3bb34aee9..31145ab9a90d1bf7afef8771d9cecd9615faf060 100644 (file)
@@ -2310,7 +2310,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->eattrs, buf+4, buf + MAX_ATTRS_LENGTH);
+  la = bgp_encode_attrs(s, buck->attrs, buf+4, buf + MAX_ATTRS_LENGTH);
   if (la < 0)
   {
     /* Attribute list too long */
@@ -2359,7 +2359,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->eattrs, abuf, abuf + MAX_ATTRS_LENGTH);
+  la = bgp_encode_attrs(s, buck->attrs, abuf, abuf + MAX_ATTRS_LENGTH);
   if (la < 0)
   {
     /* Attribute list too long */