SEC: Reduce lock hold times.
Only flush a subset of extents during flushing, and drop the lock while doing so.
This commit is contained in:
committed by
David Goldblatt
parent
1944ebbe7f
commit
bf448d7a5a
@@ -8,13 +8,9 @@
|
||||
* Small extent cache.
|
||||
*
|
||||
* This includes some utilities to cache small extents. We have a per-pszind
|
||||
* bin with its own lock and edata heap (including only extents of that size).
|
||||
* We don't try to do any coalescing of extents (since it would require
|
||||
* cross-bin locks). As a result, we need to be careful about fragmentation.
|
||||
* As a gesture in that direction, we limit the size of caches, apply first-fit
|
||||
* within the bins, and, when flushing a bin, flush all of its extents rather
|
||||
* than just those up to some threshold. When we allocate again, we'll get a
|
||||
* chance to move to better ones.
|
||||
* bin with its own list of extents of that size. We don't try to do any
|
||||
* coalescing of extents (since it would in general require cross-shard locks or
|
||||
* knowledge of the underlying PAI implementation).
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -46,6 +42,19 @@ sec_stats_accum(sec_stats_t *dst, sec_stats_t *src) {
|
||||
dst->bytes += src->bytes;
|
||||
}
|
||||
|
||||
/* A collections of free extents, all of the same size. */
|
||||
typedef struct sec_bin_s sec_bin_t;
|
||||
struct sec_bin_s {
|
||||
/*
|
||||
* Number of bytes in this particular bin (as opposed to the
|
||||
* sec_shard_t's bytes_cur. This isn't user visible or reported in
|
||||
* stats; rather, it allows us to quickly determine the change in the
|
||||
* centralized counter when flushing.
|
||||
*/
|
||||
size_t bytes_cur;
|
||||
edata_list_active_t freelist;
|
||||
};
|
||||
|
||||
typedef struct sec_shard_s sec_shard_t;
|
||||
struct sec_shard_s {
|
||||
/*
|
||||
@@ -64,8 +73,11 @@ struct sec_shard_s {
|
||||
* hooks are installed.
|
||||
*/
|
||||
bool enabled;
|
||||
edata_list_active_t freelist[SEC_NPSIZES];
|
||||
sec_bin_t bins[SEC_NPSIZES];
|
||||
/* Number of bytes in all bins in the shard. */
|
||||
size_t bytes_cur;
|
||||
/* The next pszind to flush in the flush-some pathways. */
|
||||
pszind_t to_flush_next;
|
||||
};
|
||||
|
||||
typedef struct sec_s sec_t;
|
||||
@@ -83,6 +95,18 @@ struct sec_s {
|
||||
* the bins in that shard to be flushed.
|
||||
*/
|
||||
size_t bytes_max;
|
||||
/*
|
||||
* The number of bytes (in all bins) we flush down to when we exceed
|
||||
* bytes_cur. We want this to be less than bytes_cur, because
|
||||
* otherwise we could get into situations where a shard undergoing
|
||||
* net-deallocation keeps bytes_cur very near to bytes_max, so that
|
||||
* most deallocations get immediately forwarded to the underlying PAI
|
||||
* implementation, defeating the point of the SEC.
|
||||
*
|
||||
* Currently this is just set to bytes_max / 2, but eventually can be
|
||||
* configurable.
|
||||
*/
|
||||
size_t bytes_after_flush;
|
||||
|
||||
/*
|
||||
* We don't necessarily always use all the shards; requests are
|
||||
|
Reference in New Issue
Block a user