summaryrefslogtreecommitdiff
path: root/net/bird3/files/patch-06-cli-allocate-tx-buffers
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--net/bird3/files/patch-06-cli-allocate-tx-buffers134
1 files changed, 134 insertions, 0 deletions
diff --git a/net/bird3/files/patch-06-cli-allocate-tx-buffers b/net/bird3/files/patch-06-cli-allocate-tx-buffers
new file mode 100644
index 000000000000..0e9af5de5d63
--- /dev/null
+++ b/net/bird3/files/patch-06-cli-allocate-tx-buffers
@@ -0,0 +1,134 @@
+From de9dbee796876f5b621e40e0082612aad746cac1 Mon Sep 17 00:00:00 2001
+From: Maria Matejka <mq@ucw.cz>
+Date: Sun, 22 Dec 2024 22:10:38 +0100
+Subject: [PATCH] CLI: allocate TX buffers as pages, not by malloc
+
+Every malloc risks heap bloating and these blocks are already
+the same size as pages.
+---
+ nest/cli.c | 59 ++++++++++++++++++++++++++++++++++++++++++------------
+ nest/cli.h | 2 +-
+ 2 files changed, 47 insertions(+), 14 deletions(-)
+
+diff --git a/nest/cli.c b/nest/cli.c
+index 3b8e6f468..b33ffd437 100644
+--- nest/cli.c
++++ nest/cli.c
+@@ -81,13 +81,14 @@ cli_alloc_out(cli *c, int size)
+ o = c->tx_buf;
+ else
+ {
+- o = mb_alloc(c->pool, sizeof(struct cli_out) + CLI_TX_BUF_SIZE);
++ o = alloc_page();
++ c->tx_pending_count++;
+ if (c->tx_write)
+ c->tx_write->next = o;
+ else
+ c->tx_buf = o;
+ o->wpos = o->outpos = o->buf;
+- o->end = o->buf + CLI_TX_BUF_SIZE;
++ o->end = (void *) o + page_size;
+ }
+ c->tx_write = o;
+ if (!c->tx_pos)
+@@ -167,19 +168,18 @@ cli_hello(cli *c)
+ static void
+ cli_free_out(cli *c)
+ {
+- struct cli_out *o, *p;
++ for (struct cli_out *o = c->tx_buf, *n; o; o = n)
++ {
++ n = o->next;
++ free_page(o);
++ c->tx_pending_count--;
++ }
+
+- if (o = c->tx_buf)
+- {
+- o->wpos = o->outpos = o->buf;
+- while (p = o->next)
+- {
+- o->next = p->next;
+- mb_free(p);
+- }
+- }
++ c->tx_buf = NULL;
+ c->tx_write = c->tx_pos = NULL;
+ c->async_msg_size = 0;
++
++ ASSERT_DIE(c->tx_pending_count == 0);
+ }
+
+ void
+@@ -189,6 +189,38 @@ cli_written(cli *c)
+ ev_schedule(c->event);
+ }
+
++/* A dummy resource to show and free memory pages allocated for pending TX */
++struct cli_tx_resource {
++ resource r;
++ struct cli *c;
++};
++
++static void
++cli_tx_resource_free(resource *r)
++{
++ cli_free_out(SKIP_BACK(struct cli_tx_resource, r, r)->c);
++}
++
++static void
++cli_tx_resource_dump(struct dump_request *dreq UNUSED, resource *r UNUSED) {}
++
++static struct resmem
++cli_tx_resource_memsize(resource *r)
++{
++ return (struct resmem) {
++ .effective = SKIP_BACK(struct cli_tx_resource, r, r)->c->tx_pending_count * page_size,
++ .overhead = sizeof(struct cli_tx_resource),
++ };
++}
++
++static struct resclass cli_tx_resource_class = {
++ .name = "CLI TX buffers",
++ .size = sizeof (struct cli_tx_resource),
++ .free = cli_tx_resource_free,
++ .dump = cli_tx_resource_dump,
++ .memsize = cli_tx_resource_memsize,
++};
++
+
+ static byte *cli_rh_pos;
+ static uint cli_rh_len;
+@@ -272,7 +304,8 @@ cli *
+ cli_new(struct birdsock *sock, struct cli_config *cf)
+ {
+ pool *p = rp_new(cli_pool, the_bird_domain.the_bird, "CLI");
+- cli *c = mb_alloc(p, sizeof(cli));
++ struct cli_tx_resource *ctr = ralloc(p, &cli_tx_resource_class);
++ cli *c = ctr->c = mb_alloc(p, sizeof(cli));
+
+ bzero(c, sizeof(cli));
+ c->pool = p;
+diff --git a/nest/cli.h b/nest/cli.h
+index d86ec3801..671be04d8 100644
+--- nest/cli.h
++++ nest/cli.h
+@@ -17,7 +17,6 @@
+ #include "conf/conf.h"
+
+ #define CLI_RX_BUF_SIZE 4096
+-#define CLI_TX_BUF_SIZE 4096
+ #define CLI_MAX_ASYNC_QUEUE 4096
+
+ #define CLI_MSG_SIZE 500
+@@ -49,6 +48,7 @@ typedef struct cli {
+ uint log_mask; /* Mask of allowed message levels */
+ uint log_threshold; /* When free < log_threshold, store only important messages */
+ uint async_msg_size; /* Total size of async messages queued in tx_buf */
++ uint tx_pending_count; /* How many blocks are pending */
+ } cli;
+
+ struct cli_config {
+--
+GitLab
+