* [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem...
@ 2008-09-09 21:03 Daniel J Blueman
2008-09-10 4:07 ` Nick Piggin
0 siblings, 1 reply; 10+ messages in thread
From: Daniel J Blueman @ 2008-09-09 21:03 UTC (permalink / raw)
To: Linux Kernel
I observed this locking violation [1] while gnome-panel was loading;
this was previously reported at
http://uwsg.iu.edu/hypermail/linux/kernel/0806.3/2881.html .
Let me know for more information/config/testing. Thanks!
Daniel
--- [1]
=======================================================
[ INFO: possible circular locking dependency detected ]
2.6.27-rc5-233c-debug #2
-------------------------------------------------------
gnome-panel/4944 is trying to acquire lock:
(&mm->mmap_sem){----}, at: [<ffffffff806aa40f>] do_page_fault+0x12f/0xae0
but task is already holding lock:
(&dev->ev_mutex){--..}, at: [<ffffffff80320ac3>] inotify_read+0xe3/0x200
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #3 (&dev->ev_mutex){--..}:
[<ffffffff80271889>] __lock_acquire+0xd49/0x1190
[<ffffffff80271d61>] lock_acquire+0x91/0xc0
[<ffffffff806a5069>] __mutex_lock_common+0xb9/0x430
[<ffffffff806a54bf>] mutex_lock_nested+0x3f/0x50
[<ffffffff80321216>] inotify_dev_queue_event+0x46/0x1c0
[<ffffffff803200e6>] inotify_inode_queue_event+0xc6/0x110
[<ffffffff802f424c>] fsnotify_create+0x3c/0x70
[<ffffffff802f4c5d>] vfs_create+0xbd/0xd0
[<ffffffff802f7dfe>] do_filp_open+0x80e/0x910
[<ffffffff802e82b0>] do_sys_open+0x80/0x110
[<ffffffff802e8380>] sys_open+0x20/0x30
[<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
-> #2 (&ih->mutex){--..}:
[<ffffffff80271889>] __lock_acquire+0xd49/0x1190
[<ffffffff80271d61>] lock_acquire+0x91/0xc0
[<ffffffff806a5069>] __mutex_lock_common+0xb9/0x430
[<ffffffff806a54bf>] mutex_lock_nested+0x3f/0x50
[<ffffffff8031fe73>] inotify_find_update_watch+0x53/0xe0
[<ffffffff80320d85>] sys_inotify_add_watch+0x115/0x1d0
[<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
-> #1 (&inode->inotify_mutex){--..}:
[<ffffffff80271889>] __lock_acquire+0xd49/0x1190
[<ffffffff80271d61>] lock_acquire+0x91/0xc0
[<ffffffff806a5069>] __mutex_lock_common+0xb9/0x430
[<ffffffff806a54bf>] mutex_lock_nested+0x3f/0x50
[<ffffffff80320070>] inotify_inode_queue_event+0x50/0x110
[<ffffffff803206e1>] inotify_dentry_parent_queue_event+0x91/0xb0
[<ffffffff802ebb7f>] __fput+0x7f/0x1f0
[<ffffffff802ebd15>] fput+0x25/0x30
[<ffffffff802c84ff>] remove_vma+0x4f/0x90
[<ffffffff802ca359>] do_munmap+0x2e9/0x330
[<ffffffff802ca3f5>] sys_munmap+0x55/0x80
[<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
-> #0 (&mm->mmap_sem){----}:
[<ffffffff80271950>] __lock_acquire+0xe10/0x1190
[<ffffffff80271d61>] lock_acquire+0x91/0xc0
[<ffffffff806a56eb>] down_read+0x4b/0x80
[<ffffffff806aa40f>] do_page_fault+0x12f/0xae0
[<ffffffff806a7bdd>] error_exit+0x0/0xa9
[<ffffffff802eac08>] vfs_read+0xc8/0x170
[<ffffffff802eadb5>] sys_read+0x55/0x90
[<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
other info that might help us debug this:
1 lock held by gnome-panel/4944:
#0: (&dev->ev_mutex){--..}, at: [<ffffffff80320ac3>] inotify_read+0xe3/0x200
stack backtrace:
Pid: 4944, comm: gnome-panel Not tainted 2.6.27-rc5-233c-debug #2
Call Trace:
[<ffffffff8026f807>] print_circular_bug_tail+0xa7/0xf0
[<ffffffff80271950>] __lock_acquire+0xe10/0x1190
[<ffffffff80271d61>] lock_acquire+0x91/0xc0
[<ffffffff806aa40f>] ? do_page_fault+0x12f/0xae0
[<ffffffff806a56eb>] down_read+0x4b/0x80
[<ffffffff806aa40f>] ? do_page_fault+0x12f/0xae0
[<ffffffff8025c51a>] ? search_exception_tables+0x2a/0x50
[<ffffffff806aa40f>] do_page_fault+0x12f/0xae0
[<ffffffff8026d951>] ? trace_hardirqs_off_caller+0x21/0xc0
[<ffffffff80213fc0>] ? native_sched_clock+0x90/0xb0
[<ffffffff80270e39>] ? __lock_acquire+0x2f9/0x1190
[<ffffffff80270606>] ? mark_held_locks+0x56/0xa0
[<ffffffff802708bd>] ? trace_hardirqs_on+0xd/0x10
[<ffffffff80270849>] ? trace_hardirqs_on_caller+0x149/0x1b0
[<ffffffff806a7bdd>] error_exit+0x0/0xa9
[<ffffffff80459acd>] ? copy_user_generic_string+0x2d/0x40
[<ffffffff80320b5d>] ? inotify_read+0x17d/0x200
[<ffffffff8025ee00>] ? autoremove_wake_function+0x0/0x40
[<ffffffff802708bd>] ? trace_hardirqs_on+0xd/0x10
[<ffffffff802eac08>] vfs_read+0xc8/0x170
[<ffffffff802eadb5>] sys_read+0x55/0x90
[<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b
--
Daniel J Blueman
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem... 2008-09-09 21:03 [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem Daniel J Blueman @ 2008-09-10 4:07 ` Nick Piggin 2008-09-10 7:57 ` Peter Zijlstra 2008-09-10 20:12 ` Nick Piggin 0 siblings, 2 replies; 10+ messages in thread From: Nick Piggin @ 2008-09-10 4:07 UTC (permalink / raw) To: Daniel J Blueman, torvalds, Peter Zijlstra, Andrew Morton; +Cc: Linux Kernel [-- Attachment #1: Type: text/plain, Size: 5482 bytes --] On Wednesday 10 September 2008 07:03, Daniel J Blueman wrote: > I observed this locking violation [1] while gnome-panel was loading; > this was previously reported at > http://uwsg.iu.edu/hypermail/linux/kernel/0806.3/2881.html . > > Let me know for more information/config/testing. Thanks! Thanks for the report. I've attached a patch you could test. It compiles (and boots a UML here) but I don't think I've actually tested the inotify path at all, so it may explode on you. Peter, this copy_*_user stuff is quite a nightmare... Well actually it isn't, if the code is designed with it in mind from the start, but it is easy for people to forget it can take mmap_sem and filesystem locks... Is there a way to annotate it and say "might take mmap_sem for read" for example? So that these LORs will _always_ trigger rather than just once in a million times when the reclaim gods frown on us? Anyway, Daniel, thanks again... > Daniel > > --- [1] > > ======================================================= > [ INFO: possible circular locking dependency detected ] > 2.6.27-rc5-233c-debug #2 > ------------------------------------------------------- > gnome-panel/4944 is trying to acquire lock: > (&mm->mmap_sem){----}, at: [<ffffffff806aa40f>] do_page_fault+0x12f/0xae0 > > but task is already holding lock: > (&dev->ev_mutex){--..}, at: [<ffffffff80320ac3>] inotify_read+0xe3/0x200 > > which lock already depends on the new lock. > > > the existing dependency chain (in reverse order) is: > > -> #3 (&dev->ev_mutex){--..}: > [<ffffffff80271889>] __lock_acquire+0xd49/0x1190 > [<ffffffff80271d61>] lock_acquire+0x91/0xc0 > [<ffffffff806a5069>] __mutex_lock_common+0xb9/0x430 > [<ffffffff806a54bf>] mutex_lock_nested+0x3f/0x50 > [<ffffffff80321216>] inotify_dev_queue_event+0x46/0x1c0 > [<ffffffff803200e6>] inotify_inode_queue_event+0xc6/0x110 > [<ffffffff802f424c>] fsnotify_create+0x3c/0x70 > [<ffffffff802f4c5d>] vfs_create+0xbd/0xd0 > [<ffffffff802f7dfe>] do_filp_open+0x80e/0x910 > [<ffffffff802e82b0>] do_sys_open+0x80/0x110 > [<ffffffff802e8380>] sys_open+0x20/0x30 > [<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b > [<ffffffffffffffff>] 0xffffffffffffffff > > -> #2 (&ih->mutex){--..}: > [<ffffffff80271889>] __lock_acquire+0xd49/0x1190 > [<ffffffff80271d61>] lock_acquire+0x91/0xc0 > [<ffffffff806a5069>] __mutex_lock_common+0xb9/0x430 > [<ffffffff806a54bf>] mutex_lock_nested+0x3f/0x50 > [<ffffffff8031fe73>] inotify_find_update_watch+0x53/0xe0 > [<ffffffff80320d85>] sys_inotify_add_watch+0x115/0x1d0 > [<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b > [<ffffffffffffffff>] 0xffffffffffffffff > > -> #1 (&inode->inotify_mutex){--..}: > [<ffffffff80271889>] __lock_acquire+0xd49/0x1190 > [<ffffffff80271d61>] lock_acquire+0x91/0xc0 > [<ffffffff806a5069>] __mutex_lock_common+0xb9/0x430 > [<ffffffff806a54bf>] mutex_lock_nested+0x3f/0x50 > [<ffffffff80320070>] inotify_inode_queue_event+0x50/0x110 > [<ffffffff803206e1>] inotify_dentry_parent_queue_event+0x91/0xb0 > [<ffffffff802ebb7f>] __fput+0x7f/0x1f0 > [<ffffffff802ebd15>] fput+0x25/0x30 > [<ffffffff802c84ff>] remove_vma+0x4f/0x90 > [<ffffffff802ca359>] do_munmap+0x2e9/0x330 > [<ffffffff802ca3f5>] sys_munmap+0x55/0x80 > [<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b > [<ffffffffffffffff>] 0xffffffffffffffff > > -> #0 (&mm->mmap_sem){----}: > [<ffffffff80271950>] __lock_acquire+0xe10/0x1190 > [<ffffffff80271d61>] lock_acquire+0x91/0xc0 > [<ffffffff806a56eb>] down_read+0x4b/0x80 > [<ffffffff806aa40f>] do_page_fault+0x12f/0xae0 > [<ffffffff806a7bdd>] error_exit+0x0/0xa9 > [<ffffffff802eac08>] vfs_read+0xc8/0x170 > [<ffffffff802eadb5>] sys_read+0x55/0x90 > [<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b > [<ffffffffffffffff>] 0xffffffffffffffff > > other info that might help us debug this: > > 1 lock held by gnome-panel/4944: > #0: (&dev->ev_mutex){--..}, at: [<ffffffff80320ac3>] > inotify_read+0xe3/0x200 > > stack backtrace: > Pid: 4944, comm: gnome-panel Not tainted 2.6.27-rc5-233c-debug #2 > > Call Trace: > [<ffffffff8026f807>] print_circular_bug_tail+0xa7/0xf0 > [<ffffffff80271950>] __lock_acquire+0xe10/0x1190 > [<ffffffff80271d61>] lock_acquire+0x91/0xc0 > [<ffffffff806aa40f>] ? do_page_fault+0x12f/0xae0 > [<ffffffff806a56eb>] down_read+0x4b/0x80 > [<ffffffff806aa40f>] ? do_page_fault+0x12f/0xae0 > [<ffffffff8025c51a>] ? search_exception_tables+0x2a/0x50 > [<ffffffff806aa40f>] do_page_fault+0x12f/0xae0 > [<ffffffff8026d951>] ? trace_hardirqs_off_caller+0x21/0xc0 > [<ffffffff80213fc0>] ? native_sched_clock+0x90/0xb0 > [<ffffffff80270e39>] ? __lock_acquire+0x2f9/0x1190 > [<ffffffff80270606>] ? mark_held_locks+0x56/0xa0 > [<ffffffff802708bd>] ? trace_hardirqs_on+0xd/0x10 > [<ffffffff80270849>] ? trace_hardirqs_on_caller+0x149/0x1b0 > [<ffffffff806a7bdd>] error_exit+0x0/0xa9 > [<ffffffff80459acd>] ? copy_user_generic_string+0x2d/0x40 > [<ffffffff80320b5d>] ? inotify_read+0x17d/0x200 > [<ffffffff8025ee00>] ? autoremove_wake_function+0x0/0x40 > [<ffffffff802708bd>] ? trace_hardirqs_on+0xd/0x10 > [<ffffffff802eac08>] vfs_read+0xc8/0x170 > [<ffffffff802eadb5>] sys_read+0x55/0x90 > [<ffffffff8020c86b>] system_call_fastpath+0x16/0x1b [-- Attachment #2: inotify-lor-fix.patch --] [-- Type: text/x-diff, Size: 2356 bytes --] Fix inotify lock order reversal with mmap_sem due to holding locks over copy_to_user. Signed-off-by: Nick Piggin <npiggin@suse.de> --- Index: linux-2.6/fs/inotify_user.c =================================================================== --- linux-2.6.orig/fs/inotify_user.c +++ linux-2.6/fs/inotify_user.c @@ -323,7 +323,7 @@ out: } /* - * remove_kevent - cleans up and ultimately frees the given kevent + * remove_kevent - cleans up the given kevent * * Caller must hold dev->ev_mutex. */ @@ -334,7 +334,13 @@ static void remove_kevent(struct inotify dev->event_count--; dev->queue_size -= sizeof(struct inotify_event) + kevent->event.len; +} +/* + * free_kevent - frees the given kevent. + */ +static void free_kevent(struct inotify_kernel_event *kevent) +{ kfree(kevent->name); kmem_cache_free(event_cachep, kevent); } @@ -350,6 +356,7 @@ static void inotify_dev_event_dequeue(st struct inotify_kernel_event *kevent; kevent = inotify_dev_get_event(dev); remove_kevent(dev, kevent); + free_kevent(kevent); } } @@ -433,17 +440,15 @@ static ssize_t inotify_read(struct file dev = file->private_data; while (1) { - int events; prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE); mutex_lock(&dev->ev_mutex); - events = !list_empty(&dev->events); - mutex_unlock(&dev->ev_mutex); - if (events) { + if (!list_empty(&dev->events)) { ret = 0; - break; + goto have_events; } + mutex_unlock(&dev->ev_mutex); if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; @@ -459,10 +464,9 @@ static ssize_t inotify_read(struct file } finish_wait(&dev->wq, &wait); - if (ret) - return ret; + return ret; - mutex_lock(&dev->ev_mutex); +have_events: while (1) { struct inotify_kernel_event *kevent; @@ -481,6 +485,13 @@ static ssize_t inotify_read(struct file } break; } + remove_kevent(dev, kevent); + + /* + * Must perform the copy_to_user outside the mutex in order + * to avoid a lock order reversal with mmap_sem. + */ + mutex_unlock(&dev->ev_mutex); if (copy_to_user(buf, &kevent->event, event_size)) { ret = -EFAULT; @@ -498,7 +509,9 @@ static ssize_t inotify_read(struct file count -= kevent->event.len; } - remove_kevent(dev, kevent); + free_kevent(kevent); + + mutex_lock(&dev->ev_mutex); } mutex_unlock(&dev->ev_mutex); ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem... 2008-09-10 4:07 ` Nick Piggin @ 2008-09-10 7:57 ` Peter Zijlstra 2008-09-10 8:03 ` Nick Piggin 2008-09-10 20:12 ` Nick Piggin 1 sibling, 1 reply; 10+ messages in thread From: Peter Zijlstra @ 2008-09-10 7:57 UTC (permalink / raw) To: Nick Piggin Cc: Daniel J Blueman, torvalds, Andrew Morton, Linux Kernel, mingo On Wed, 2008-09-10 at 14:07 +1000, Nick Piggin wrote: > On Wednesday 10 September 2008 07:03, Daniel J Blueman wrote: > > I observed this locking violation [1] while gnome-panel was loading; > > this was previously reported at > > http://uwsg.iu.edu/hypermail/linux/kernel/0806.3/2881.html . > > > > Let me know for more information/config/testing. Thanks! > > Thanks for the report. I've attached a patch you could test. It compiles > (and boots a UML here) but I don't think I've actually tested the inotify > path at all, so it may explode on you. > > Peter, this copy_*_user stuff is quite a nightmare... Well actually it > isn't, if the code is designed with it in mind from the start, but it is > easy for people to forget it can take mmap_sem and filesystem locks... Is > there a way to annotate it and say "might take mmap_sem for read" for > example? So that these LORs will _always_ trigger rather than just once > in a million times when the reclaim gods frown on us? Sure, how about the below - untested - uncompiled, might eat kittens, etc.. Just sprinkle something like: might_lock_read(&mm->mmap_sem); in the right places. --- Subject: lockdep: might_lock annotation useful to establish a lock dependency in case the actual dependency is rare or hard to trigger. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> --- diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 331e5f1..0aa657a 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -480,4 +480,22 @@ static inline void print_irqtrace_events(struct task_struct *curr) # define lock_map_release(l) do { } while (0) #endif +#ifdef CONFIG_PROVE_LOCKING +# define might_lock(lock) \ +do { \ + typecheck(struct lockdep_map *, &(lock)->dep_map); \ + lock_acquire(&(lock)->dep_map, 0, 0, 0, 2, NULL, _THIS_IP_); \ + lock_release(&(lock)->dep_map, 0, _THIS_IP_); \ +} while (0) +# define might_lock_read(lock) \ +do { \ + typecheck(struct lockdep_map *, &(lock)->dep_map); \ + lock_acquire(&(lock)->dep_map, 0, 0, 1, 2, NULL, _THIS_IP_); \ + lock_release(&(lock)->dep_map, 0, _THIS_IP_); \ +} while (0) +#else +# define might_lock(lock) do { } while (0) +# define might_lock_read(lock) do { } while (0) +#endif + #endif /* __LINUX_LOCKDEP_H */ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem... 2008-09-10 7:57 ` Peter Zijlstra @ 2008-09-10 8:03 ` Nick Piggin 2008-09-10 8:37 ` Ingo Molnar 0 siblings, 1 reply; 10+ messages in thread From: Nick Piggin @ 2008-09-10 8:03 UTC (permalink / raw) To: Peter Zijlstra Cc: Daniel J Blueman, torvalds, Andrew Morton, Linux Kernel, mingo On Wednesday 10 September 2008 17:57, Peter Zijlstra wrote: > On Wed, 2008-09-10 at 14:07 +1000, Nick Piggin wrote: > > On Wednesday 10 September 2008 07:03, Daniel J Blueman wrote: > > > I observed this locking violation [1] while gnome-panel was loading; > > > this was previously reported at > > > http://uwsg.iu.edu/hypermail/linux/kernel/0806.3/2881.html . > > > > > > Let me know for more information/config/testing. Thanks! > > > > Thanks for the report. I've attached a patch you could test. It compiles > > (and boots a UML here) but I don't think I've actually tested the inotify > > path at all, so it may explode on you. > > > > Peter, this copy_*_user stuff is quite a nightmare... Well actually it > > isn't, if the code is designed with it in mind from the start, but it is > > easy for people to forget it can take mmap_sem and filesystem locks... Is > > there a way to annotate it and say "might take mmap_sem for read" for > > example? So that these LORs will _always_ trigger rather than just once > > in a million times when the reclaim gods frown on us? > > Sure, how about the below - untested - uncompiled, might eat kittens, > etc.. > > Just sprinkle something like: > > might_lock_read(&mm->mmap_sem); > > in the right places. Ahh, very nice, thanks! I'll give that a try... > --- > Subject: lockdep: might_lock annotation > > useful to establish a lock dependency in case the actual dependency is > rare or hard to trigger. > > Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> > --- > diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h > index 331e5f1..0aa657a 100644 > --- a/include/linux/lockdep.h > +++ b/include/linux/lockdep.h > @@ -480,4 +480,22 @@ static inline void print_irqtrace_events(struct > task_struct *curr) # define lock_map_release(l) do { } while (0) > #endif > > +#ifdef CONFIG_PROVE_LOCKING > +# define might_lock(lock) \ > +do { \ > + typecheck(struct lockdep_map *, &(lock)->dep_map); \ > + lock_acquire(&(lock)->dep_map, 0, 0, 0, 2, NULL, _THIS_IP_); \ > + lock_release(&(lock)->dep_map, 0, _THIS_IP_); \ > +} while (0) > +# define might_lock_read(lock) \ > +do { \ > + typecheck(struct lockdep_map *, &(lock)->dep_map); \ > + lock_acquire(&(lock)->dep_map, 0, 0, 1, 2, NULL, _THIS_IP_); \ > + lock_release(&(lock)->dep_map, 0, _THIS_IP_); \ > +} while (0) > +#else > +# define might_lock(lock) do { } while (0) > +# define might_lock_read(lock) do { } while (0) > +#endif > + > #endif /* __LINUX_LOCKDEP_H */ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem... 2008-09-10 8:03 ` Nick Piggin @ 2008-09-10 8:37 ` Ingo Molnar 2008-09-10 9:50 ` Nick Piggin 0 siblings, 1 reply; 10+ messages in thread From: Ingo Molnar @ 2008-09-10 8:37 UTC (permalink / raw) To: Nick Piggin Cc: Peter Zijlstra, Daniel J Blueman, torvalds, Andrew Morton, Linux Kernel * Nick Piggin <nickpiggin@yahoo.com.au> wrote: > On Wednesday 10 September 2008 17:57, Peter Zijlstra wrote: > > On Wed, 2008-09-10 at 14:07 +1000, Nick Piggin wrote: > > > On Wednesday 10 September 2008 07:03, Daniel J Blueman wrote: > > > > I observed this locking violation [1] while gnome-panel was loading; > > > > this was previously reported at > > > > http://uwsg.iu.edu/hypermail/linux/kernel/0806.3/2881.html . > > > > > > > > Let me know for more information/config/testing. Thanks! > > > > > > Thanks for the report. I've attached a patch you could test. It compiles > > > (and boots a UML here) but I don't think I've actually tested the inotify > > > path at all, so it may explode on you. > > > > > > Peter, this copy_*_user stuff is quite a nightmare... Well actually it > > > isn't, if the code is designed with it in mind from the start, but it is > > > easy for people to forget it can take mmap_sem and filesystem locks... Is > > > there a way to annotate it and say "might take mmap_sem for read" for > > > example? So that these LORs will _always_ trigger rather than just once > > > in a million times when the reclaim gods frown on us? > > > > Sure, how about the below - untested - uncompiled, might eat kittens, > > etc.. > > > > Just sprinkle something like: > > > > might_lock_read(&mm->mmap_sem); > > > > in the right places. > > Ahh, very nice, thanks! I'll give that a try... cool! Please send in an RFC patch once you have something that boots - we can stick it into tip/core/locking and see whether there's any new messages on a wide range of systems and workloads. (and we'd also check whether the number of kittens is an invariant.) Ingo ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem... 2008-09-10 8:37 ` Ingo Molnar @ 2008-09-10 9:50 ` Nick Piggin 2008-09-10 9:59 ` Peter Zijlstra 0 siblings, 1 reply; 10+ messages in thread From: Nick Piggin @ 2008-09-10 9:50 UTC (permalink / raw) To: Ingo Molnar Cc: Peter Zijlstra, Daniel J Blueman, torvalds, Andrew Morton, Linux Kernel On Wednesday 10 September 2008 18:37, Ingo Molnar wrote: > * Nick Piggin <nickpiggin@yahoo.com.au> wrote: > > On Wednesday 10 September 2008 17:57, Peter Zijlstra wrote: > > > Sure, how about the below - untested - uncompiled, might eat kittens, > > > etc.. > > > > > > Just sprinkle something like: > > > > > > might_lock_read(&mm->mmap_sem); > > > > > > in the right places. > > > > Ahh, very nice, thanks! I'll give that a try... > > cool! Please send in an RFC patch once you have something that boots - > we can stick it into tip/core/locking and see whether there's any new > messages on a wide range of systems and workloads. (and we'd also check > whether the number of kittens is an invariant.) Well I have verified it boots, and have used the annotation in some of x86-64's user copy routines (luckily no flood of bugs I was scared of, phew!) So I would like to request you merge Peter's patch, and we'll hopefully start seeing the annotations being used. FWIW, I don't suppose lockdep can determine that it is a sleeping lock, and do the appropriate might_sleep checks at this point as well? Thanks, Nick ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem... 2008-09-10 9:50 ` Nick Piggin @ 2008-09-10 9:59 ` Peter Zijlstra 2008-09-10 20:11 ` Nick Piggin 0 siblings, 1 reply; 10+ messages in thread From: Peter Zijlstra @ 2008-09-10 9:59 UTC (permalink / raw) To: Nick Piggin Cc: Ingo Molnar, Daniel J Blueman, torvalds, Andrew Morton, Linux Kernel On Wed, 2008-09-10 at 19:50 +1000, Nick Piggin wrote: > On Wednesday 10 September 2008 18:37, Ingo Molnar wrote: > > * Nick Piggin <nickpiggin@yahoo.com.au> wrote: > > > On Wednesday 10 September 2008 17:57, Peter Zijlstra wrote: > > > > > Sure, how about the below - untested - uncompiled, might eat kittens, > > > > etc.. > > > > > > > > Just sprinkle something like: > > > > > > > > might_lock_read(&mm->mmap_sem); > > > > > > > > in the right places. > > > > > > Ahh, very nice, thanks! I'll give that a try... > > > > cool! Please send in an RFC patch once you have something that boots - > > we can stick it into tip/core/locking and see whether there's any new > > messages on a wide range of systems and workloads. (and we'd also check > > whether the number of kittens is an invariant.) > > Well I have verified it boots, and have used the annotation in some of > x86-64's user copy routines (luckily no flood of bugs I was scared of, > phew!) > > So I would like to request you merge Peter's patch, and we'll hopefully > start seeing the annotations being used. Will you send your x86_64 patch to be the first? > FWIW, I don't suppose lockdep > can determine that it is a sleeping lock, and do the appropriate > might_sleep checks at this point as well? Humm, no - we don't actually have that information there - I guess one could add it to lockdep_map and set it from the various init routines, but I'm not sure its worth it - just add might_sleep() along with might_lock() :-) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem... 2008-09-10 9:59 ` Peter Zijlstra @ 2008-09-10 20:11 ` Nick Piggin 0 siblings, 0 replies; 10+ messages in thread From: Nick Piggin @ 2008-09-10 20:11 UTC (permalink / raw) To: Peter Zijlstra Cc: Ingo Molnar, Daniel J Blueman, torvalds, Andrew Morton, Linux Kernel On Wednesday 10 September 2008 19:59, Peter Zijlstra wrote: > On Wed, 2008-09-10 at 19:50 +1000, Nick Piggin wrote: > > On Wednesday 10 September 2008 18:37, Ingo Molnar wrote: > > > * Nick Piggin <nickpiggin@yahoo.com.au> wrote: > > > > On Wednesday 10 September 2008 17:57, Peter Zijlstra wrote: > > > > > Sure, how about the below - untested - uncompiled, might eat > > > > > kittens, etc.. > > > > > > > > > > Just sprinkle something like: > > > > > > > > > > might_lock_read(&mm->mmap_sem); > > > > > > > > > > in the right places. > > > > > > > > Ahh, very nice, thanks! I'll give that a try... > > > > > > cool! Please send in an RFC patch once you have something that boots - > > > we can stick it into tip/core/locking and see whether there's any new > > > messages on a wide range of systems and workloads. (and we'd also check > > > whether the number of kittens is an invariant.) > > > > Well I have verified it boots, and have used the annotation in some of > > x86-64's user copy routines (luckily no flood of bugs I was scared of, > > phew!) > > > > So I would like to request you merge Peter's patch, and we'll hopefully > > start seeing the annotations being used. > > Will you send your x86_64 patch to be the first? OK. > > FWIW, I don't suppose lockdep > > can determine that it is a sleeping lock, and do the appropriate > > might_sleep checks at this point as well? > > Humm, no - we don't actually have that information there - I guess one > could add it to lockdep_map and set it from the various init routines, > but I'm not sure its worth it - just add might_sleep() along with > might_lock() :-) I guess so... seems like lockdep should know about "locks", however :) Spinlock isn't always a spinlock, and ordinary kernel code usually should not care about that. But I'll add it in this case. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem... 2008-09-10 4:07 ` Nick Piggin 2008-09-10 7:57 ` Peter Zijlstra @ 2008-09-10 20:12 ` Nick Piggin 2008-09-10 20:10 ` Daniel J Blueman 1 sibling, 1 reply; 10+ messages in thread From: Nick Piggin @ 2008-09-10 20:12 UTC (permalink / raw) To: Daniel J Blueman; +Cc: torvalds, Peter Zijlstra, Andrew Morton, Linux Kernel [-- Attachment #1: Type: text/plain, Size: 647 bytes --] On Wednesday 10 September 2008 14:07, Nick Piggin wrote: > On Wednesday 10 September 2008 07:03, Daniel J Blueman wrote: > > I observed this locking violation [1] while gnome-panel was loading; > > this was previously reported at > > http://uwsg.iu.edu/hypermail/linux/kernel/0806.3/2881.html . > > > > Let me know for more information/config/testing. Thanks! > > Thanks for the report. I've attached a patch you could test. It compiles > (and boots a UML here) but I don't think I've actually tested the inotify > path at all, so it may explode on you. Indeed it was wrong, I messed up the waitqueue handling. This one survives longer for me... [-- Attachment #2: inotify-lor-fix.patch --] [-- Type: text/x-diff, Size: 2629 bytes --] Fix inotify lock order reversal with mmap_sem due to holding locks over copy_to_user. Signed-off-by: Nick Piggin <npiggin@suse.de> --- Index: linux-2.6/fs/inotify_user.c =================================================================== --- linux-2.6.orig/fs/inotify_user.c +++ linux-2.6/fs/inotify_user.c @@ -323,7 +323,7 @@ out: } /* - * remove_kevent - cleans up and ultimately frees the given kevent + * remove_kevent - cleans up the given kevent * * Caller must hold dev->ev_mutex. */ @@ -334,7 +334,13 @@ static void remove_kevent(struct inotify dev->event_count--; dev->queue_size -= sizeof(struct inotify_event) + kevent->event.len; +} +/* + * free_kevent - frees the given kevent. + */ +static void free_kevent(struct inotify_kernel_event *kevent) +{ kfree(kevent->name); kmem_cache_free(event_cachep, kevent); } @@ -350,6 +356,7 @@ static void inotify_dev_event_dequeue(st struct inotify_kernel_event *kevent; kevent = inotify_dev_get_event(dev); remove_kevent(dev, kevent); + free_kevent(kevent); } } @@ -433,17 +440,15 @@ static ssize_t inotify_read(struct file dev = file->private_data; while (1) { - int events; prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE); mutex_lock(&dev->ev_mutex); - events = !list_empty(&dev->events); - mutex_unlock(&dev->ev_mutex); - if (events) { + if (!list_empty(&dev->events)) { ret = 0; break; } + mutex_unlock(&dev->ev_mutex); if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; @@ -462,7 +467,6 @@ static ssize_t inotify_read(struct file if (ret) return ret; - mutex_lock(&dev->ev_mutex); while (1) { struct inotify_kernel_event *kevent; @@ -481,6 +485,13 @@ static ssize_t inotify_read(struct file } break; } + remove_kevent(dev, kevent); + + /* + * Must perform the copy_to_user outside the mutex in order + * to avoid a lock order reversal with mmap_sem. + */ + mutex_unlock(&dev->ev_mutex); if (copy_to_user(buf, &kevent->event, event_size)) { ret = -EFAULT; @@ -498,7 +509,9 @@ static ssize_t inotify_read(struct file count -= kevent->event.len; } - remove_kevent(dev, kevent); + free_kevent(kevent); + + mutex_lock(&dev->ev_mutex); } mutex_unlock(&dev->ev_mutex); Index: linux-2.6/include/asm-x86/uaccess_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/uaccess_64.h +++ linux-2.6/include/asm-x86/uaccess_64.h @@ -7,6 +7,7 @@ #include <linux/compiler.h> #include <linux/errno.h> #include <linux/prefetch.h> +#include <linux/lockdep.h> #include <asm/page.h> /* ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem... 2008-09-10 20:12 ` Nick Piggin @ 2008-09-10 20:10 ` Daniel J Blueman 0 siblings, 0 replies; 10+ messages in thread From: Daniel J Blueman @ 2008-09-10 20:10 UTC (permalink / raw) To: Nick Piggin; +Cc: torvalds, Peter Zijlstra, Andrew Morton, Linux Kernel On Wed, Sep 10, 2008 at 9:12 PM, Nick Piggin <nickpiggin@yahoo.com.au> wrote: > On Wednesday 10 September 2008 14:07, Nick Piggin wrote: >> On Wednesday 10 September 2008 07:03, Daniel J Blueman wrote: >> > I observed this locking violation [1] while gnome-panel was loading; >> > this was previously reported at >> > http://uwsg.iu.edu/hypermail/linux/kernel/0806.3/2881.html . >> > >> > Let me know for more information/config/testing. Thanks! >> >> Thanks for the report. I've attached a patch you could test. It compiles >> (and boots a UML here) but I don't think I've actually tested the inotify >> path at all, so it may explode on you. > > Indeed it was wrong, I messed up the waitqueue handling. This one > survives longer for me... So far, so good with that last patch. I'll continue testing this and follow up if I find any problem. Thanks for the patching, Nick! Daniel -- Daniel J Blueman ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-09-10 20:10 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-09-09 21:03 [2.6.27-rc5] inotify_read's ev_mutex vs do_page_fault's mmap_sem Daniel J Blueman 2008-09-10 4:07 ` Nick Piggin 2008-09-10 7:57 ` Peter Zijlstra 2008-09-10 8:03 ` Nick Piggin 2008-09-10 8:37 ` Ingo Molnar 2008-09-10 9:50 ` Nick Piggin 2008-09-10 9:59 ` Peter Zijlstra 2008-09-10 20:11 ` Nick Piggin 2008-09-10 20:12 ` Nick Piggin 2008-09-10 20:10 ` Daniel J Blueman
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®