Skip to content

Commit 5e1e176

Browse files
committed
optimize locking checks in mempool allocator
avoid checking the whole array of objects each time by removing the self organized memory reaping. this can be managed by the global memory reap callback which is called every 60 seconds. this will reduce the use if locking operations significant. Signed-off-by: Sebastian Gottschall <[email protected]>
1 parent 65a343b commit 5e1e176

File tree

1 file changed

+33
-19
lines changed

1 file changed

+33
-19
lines changed

module/zstd/zfs_zstd.c

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,34 @@ static struct zstd_fallback_mem zstd_dctx_fallback;
202202
static struct zstd_pool *zstd_mempool_cctx;
203203
static struct zstd_pool *zstd_mempool_dctx;
204204

205+
206+
static void
207+
zstd_mempool_reap(struct zstd_pool *zstd_mempool)
208+
{
209+
struct zstd_pool *pool;
210+
211+
if (!zstd_mempool) {
212+
return;
213+
}
214+
215+
/* free obsolete slots */
216+
for (int i = 0; i < ZSTD_POOL_MAX; i++) {
217+
pool = &zstd_mempool[i];
218+
if (mutex_tryenter(&pool->barrier)) {
219+
/* Free memory if unused object older than 2 minutes */
220+
if (pool->mem && gethrestime_sec() > pool->timeout) {
221+
vmem_free(pool->mem, pool->size);
222+
ZSTDSTAT_SUB(zstd_stat_buffers, 1);
223+
ZSTDSTAT_SUB(zstd_stat_size, pool->size);
224+
pool->mem = NULL;
225+
pool->size = 0;
226+
pool->timeout = 0;
227+
}
228+
mutex_exit(&pool->barrier);
229+
}
230+
}
231+
}
232+
205233
/*
206234
* Try to get a cached allocated buffer from memory pool or allocate a new one
207235
* if necessary. If a object is older than 2 minutes and does not fit the
@@ -215,6 +243,7 @@ static struct zstd_pool *zstd_mempool_dctx;
215243
*
216244
* The scheduled release will be updated every time a object is reused.
217245
*/
246+
218247
static void *
219248
zstd_mempool_alloc(struct zstd_pool *zstd_mempool, size_t size)
220249
{
@@ -242,31 +271,16 @@ zstd_mempool_alloc(struct zstd_pool *zstd_mempool, size_t size)
242271
* Check if objects fits the size, if so we take it and
243272
* update the timestamp.
244273
*/
245-
if (size && !mem && pool->mem && size <= pool->size) {
274+
if (pool->mem && size <= pool->size) {
246275
pool->timeout = gethrestime_sec() +
247276
ZSTD_POOL_TIMEOUT;
248277
mem = pool->mem;
249-
continue;
278+
return (mem);
250279
}
251-
252-
/* Free memory if unused object older than 2 minutes */
253-
if (pool->mem && gethrestime_sec() > pool->timeout) {
254-
vmem_free(pool->mem, pool->size);
255-
ZSTDSTAT_SUB(zstd_stat_buffers, 1);
256-
ZSTDSTAT_SUB(zstd_stat_size, pool->size);
257-
pool->mem = NULL;
258-
pool->size = 0;
259-
pool->timeout = 0;
260-
}
261-
262280
mutex_exit(&pool->barrier);
263281
}
264282
}
265283

266-
if (!size || mem) {
267-
return (mem);
268-
}
269-
270284
/*
271285
* If no preallocated slot was found, try to fill in a new one.
272286
*
@@ -704,8 +718,8 @@ zfs_zstd_cache_reap_now(void)
704718
* calling alloc with zero size seeks
705719
* and releases old unused objects
706720
*/
707-
zstd_mempool_alloc(zstd_mempool_cctx, 0);
708-
zstd_mempool_alloc(zstd_mempool_dctx, 0);
721+
zstd_mempool_reap(zstd_mempool_cctx);
722+
zstd_mempool_reap(zstd_mempool_dctx);
709723
}
710724

711725
extern int __init

0 commit comments

Comments
 (0)