[dm-devel] [patch 2/3] dm-writecache: convert wait queue to wake_up_process
Mikulas Patocka
mpatocka at redhat.com
Wed Jun 6 15:31:44 UTC 2018
If there's just one process that can wait on a queue, we can use
wake_up_process. According to Linus, it is safe to call wake_up_process
on a process even if the process may be doing something else.
Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
---
drivers/md/dm-writecache.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
Index: linux-2.6/drivers/md/dm-writecache.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-writecache.c 2018-06-05 22:54:49.000000000 +0200
+++ linux-2.6/drivers/md/dm-writecache.c 2018-06-05 23:02:00.000000000 +0200
@@ -10,7 +10,6 @@
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/kthread.h>
-#include <linux/swait.h>
#include <linux/dm-io.h>
#include <linux/dm-kcopyd.h>
#include <linux/dax.h>
@@ -168,7 +167,7 @@ struct dm_writecache {
struct dm_io_client *dm_io;
- struct swait_queue_head endio_thread_wait;
+ raw_spinlock_t endio_list_lock;
struct list_head endio_list;
struct task_struct *endio_thread;
@@ -1273,10 +1272,11 @@ static void writecache_writeback_endio(s
struct dm_writecache *wc = wb->wc;
unsigned long flags;
- raw_spin_lock_irqsave(&wc->endio_thread_wait.lock, flags);
+ raw_spin_lock_irqsave(&wc->endio_list_lock, flags);
+ if (unlikely(list_empty(&wc->endio_list)))
+ wake_up_process(wc->endio_thread);
list_add_tail(&wb->endio_entry, &wc->endio_list);
- swake_up_locked(&wc->endio_thread_wait);
- raw_spin_unlock_irqrestore(&wc->endio_thread_wait.lock, flags);
+ raw_spin_unlock_irqrestore(&wc->endio_list_lock, flags);
}
static void writecache_copy_endio(int read_err, unsigned long write_err, void *ptr)
@@ -1286,10 +1286,11 @@ static void writecache_copy_endio(int re
c->error = likely(!(read_err | write_err)) ? 0 : -EIO;
- raw_spin_lock_irq(&wc->endio_thread_wait.lock);
+ raw_spin_lock_irq(&wc->endio_list_lock);
+ if (unlikely(list_empty(&wc->endio_list)))
+ wake_up_process(wc->endio_thread);
list_add_tail(&c->endio_entry, &wc->endio_list);
- swake_up_locked(&wc->endio_thread_wait);
- raw_spin_unlock_irq(&wc->endio_thread_wait.lock);
+ raw_spin_unlock_irq(&wc->endio_list_lock);
}
static void __writecache_endio_pmem(struct dm_writecache *wc, struct list_head *list)
@@ -1364,33 +1365,30 @@ static int writecache_endio_thread(void
struct dm_writecache *wc = data;
while (1) {
- DECLARE_SWAITQUEUE(wait);
struct list_head list;
- raw_spin_lock_irq(&wc->endio_thread_wait.lock);
+ raw_spin_lock_irq(&wc->endio_list_lock);
continue_locked:
if (!list_empty(&wc->endio_list))
goto pop_from_list;
set_current_state(TASK_INTERRUPTIBLE);
- __prepare_to_swait(&wc->endio_thread_wait, &wait);
- raw_spin_unlock_irq(&wc->endio_thread_wait.lock);
+ raw_spin_unlock_irq(&wc->endio_list_lock);
if (unlikely(kthread_should_stop())) {
- finish_swait(&wc->endio_thread_wait, &wait);
+ set_current_state(TASK_RUNNING);
break;
}
schedule();
- raw_spin_lock_irq(&wc->endio_thread_wait.lock);
- __finish_swait(&wc->endio_thread_wait, &wait);
+ raw_spin_lock_irq(&wc->endio_list_lock);
goto continue_locked;
pop_from_list:
list = wc->endio_list;
list.next->prev = list.prev->next = &list;
INIT_LIST_HEAD(&wc->endio_list);
- raw_spin_unlock_irq(&wc->endio_thread_wait.lock);
+ raw_spin_unlock_irq(&wc->endio_list_lock);
if (!WC_MODE_FUA(wc))
writecache_disk_flush(wc, wc->dev);
@@ -1848,7 +1846,7 @@ static int writecache_ctr(struct dm_targ
INIT_WORK(&wc->writeback_work, writecache_writeback);
INIT_WORK(&wc->flush_work, writecache_flush_work);
- init_swait_queue_head(&wc->endio_thread_wait);
+ raw_spin_lock_init(&wc->endio_list_lock);
INIT_LIST_HEAD(&wc->endio_list);
wc->endio_thread = kthread_create(writecache_endio_thread, wc, "writecache_endio");
if (IS_ERR(wc->endio_thread)) {
More information about the dm-devel
mailing list