fellow_log: Extend memsz check to shared memory cache

Each fellow storage reserves a minimum amount of memory.

Closes #51
parent 4144fd97
......@@ -1385,6 +1385,8 @@ BUDDYF(init_)(unsigned witness, buddy_t *buddy, unsigned min, size_t size,
for (u = 0; u <= BUDDY_WAIT_MAXPRI; u++)
VTAILQ_INIT(&buddy->reqs_head[u]);
buddy->rsv_avail = size;
}
void
......
......@@ -62,6 +62,8 @@ struct BUDDY {
pthread_mutex_t minfo_mtx;
struct buddy_minfo_head minfo_head;
size_t rsv_avail;
// under map_mtx
size_t deficit;
unsigned waiting;
......@@ -161,6 +163,17 @@ BUDDYF(rndup)(const buddy_t *buddy, size_t sz)
return (rup_min(sz, map->min));
}
static inline size_t
BUDDYF(reserve)(buddy_t *buddy, size_t sz)
{
CHECK_OBJ_NOTNULL(buddy, BUDDY_MAGIC);
if (sz > buddy->rsv_avail)
sz = buddy->rsv_avail;
buddy->rsv_avail -= sz;
return (sz);
}
/* shall be defined as the larger of intptr_t and off_t */
typedef off_t buddyoff_t;
......
......@@ -6362,7 +6362,7 @@ fellow_log_init(const char *path, size_t wantsize, size_t objsz_hint,
struct stat st;
unsigned i;
unsigned entries;
size_t sz;
size_t sz, got;
int32_t ssz;
uint64_t objsize = 0;
char last_err[256] = "";
......@@ -6523,19 +6523,25 @@ fellow_log_init(const char *path, size_t wantsize, size_t objsz_hint,
path, ffd->active_hdr, ffd->log_info.generation);
}
if (objsize > MIN_FELLOW_BLOCK)
sz = MEMBUDDY_MINSIZE(wantsize, objsize);
else
sz = 0;
if (objsize < MIN_FELLOW_BLOCK)
objsize = objsz_hint;
sz = MEMBUDDY_MINSIZE(wantsize, objsize);
if (buddy_size(membuddy) < sz) {
ffd->diag("\nfellow:\tFATAL: memsz too small for "
"actual objsize %zu < objsize_hint %zu!\n"
"fellow:\tlower objsize_hint to %s or "
"increase memsz to %s and restart.\n",
(size_t)objsize, objsz_hint,
pow2_unit(log2down(objsize)),
pow2_unit(log2up(sz)));
if ((got = buddy_reserve(membuddy, sz)) < sz) {
ffd->diag("\nfellow:\tFATAL:\tfailed reserve of "
"minimum memory size %zu.\n", sz);
if (objsize < objsz_hint) {
ffd->diag("fellow:\t\tactual objsize %zu "
"< objsize_hint %zu.\n",
(size_t)objsize, objsz_hint);
ffd->diag("fellow:\t\tlower objsize_hint to %s or ",
pow2_unit(log2down(objsize)));
}
else
ffd->diag("fellow:\t\t");
ffd->diag("increase memsz by %s and restart.\n",
pow2_unit(log2up(sz - got)));
goto err_close;
}
......
......@@ -222,9 +222,9 @@ argument.
Memory Cache Sharing
~~~~~~~~~~~~~~~~~~~~
When memory cache sharing with the ``<memsize>[=<storage>]``
syntax is configured, *<memsize>* is used for sanity checking
only. The actual memory size is always that of the referenced storage.
When memory cache sharing with the ``<memsize>[=<storage>]`` syntax is
configured, *<memsize>* is ignored. The actual memory size is always
that of the referenced storage.
LRU with memory cache sharing is cooperative. Whenever memory is
needed by any storage, all storages using the shared cache are asked
......@@ -417,10 +417,16 @@ actual figures are output at startup as ``fellow: metadata (bitmap)
memory``.
*objsize_hint* (default 256KB) is used to sanity check *memsize* in
relation to *dsksize*. It should be set to a value lower than the
average object size (actual or expected). If *memsize* is configured
too low with respect to *dsksize* and *objsize_hint*, a higher value
will be used (which might fail of insufficient memory is available).
relation to *dsksize* and to size the fixed log regions. It should be
set to a value **lower** than the expected average object size. If
*memsize* is configured too low with respect to *dsksize* and
*objsize_hint*, a higher *memsize* value will be used (which might
fail if insufficient memory is available).
For an already populated storage, the configured *memsize* is checked
against the minimum amount of memory required for the actual average
object size. If it is too low, fellow will not start and emit a fatal
error with sizing requirements.
*delete* specifies if the storage is to be emptied.
......
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