Support camming of segment memory allocation

adjust dsk size if mem allocation was smaller than requested
parent d1d23704
......@@ -2039,6 +2039,39 @@ fellow_busy_body_seg_alloc(struct fellow_busy *fbo,
return (want);
}
// adjust fds size to fcs size
static void
fellow_busy_body_seg_adjust(struct fellow_busy *fbo,
const struct fellow_cache_seg *fcs)
{
struct fellow_body_region *fbr;
struct buddy_off_extent *fdr;
struct fellow_disk_seg *fds;
size_t surplus;
CHECK_OBJ_NOTNULL(fbo, FELLOW_BUSY_MAGIC);
CHECK_OBJ_NOTNULL(fcs, FELLOW_CACHE_SEG_MAGIC);
fds = fcs->disk_seg;
CHECK_OBJ_NOTNULL(fds, FELLOW_DISK_SEG_MAGIC);
if (fcs->alloc.size == fds->seg.size)
return;
AN(fds->seg.off);
AN(fds->seg.size);
assert(fds->seg.size > fcs->alloc.size);
surplus = fds->seg.size - fcs->alloc.size;
assert((surplus & FELLOW_BLOCK_ALIGN) == 0);
fbr = &fbo->body_region;
fdr = fbr->reg;
AN(fdr);
assert(fbr->len >= surplus);
fbr->len -= surplus;
}
/* return an fds to the body seg (for failed memalloc) */
static void
fellow_busy_body_seg_return(struct fellow_busy *fbo,
......@@ -3432,7 +3465,7 @@ fellow_busy_body_seg_next(struct fellow_busy *fbo)
* used for body and auxattr
*/
static size_t fellow_busy_seg_memalloc(buddy_t *membuddy,
struct fellow_cache_seg *fcs)
struct fellow_cache_seg *fcs, int8_t cram)
{
struct fellow_disk_seg *fds;
......@@ -3448,15 +3481,19 @@ static size_t fellow_busy_seg_memalloc(buddy_t *membuddy,
AZ(fcs->alloc.size);
fcs->alloc = buddy_alloc1_ptr_extent_wait(membuddy, FEP_SPC,
fds->seg.size, 0);
fds->seg.size, cram);
if (fcs->alloc.ptr == NULL)
return (0);
// cram needs to be chosen correctly
assert(fcs->alloc.size >= MIN_FELLOW_BLOCK);
assert((fcs->alloc.size & FELLOW_BLOCK_ALIGN) == 0);
// membuddy min < dskbuddy min
assert(fcs->alloc.size <= fds->seg.size);
memset(fcs->alloc.ptr, 0, fcs->alloc.size);
// membuddy min < dskbuddy min
assert(fds->seg.size == fcs->alloc.size);
AZ(fcs->refcnt);
fcs->refcnt = 1;
fellow_cache_seg_transition_locked_notincore(fcs, FCS_BUSY);
......@@ -3489,7 +3526,7 @@ fellow_busy_seg_alloc(struct fellow_busy *fbo,
if (fdr == NULL)
return (0);
fds->seg = *fdr;
if (fellow_busy_seg_memalloc(fbo->fc->membuddy, fcs) == 0)
if (fellow_busy_seg_memalloc(fbo->fc->membuddy, fcs, 0) == 0)
// we do not need to free because we use the busy region
return (0);
return (1);
......@@ -3577,12 +3614,16 @@ fellow_busy_obj_getspace(struct fellow_busy *fbo, size_t *sz, uint8_t **ptr)
goto out;
}
spc = fellow_busy_seg_memalloc(fbo->fc->membuddy, fcs);
spc = fellow_busy_seg_memalloc(fbo->fc->membuddy, fcs,
buddy_cramlimit_bits(spc, fbo->fc->tune->cram, MIN_FELLOW_BITS));
if (spc == 0) {
fellow_busy_body_seg_return(fbo, fcs->disk_seg);
fcr = FCR_ALLOCFAIL("body memory seg alloc");
goto out;
}
// reduce fds size if fcs alloc crammed
fellow_busy_body_seg_adjust(fbo, fcs);
assert(fcs->state == FCS_BUSY);
fbo->body_seglist->fdsl->nsegs++;
assert(fbo->body_seglist->fdsl->nsegs <= fbo->body_seglist->lsegs);
......
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