]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
All linpools use pages to allocate regular blocks
authorMaria Matejka <mq@ucw.cz>
Mon, 4 Apr 2022 20:34:14 +0000 (22:34 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 6 Apr 2022 16:14:08 +0000 (18:14 +0200)
lib/mempool.c
lib/resource.h
nest/rt-table.c
proto/mrt/mrt.c
proto/ospf/ospf.c
proto/static/static.c

index c75f1f5b11e5ee77655205af68b5df86d4b01d3e..325b1ecfccba14f130ee18e79f0176bd8aeadeb0 100644 (file)
 
 struct lp_chunk {
   struct lp_chunk *next;
-  uint size;
   uintptr_t data_align[0];
   byte data[0];
 };
 
-const int lp_chunk_size = sizeof(struct lp_chunk);
+#define LP_DATA_SIZE   (page_size - OFFSETOF(struct lp_chunk, data))
 
 struct linpool {
   resource r;
   byte *ptr, *end;
   struct lp_chunk *first, *current;            /* Normal (reusable) chunks */
   struct lp_chunk *first_large;                        /* Large chunks */
-  uint chunk_size, threshold, total:31, use_pages:1, total_large;
+  uint total, total_large;
 };
 
 _Thread_local linpool *tmp_linpool;
@@ -61,25 +60,14 @@ static struct resclass lp_class = {
 /**
  * lp_new - create a new linear memory pool
  * @p: pool
- * @blk: block size
  *
  * lp_new() creates a new linear memory pool resource inside the pool @p.
- * The linear pool consists of a list of memory chunks of size at least
- * @blk.
+ * The linear pool consists of a list of memory chunks of page size.
  */
 linpool
-*lp_new(pool *p, uint blk)
+*lp_new(pool *p)
 {
-  linpool *m = ralloc(p, &lp_class);
-  if (!blk)
-  {
-    m->use_pages = 1;
-    blk = page_size - lp_chunk_size;
-  }
-
-  m->chunk_size = blk;
-  m->threshold = 3*blk/4;
-  return m;
+  return ralloc(p, &lp_class);
 }
 
 /**
@@ -110,14 +98,13 @@ lp_alloc(linpool *m, uint size)
   else
     {
       struct lp_chunk *c;
-      if (size >= m->threshold)
+      if (size > LP_DATA_SIZE)
        {
          /* Too large => allocate large chunk */
          c = xmalloc(sizeof(struct lp_chunk) + size);
          m->total_large += size;
          c->next = m->first_large;
          m->first_large = c;
-         c->size = size;
        }
       else
        {
@@ -129,14 +116,10 @@ lp_alloc(linpool *m, uint size)
          else
            {
              /* Need to allocate a new chunk */
-             if (m->use_pages)
-               c = alloc_page();
-             else
-               c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size);
+             c = alloc_page();
 
-             m->total += m->chunk_size;
+             m->total += LP_DATA_SIZE;
              c->next = NULL;
-             c->size = m->chunk_size;
 
              if (m->current)
                m->current->next = c;
@@ -145,7 +128,7 @@ lp_alloc(linpool *m, uint size)
            }
          m->current = c;
          m->ptr = c->data + size;
-         m->end = c->data + m->chunk_size;
+         m->end = c->data + LP_DATA_SIZE;
        }
       return c->data;
     }
@@ -207,7 +190,7 @@ lp_flush(linpool *m)
   /* Move ptr to the first chunk and free all large chunks */
   m->current = c = m->first;
   m->ptr = c ? c->data : NULL;
-  m->end = c ? c->data + m->chunk_size : NULL;
+  m->end = c ? c->data + LP_DATA_SIZE : NULL;
 
   while (c = m->first_large)
     {
@@ -230,6 +213,7 @@ lp_save(linpool *m, lp_state *p)
 {
   p->current = m->current;
   p->large = m->first_large;
+  p->total_large = m->total_large;
   p->ptr = m->ptr;
 }
 
@@ -251,12 +235,12 @@ lp_restore(linpool *m, lp_state *p)
   /* Move ptr to the saved pos and free all newer large chunks */
   m->current = c = p->current;
   m->ptr = p->ptr;
-  m->end = c ? c->data + m->chunk_size : NULL;
+  m->end = c ? c->data + LP_DATA_SIZE : NULL;
+  m->total_large = p->total_large;
 
   while ((c = m->first_large) && (c != p->large))
     {
       m->first_large = c->next;
-      m->total_large -= c->size;
       xfree(c);
     }
 }
