Messages in this thread Patch in this message |  | | Subject | [FIX] Make deadlock detection work for file locking | Date | Mon, 21 Aug 2000 16:40:21 +1000 | From | Stephen Rothwell <> |
| |
Hi Linus,
Somewhere along the line, deadlock detection on fcntl locks broke. Again, this was deteced by Chris Yeoh's POSIX compliance testing. The following patch (part of a patch originally from Matthew Wilcox (willy@thepuffingroup.com)) seems to cure the problem and as a side effect speeds up deadlock detection some what.
Patch is against 2.4.0-test7pre4 but applies just as well against 2.4.0-test7pre5.
Cheers, Stephen -- Stephen Rothwell, Open Source Researcher, Linuxcare, Inc. +61-2-62628990 tel, +61-2-62628991 fax sfr@linuxcare.com, http://www.linuxcare.com/ Linuxcare. Support for the revolution.
diff -ruN 2.4.0-test7pre4/fs/locks.c 2.4.0-test7pre4-DL/fs/locks.c --- 2.4.0-test7pre4/fs/locks.c Thu Aug 17 21:29:48 2000 +++ 2.4.0-test7pre4-DL/fs/locks.c Mon Aug 21 15:15:41 2000 @@ -103,6 +103,11 @@ * * Fixed /proc/locks interface so that we can't overrun the buffer we are handed. * Andy Walker (andy@lysaker.kvaerner.no), May 12, 1997. + * + * Use slab allocator instead of kmalloc/kfree. + * Use generic list implementation from <linux/list.h>. + * Sped up posix_locks_deadlock by only considering blocked locks. + * Matthew Wilcox <willy@thepuffingroup.com>, March, 2000. */ #include <linux/malloc.h> @@ -351,8 +356,8 @@ locks_delete_block(waiter); } list_add_tail(&waiter->fl_block, &blocker->fl_block); -// list_add(&waiter->fl_link, &blocked_list); -// waiter->fl_next = blocker; + list_add(&waiter->fl_link, &blocked_list); + waiter->fl_next = blocker; } /* Wake up processes blocked waiting for blocker. @@ -511,34 +516,27 @@ struct file_lock *block_fl) { struct list_head *tmp; - void *caller_owner, *blocked_owner; + fl_owner_t caller_owner, blocked_owner; unsigned int caller_pid, blocked_pid; caller_owner = caller_fl->fl_owner; caller_pid = caller_fl->fl_pid; blocked_owner = block_fl->fl_owner; blocked_pid = block_fl->fl_pid; + tmp = blocked_list.next; next_task: if (caller_owner == blocked_owner && caller_pid == blocked_pid) return 1; - list_for_each(tmp, &file_lock_list) { - struct list_head *btmp; + while (tmp != &blocked_list) { struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link); - if (fl->fl_owner == NULL || list_empty(&fl->fl_block)) - continue; - list_for_each(btmp, &fl->fl_block) { - struct file_lock *bfl = list_entry(tmp, struct file_lock, fl_block); - if (bfl->fl_owner == blocked_owner && - bfl->fl_pid == blocked_pid) { - if (fl->fl_owner == caller_owner && - fl->fl_pid == caller_pid) { - return (1); - } - blocked_owner = fl->fl_owner; - blocked_pid = fl->fl_pid; - goto next_task; - } + tmp = tmp->next; + if ((fl->fl_owner == blocked_owner) + && (fl->fl_pid == blocked_pid)) { + fl = fl->fl_next; + blocked_owner = fl->fl_owner; + blocked_pid = fl->fl_pid; + goto next_task; } } return 0; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
|  |