Messages in this thread Patch in this message | | | Date | Wed, 24 Feb 1999 21:42:33 +0100 (CET) | From | Andrea Arcangeli <> | Subject | [patch] fixed lock_super() deadlock (process in D state) |
| |
With the help of David Mansfield I am been able to remotely debug the process in D state problem of 2.2.2 (and previous).
The problem is that the same process does lock_super() two times.
This patch I developed some hours ago against 2.2.2 fix the deadlock perfectly:
Index: include/linux/locks.h =================================================================== RCS file: /var/cvs/linux/include/linux/locks.h,v retrieving revision 1.1.2.3 diff -u -r1.1.2.3 locks.h --- locks.h 1999/02/09 20:27:39 1.1.2.3 +++ linux/include/linux/locks.h 1999/02/24 18:28:19 @@ -39,17 +39,20 @@ */ extern void __wait_on_super(struct super_block *); +#define is_super_locked(sb) ((sb)->s_lock && (sb)->s_owner != current) + extern inline void wait_on_super(struct super_block * sb) { - if (sb->s_lock) + if (is_super_locked(sb)) __wait_on_super(sb); } extern inline void lock_super(struct super_block * sb) { - if (sb->s_lock) + if (is_super_locked(sb)) __wait_on_super(sb); sb->s_lock = 1; + sb->s_owner = current; } extern inline void unlock_super(struct super_block * sb) Index: include/linux/fs.h =================================================================== RCS file: /var/cvs/linux/include/linux/fs.h,v retrieving revision 1.1.2.9 diff -u -r1.1.2.9 fs.h --- fs.h 1999/02/16 17:30:00 1.1.2.9 +++ linux/include/linux/fs.h 1999/02/24 18:23:20 @@ -519,6 +519,7 @@ unsigned char s_lock; unsigned char s_rd_only; unsigned char s_dirt; + struct task_struct * s_owner; struct file_system_type *s_type; struct super_operations *s_op; struct dquot_operations *dq_op; Index: fs//super.c =================================================================== RCS file: /var/cvs/linux/fs/super.c,v retrieving revision 1.1.2.3 diff -u -r1.1.2.3 super.c --- super.c 1999/01/31 22:44:49 1.1.2.3 +++ linux/fs/super.c 1999/02/24 18:28:39 @@ -517,7 +517,7 @@ s = sb_entry(s->s_list.next)) { if (s->s_dev) continue; - if (!s->s_lock) + if (!is_super_locked(s)) return s; printk("VFS: empty superblock %p locked!\n", s); }
I don't know _why_ this patch is needed and if it's 100% safe. Right now I am trying with David's help to understand where the kernel is recursively calling lock_super().
I want also to point out that the new semaphores of 2.2.2 had nothing to do with these deadlock (so be quiet and go ahead porting them to all archs ;).
Andrea Arcangeli
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |