David Teigland | 869d81d | 2006-01-17 08:47:12 +0000 | [diff] [blame] | 1 | /* |
| 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 Whitehouse | e9fc2aa | 2006-09-01 11:05:15 -0400 | [diff] [blame] | 7 | * of the GNU General Public License version 2. |
David Teigland | 869d81d | 2006-01-17 08:47:12 +0000 | [diff] [blame] | 8 | */ |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 9 | |
| 10 | #include "lock_dlm.h" |
| 11 | |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 12 | static inline int no_work(struct gdlm_ls *ls) |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 13 | { |
| 14 | int ret; |
| 15 | |
| 16 | spin_lock(&ls->async_lock); |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 17 | ret = list_empty(&ls->submit); |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 18 | spin_unlock(&ls->async_lock); |
| 19 | |
| 20 | return ret; |
| 21 | } |
| 22 | |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 23 | static int gdlm_thread(void *data) |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 24 | { |
| 25 | struct gdlm_ls *ls = (struct gdlm_ls *) data; |
| 26 | struct gdlm_lock *lp = NULL; |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 27 | |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 28 | while (!kthread_should_stop()) { |
David Teigland | 8cbc434 | 2007-11-07 09:03:56 -0600 | [diff] [blame] | 29 | wait_event_interruptible(ls->thread_wait, |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 30 | !no_work(ls) || kthread_should_stop()); |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 31 | |
| 32 | spin_lock(&ls->async_lock); |
| 33 | |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 34 | if (!list_empty(&ls->submit)) { |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 35 | lp = list_entry(ls->submit.next, struct gdlm_lock, |
| 36 | delay_list); |
| 37 | list_del_init(&lp->delay_list); |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 38 | spin_unlock(&ls->async_lock); |
David Teigland | 8d3b35a | 2006-02-23 10:00:56 +0000 | [diff] [blame] | 39 | gdlm_do_lock(lp); |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 40 | spin_lock(&ls->async_lock); |
| 41 | } |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 42 | spin_unlock(&ls->async_lock); |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 43 | } |
| 44 | |
| 45 | return 0; |
| 46 | } |
| 47 | |
| 48 | int gdlm_init_threads(struct gdlm_ls *ls) |
| 49 | { |
| 50 | struct task_struct *p; |
| 51 | int error; |
| 52 | |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 53 | p = kthread_run(gdlm_thread, ls, "lock_dlm"); |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 54 | error = IS_ERR(p); |
| 55 | if (error) { |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 56 | log_error("can't start lock_dlm thread %d", error); |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 57 | return error; |
| 58 | } |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 59 | ls->thread = p; |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 60 | |
| 61 | return 0; |
| 62 | } |
| 63 | |
| 64 | void gdlm_release_threads(struct gdlm_ls *ls) |
| 65 | { |
Steven Whitehouse | f3c9d38 | 2008-05-21 17:21:42 +0100 | [diff] [blame] | 66 | kthread_stop(ls->thread); |
David Teigland | 29b7998 | 2006-01-16 16:52:38 +0000 | [diff] [blame] | 67 | } |
| 68 | |