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, ...@@ -2039,6 +2039,39 @@ fellow_busy_body_seg_alloc(struct fellow_busy *fbo,
return (want); 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) */ /* return an fds to the body seg (for failed memalloc) */
static void static void
fellow_busy_body_seg_return(struct fellow_busy *fbo, fellow_busy_body_seg_return(struct fellow_busy *fbo,
...@@ -3432,7 +3465,7 @@ fellow_busy_body_seg_next(struct fellow_busy *fbo) ...@@ -3432,7 +3465,7 @@ fellow_busy_body_seg_next(struct fellow_busy *fbo)
* used for body and auxattr * used for body and auxattr
*/ */
static size_t fellow_busy_seg_memalloc(buddy_t *membuddy, 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; struct fellow_disk_seg *fds;
...@@ -3448,15 +3481,19 @@ static size_t fellow_busy_seg_memalloc(buddy_t *membuddy, ...@@ -3448,15 +3481,19 @@ static size_t fellow_busy_seg_memalloc(buddy_t *membuddy,
AZ(fcs->alloc.size); AZ(fcs->alloc.size);
fcs->alloc = buddy_alloc1_ptr_extent_wait(membuddy, FEP_SPC, fcs->alloc = buddy_alloc1_ptr_extent_wait(membuddy, FEP_SPC,
fds->seg.size, 0); fds->seg.size, cram);
if (fcs->alloc.ptr == NULL) if (fcs->alloc.ptr == NULL)
return (0); 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); memset(fcs->alloc.ptr, 0, fcs->alloc.size);
// membuddy min < dskbuddy min
assert(fds->seg.size == fcs->alloc.size);
AZ(fcs->refcnt); AZ(fcs->refcnt);
fcs->refcnt = 1; fcs->refcnt = 1;
fellow_cache_seg_transition_locked_notincore(fcs, FCS_BUSY); fellow_cache_seg_transition_locked_notincore(fcs, FCS_BUSY);
...@@ -3489,7 +3526,7 @@ fellow_busy_seg_alloc(struct fellow_busy *fbo, ...@@ -3489,7 +3526,7 @@ fellow_busy_seg_alloc(struct fellow_busy *fbo,
if (fdr == NULL) if (fdr == NULL)
return (0); return (0);
fds->seg = *fdr; 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 // we do not need to free because we use the busy region
return (0); return (0);
return (1); return (1);
...@@ -3577,12 +3614,16 @@ fellow_busy_obj_getspace(struct fellow_busy *fbo, size_t *sz, uint8_t **ptr) ...@@ -3577,12 +3614,16 @@ fellow_busy_obj_getspace(struct fellow_busy *fbo, size_t *sz, uint8_t **ptr)
goto out; 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) { if (spc == 0) {
fellow_busy_body_seg_return(fbo, fcs->disk_seg); fellow_busy_body_seg_return(fbo, fcs->disk_seg);
fcr = FCR_ALLOCFAIL("body memory seg alloc"); fcr = FCR_ALLOCFAIL("body memory seg alloc");
goto out; goto out;
} }
// reduce fds size if fcs alloc crammed
fellow_busy_body_seg_adjust(fbo, fcs);
assert(fcs->state == FCS_BUSY); assert(fcs->state == FCS_BUSY);
fbo->body_seglist->fdsl->nsegs++; fbo->body_seglist->fdsl->nsegs++;
assert(fbo->body_seglist->fdsl->nsegs <= fbo->body_seglist->lsegs); 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