blob: 38823efd698c809513f87c6585c91084a9517a43 [file] [log] [blame]
David Teigland869d81d2006-01-17 08:47:12 +00001/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
4 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
Steven Whitehousee9fc2aa2006-09-01 11:05:15 -04007 * of the GNU General Public License version 2.
David Teigland869d81d2006-01-17 08:47:12 +00008 */
David Teigland29b79982006-01-16 16:52:38 +00009
10#include "lock_dlm.h"
11
Steven Whitehousef3c9d382008-05-21 17:21:42 +010012static inline int no_work(struct gdlm_ls *ls)
David Teigland29b79982006-01-16 16:52:38 +000013{
14 int ret;
15
16 spin_lock(&ls->async_lock);
Steven Whitehousef3c9d382008-05-21 17:21:42 +010017 ret = list_empty(&ls->submit);
David Teigland29b79982006-01-16 16:52:38 +000018 spin_unlock(&ls->async_lock);
19
20 return ret;
21}
22
Steven Whitehousef3c9d382008-05-21 17:21:42 +010023static int gdlm_thread(void *data)
David Teigland29b79982006-01-16 16:52:38 +000024{
25 struct gdlm_ls *ls = (struct gdlm_ls *) data;
26 struct gdlm_lock *lp = NULL;
David Teigland29b79982006-01-16 16:52:38 +000027
David Teigland29b79982006-01-16 16:52:38 +000028 while (!kthread_should_stop()) {
David Teigland8cbc4342007-11-07 09:03:56 -060029 wait_event_interruptible(ls->thread_wait,
Steven Whitehousef3c9d382008-05-21 17:21:42 +010030 !no_work(ls) || kthread_should_stop());
David Teigland29b79982006-01-16 16:52:38 +000031
32 spin_lock(&ls->async_lock);
33
Steven Whitehousef3c9d382008-05-21 17:21:42 +010034 if (!list_empty(&ls->submit)) {
David Teigland29b79982006-01-16 16:52:38 +000035 lp = list_entry(ls->submit.next, struct gdlm_lock,
36 delay_list);
37 list_del_init(&lp->delay_list);
Steven Whitehousef3c9d382008-05-21 17:21:42 +010038 spin_unlock(&ls->async_lock);
David Teigland8d3b35a2006-02-23 10:00:56 +000039 gdlm_do_lock(lp);
Steven Whitehousef3c9d382008-05-21 17:21:42 +010040 spin_lock(&ls->async_lock);
41 }
Steven Whitehousef3c9d382008-05-21 17:21:42 +010042 spin_unlock(&ls->async_lock);
David Teigland29b79982006-01-16 16:52:38 +000043 }
44
45 return 0;
46}
47
48int gdlm_init_threads(struct gdlm_ls *ls)
49{
50 struct task_struct *p;
51 int error;
52
Steven Whitehousef3c9d382008-05-21 17:21:42 +010053 p = kthread_run(gdlm_thread, ls, "lock_dlm");
David Teigland29b79982006-01-16 16:52:38 +000054 error = IS_ERR(p);
55 if (error) {
Steven Whitehousef3c9d382008-05-21 17:21:42 +010056 log_error("can't start lock_dlm thread %d", error);
David Teigland29b79982006-01-16 16:52:38 +000057 return error;
58 }
Steven Whitehousef3c9d382008-05-21 17:21:42 +010059 ls->thread = p;
David Teigland29b79982006-01-16 16:52:38 +000060
61 return 0;
62}
63
64void gdlm_release_threads(struct gdlm_ls *ls)
65{
Steven Whitehousef3c9d382008-05-21 17:21:42 +010066 kthread_stop(ls->thread);
David Teigland29b79982006-01-16 16:52:38 +000067}
68