diff --git a/lib/lockfree.c b/lib/lockfree.c index c68899d3..adfca04e 100644 --- a/lib/lockfree.c +++ b/lib/lockfree.c @@ -604,3 +604,45 @@ lfjour_init(struct lfjour *j, struct settle_config *scf) }; j->max_tokens = 20; } + +void +lfjour_dump(struct dump_request *dreq, struct lfjour *j) +{ + RDUMP("item_size=%u, item_count=%u\n", j->item_size, j->item_count); + + struct lfjour_item *first = atomic_load_explicit(&j->first, memory_order_relaxed); + RDUMP("first=%p", first); + if (first) + RDUMP(" (seq %lu)", first->seq); + RDUMP(", next_seq=%lu", j->next_seq); + + RDUMP("max_tokens=%lu, issued_tokens=%lu", + j->max_tokens, atomic_load_explicit(&j->issued_tokens, memory_order_relaxed)); + + RDUMP("Blocks:\n"); + dreq->indent += 3; + WALK_TLIST(lfjour_block, block, &j->pending) + RDUMP("%p: end=%u, not_last=%u\n", block, + atomic_load_explicit(&block->end, memory_order_relaxed), + atomic_load_explicit(&block->not_last, memory_order_relaxed) + ); + dreq->indent -= 3; +} + +struct resmem lfjour_memsize(struct lfjour *j) +{ + u64 blocks = 0; + WALK_TLIST(lfjour_block, block, &j->pending) + blocks++; + + struct lfjour_item *first = atomic_load_explicit(&j->first, memory_order_relaxed); + + if (!first) + return (struct resmem) { .overhead = blocks * page_size, }; + + struct resmem out; + out.effective = (j->next_seq - first->seq) * j->item_size; + out.overhead = blocks * page_size - out.effective; + + return out; +} diff --git a/lib/lockfree.h b/lib/lockfree.h index 8dc8f82d..9df96671 100644 --- a/lib/lockfree.h +++ b/lib/lockfree.h @@ -277,7 +277,8 @@ static inline uint lfjour_count_recipients(struct lfjour *j) { return TLIST_LENGTH(lfjour_recipient, &j->recipients); } void lfjour_init(struct lfjour *, struct settle_config *); - +void lfjour_dump(struct dump_request *, struct lfjour *); +struct resmem lfjour_memsize(struct lfjour *); static inline struct lfjour *lfjour_of_recipient(struct lfjour_recipient *r) { diff --git a/nest/route.h b/nest/route.h index e512dc36..fd46b042 100644 --- a/nest/route.h +++ b/nest/route.h @@ -164,11 +164,6 @@ struct rt_export_request { struct rt_feeding_request *next; /* Next in request chain */ void (*done)(struct rt_feeding_request *);/* Called when this refeed finishes */ struct rt_prefilter prefilter; /* Reload only matching nets */ - PACKED enum { - RFRS_INACTIVE = 0, /* Inactive request */ - RFRS_PENDING, /* Request enqueued, do not touch */ - RFRS_RUNNING, /* Request active, do not touch */ - } state; } *feeding, *feed_pending; TLIST_DEFAULT_NODE; u8 trace_routes; @@ -239,6 +234,10 @@ struct rt_export_item *rt_exporter_push(struct rt_exporter *, const struct rt_ex struct rt_export_feed *rt_alloc_feed(uint routes, uint exports); void rt_exporter_shutdown(struct rt_exporter *, void (*stopped)(struct rt_exporter *)); +void rt_exporter_dump(struct dump_request *, struct rt_exporter *); +static inline struct resmem rt_exporter_memsize(struct rt_exporter *e) +{ return lfjour_memsize(&e->journal); } + /* Standalone feeds */ void rt_feeder_subscribe(struct rt_exporter *, struct rt_export_feeder *); void rt_feeder_unsubscribe(struct rt_export_feeder *); diff --git a/nest/rt-export.c b/nest/rt-export.c index a1d17a39..7368447d 100644 --- a/nest/rt-export.c +++ b/nest/rt-export.c @@ -573,3 +573,20 @@ rt_exporter_shutdown(struct rt_exporter *e, void (*stopped)(struct rt_exporter * // e->stopped = stopped; bug("not implemented yet"); } + +void +rt_exporter_dump(struct dump_request *dreq, struct rt_exporter *e) +{ + RDUMP("Feeders (max_feed_index=%u):\n", + atomic_load_explicit(&e->max_feed_index, memory_order_relaxed)); + dreq->indent += 3; + WALK_TLIST(rt_export_feeder, f, &e->feeders) + RDUMP("%p (%s), index %u\n", + f, f->name, f->feed_index); + dreq->indent -= 3; + + RDUMP("Journal:\n"); + dreq->indent += 3; + lfjour_dump(dreq, &e->journal); + dreq->indent -= 3; +} diff --git a/nest/rt-table.c b/nest/rt-table.c index 295296bf..fd8bb50d 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -3243,15 +3243,28 @@ rt_res_dump(struct dump_request *dreq, resource *_r) RDUMP("name \"%s\", addr_type=%s, rt_count=%u, use_count=%d\n", r->name, net_label[r->addr_type], r->rt_count, r->use_count); -#if 0 - /* TODO: rethink this completely */ - /* TODO: move this to lfjour */ - char x[32]; - bsprintf(x, "%%%dspending export %%p\n", indent + 2); + RDUMP("Exporter ALL:\n"); + dreq->indent += 3; + rt_exporter_dump(dreq, &r->export_all); + dreq->indent -= 3; + RDUMP("Exporter BEST:\n"); + dreq->indent += 3; + rt_exporter_dump(dreq, &r->export_best); + dreq->indent -= 3; +} - WALK_TLIST(lfjour_block, n, &r->journal.pending) - debug(x, "", n); -#endif +static struct resmem +rt_res_memsize(resource *_r) +{ + SKIP_BACK_DECLARE(struct rtable_private, r, r, _r); + + struct resmem amem = rt_exporter_memsize(&r->export_all); + struct resmem bmem = rt_exporter_memsize(&r->export_best); + + return (struct resmem) { + .effective = amem.effective + bmem.effective, + .overhead = amem.overhead + bmem.overhead, + }; } static struct resclass rt_class = { @@ -3260,7 +3273,7 @@ static struct resclass rt_class = { .free = rt_free, .dump = rt_res_dump, .lookup = NULL, - .memsize = NULL, + .memsize = rt_res_memsize, }; static struct idm rtable_idm;