Btrfs: fix spinlock assertions on UP systems
[safe/jmp/linux-2.6] / fs / btrfs / locking.c
1 /*
2  * Copyright (C) 2008 Oracle.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 021110-1307, USA.
17  */
18 #include <linux/sched.h>
19 #include <linux/gfp.h>
20 #include <linux/pagemap.h>
21 #include <linux/spinlock.h>
22 #include <linux/page-flags.h>
23 #include <asm/bug.h>
24 #include "ctree.h"
25 #include "extent_io.h"
26 #include "locking.h"
27
28 static inline void spin_nested(struct extent_buffer *eb)
29 {
30         spin_lock(&eb->lock);
31 }
32
33 /*
34  * Setting a lock to blocking will drop the spinlock and set the
35  * flag that forces other procs who want the lock to wait.  After
36  * this you can safely schedule with the lock held.
37  */
38 void btrfs_set_lock_blocking(struct extent_buffer *eb)
39 {
40         if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) {
41                 set_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags);
42                 spin_unlock(&eb->lock);
43         }
44         /* exit with the spin lock released and the bit set */
45 }
46
47 /*
48  * clearing the blocking flag will take the spinlock again.
49  * After this you can't safely schedule
50  */
51 void btrfs_clear_lock_blocking(struct extent_buffer *eb)
52 {
53         if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) {
54                 spin_nested(eb);
55                 clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags);
56                 smp_mb__after_clear_bit();
57         }
58         /* exit with the spin lock held */
59 }
60
61 /*
62  * unfortunately, many of the places that currently set a lock to blocking
63  * don't end up blocking for every long, and often they don't block
64  * at all.  For a dbench 50 run, if we don't spin one the blocking bit
65  * at all, the context switch rate can jump up to 400,000/sec or more.
66  *
67  * So, we're still stuck with this crummy spin on the blocking bit,
68  * at least until the most common causes of the short blocks
69  * can be dealt with.
70  */
71 static int btrfs_spin_on_block(struct extent_buffer *eb)
72 {
73         int i;
74         for (i = 0; i < 512; i++) {
75                 cpu_relax();
76                 if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
77                         return 1;
78                 if (need_resched())
79                         break;
80         }
81         return 0;
82 }
83
84 /*
85  * This is somewhat different from trylock.  It will take the
86  * spinlock but if it finds the lock is set to blocking, it will
87  * return without the lock held.
88  *
89  * returns 1 if it was able to take the lock and zero otherwise
90  *
91  * After this call, scheduling is not safe without first calling
92  * btrfs_set_lock_blocking()
93  */
94 int btrfs_try_spin_lock(struct extent_buffer *eb)
95 {
96         int i;
97
98         spin_nested(eb);
99         if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
100                 return 1;
101         spin_unlock(&eb->lock);
102
103         /* spin for a bit on the BLOCKING flag */
104         for (i = 0; i < 2; i++) {
105                 if (!btrfs_spin_on_block(eb))
106                         break;
107
108                 spin_nested(eb);
109                 if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
110                         return 1;
111                 spin_unlock(&eb->lock);
112         }
113         return 0;
114 }
115
116 /*
117  * the autoremove wake function will return 0 if it tried to wake up
118  * a process that was already awake, which means that process won't
119  * count as an exclusive wakeup.  The waitq code will continue waking
120  * procs until it finds one that was actually sleeping.
121  *
122  * For btrfs, this isn't quite what we want.  We want a single proc
123  * to be notified that the lock is ready for taking.  If that proc
124  * already happen to be awake, great, it will loop around and try for
125  * the lock.
126  *
127  * So, btrfs_wake_function always returns 1, even when the proc that we
128  * tried to wake up was already awake.
129  */
130 static int btrfs_wake_function(wait_queue_t *wait, unsigned mode,
131                                int sync, void *key)
132 {
133         autoremove_wake_function(wait, mode, sync, key);
134         return 1;
135 }
136
137 /*
138  * returns with the extent buffer spinlocked.
139  *
140  * This will spin and/or wait as required to take the lock, and then
141  * return with the spinlock held.
142  *
143  * After this call, scheduling is not safe without first calling
144  * btrfs_set_lock_blocking()
145  */
146 int btrfs_tree_lock(struct extent_buffer *eb)
147 {
148         DEFINE_WAIT(wait);
149         wait.func = btrfs_wake_function;
150
151         while(1) {
152                 spin_nested(eb);
153
154                 /* nobody is blocking, exit with the spinlock held */
155                 if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
156                         return 0;
157
158                 /*
159                  * we have the spinlock, but the real owner is blocking.
160                  * wait for them
161                  */
162                 spin_unlock(&eb->lock);
163
164                 /*
165                  * spin for a bit, and if the blocking flag goes away,
166                  * loop around
167                  */
168                 if (btrfs_spin_on_block(eb))
169                         continue;
170
171                 prepare_to_wait_exclusive(&eb->lock_wq, &wait,
172                                           TASK_UNINTERRUPTIBLE);
173
174                 if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
175                         schedule();
176
177                 finish_wait(&eb->lock_wq, &wait);
178         }
179         return 0;
180 }
181
182 /*
183  * Very quick trylock, this does not spin or schedule.  It returns
184  * 1 with the spinlock held if it was able to take the lock, or it
185  * returns zero if it was unable to take the lock.
186  *
187  * After this call, scheduling is not safe without first calling
188  * btrfs_set_lock_blocking()
189  */
190 int btrfs_try_tree_lock(struct extent_buffer *eb)
191 {
192         if (spin_trylock(&eb->lock)) {
193                 if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) {
194                         /*
195                          * we've got the spinlock, but the real owner is
196                          * blocking.  Drop the spinlock and return failure
197                          */
198                         spin_unlock(&eb->lock);
199                         return 0;
200                 }
201                 return 1;
202         }
203         /* someone else has the spinlock giveup */
204         return 0;
205 }
206
207 int btrfs_tree_unlock(struct extent_buffer *eb)
208 {
209         /*
210          * if we were a blocking owner, we don't have the spinlock held
211          * just clear the bit and look for waiters
212          */
213         if (test_and_clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
214                 smp_mb__after_clear_bit();
215         else
216                 spin_unlock(&eb->lock);
217
218         if (waitqueue_active(&eb->lock_wq))
219                 wake_up(&eb->lock_wq);
220         return 0;
221 }
222
223 void btrfs_assert_tree_locked(struct extent_buffer *eb)
224 {
225         if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
226                 assert_spin_locked(&eb->lock);
227 }