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)
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
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;
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;
#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
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 {