@@ -270,10 +254,7 @@ lp_free(resource *r)
   for(d=m->first; d; d = c)
     {
       c = d->next;
-      if (m->use_pages)
-       free_page(d);
-      else
-       xfree(d);
+      free_page(d);
     }
   for(d=m->first_large; d; d = c)
     {
@@ -293,9 +274,7 @@ lp_dump(resource *r)
     ;
   for(cntl=0, c=m->first_large; c; c=c->next, cntl++)
     ;
-  debug("(chunk=%d threshold=%d count=%d+%d total=%d+%d)\n",
-       m->chunk_size,
-       m->threshold,
+  debug("(count=%d+%d total=%d+%d)\n",
        cnt,
        cntl,
        m->total,
@@ -308,20 +287,18 @@ lp_memsize(resource *r)
   linpool *m = (linpool *) r;
   struct resmem sz = {
     .overhead = sizeof(struct linpool) + ALLOC_OVERHEAD,
+    .effective = m->total_large,
   };
 
   for (struct lp_chunk *c = m->first_large; c; c = c->next)
-  {
-    sz.effective += c->size;
-    sz.overhead += lp_chunk_size + ALLOC_OVERHEAD;
-  }
+    sz.overhead += sizeof(struct lp_chunk) + ALLOC_OVERHEAD;
 
   uint regular = 0;
   for (struct lp_chunk *c = m->first; c; c = c->next)
     regular++;
 
-  sz.effective += m->chunk_size * regular;
-  sz.overhead += (lp_chunk_size + ALLOC_OVERHEAD) * regular;
+  sz.effective += LP_DATA_SIZE * regular;
+  sz.overhead += (sizeof(struct lp_chunk) + ALLOC_OVERHEAD) * regular;
 
   return sz;
 }
@@ -334,10 +311,7 @@ lp_lookup(resource *r, unsigned long a)
   struct lp_chunk *c;
 
   for(c=m->first; c; c=c->next)
-    if ((unsigned long) c->data <= a && (unsigned long) c->data + c->size > a)
-      return r;
-  for(c=m->first_large; c; c=c->next)
-    if ((unsigned long) c->data <= a && (unsigned long) c->data + c->size > a)
+    if ((unsigned long) c->data <= a && (unsigned long) c->data + LP_DATA_SIZE > a)
       return r;
   return NULL;
 }
index 8b180603566b3eb9ffe83af9b9cc355d90f233e6..a4e110a5144d086b35380b7548a2dca6c6774949 100644 (file)
@@ -69,9 +69,10 @@ typedef struct linpool linpool;
 typedef struct lp_state {
   void *current, *large;
   byte *ptr;
+  uint total_large;
 } lp_state;
 
-linpool *lp_new(pool *, unsigned blk);
+linpool *lp_new(pool *);
 void *lp_alloc(linpool *, unsigned size);      /* Aligned */
 void *lp_allocu(linpool *, unsigned size);     /* Unaligned */
 void *lp_allocz(linpool *, unsigned size);     /* With clear */
@@ -88,10 +89,7 @@ extern _Thread_local linpool *tmp_linpool;   /* Temporary linpool autoflushed regu
 #define tmp_init(p)    tmp_linpool = lp_new_default(p)
 #define tmp_flush()    lp_flush(tmp_linpool)
 
-extern const int lp_chunk_size;
-#define LP_GAS             1024
-#define LP_GOOD_SIZE(x)            (((x + LP_GAS - 1) & (~(LP_GAS - 1))) - lp_chunk_size)
-#define lp_new_default(p)   lp_new(p, 0)
+#define lp_new_default lp_new
 
 /* Slabs */
 
index 1885e602bca1d73fbcd67a3c655da4955e28a35d..fbfdb1e6d3b8c77cf9691950a21399b4510e8f3e 100644 (file)
@@ -3410,7 +3410,7 @@ rt_init_hostcache(rtable *tab)
   hc_alloc_table(hc, tab->rp, HC_DEF_ORDER);
   hc->slab = sl_new(tab->rp, sizeof(struct hostentry));
 
-  hc->lp = lp_new(tab->rp, LP_GOOD_SIZE(1024));
+  hc->lp = lp_new(tab->rp);
   hc->trie = f_new_trie(hc->lp, 0);
 
   tab->hostcache = hc;
index 70b2aeff4eeffcfb5f35ef9415aa286cef29fc83..321c6395523b0059e8d1a65489bd415f736b73e8 100644 (file)
@@ -560,8 +560,8 @@ mrt_table_dump_init(pool *pp)
   struct mrt_table_dump_state *s = mb_allocz(pool, sizeof(struct mrt_table_dump_state));
 
   s->pool = pool;
-  s->linpool = lp_new(pool, 4080);
-  s->peer_lp = lp_new(pool, 4080);
+  s->linpool = lp_new(pool);
+  s->peer_lp = lp_new(pool);
   mrt_buffer_init(&s->buf, pool, 2 * MRT_ATTR_BUFFER_SIZE);
 
   /* We lock the current config as we may reference it indirectly by filter */
index 4ea539421800f78ad809c2b30e8b00c4539be787..d8bcc8383b72db0667fca0e78deb4b19a69330fc 100644 (file)
@@ -299,7 +299,7 @@ ospf_start(struct proto *P)
   p->lsab_size = 256;
   p->lsab_used = 0;
   p->lsab = mb_alloc(P->pool, p->lsab_size);
-  p->nhpool = lp_new(P->pool, 12*sizeof(struct nexthop));
+  p->nhpool = lp_new(P->pool);
   init_list(&(p->iface_list));
   init_list(&(p->area_list));
   fib_init(&p->rtf, P->pool, ospf_get_af(p), sizeof(ort), OFFSETOF(ort, fn), 0, NULL);
index cf2e458516b5e942a758859acc069dd305bc896d..cd31afd3aff9e68060c7ce4002b95e74e768031b 100644 (file)
@@ -486,7 +486,7 @@ static_start(struct proto *P)
   struct static_route *r;
 
   if (!static_lp)
-    static_lp = lp_new(&root_pool, LP_GOOD_SIZE(1024));
+    static_lp = lp_new(&root_pool);
 
   if (p->igp_table_ip4)
     rt_lock_table(p->igp_table_ip4);