Fix hangs with processes stuck sleeping on btalloc on i386.
[freebsd.git] / sys / cddl / contrib / opensolaris / uts / common / fs / zfs / zfs_rlock.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
27  */
28
29 /*
30  * This file contains the code to implement file range locking in
31  * ZFS, although there isn't much specific to ZFS (all that comes to mind is
32  * support for growing the blocksize).
33  *
34  * Interface
35  * ---------
36  * Defined in zfs_rlock.h but essentially:
37  *      lr = rangelock_enter(zp, off, len, lock_type);
38  *      rangelock_reduce(lr, off, len); // optional
39  *      rangelock_exit(lr);
40  *
41  * AVL tree
42  * --------
43  * An AVL tree is used to maintain the state of the existing ranges
44  * that are locked for exclusive (writer) or shared (reader) use.
45  * The starting range offset is used for searching and sorting the tree.
46  *
47  * Common case
48  * -----------
49  * The (hopefully) usual case is of no overlaps or contention for locks. On
50  * entry to rangelock_enter(), a locked_range_t is allocated; the tree
51  * searched that finds no overlap, and *this* locked_range_t is placed in the
52  * tree.
53  *
54  * Overlaps/Reference counting/Proxy locks
55  * ---------------------------------------
56  * The avl code only allows one node at a particular offset. Also it's very
57  * inefficient to search through all previous entries looking for overlaps
58  * (because the very 1st in the ordered list might be at offset 0 but
59  * cover the whole file).
60  * So this implementation uses reference counts and proxy range locks.
61  * Firstly, only reader locks use reference counts and proxy locks,
62  * because writer locks are exclusive.
63  * When a reader lock overlaps with another then a proxy lock is created
64  * for that range and replaces the original lock. If the overlap
65  * is exact then the reference count of the proxy is simply incremented.
66  * Otherwise, the proxy lock is split into smaller lock ranges and
67  * new proxy locks created for non overlapping ranges.
68  * The reference counts are adjusted accordingly.
69  * Meanwhile, the orginal lock is kept around (this is the callers handle)
70  * and its offset and length are used when releasing the lock.
71  *
72  * Thread coordination
73  * -------------------
74  * In order to make wakeups efficient and to ensure multiple continuous
75  * readers on a range don't starve a writer for the same range lock,
76  * two condition variables are allocated in each rl_t.
77  * If a writer (or reader) can't get a range it initialises the writer
78  * (or reader) cv; sets a flag saying there's a writer (or reader) waiting;
79  * and waits on that cv. When a thread unlocks that range it wakes up all
80  * writers then all readers before destroying the lock.
81  *
82  * Append mode writes
83  * ------------------
84  * Append mode writes need to lock a range at the end of a file.
85  * The offset of the end of the file is determined under the
86  * range locking mutex, and the lock type converted from RL_APPEND to
87  * RL_WRITER and the range locked.
88  *
89  * Grow block handling
90  * -------------------
91  * ZFS supports multiple block sizes, up to 16MB. The smallest
92  * block size is used for the file which is grown as needed. During this
93  * growth all other writers and readers must be excluded.
94  * So if the block size needs to be grown then the whole file is
95  * exclusively locked, then later the caller will reduce the lock
96  * range to just the range to be written using rangelock_reduce().
97  */
98
99 #include <sys/zfs_context.h>
100 #include <sys/avl.h>
101 #include <sys/zfs_rlock.h>
102
103 /*
104  * AVL comparison function used to order range locks
105  * Locks are ordered on the start offset of the range.
106  */
107 static int
108 rangelock_compare(const void *arg1, const void *arg2)
109 {
110         const locked_range_t *rl1 = (const locked_range_t *)arg1;
111         const locked_range_t *rl2 = (const locked_range_t *)arg2;
112
113         return (AVL_CMP(rl1->lr_offset, rl2->lr_offset));
114 }
115
116 /*
117  * The callback is invoked when acquiring a RL_WRITER or RL_APPEND lock.
118  * It must convert RL_APPEND to RL_WRITER (starting at the end of the file),
119  * and may increase the range that's locked for RL_WRITER.
120  */
121 void
122 rangelock_init(rangelock_t *rl, rangelock_cb_t *cb, void *arg)
123 {
124         mutex_init(&rl->rl_lock, NULL, MUTEX_DEFAULT, NULL);
125         avl_create(&rl->rl_tree, rangelock_compare,
126             sizeof (locked_range_t), offsetof(locked_range_t, lr_node));
127         rl->rl_cb = cb;
128         rl->rl_arg = arg;
129 }
130
131 void
132 rangelock_fini(rangelock_t *rl)
133 {
134         mutex_destroy(&rl->rl_lock);
135         avl_destroy(&rl->rl_tree);
136 }
137
138 /*
139  * Check if a write lock can be grabbed.  If not, fail immediately or sleep and
140  * recheck until available, depending on the value of the "nonblock" parameter.
141  */
142 static boolean_t
143 rangelock_enter_writer(rangelock_t *rl, locked_range_t *new, boolean_t nonblock)
144 {
145         avl_tree_t *tree = &rl->rl_tree;
146         locked_range_t *lr;
147         avl_index_t where;
148         uint64_t orig_off = new->lr_offset;
149         uint64_t orig_len = new->lr_length;
150         rangelock_type_t orig_type = new->lr_type;
151
152         for (;;) {
153                 /*
154                  * Call callback which can modify new->r_off,len,type.
155                  * Note, the callback is used by the ZPL to handle appending
156                  * and changing blocksizes.  It isn't needed for zvols.
157                  */
158                 if (rl->rl_cb != NULL) {
159                         rl->rl_cb(new, rl->rl_arg);
160                 }
161
162                 /*
163                  * If the type was APPEND, the callback must convert it to
164                  * WRITER.
165                  */
166                 ASSERT3U(new->lr_type, ==, RL_WRITER);
167
168                 /*
169                  * First check for the usual case of no locks
170                  */
171                 if (avl_numnodes(tree) == 0) {
172                         avl_add(tree, new);
173                         return (B_TRUE);
174                 }
175
176                 /*
177                  * Look for any locks in the range.
178                  */
179                 lr = avl_find(tree, new, &where);
180                 if (lr != NULL)
181                         goto wait; /* already locked at same offset */
182
183                 lr = (locked_range_t *)avl_nearest(tree, where, AVL_AFTER);
184                 if (lr != NULL &&
185                     lr->lr_offset < new->lr_offset + new->lr_length)
186                         goto wait;
187
188                 lr = (locked_range_t *)avl_nearest(tree, where, AVL_BEFORE);
189                 if (lr != NULL &&
190                     lr->lr_offset + lr->lr_length > new->lr_offset)
191                         goto wait;
192
193                 avl_insert(tree, new, where);
194                 return (B_TRUE);
195 wait:
196                 if (nonblock)
197                         return (B_FALSE);
198                 if (!lr->lr_write_wanted) {
199                         cv_init(&lr->lr_write_cv, NULL, CV_DEFAULT, NULL);
200                         lr->lr_write_wanted = B_TRUE;
201                 }
202                 cv_wait(&lr->lr_write_cv, &rl->rl_lock);
203
204                 /* reset to original */
205                 new->lr_offset = orig_off;
206                 new->lr_length = orig_len;
207                 new->lr_type = orig_type;
208         }
209 }
210
211 /*
212  * If this is an original (non-proxy) lock then replace it by
213  * a proxy and return the proxy.
214  */
215 static locked_range_t *
216 rangelock_proxify(avl_tree_t *tree, locked_range_t *lr)
217 {
218         locked_range_t *proxy;
219
220         if (lr->lr_proxy)
221                 return (lr); /* already a proxy */
222
223         ASSERT3U(lr->lr_count, ==, 1);
224         ASSERT(lr->lr_write_wanted == B_FALSE);
225         ASSERT(lr->lr_read_wanted == B_FALSE);
226         avl_remove(tree, lr);
227         lr->lr_count = 0;
228
229         /* create a proxy range lock */
230         proxy = kmem_alloc(sizeof (locked_range_t), KM_SLEEP);
231         proxy->lr_offset = lr->lr_offset;
232         proxy->lr_length = lr->lr_length;
233         proxy->lr_count = 1;
234         proxy->lr_type = RL_READER;
235         proxy->lr_proxy = B_TRUE;
236         proxy->lr_write_wanted = B_FALSE;
237         proxy->lr_read_wanted = B_FALSE;
238         avl_add(tree, proxy);
239
240         return (proxy);
241 }
242
243 /*
244  * Split the range lock at the supplied offset
245  * returning the *front* proxy.
246  */
247 static locked_range_t *
248 rangelock_split(avl_tree_t *tree, locked_range_t *lr, uint64_t off)
249 {
250         ASSERT3U(lr->lr_length, >, 1);
251         ASSERT3U(off, >, lr->lr_offset);
252         ASSERT3U(off, <, lr->lr_offset + lr->lr_length);
253         ASSERT(lr->lr_write_wanted == B_FALSE);
254         ASSERT(lr->lr_read_wanted == B_FALSE);
255
256         /* create the rear proxy range lock */
257         locked_range_t *rear = kmem_alloc(sizeof (locked_range_t), KM_SLEEP);
258         rear->lr_offset = off;
259         rear->lr_length = lr->lr_offset + lr->lr_length - off;
260         rear->lr_count = lr->lr_count;
261         rear->lr_type = RL_READER;
262         rear->lr_proxy = B_TRUE;
263         rear->lr_write_wanted = B_FALSE;
264         rear->lr_read_wanted = B_FALSE;
265
266         locked_range_t *front = rangelock_proxify(tree, lr);
267         front->lr_length = off - lr->lr_offset;
268
269         avl_insert_here(tree, rear, front, AVL_AFTER);
270         return (front);
271 }
272
273 /*
274  * Create and add a new proxy range lock for the supplied range.
275  */
276 static void
277 rangelock_new_proxy(avl_tree_t *tree, uint64_t off, uint64_t len)
278 {
279         ASSERT(len != 0);
280         locked_range_t *lr = kmem_alloc(sizeof (locked_range_t), KM_SLEEP);
281         lr->lr_offset = off;
282         lr->lr_length = len;
283         lr->lr_count = 1;
284         lr->lr_type = RL_READER;
285         lr->lr_proxy = B_TRUE;
286         lr->lr_write_wanted = B_FALSE;
287         lr->lr_read_wanted = B_FALSE;
288         avl_add(tree, lr);
289 }
290
291 static void
292 rangelock_add_reader(avl_tree_t *tree, locked_range_t *new,
293     locked_range_t *prev, avl_index_t where)
294 {
295         locked_range_t *next;
296         uint64_t off = new->lr_offset;
297         uint64_t len = new->lr_length;
298
299         /*
300          * prev arrives either:
301          * - pointing to an entry at the same offset
302          * - pointing to the entry with the closest previous offset whose
303          *   range may overlap with the new range
304          * - null, if there were no ranges starting before the new one
305          */
306         if (prev != NULL) {
307                 if (prev->lr_offset + prev->lr_length <= off) {
308                         prev = NULL;
309                 } else if (prev->lr_offset != off) {
310                         /*
311                          * convert to proxy if needed then
312                          * split this entry and bump ref count
313                          */
314                         prev = rangelock_split(tree, prev, off);
315                         prev = AVL_NEXT(tree, prev); /* move to rear range */
316                 }
317         }
318         ASSERT((prev == NULL) || (prev->lr_offset == off));
319
320         if (prev != NULL)
321                 next = prev;
322         else
323                 next = avl_nearest(tree, where, AVL_AFTER);
324
325         if (next == NULL || off + len <= next->lr_offset) {
326                 /* no overlaps, use the original new rl_t in the tree */
327                 avl_insert(tree, new, where);
328                 return;
329         }
330
331         if (off < next->lr_offset) {
332                 /* Add a proxy for initial range before the overlap */
333                 rangelock_new_proxy(tree, off, next->lr_offset - off);
334         }
335
336         new->lr_count = 0; /* will use proxies in tree */
337         /*
338          * We now search forward through the ranges, until we go past the end
339          * of the new range. For each entry we make it a proxy if it
340          * isn't already, then bump its reference count. If there's any
341          * gaps between the ranges then we create a new proxy range.
342          */
343         for (prev = NULL; next; prev = next, next = AVL_NEXT(tree, next)) {
344                 if (off + len <= next->lr_offset)
345                         break;
346                 if (prev != NULL && prev->lr_offset + prev->lr_length <
347                     next->lr_offset) {
348                         /* there's a gap */
349                         ASSERT3U(next->lr_offset, >,
350                             prev->lr_offset + prev->lr_length);
351                         rangelock_new_proxy(tree,
352                             prev->lr_offset + prev->lr_length,
353                             next->lr_offset -
354                             (prev->lr_offset + prev->lr_length));
355                 }
356                 if (off + len == next->lr_offset + next->lr_length) {
357                         /* exact overlap with end */
358                         next = rangelock_proxify(tree, next);
359                         next->lr_count++;
360                         return;
361                 }
362                 if (off + len < next->lr_offset + next->lr_length) {
363                         /* new range ends in the middle of this block */
364                         next = rangelock_split(tree, next, off + len);
365                         next->lr_count++;
366                         return;
367                 }
368                 ASSERT3U(off + len, >, next->lr_offset + next->lr_length);
369                 next = rangelock_proxify(tree, next);
370                 next->lr_count++;
371         }
372
373         /* Add the remaining end range. */
374         rangelock_new_proxy(tree, prev->lr_offset + prev->lr_length,
375             (off + len) - (prev->lr_offset + prev->lr_length));
376 }
377
378 /*
379  * Check if a reader lock can be grabbed.  If not, fail immediately or sleep and
380  * recheck until available, depending on the value of the "nonblock" parameter.
381  */
382 static boolean_t
383 rangelock_enter_reader(rangelock_t *rl, locked_range_t *new, boolean_t nonblock)
384 {
385         avl_tree_t *tree = &rl->rl_tree;
386         locked_range_t *prev, *next;
387         avl_index_t where;
388         uint64_t off = new->lr_offset;
389         uint64_t len = new->lr_length;
390
391         /*
392          * Look for any writer locks in the range.
393          */
394 retry:
395         prev = avl_find(tree, new, &where);
396         if (prev == NULL)
397                 prev = (locked_range_t *)avl_nearest(tree, where, AVL_BEFORE);
398
399         /*
400          * Check the previous range for a writer lock overlap.
401          */
402         if (prev && (off < prev->lr_offset + prev->lr_length)) {
403                 if ((prev->lr_type == RL_WRITER) || (prev->lr_write_wanted)) {
404                         if (nonblock)
405                                 return (B_FALSE);
406                         if (!prev->lr_read_wanted) {
407                                 cv_init(&prev->lr_read_cv,
408                                     NULL, CV_DEFAULT, NULL);
409                                 prev->lr_read_wanted = B_TRUE;
410                         }
411                         cv_wait(&prev->lr_read_cv, &rl->rl_lock);
412                         goto retry;
413                 }
414                 if (off + len < prev->lr_offset + prev->lr_length)
415                         goto got_lock;
416         }
417
418         /*
419          * Search through the following ranges to see if there's
420          * write lock any overlap.
421          */
422         if (prev != NULL)
423                 next = AVL_NEXT(tree, prev);
424         else
425                 next = (locked_range_t *)avl_nearest(tree, where, AVL_AFTER);
426         for (; next != NULL; next = AVL_NEXT(tree, next)) {
427                 if (off + len <= next->lr_offset)
428                         goto got_lock;
429                 if ((next->lr_type == RL_WRITER) || (next->lr_write_wanted)) {
430                         if (nonblock)
431                                 return (B_FALSE);
432                         if (!next->lr_read_wanted) {
433                                 cv_init(&next->lr_read_cv,
434                                     NULL, CV_DEFAULT, NULL);
435                                 next->lr_read_wanted = B_TRUE;
436                         }
437                         cv_wait(&next->lr_read_cv, &rl->rl_lock);
438                         goto retry;
439                 }
440                 if (off + len <= next->lr_offset + next->lr_length)
441                         goto got_lock;
442         }
443
444 got_lock:
445         /*
446          * Add the read lock, which may involve splitting existing
447          * locks and bumping ref counts (r_count).
448          */
449         rangelock_add_reader(tree, new, prev, where);
450         return (B_TRUE);
451 }
452
453 /*
454  * Lock a range (offset, length) as either shared (RL_READER) or exclusive
455  * (RL_WRITER or RL_APPEND).  If RL_APPEND is specified, rl_cb() will convert
456  * it to a RL_WRITER lock (with the offset at the end of the file).  Returns
457  * the range lock structure for later unlocking (or reduce range if the
458  * entire file is locked as RL_WRITER).
459  */
460 static locked_range_t *
461 _rangelock_enter(rangelock_t *rl, uint64_t off, uint64_t len,
462     rangelock_type_t type, boolean_t nonblock)
463 {
464         ASSERT(type == RL_READER || type == RL_WRITER || type == RL_APPEND);
465
466         locked_range_t *new = kmem_alloc(sizeof (*new), KM_SLEEP);
467         new->lr_rangelock = rl;
468         new->lr_offset = off;
469         if (len + off < off)    /* overflow */
470                 len = UINT64_MAX - off;
471         new->lr_length = len;
472         new->lr_count = 1; /* assume it's going to be in the tree */
473         new->lr_type = type;
474         new->lr_proxy = B_FALSE;
475         new->lr_write_wanted = B_FALSE;
476         new->lr_read_wanted = B_FALSE;
477
478         mutex_enter(&rl->rl_lock);
479         if (type == RL_READER) {
480                 /*
481                  * First check for the usual case of no locks
482                  */
483                 if (avl_numnodes(&rl->rl_tree) == 0) {
484                         avl_add(&rl->rl_tree, new);
485                 } else if (!rangelock_enter_reader(rl, new, nonblock)) {
486                         kmem_free(new, sizeof (*new));
487                         new = NULL;
488                 }
489         } else if (!rangelock_enter_writer(rl, new, nonblock)) {
490                 kmem_free(new, sizeof (*new));
491                 new = NULL;
492         }
493         mutex_exit(&rl->rl_lock);
494         return (new);
495 }
496
497 locked_range_t *
498 rangelock_enter(rangelock_t *rl, uint64_t off, uint64_t len,
499     rangelock_type_t type)
500 {
501         return (_rangelock_enter(rl, off, len, type, B_FALSE));
502 }
503
504 locked_range_t *
505 rangelock_tryenter(rangelock_t *rl, uint64_t off, uint64_t len,
506     rangelock_type_t type)
507 {
508         return (_rangelock_enter(rl, off, len, type, B_TRUE));
509 }
510
511 /*
512  * Unlock a reader lock
513  */
514 static void
515 rangelock_exit_reader(rangelock_t *rl, locked_range_t *remove)
516 {
517         avl_tree_t *tree = &rl->rl_tree;
518         uint64_t len;
519
520         /*
521          * The common case is when the remove entry is in the tree
522          * (cnt == 1) meaning there's been no other reader locks overlapping
523          * with this one. Otherwise the remove entry will have been
524          * removed from the tree and replaced by proxies (one or
525          * more ranges mapping to the entire range).
526          */
527         if (remove->lr_count == 1) {
528                 avl_remove(tree, remove);
529                 if (remove->lr_write_wanted) {
530                         cv_broadcast(&remove->lr_write_cv);
531                         cv_destroy(&remove->lr_write_cv);
532                 }
533                 if (remove->lr_read_wanted) {
534                         cv_broadcast(&remove->lr_read_cv);
535                         cv_destroy(&remove->lr_read_cv);
536                 }
537         } else {
538                 ASSERT0(remove->lr_count);
539                 ASSERT0(remove->lr_write_wanted);
540                 ASSERT0(remove->lr_read_wanted);
541                 /*
542                  * Find start proxy representing this reader lock,
543                  * then decrement ref count on all proxies
544                  * that make up this range, freeing them as needed.
545                  */
546                 locked_range_t *lr = avl_find(tree, remove, NULL);
547                 ASSERT3P(lr, !=, NULL);
548                 ASSERT3U(lr->lr_count, !=, 0);
549                 ASSERT3U(lr->lr_type, ==, RL_READER);
550                 locked_range_t *next = NULL;
551                 for (len = remove->lr_length; len != 0; lr = next) {
552                         len -= lr->lr_length;
553                         if (len != 0) {
554                                 next = AVL_NEXT(tree, lr);
555                                 ASSERT3P(next, !=, NULL);
556                                 ASSERT3U(lr->lr_offset + lr->lr_length, ==,
557                                     next->lr_offset);
558                                 ASSERT3U(next->lr_count, !=, 0);
559                                 ASSERT3U(next->lr_type, ==, RL_READER);
560                         }
561                         lr->lr_count--;
562                         if (lr->lr_count == 0) {
563                                 avl_remove(tree, lr);
564                                 if (lr->lr_write_wanted) {
565                                         cv_broadcast(&lr->lr_write_cv);
566                                         cv_destroy(&lr->lr_write_cv);
567                                 }
568                                 if (lr->lr_read_wanted) {
569                                         cv_broadcast(&lr->lr_read_cv);
570                                         cv_destroy(&lr->lr_read_cv);
571                                 }
572                                 kmem_free(lr, sizeof (locked_range_t));
573                         }
574                 }
575         }
576         kmem_free(remove, sizeof (locked_range_t));
577 }
578
579 /*
580  * Unlock range and destroy range lock structure.
581  */
582 void
583 rangelock_exit(locked_range_t *lr)
584 {
585         rangelock_t *rl = lr->lr_rangelock;
586
587         ASSERT(lr->lr_type == RL_WRITER || lr->lr_type == RL_READER);
588         ASSERT(lr->lr_count == 1 || lr->lr_count == 0);
589         ASSERT(!lr->lr_proxy);
590
591         mutex_enter(&rl->rl_lock);
592         if (lr->lr_type == RL_WRITER) {
593                 /* writer locks can't be shared or split */
594                 avl_remove(&rl->rl_tree, lr);
595                 mutex_exit(&rl->rl_lock);
596                 if (lr->lr_write_wanted) {
597                         cv_broadcast(&lr->lr_write_cv);
598                         cv_destroy(&lr->lr_write_cv);
599                 }
600                 if (lr->lr_read_wanted) {
601                         cv_broadcast(&lr->lr_read_cv);
602                         cv_destroy(&lr->lr_read_cv);
603                 }
604                 kmem_free(lr, sizeof (locked_range_t));
605         } else {
606                 /*
607                  * lock may be shared, let rangelock_exit_reader()
608                  * release the lock and free the rl_t
609                  */
610                 rangelock_exit_reader(rl, lr);
611                 mutex_exit(&rl->rl_lock);
612         }
613 }
614
615 /*
616  * Reduce range locked as RL_WRITER from whole file to specified range.
617  * Asserts the whole file is exclusively locked and so there's only one
618  * entry in the tree.
619  */
620 void
621 rangelock_reduce(locked_range_t *lr, uint64_t off, uint64_t len)
622 {
623         rangelock_t *rl = lr->lr_rangelock;
624
625         /* Ensure there are no other locks */
626         ASSERT3U(avl_numnodes(&rl->rl_tree), ==, 1);
627         ASSERT3U(lr->lr_offset, ==, 0);
628         ASSERT3U(lr->lr_type, ==, RL_WRITER);
629         ASSERT(!lr->lr_proxy);
630         ASSERT3U(lr->lr_length, ==, UINT64_MAX);
631         ASSERT3U(lr->lr_count, ==, 1);
632
633         mutex_enter(&rl->rl_lock);
634         lr->lr_offset = off;
635         lr->lr_length = len;
636         mutex_exit(&rl->rl_lock);
637         if (lr->lr_write_wanted)
638                 cv_broadcast(&lr->lr_write_cv);
639         if (lr->lr_read_wanted)
640                 cv_broadcast(&lr->lr_read_cv);
641 }