Skip to content

Commit 30e388d

Browse files
author
Andreas Gruenbacher
committed
gfs2: Switch to a per-filesystem glock workqueue
Switch to a per-filesystem glock workqueue. Additional workqueues are cheap nowadays, and keeping separate workqueues allows to flush the work of each filesystem without affecting the others. Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent 51568ac commit 30e388d

File tree

3 files changed

+18
-15
lines changed

3 files changed

+18
-15
lines changed

fs/gfs2/glock.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ static void request_demote(struct gfs2_glock *gl, unsigned int state,
6565
unsigned long delay, bool remote);
6666

6767
static struct dentry *gfs2_root;
68-
static struct workqueue_struct *glock_workqueue;
6968
static LIST_HEAD(lru_list);
7069
static atomic_t lru_count = ATOMIC_INIT(0);
7170
static DEFINE_SPINLOCK(lru_lock);
@@ -274,7 +273,9 @@ static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
274273
* work queue.
275274
*/
276275
static void gfs2_glock_queue_work(struct gfs2_glock *gl, unsigned long delay) {
277-
if (!queue_delayed_work(glock_workqueue, &gl->gl_work, delay)) {
276+
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
277+
278+
if (!queue_delayed_work(sdp->sd_glock_wq, &gl->gl_work, delay)) {
278279
/*
279280
* We are holding the lockref spinlock, and the work was still
280281
* queued above. The queued work (glock_work_func) takes that
@@ -2252,9 +2253,10 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
22522253
bool timed_out = false;
22532254

22542255
set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags);
2255-
flush_workqueue(glock_workqueue);
2256+
flush_workqueue(sdp->sd_glock_wq);
22562257
glock_hash_walk(clear_glock, sdp);
2257-
flush_workqueue(glock_workqueue);
2258+
flush_workqueue(sdp->sd_glock_wq);
2259+
22582260
while (!timed_out) {
22592261
wait_event_timeout(sdp->sd_kill_wait,
22602262
!atomic_read(&sdp->sd_glock_disposal),
@@ -2270,6 +2272,7 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
22702272
gfs2_lm_unmount(sdp);
22712273
gfs2_free_dead_glocks(sdp);
22722274
glock_hash_walk(dump_glock_func, sdp);
2275+
destroy_workqueue(sdp->sd_glock_wq);
22732276
}
22742277

22752278
static const char *state2str(unsigned state)
@@ -2534,16 +2537,8 @@ int __init gfs2_glock_init(void)
25342537
if (ret < 0)
25352538
return ret;
25362539

2537-
glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM |
2538-
WQ_HIGHPRI | WQ_FREEZABLE, 0);
2539-
if (!glock_workqueue) {
2540-
rhashtable_destroy(&gl_hash_table);
2541-
return -ENOMEM;
2542-
}
2543-
25442540
glock_shrinker = shrinker_alloc(0, "gfs2-glock");
25452541
if (!glock_shrinker) {
2546-
destroy_workqueue(glock_workqueue);
25472542
rhashtable_destroy(&gl_hash_table);
25482543
return -ENOMEM;
25492544
}
@@ -2563,7 +2558,6 @@ void gfs2_glock_exit(void)
25632558
{
25642559
shrinker_free(glock_shrinker);
25652560
rhashtable_destroy(&gl_hash_table);
2566-
destroy_workqueue(glock_workqueue);
25672561
}
25682562

25692563
static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi, loff_t n)

fs/gfs2/incore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ struct gfs2_sbd {
772772

773773
/* Workqueue stuff */
774774

775+
struct workqueue_struct *sd_glock_wq;
775776
struct workqueue_struct *sd_delete_wq;
776777

777778
/* Daemon stuff */

fs/gfs2/ops_fstype.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,11 +1188,17 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
11881188

11891189
snprintf(sdp->sd_fsname, sizeof(sdp->sd_fsname), "%s", sdp->sd_table_name);
11901190

1191+
error = -ENOMEM;
1192+
sdp->sd_glock_wq = alloc_workqueue("gfs2-glock/%s",
1193+
WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_FREEZABLE, 0,
1194+
sdp->sd_fsname);
1195+
if (!sdp->sd_glock_wq)
1196+
goto fail_free;
1197+
11911198
sdp->sd_delete_wq = alloc_workqueue("gfs2-delete/%s",
11921199
WQ_MEM_RECLAIM | WQ_FREEZABLE, 0, sdp->sd_fsname);
1193-
error = -ENOMEM;
11941200
if (!sdp->sd_delete_wq)
1195-
goto fail_free;
1201+
goto fail_glock_wq;
11961202

11971203
error = gfs2_sys_fs_add(sdp);
11981204
if (error)
@@ -1301,6 +1307,8 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
13011307
gfs2_sys_fs_del(sdp);
13021308
fail_delete_wq:
13031309
destroy_workqueue(sdp->sd_delete_wq);
1310+
fail_glock_wq:
1311+
destroy_workqueue(sdp->sd_glock_wq);
13041312
fail_free:
13051313
free_sbd(sdp);
13061314
sb->s_fs_info = NULL;

0 commit comments

Comments
 (0)