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