Skip to content

Commit 52691d3

Browse files
adam900710kdave
authored andcommitted
btrfs: migrate to use per-fs workspace manager
There are several interfaces involved for each algorithm: - alloc workspace All algorithms allocate a workspace without the need for workspace manager. So no change needs to be done. - get workspace This involves checking the workspace manager to find a free one, and if not, allocate a new one. For none and lzo, they share the same generic btrfs_get_workspace() helper, only needs to update that function to use the per-fs manager. For zlib it uses a wrapper around btrfs_get_workspace(), so no special work needed. For zstd, update zstd_find_workspace() and zstd_get_workspace() to utilize the per-fs manager. - put workspace For none/zlib/lzo they share the same btrfs_put_workspace(), update that function to use the per-fs manager. For zstd, it's zstd_put_workspace(), the same update. - zstd specific timer This is the timer to reclaim workspace, change it to grab the per-fs workspace manager instead. Now all workspace are managed by the per-fs manager. Signed-off-by: Qu Wenruo <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 56e77fc commit 52691d3

File tree

2 files changed

+48
-41
lines changed

2 files changed

+48
-41
lines changed

fs/btrfs/compression.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,7 @@ static void btrfs_cleanup_workspace_manager(int type)
875875
*/
876876
struct list_head *btrfs_get_workspace(struct btrfs_fs_info *fs_info, int type, int level)
877877
{
878-
struct workspace_manager *wsm;
878+
struct workspace_manager *wsm = fs_info->compr_wsm[type];
879879
struct list_head *workspace;
880880
int cpus = num_online_cpus();
881881
unsigned nofs_flag;
@@ -885,7 +885,7 @@ struct list_head *btrfs_get_workspace(struct btrfs_fs_info *fs_info, int type, i
885885
wait_queue_head_t *ws_wait;
886886
int *free_ws;
887887

888-
wsm = btrfs_compress_op[type]->workspace_manager;
888+
ASSERT(wsm);
889889
idle_ws = &wsm->idle_ws;
890890
ws_lock = &wsm->ws_lock;
891891
total_ws = &wsm->total_ws;
@@ -974,19 +974,19 @@ static struct list_head *get_workspace(struct btrfs_fs_info *fs_info, int type,
974974
*/
975975
void btrfs_put_workspace(struct btrfs_fs_info *fs_info, int type, struct list_head *ws)
976976
{
977-
struct workspace_manager *wsm;
977+
struct workspace_manager *gwsm = fs_info->compr_wsm[type];
978978
struct list_head *idle_ws;
979979
spinlock_t *ws_lock;
980980
atomic_t *total_ws;
981981
wait_queue_head_t *ws_wait;
982982
int *free_ws;
983983

984-
wsm = btrfs_compress_op[type]->workspace_manager;
985-
idle_ws = &wsm->idle_ws;
986-
ws_lock = &wsm->ws_lock;
987-
total_ws = &wsm->total_ws;
988-
ws_wait = &wsm->ws_wait;
989-
free_ws = &wsm->free_ws;
984+
ASSERT(gwsm);
985+
idle_ws = &gwsm->idle_ws;
986+
ws_lock = &gwsm->ws_lock;
987+
total_ws = &gwsm->total_ws;
988+
ws_wait = &gwsm->ws_wait;
989+
free_ws = &gwsm->free_ws;
990990

991991
spin_lock(ws_lock);
992992
if (*free_ws <= num_online_cpus()) {

fs/btrfs/zstd.c

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -112,19 +112,19 @@ static inline int clip_level(int level)
112112
*/
113113
static void zstd_reclaim_timer_fn(struct timer_list *timer)
114114
{
115+
struct zstd_workspace_manager *zwsm =
116+
container_of(timer, struct zstd_workspace_manager, timer);
115117
unsigned long reclaim_threshold = jiffies - ZSTD_BTRFS_RECLAIM_JIFFIES;
116118
struct list_head *pos, *next;
117119

118-
ASSERT(timer == &wsm.timer);
120+
spin_lock(&zwsm->lock);
119121

120-
spin_lock(&wsm.lock);
121-
122-
if (list_empty(&wsm.lru_list)) {
123-
spin_unlock(&wsm.lock);
122+
if (list_empty(&zwsm->lru_list)) {
123+
spin_unlock(&zwsm->lock);
124124
return;
125125
}
126126

127-
list_for_each_prev_safe(pos, next, &wsm.lru_list) {
127+
list_for_each_prev_safe(pos, next, &zwsm->lru_list) {
128128
struct workspace *victim = container_of(pos, struct workspace,
129129
lru_list);
130130
int level;
@@ -141,15 +141,15 @@ static void zstd_reclaim_timer_fn(struct timer_list *timer)
141141
list_del(&victim->list);
142142
zstd_free_workspace(&victim->list);
143143

144-
if (list_empty(&wsm.idle_ws[level]))
145-
clear_bit(level, &wsm.active_map);
144+
if (list_empty(&zwsm->idle_ws[level]))
145+
clear_bit(level, &zwsm->active_map);
146146

147147
}
148148

149-
if (!list_empty(&wsm.lru_list))
150-
mod_timer(&wsm.timer, jiffies + ZSTD_BTRFS_RECLAIM_JIFFIES);
149+
if (!list_empty(&zwsm->lru_list))
150+
mod_timer(&zwsm->timer, jiffies + ZSTD_BTRFS_RECLAIM_JIFFIES);
151151

152-
spin_unlock(&wsm.lock);
152+
spin_unlock(&zwsm->lock);
153153
}
154154

155155
/*
@@ -292,29 +292,31 @@ void zstd_cleanup_workspace_manager(void)
292292
* offer the opportunity to reclaim the workspace in favor of allocating an
293293
* appropriately sized one in the future.
294294
*/
295-
static struct list_head *zstd_find_workspace(int level)
295+
static struct list_head *zstd_find_workspace(struct btrfs_fs_info *fs_info, int level)
296296
{
297+
struct zstd_workspace_manager *zwsm = fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD];
297298
struct list_head *ws;
298299
struct workspace *workspace;
299300
int i = clip_level(level);
300301

301-
spin_lock_bh(&wsm.lock);
302-
for_each_set_bit_from(i, &wsm.active_map, ZSTD_BTRFS_MAX_LEVEL) {
303-
if (!list_empty(&wsm.idle_ws[i])) {
304-
ws = wsm.idle_ws[i].next;
302+
ASSERT(zwsm);
303+
spin_lock_bh(&zwsm->lock);
304+
for_each_set_bit_from(i, &zwsm->active_map, ZSTD_BTRFS_MAX_LEVEL) {
305+
if (!list_empty(&zwsm->idle_ws[i])) {
306+
ws = zwsm->idle_ws[i].next;
305307
workspace = list_to_workspace(ws);
306308
list_del_init(ws);
307309
/* keep its place if it's a lower level using this */
308310
workspace->req_level = level;
309311
if (clip_level(level) == workspace->level)
310312
list_del(&workspace->lru_list);
311-
if (list_empty(&wsm.idle_ws[i]))
312-
clear_bit(i, &wsm.active_map);
313-
spin_unlock_bh(&wsm.lock);
313+
if (list_empty(&zwsm->idle_ws[i]))
314+
clear_bit(i, &zwsm->active_map);
315+
spin_unlock_bh(&zwsm->lock);
314316
return ws;
315317
}
316318
}
317-
spin_unlock_bh(&wsm.lock);
319+
spin_unlock_bh(&zwsm->lock);
318320

319321
return NULL;
320322
}
@@ -331,15 +333,18 @@ static struct list_head *zstd_find_workspace(int level)
331333
*/
332334
struct list_head *zstd_get_workspace(struct btrfs_fs_info *fs_info, int level)
333335
{
336+
struct zstd_workspace_manager *zwsm = fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD];
334337
struct list_head *ws;
335338
unsigned int nofs_flag;
336339

340+
ASSERT(zwsm);
341+
337342
/* level == 0 means we can use any workspace */
338343
if (!level)
339344
level = 1;
340345

341346
again:
342-
ws = zstd_find_workspace(level);
347+
ws = zstd_find_workspace(fs_info, level);
343348
if (ws)
344349
return ws;
345350

@@ -350,9 +355,9 @@ struct list_head *zstd_get_workspace(struct btrfs_fs_info *fs_info, int level)
350355
if (IS_ERR(ws)) {
351356
DEFINE_WAIT(wait);
352357

353-
prepare_to_wait(&wsm.wait, &wait, TASK_UNINTERRUPTIBLE);
358+
prepare_to_wait(&zwsm->wait, &wait, TASK_UNINTERRUPTIBLE);
354359
schedule();
355-
finish_wait(&wsm.wait, &wait);
360+
finish_wait(&zwsm->wait, &wait);
356361

357362
goto again;
358363
}
@@ -373,32 +378,34 @@ struct list_head *zstd_get_workspace(struct btrfs_fs_info *fs_info, int level)
373378
*/
374379
void zstd_put_workspace(struct btrfs_fs_info *fs_info, struct list_head *ws)
375380
{
381+
struct zstd_workspace_manager *zwsm = fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD];
376382
struct workspace *workspace = list_to_workspace(ws);
377383

378-
spin_lock_bh(&wsm.lock);
384+
ASSERT(zwsm);
385+
spin_lock_bh(&zwsm->lock);
379386

380387
/* A node is only taken off the lru if we are the corresponding level */
381388
if (clip_level(workspace->req_level) == workspace->level) {
382389
/* Hide a max level workspace from reclaim */
383-
if (list_empty(&wsm.idle_ws[ZSTD_BTRFS_MAX_LEVEL - 1])) {
390+
if (list_empty(&zwsm->idle_ws[ZSTD_BTRFS_MAX_LEVEL - 1])) {
384391
INIT_LIST_HEAD(&workspace->lru_list);
385392
} else {
386393
workspace->last_used = jiffies;
387-
list_add(&workspace->lru_list, &wsm.lru_list);
388-
if (!timer_pending(&wsm.timer))
389-
mod_timer(&wsm.timer,
394+
list_add(&workspace->lru_list, &zwsm->lru_list);
395+
if (!timer_pending(&zwsm->timer))
396+
mod_timer(&zwsm->timer,
390397
jiffies + ZSTD_BTRFS_RECLAIM_JIFFIES);
391398
}
392399
}
393400

394-
set_bit(workspace->level, &wsm.active_map);
395-
list_add(&workspace->list, &wsm.idle_ws[workspace->level]);
401+
set_bit(workspace->level, &zwsm->active_map);
402+
list_add(&workspace->list, &zwsm->idle_ws[workspace->level]);
396403
workspace->req_level = 0;
397404

398-
spin_unlock_bh(&wsm.lock);
405+
spin_unlock_bh(&zwsm->lock);
399406

400407
if (workspace->level == clip_level(ZSTD_BTRFS_MAX_LEVEL))
401-
cond_wake_up(&wsm.wait);
408+
cond_wake_up(&zwsm->wait);
402409
}
403410

404411
void zstd_free_workspace(struct list_head *ws)

0 commit comments

Comments
 (0)