lkml.org 
[lkml]   [2000]   [Aug]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[FIX] Make deadlock detection work for file locking
Date
From
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/
\
 
 \ /
  Last update: 2005-03-22 12:37    [W:0.023 / U:22.096 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site