From c394aea297ff4fffc6ada1d4f910a2f2c80a3a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20=C5=9Awi=C4=99cki?= Date: Fri, 5 Feb 2016 18:09:38 +0100 Subject: [PATCH] Switch workers to system_unbound_wq. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch does greatly reduce the probability of kernel hang caused by memory reclamation executed through flashcache's code. The probability is reduced because io required by memory reclamation can use thread spawned on different cores. The correct patch would be to create dedicated workqueue with WQ_MEM_RECLAIM but this patch is relatively unintruisive and does provably fix the issue in prodiction environments. Signed-off-by: Bartłomiej Święcki --- src/flashcache_conf.c | 2 +- src/flashcache_main.c | 12 ++++++------ src/flashcache_procfs.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/flashcache_conf.c b/src/flashcache_conf.c index 1a63c2d..658a95d 100644 --- a/src/flashcache_conf.c +++ b/src/flashcache_conf.c @@ -1652,7 +1652,7 @@ flashcache_sync_for_remove(struct cache_c *dmc) /* Wait for all the dirty blocks to get written out, and any other IOs */ wait_event(dmc->destroyq, !atomic_read(&dmc->nr_jobs)); cancel_delayed_work(&dmc->delayed_clean); - flush_scheduled_work(); + flush_workqueue(system_unbound_wq); } while (!dmc->sysctl_fast_remove && atomic_read(&dmc->nr_dirty) > 0); } diff --git a/src/flashcache_main.c b/src/flashcache_main.c index e2d809b..9e1bfc4 100644 --- a/src/flashcache_main.c +++ b/src/flashcache_main.c @@ -216,7 +216,7 @@ flashcache_io_callback(unsigned long error, void *context) /* Kick off the write to the cache */ job->action = READFILL; push_io(job); - schedule_work(&_kcached_wq); + queue_work(system_unbound_wq, &_kcached_wq); return; } else { disk_error = -EIO; @@ -336,7 +336,7 @@ flashcache_io_callback(unsigned long error, void *context) if (unlikely(error || cacheblk->nr_queued > 0)) { spin_unlock_irqrestore(&cache_set->set_spin_lock, flags); push_pending(job); - schedule_work(&_kcached_wq); + queue_work(system_unbound_wq, &_kcached_wq); } else { cacheblk->cache_state &= ~BLOCK_IO_INPROG; spin_unlock_irqrestore(&cache_set->set_spin_lock, flags); @@ -686,7 +686,7 @@ flashcache_md_write_callback(unsigned long error, void *context) else job->error = 0; push_md_complete(job); - schedule_work(&_kcached_wq); + queue_work(system_unbound_wq, &_kcached_wq); } static int @@ -976,7 +976,7 @@ flashcache_md_write(struct kcached_job *job) * deadlock. */ push_md_io(job); - schedule_work(&_kcached_wq); + queue_work(system_unbound_wq, &_kcached_wq); } } @@ -1288,7 +1288,7 @@ flashcache_clean_set(struct cache_c *dmc, int set, int force_clean_blocks) do_delayed_clean = 1; spin_unlock_irq(&cache_set->set_spin_lock); if (do_delayed_clean) - schedule_delayed_work(&dmc->delayed_clean, 1*HZ); + queue_delayed_work(system_unbound_wq, &dmc->delayed_clean, 1*HZ); } flashcache_diskclean_free(dmc, writes_list, set_dirty_list); } @@ -2364,7 +2364,7 @@ flashcache_uncached_io_callback(unsigned long error, void *context) else job->error = 0; push_uncached_io_complete(job); - schedule_work(&_kcached_wq); + queue_work(system_unbound_wq, &_kcached_wq); } static void diff --git a/src/flashcache_procfs.c b/src/flashcache_procfs.c index 2ff33c0..95e939d 100644 --- a/src/flashcache_procfs.c +++ b/src/flashcache_procfs.c @@ -115,7 +115,7 @@ flashcache_sync_sysctl(ctl_table *table, int write, if (dmc->sysctl_do_sync) { dmc->sysctl_stop_sync = 0; cancel_delayed_work(&dmc->delayed_clean); - flush_scheduled_work(); + flush_workqueue(system_unbound_wq); flashcache_sync_all(dmc); } }