Regionlist overhaul: Size accounting for regionlist

parent 263f15a5
...@@ -54,6 +54,7 @@ struct regl { ...@@ -54,6 +54,7 @@ struct regl {
struct regionlist { struct regionlist {
unsigned magic; unsigned magic;
#define REGIONLIST_MAGIC 0xeb869815 #define REGIONLIST_MAGIC 0xeb869815
size_t size;
VSTAILQ_HEAD(,regl) head; VSTAILQ_HEAD(,regl) head;
buddy_t *membuddy; buddy_t *membuddy;
}; };
...@@ -112,7 +113,7 @@ regl_alloc_bits(buddy_t *membuddy, const uint8_t bits, int8_t cram, ...@@ -112,7 +113,7 @@ regl_alloc_bits(buddy_t *membuddy, const uint8_t bits, int8_t cram,
int8_t c; int8_t c;
size_t sz, b; size_t sz, b;
sz = 2 * sizeof *r; sz = 2 * sizeof *r + sizeof *rl;
b = log2up(sz); b = log2up(sz);
assert(bits >= b); assert(bits >= b);
...@@ -201,7 +202,7 @@ regionlist_append(struct regionlist *to, struct regionlist **fromp) ...@@ -201,7 +202,7 @@ regionlist_append(struct regionlist *to, struct regionlist **fromp)
CHECK_OBJ_NOTNULL(to, REGIONLIST_MAGIC); CHECK_OBJ_NOTNULL(to, REGIONLIST_MAGIC);
TAKE_OBJ_NOTNULL(from, fromp, REGIONLIST_MAGIC); TAKE_OBJ_NOTNULL(from, fromp, REGIONLIST_MAGIC);
to->size += from->size;
VSTAILQ_CONCAT(&to->head, &from->head); VSTAILQ_CONCAT(&to->head, &from->head);
} }
...@@ -222,7 +223,8 @@ regionlist_add(struct regionlist *rl, ...@@ -222,7 +223,8 @@ regionlist_add(struct regionlist *rl,
const struct buddy_off_extent *regs, unsigned n) const struct buddy_off_extent *regs, unsigned n)
{ {
struct regl *regl; struct regl *regl;
uint16_t av, nn; uint16_t i, nn;
size_t size;
CHECK_OBJ_NOTNULL(rl, REGIONLIST_MAGIC); CHECK_OBJ_NOTNULL(rl, REGIONLIST_MAGIC);
regl = VSTAILQ_LAST(&rl->head, regl, list); regl = VSTAILQ_LAST(&rl->head, regl, list);
...@@ -235,14 +237,18 @@ regionlist_add(struct regionlist *rl, ...@@ -235,14 +237,18 @@ regionlist_add(struct regionlist *rl,
CHECK_OBJ_NOTNULL(regl, REGL_MAGIC); CHECK_OBJ_NOTNULL(regl, REGL_MAGIC);
assert(regl->space > regl->n); assert(regl->space > regl->n);
av = regl->space - regl->n; i = regl->space - regl->n;
if (av < n) if (i < n)
nn = av; nn = i;
else else
nn = (typeof(nn))n; nn = (typeof(nn))n;
memcpy(&regl->arr[regl->n], regs, nn * sizeof *regs); memcpy(&regl->arr[regl->n], regs, nn * sizeof *regs);
size = 0;
for (i = 0; i < nn; i++)
size += regs[i].size;
rl->size += size;
regl->n += nn; regl->n += nn;
regs += nn; regs += nn;
n -= nn; n -= nn;
...@@ -255,21 +261,29 @@ regionlist_free(struct regionlist **rlp, buddy_t *dskbuddy) ...@@ -255,21 +261,29 @@ regionlist_free(struct regionlist **rlp, buddy_t *dskbuddy)
struct buddy_returns *dskret, *memret; struct buddy_returns *dskret, *memret;
struct regionlist *rl; struct regionlist *rl;
struct regl *regl, *save; struct regl *regl, *save;
size_t size, tot;
unsigned n; unsigned n;
TAKE_OBJ_NOTNULL(rl, rlp, REGIONLIST_MAGIC); TAKE_OBJ_NOTNULL(rl, rlp, REGIONLIST_MAGIC);
dskret = BUDDY_RETURNS_STK(dskbuddy, BUDDY_RETURNS_MAX); dskret = BUDDY_RETURNS_STK(dskbuddy, BUDDY_RETURNS_MAX);
memret = BUDDY_RETURNS_STK(rl->membuddy, BUDDY_RETURNS_MAX); memret = BUDDY_RETURNS_STK(rl->membuddy, BUDDY_RETURNS_MAX);
tot = rl->size;
VSTAILQ_FOREACH_SAFE(regl, &rl->head, list, save) { VSTAILQ_FOREACH_SAFE(regl, &rl->head, list, save) {
CHECK_OBJ_NOTNULL(regl, REGL_MAGIC); CHECK_OBJ_NOTNULL(regl, REGL_MAGIC);
for (n = 0; n < regl->n; n++) size = 0;
for (n = 0; n < regl->n; n++) {
size += regl->arr[n].size;
AN(buddy_return_off_extent(dskret, &regl->arr[n])); AN(buddy_return_off_extent(dskret, &regl->arr[n]));
}
assert(tot >= size);
tot -= size;
AN(buddy_return_ptr_page(memret, &regl->alloc)); AN(buddy_return_ptr_page(memret, &regl->alloc));
} }
AZ(tot);
buddy_return(dskret); buddy_return(dskret);
buddy_return(memret); buddy_return(memret);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment