Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

add spin_lock_irqsave_nolockdep and mutex type MUTEX_NOLOCKDEP #480

Closed
wants to merge 3 commits into from

Conversation

ofaaland
Copy link
Contributor

@ofaaland ofaaland commented Oct 7, 2015

When running a kernel with CONFIG_LOCKDEP=y, lockdep reports possible
recursive locking in some cases and possible circular locking dependency
in others, within the SPL and ZFS modules.

When lockdep detects these conditions, it disables further lock analysis
for all locks. This causes /proc/lock_stats not to reflect full
information about lock contention, even in locks without dependency
issues.

This commit creates new macros spin_lock_irqsave_nolockdep and
spin_unlock_irqrestore_nolockdep. These macros use lockdep_off() and
lockdep_on() to temporarily disable lockdep when taking/releasing the
locks.

This commit also creates a new type of mutex, MUTEX_NOLOCKDEP. This
mutex type causes subsequent attempts to take or release those locks to
be wrapped in lockdep_off() and lockdep_on().

At this time it's unknown whether this method distorts the statistics
reported by lock_stats.

This commit uses the new spin_lock macros for one such offending lock.

See also commit "Identify locks flagged by lockdep" at openzfs/zfs#3895

Combined, these two commits mark all offending locks at this time, for
later analysis and fixes or annotation.

@ofaaland
Copy link
Contributor Author

ofaaland commented Oct 7, 2015

Lockdep reported potential issues with five locks. Here is the output for each, for investigation.

List of locks affected                                                     
======================                                                     
1) (&mls->mls_lock){+.+...}, at: [<ffffffffa03a38d2>] multilist_sublist_lock+0x22/0x40 [zfs]
2) (&zio->io_lock){+.+...}, at: [<ffffffffa04393a3>] zio_add_child+0x93/0x2b0 [zfs]         
3) (&vd->vdev_dtl_lock){+.+...}, at: [<ffffffffa03b9942>] vdev_dtl_reassess+0x3b2/0x710 [zfs]
4) (&tq->tq_lock){......}, at: [<ffffffffa02e3372>] taskq_dispatch+0x32/0x170 [spl]          
5) (&db->db_mtx){+.+.+.}, at: [<ffffffffa033e558>] dbuf_sync_leaf+0x48/0x4f0 [zfs]           
   (&dr->dt.di.dr_mtx){+.+...}, at: [<ffffffffa033eb62>] dbuf_sync_indirect+0x102/0x330 [zfs]

Lockdep output for those locks
==============================
1) (&mls->mls_lock){+.+...}, at: [<ffffffffa03a38d2>] multilist_sublist_lock+0x22/0x40 [zfs]
[ INFO: possible recursive locking detected ]                                               

arc_adapt/24873 is trying to acquire lock:
 (&mls->mls_lock){+.+...}, at: [<ffffffffa03a38d2>] multilist_sublist_lock+0x22/0x40 [zfs]

but task is already holding lock:
 (&mls->mls_lock){+.+...}, at: [<ffffffffa03a38d2>] multilist_sublist_lock+0x22/0x40 [zfs]

other info that might help us debug this:
1 lock held by arc_adapt/24873:          
 #0:  (&mls->mls_lock){+.+...}, at: [<ffffffffa03a38d2>] multilist_sublist_lock+0x22/0x40 [zfs]

stack backtrace:
Pid: 24873, comm: arc_adapt Not tainted 2.6.32-504.16.2.1chaos.ch5.3.x86_64.debug #1
Call Trace:                                                                         
 [<ffffffff810bfe90>] ? __lock_acquire+0x11b0/0x1560                                
 [<ffffffff810c02e4>] ? lock_acquire+0xa4/0x120                                     
 [<ffffffffa03a38d2>] ? multilist_sublist_lock+0x22/0x40 [zfs]                      
 [<ffffffff810be1d3>] ? mark_held_locks+0x73/0xa0                                   
 [<ffffffff8155f4db>] ? mutex_lock_nested+0x2eb/0x3b0                               
 [<ffffffffa03a38d2>] ? multilist_sublist_lock+0x22/0x40 [zfs]                      
 [<ffffffffa03a38d2>] ? multilist_sublist_lock+0x22/0x40 [zfs]                      
 [<ffffffff8155f24c>] ? mutex_lock_nested+0x5c/0x3b0                                
 [<ffffffffa03a38d2>] ? multilist_sublist_lock+0x22/0x40 [zfs]                      
 [<ffffffff813590c4>] ? get_random_bytes+0xa4/0xc0                                  
 [<ffffffffa03a38d2>] ? multilist_sublist_lock+0x22/0x40 [zfs]                      
 [<ffffffffa0353623>] ? arc_adjust_type+0x43/0x110 [zfs]                            
 [<ffffffffa03572f2>] ? arc_adjust+0xe2/0x470 [zfs]                                 
 [<ffffffffa03577e9>] ? arc_adapt_thread+0x169/0x220 [zfs]                          
 [<ffffffffa0357680>] ? arc_adapt_thread+0x0/0x220 [zfs]                            
 [<ffffffffa0309908>] ? thread_generic_wrapper+0x68/0x80 [spl]                      
 [<ffffffffa03098a0>] ? thread_generic_wrapper+0x0/0x80 [spl]                       
 [<ffffffff810a4cbe>] ? kthread+0x9e/0xc0                                           
 [<ffffffff8100c30a>] ? child_rip+0xa/0x20                                          
 [<ffffffff8100bb10>] ? restore_args+0x0/0x30                                       
 [<ffffffff810a4c20>] ? kthread+0x0/0xc0                                            
 [<ffffffff8100c300>] ? child_rip+0x0/0x20                                          


2) (&zio->io_lock){+.+...}, at: [<ffffffffa04393a3>] zio_add_child+0x93/0x2b0 [zfs]
[ INFO: possible recursive locking detected ]                                      

vdev_open/1884 is trying to acquire lock:
 (&zio->io_lock){+.+...}, at: [<ffffffffa04393a3>] zio_add_child+0x93/0x2b0 [zfs]

but task is already holding lock:
 (&zio->io_lock){+.+...}, at: [<ffffffffa0439372>] zio_add_child+0x62/0x2b0 [zfs]

other info that might help us debug this:
1 lock held by vdev_open/1884:           
 #0:  (&zio->io_lock){+.+...}, at: [<ffffffffa0439372>] zio_add_child+0x62/0x2b0 [zfs]

stack backtrace:
Pid: 1884, comm: vdev_open Not tainted 2.6.32-504.16.2.1chaos.ch5.3.x86_64.debug #1
Call Trace:                                                                        
 [<ffffffff810bfe90>] ? __lock_acquire+0x11b0/0x1560                               
 [<ffffffff8100bb10>] ? restore_args+0x0/0x30                                      
 [<ffffffff810c02e4>] ? lock_acquire+0xa4/0x120                                    
 [<ffffffffa04393a3>] ? zio_add_child+0x93/0x2b0 [zfs]                             
 [<ffffffff810be1d3>] ? mark_held_locks+0x73/0xa0                                  
 [<ffffffff8155f4db>] ? mutex_lock_nested+0x2eb/0x3b0                              
 [<ffffffffa0439372>] ? zio_add_child+0x62/0x2b0 [zfs]                             
 [<ffffffffa04393a3>] ? zio_add_child+0x93/0x2b0 [zfs]                             
 [<ffffffff8155f24c>] ? mutex_lock_nested+0x5c/0x3b0                               
 [<ffffffffa04393a3>] ? zio_add_child+0x93/0x2b0 [zfs]                             
 [<ffffffff810bab78>] ? static_obj+0xb8/0xd0                                       
 [<ffffffffa04393a3>] ? zio_add_child+0x93/0x2b0 [zfs]                             
 [<ffffffffa04399cc>] ? zio_create+0x40c/0x4f0 [zfs]                               
 [<ffffffffa0439da4>] ? zio_read_phys+0x74/0x80 [zfs]                              
 [<ffffffffa03eb970>] ? vdev_probe_done+0x0/0x3c0 [zfs]                            
 [<ffffffffa03e87d2>] ? vdev_probe+0x172/0x2d0 [zfs]                               
 [<ffffffffa03eb970>] ? vdev_probe_done+0x0/0x3c0 [zfs]                            
 [<ffffffffa040a635>] ? zfs_post_state_change+0x15/0x20 [zfs]                      
 [<ffffffffa03ea315>] ? vdev_open+0x4d5/0x5e0 [zfs]                                
 [<ffffffff815619e0>] ? _spin_unlock_irqrestore+0x40/0x80                          
 [<ffffffffa03eb076>] ? vdev_open_child+0x26/0x40 [zfs]                            
 [<ffffffffa030b70f>] ? taskq_thread+0x25f/0x5a0 [spl]                             
 [<ffffffff81066f00>] ? default_wake_function+0x0/0x20                             
 [<ffffffffa030b4b0>] ? taskq_thread+0x0/0x5a0 [spl]                               
 [<ffffffff810a4cbe>] ? kthread+0x9e/0xc0                                          
 [<ffffffff8100c30a>] ? child_rip+0xa/0x20                                         
 [<ffffffff8100bb10>] ? restore_args+0x0/0x30                                      
 [<ffffffff810a4c20>] ? kthread+0x0/0xc0                                           
 [<ffffffff8100c300>] ? child_rip+0x0/0x20                                         

3) (&vd->vdev_dtl_lock){+.+...}, at: [<ffffffffa03b9942>] vdev_dtl_reassess+0x3b2/0x710 [zfs]
[ INFO: possible recursive locking detected ]                                                
2.6.32-504.16.2.1chaos.ch5.3.x86_64.debug #1                                                 
---------------------------------------------                                                
lt-zpool/1764 is trying to acquire lock:                                                     
 (&vd->vdev_dtl_lock){+.+...}, at: [<ffffffffa03b9942>] vdev_dtl_reassess+0x3b2/0x710 [zfs]  

but task is already holding lock:
 (&vd->vdev_dtl_lock){+.+...}, at: [<ffffffffa03b9884>] vdev_dtl_reassess+0x2f4/0x710 [zfs]

other info that might help us debug this:
2 locks held by lt-zpool/1764:           
 #0:  (&spa_namespace_lock){+.+.+.}, at: [<ffffffffa039b414>] spa_tryimport+0x84/0x490 [zfs]
 #1:  (&vd->vdev_dtl_lock){+.+...}, at: [<ffffffffa03b9884>] vdev_dtl_reassess+0x2f4/0x710 [zfs]

stack backtrace:
Pid: 1764, comm: lt-zpool Not tainted 2.6.32-504.16.2.1chaos.ch5.3.x86_64.debug #1
Call Trace:                                                                       
 [<ffffffff810bfe90>] ? __lock_acquire+0x11b0/0x1560                              
 [<ffffffff810acb48>] ? sched_clock_cpu+0xb8/0x110                                
 [<ffffffff810baabd>] ? trace_hardirqs_off+0xd/0x10                               
 [<ffffffff810acc8f>] ? cpu_clock+0x6f/0x80                                       
2e4>] ? lock_acquire+0xa4/0x120                                                   
 [<ffffffffa03b9942>] ? vdev_dtl_reassess+0x3b2/0x710 [zfs]                       
 [<ffffffff810be1d3>] ? mark_held_locks+0x73/0xa0                                 
 [<ffffffff8155f4db>] ? mutex_lock_nested+0x2eb/0x3b0                             
 [<ffffffffa03b9884>] ? vdev_dtl_reassess+0x2f4/0x710 [zfs]                       
 [<ffffffffa03b9942>] ? vdev_dtl_reassess+0x3b2/0x710 [zfs]                       
 [<ffffffff8155f24c>] ? mutex_lock_nested+0x5c/0x3b0                              
 [<ffffffffa03b9942>] ? vdev_dtl_reassess+0x3b2/0x710 [zfs]                       
 [<ffffffffa03a384b>] ? spa_config_enter+0x17b/0x270 [zfs]                        
 [<ffffffff81041ffc>] ? kvm_clock_read+0x1c/0x20                                  
 [<ffffffffa03b9942>] ? vdev_dtl_reassess+0x3b2/0x710 [zfs]                       
 [<ffffffff810acb48>] ? sched_clock_cpu+0xb8/0x110                                
 [<ffffffffa03a99d0>] ? space_reftree_compare+0x0/0x40 [zfs]                      
 [<ffffffffa03b95fd>] ? vdev_dtl_reassess+0x6d/0x710 [zfs]                        
 [<ffffffffa03a384b>] ? spa_config_enter+0x17b/0x270 [zfs]                        
 [<ffffffffa039972b>] ? spa_load+0xe5b/0x1be0 [zfs]                               
 [<ffffffff812c4048>] ? __spin_lock_init+0x38/0x70                                
 [<ffffffffa0392a95>] ? spa_activate+0x1b5/0x510 [zfs]                            
 [<ffffffffa039b45b>] ? spa_tryimport+0xcb/0x490 [zfs]                            
 [<ffffffffa03e9039>] ? zfs_ioc_pool_tryimport+0x49/0xd0 [zfs]                    
 [<ffffffffa02dfbb9>] ? strdup+0x69/0x80 [spl]                                    
 [<ffffffffa03e4922>] ? zfsdev_ioctl+0x562/0x620 [zfs]                            
 [<ffffffff811c1532>] ? vfs_ioctl+0x22/0xa0                                       
 [<ffffffff811c16d4>] ? do_vfs_ioctl+0x84/0x590                                   
 [<ffffffff811ad3e6>] ? __fput+0x1d6/0x280                                        
 [<ffffffff8100baf5>] ? retint_swapgs+0x13/0x1b                                   
 [<ffffffff811c1c61>] ? sys_ioctl+0x81/0xa0                                       
 [<ffffffff8100b072>] ? system_call_fastpath+0x16/0x1b                            

4) (&tq->tq_lock){......}, at: [<ffffffffa02e3372>] taskq_dispatch+0x32/0x170 [spl]
[ INFO: possible recursive locking detected ]                                      
2.6.32-504.16.2.1chaos.ch5.3.x86_64.debug #1                                       
---------------------------------------------                                      
spl_system_task/1679 is trying to acquire lock:                                    
 (&tq->tq_lock){......}, at: [<ffffffffa02e3372>] taskq_dispatch+0x32/0x170 [spl]  

but task is already holding lock:
 (&tq->tq_lock){......}, at: [<ffffffffa02e3717>] taskq_thread+0x267/0x5a0 [spl]

other info that might help us debug this:
1 lock held by spl_system_task/1679:     
 #0:  (&tq->tq_lock){......}, at: [<ffffffffa02e3717>] taskq_thread+0x267/0x5a0 [spl]

stack backtrace:
Pid: 1679, comm: spl_system_task Not tainted 2.6.32-504.16.2.1chaos.ch5.3.x86_64.debug #1
Call Trace:                                                                              
 [<ffffffff810bfe90>] ? __lock_acquire+0x11b0/0x1560                                     
 [<ffffffff810baabd>] ? trace_hardirqs_off+0xd/0x10                                      
 [<ffffffff81561a07>] ? _spin_unlock_irqrestore+0x67/0x80                                
 [<ffffffff810c02e4>] ? lock_acquire+0xa4/0x120                                          
 [<ffffffffa02e3372>] ? taskq_dispatch+0x32/0x170 [spl]                                  
 [<ffffffff8118cced>] ? cache_free_debugcheck+0x1ad/0x270                                
 [<ffffffff81561d95>] ? _spin_lock_irqsave+0x55/0xa0                                     
 [<ffffffffa02e3372>] ? taskq_dispatch+0x32/0x170 [spl]                                  
 [<ffffffffa02e3f40>] ? taskq_thread_spawn_task+0x0/0x40 [spl]                           
 [<ffffffffa02e3372>] ? taskq_dispatch+0x32/0x170 [spl]                                  
 [<ffffffffa02e3a1b>] ? taskq_thread+0x56b/0x5a0 [spl]                                   
 [<ffffffff81066f00>] ? default_wake_function+0x0/0x20                                   
 [<ffffffffa02e34b0>] ? taskq_thread+0x0/0x5a0 [spl]                                     
 [<ffffffff810a4cbe>] ? kthread+0x9e/0xc0                                                
 [<ffffffff8100c30a>] ? child_rip+0xa/0x20                                               
 [<ffffffff8100bb10>] ? restore_args+0x0/0x30                                            
 [<ffffffff810a4c20>] ? kthread+0x0/0xc0                                                 
 [<ffffffff8100c300>] ? child_rip+0x0/0x20                                               

 /* NOTE
  * gdb reports following for the two locations the lock is acquired
  */                                                                

Reading symbols from /home/faaland1/spl/module/spl/spl.ko...done.
(gdb) l *(taskq_dispatch+0x32)                                   
0x43a2 is in taskq_dispatch (/home/faaland1/spl/module/spl/../../module/spl/spl-taskq.c:538).
533             ASSERT(func);                                                                
534                                                                                          
535             spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);                          
536                                                                                          
537             /* Taskq being destroyed and all tasks drained */                            
538             if (!(tq->tq_flags & TASKQ_ACTIVE))                                          
539                     goto out;                                                            
540                                                                                          
541             /* Do not queue the task unless there is idle thread for it */               
542             ASSERT(tq->tq_nactive <= tq->tq_nthreads);                                   
(gdb) l *(taskq_thread+0x267)                                                                
0x4747 is in taskq_thread (/home/faaland1/spl/module/spl/../../module/spl/spl-taskq.c:851).  
846                                                                                          
847                             /* Perform the requested task */                             
848                             t->tqent_func(t->tqent_arg);                                 
849                                                                                          
850                             spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);          
851                             tq->tq_nactive--;                                            
852                             list_del_init(&tqt->tqt_active_list);                        
853                             tqt->tqt_task = NULL;                                        
854                                                                                          
855                             /* For prealloc'd tasks, we don't free anything. */          

5) (&db->db_mtx){+.+.+.}, at: [<ffffffffa033e558>] dbuf_sync_leaf+0x48/0x4f0 [zfs]
   (&dr->dt.di.dr_mtx){+.+...}, at: [<ffffffffa033eb62>] dbuf_sync_indirect+0x102/0x330 [zfs]
[ INFO: possible circular locking dependency detected ]                                      
2.6.32-504.16.2.1chaos.ch5.3.x86_64.debug #1                                                 
-------------------------------------------------------                                      
txg_sync/1894 is trying to acquire lock:                                                     
 (&db->db_mtx){+.+.+.}, at: [<ffffffffa033e558>] dbuf_sync_leaf+0x48/0x4f0 [zfs]             

but task is already holding lock:
 (&dr->dt.di.dr_mtx){+.+...}, at: [<ffffffffa033eb62>] dbuf_sync_indirect+0x102/0x330 [zfs]

which lock already depends on the new lock.


the existing dependency chain (in reverse order) is:
-> #1 (&dr->dt.di.dr_mtx){+.+...}:                  
       [<ffffffff810bfbbe>] __lock_acquire+0xede/0x1560
       [<ffffffff810c02e4>] lock_acquire+0xa4/0x120    
       [<ffffffff8155f24c>] mutex_lock_nested+0x5c/0x3b0
       [<ffffffffa033f727>] dbuf_dirty+0x4a7/0xdf0 [zfs]
       [<ffffffffa0340753>] dmu_buf_will_dirty+0x63/0xd0 [zfs]
       [<ffffffffa0348dc0>] dmu_write+0xa0/0x1a0 [zfs]        
       [<ffffffffa03a901e>] space_map_write+0x4ae/0x750 [zfs] 
       [<ffffffffa03856d1>] metaslab_sync+0x121/0x890 [zfs]   
       [<ffffffffa03b931f>] vdev_sync+0x6f/0x140 [zfs]        
       [<ffffffffa039128b>] spa_sync+0x4cb/0xc30 [zfs]        
       [<ffffffffa03ac6c9>] txg_sync_thread+0x3c9/0x780 [zfs] 
       [<ffffffffa02e2908>] thread_generic_wrapper+0x68/0x80 [spl]
       [<ffffffff810a4cbe>] kthread+0x9e/0xc0                     
       [<ffffffff8100c30a>] child_rip+0xa/0x20                    

-> #0 (&db->db_mtx){+.+.+.}:
       [<ffffffff810c013a>] __lock_acquire+0x145a/0x1560
       [<ffffffff810c02e4>] lock_acquire+0xa4/0x120     
       [<ffffffff8155f24c>] mutex_lock_nested+0x5c/0x3b0
       [<ffffffffa033e558>] dbuf_sync_leaf+0x48/0x4f0 [zfs]
       [<ffffffffa033ee5b>] dbuf_sync_list+0xcb/0xd0 [zfs] 
       [<ffffffffa033eb8a>] dbuf_sync_indirect+0x12a/0x330 [zfs]
       [<ffffffffa033ee36>] dbuf_sync_list+0xa6/0xd0 [zfs]      
       [<ffffffffa0361dab>] dnode_sync+0x3eb/0xcd0 [zfs]        
       [<ffffffffa034c10c>] dmu_objset_sync_dnodes+0x8c/0xb0 [zfs]
       [<ffffffffa034c2fd>] dmu_objset_sync+0x1cd/0x2e0 [zfs]     
       [<ffffffffa0376913>] dsl_pool_sync+0x2b3/0x470 [zfs]       
       [<ffffffffa039120b>] spa_sync+0x44b/0xc30 [zfs]            
       [<ffffffffa03ac6c9>] txg_sync_thread+0x3c9/0x780 [zfs]     
       [<ffffffffa02e2908>] thread_generic_wrapper+0x68/0x80 [spl]
       [<ffffffff810a4cbe>] kthread+0x9e/0xc0                     
       [<ffffffff8100c30a>] child_rip+0xa/0x20                    

other info that might help us debug this:

1 lock held by txg_sync/1894:
 #0:  (&dr->dt.di.dr_mtx){+.+...}, at: [<ffffffffa033eb62>] dbuf_sync_indirect+0x102/0x330 [zfs]

stack backtrace:
Pid: 1894, comm: txg_sync Not tainted 2.6.32-504.16.2.1chaos.ch5.3.x86_64.debug #1
Call Trace:                                                                       
 [<ffffffff810bd2d3>] ? print_circular_bug+0xf3/0x100                             
 [<ffffffff810c013a>] ? __lock_acquire+0x145a/0x1560                              
 [<ffffffff810acb48>] ? sched_clock_cpu+0xb8/0x110                                
 [<ffffffffa032cd80>] ? arc_write_done+0x0/0x4b0 [zfs]                            
 [<ffffffff810c02e4>] ? lock_acquire+0xa4/0x120                                   
 [<ffffffffa033e558>] ? dbuf_sync_leaf+0x48/0x4f0 [zfs]                           
 [<ffffffffa0331b40>] ? arc_write+0xe0/0x100 [zfs]                                
 [<ffffffffa032a310>] ? arc_write_physdone+0x0/0x30 [zfs]                         
 [<ffffffffa033e558>] ? dbuf_sync_leaf+0x48/0x4f0 [zfs]                           
 [<ffffffff8155f24c>] ? mutex_lock_nested+0x5c/0x3b0                              
 [<ffffffffa033e558>] ? dbuf_sync_leaf+0x48/0x4f0 [zfs]                           
 [<ffffffff810be1d3>] ? mark_held_locks+0x73/0xa0                                 
 [<ffffffff8155f4db>] ? mutex_lock_nested+0x2eb/0x3b0                             
 [<ffffffffa033eb62>] ? dbuf_sync_indirect+0x102/0x330 [zfs]                      
 [<ffffffffa033e558>] ? dbuf_sync_leaf+0x48/0x4f0 [zfs]                           
 [<ffffffffa033ee5b>] ? dbuf_sync_list+0xcb/0xd0 [zfs]                            
 [<ffffffffa033eb8a>] ? dbuf_sync_indirect+0x12a/0x330 [zfs]                      
 [<ffffffffa033ee36>] ? dbuf_sync_list+0xa6/0xd0 [zfs]                            
 [<ffffffffa0361dab>] ? dnode_sync+0x3eb/0xcd0 [zfs]
 [<ffffffffa033ee5b>] ? dbuf_sync_list+0xcb/0xd0 [zfs]
 [<ffffffffa0361dab>] ? dnode_sync+0x3eb/0xcd0 [zfs]
 [<ffffffffa0331b40>] ? arc_write+0xe0/0x100 [zfs]
 [<ffffffffa034c10c>] ? dmu_objset_sync_dnodes+0x8c/0xb0 [zfs]
 [<ffffffffa034c2fd>] ? dmu_objset_sync+0x1cd/0x2e0 [zfs]
 [<ffffffffa034a740>] ? dmu_objset_write_ready+0x0/0x70 [zfs]
 [<ffffffffa034c410>] ? dmu_objset_write_done+0x0/0x70 [zfs]
 [<ffffffffa0376913>] ? dsl_pool_sync+0x2b3/0x470 [zfs]
 [<ffffffffa0390aad>] ? spa_sync_nvlist+0x12d/0x1d0 [zfs]
 [<ffffffffa039120b>] ? spa_sync+0x44b/0xc30 [zfs]
 [<ffffffff810acb48>] ? sched_clock_cpu+0xb8/0x110
 [<ffffffff810baabd>] ? trace_hardirqs_off+0xd/0x10
 [<ffffffff81042009>] ? kvm_clock_get_cycles+0x9/0x10
 [<ffffffffa03ac6c9>] ? txg_sync_thread+0x3c9/0x780 [zfs]
 [<ffffffff81561a07>] ? _spin_unlock_irqrestore+0x67/0x80
 [<ffffffffa03ac300>] ? txg_sync_thread+0x0/0x780 [zfs]
 [<ffffffffa03ac300>] ? txg_sync_thread+0x0/0x780 [zfs]
 [<ffffffffa02e2908>] ? thread_generic_wrapper+0x68/0x80 [spl]
 [<ffffffffa02e28a0>] ? thread_generic_wrapper+0x0/0x80 [spl]
 [<ffffffff810a4cbe>] ? kthread+0x9e/0xc0
 [<ffffffff8100c30a>] ? child_rip+0xa/0x20
 [<ffffffff8100bb10>] ? restore_args+0x0/0x30
 [<ffffffff810a4c20>] ? kthread+0x0/0xc0
 [<ffffffff8100c300>] ? child_rip+0x0/0x20

When running a kernel with CONFIG_LOCKDEP=y, lockdep reports possible
recursive locking in some cases and possible circular locking dependency
in others, within the SPL and ZFS modules.

When lockdep detects these conditions, it disables further lock analysis
for all locks.  This causes /proc/lock_stats not to reflect full
information about lock contention, even in locks without dependency
issues.

This commit creates a new type of mutex, MUTEX_NOLOCKDEP.  This mutex
type causes subsequent attempts to take or release those locks to be
wrapped in lockdep_off() and lockdep_on().

This commit also creates an RW_NOLOCKDEP type analagous to
MUTEX_NOLOCKDEP.

MUTEX_NOLOCKDEP and RW_NOLOCKDEP are also defined in zfs, in a commit to
that repo, for userspace builds.
spl_inode_{lock,unlock} are triggering possible recursive locking
warnings from lockdep.  The warning is a false positive.

The lock is used to protect a parent directory during delete/add
operations, used in zfs when writing/removing the cache file.  The inode
lock is taken on both the parent inode and the file inode.

VFS provides an enum to subclass the lock.  This patch changes the
spin_lock call to _nested version and uses the provided enum.
When taskq_dispatch() calls taskq_thread_spawn() to create a new thread
for a taskq, linux lockdep warns of possible recursive locking.  This is
a false positive.

One such call chain is as follows, when a taskq needs more threads:
	taskq_dispatch->taskq_thread_spawn->taskq_dispatch

The initial taskq_dispatch() holds tq_lock on the taskq that needed more
worker threads.  The later call into taskq_dispatch() takes
dynamic_taskq->tq_lock.  Without subclassing, lockdep believes these
could potentially be the same lock and complains.  A similar case occurs
when taskq_dispatch() then calls task_alloc().

This patch uses spin_lock_irqsave_nested() when taking tq_lock, with one
of two new lock subclasses:

subclass              taskq
TQ_LOCK_DYNAMIC       dynamic_taskq
TQ_LOCK_GENERAL       any other
behlendorf pushed a commit that referenced this pull request Dec 12, 2015
When running a kernel with CONFIG_LOCKDEP=y, lockdep reports possible
recursive locking in some cases and possible circular locking dependency
in others, within the SPL and ZFS modules.

When lockdep detects these conditions, it disables further lock analysis
for all locks.  This causes /proc/lock_stats not to reflect full
information about lock contention, even in locks without dependency
issues.

This commit creates a new type of mutex, MUTEX_NOLOCKDEP.  This mutex
type causes subsequent attempts to take or release those locks to be
wrapped in lockdep_off() and lockdep_on().

This commit also creates an RW_NOLOCKDEP type analagous to
MUTEX_NOLOCKDEP.

MUTEX_NOLOCKDEP and RW_NOLOCKDEP are also defined in zfs, in a commit to
that repo, for userspace builds.

Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #480
behlendorf pushed a commit that referenced this pull request Dec 12, 2015
spl_inode_{lock,unlock} are triggering possible recursive locking
warnings from lockdep.  The warning is a false positive.

The lock is used to protect a parent directory during delete/add
operations, used in zfs when writing/removing the cache file.  The inode
lock is taken on both the parent inode and the file inode.

VFS provides an enum to subclass the lock.  This patch changes the
spin_lock call to _nested version and uses the provided enum.

Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #480
behlendorf pushed a commit that referenced this pull request Dec 12, 2015
When taskq_dispatch() calls taskq_thread_spawn() to create a new thread
for a taskq, linux lockdep warns of possible recursive locking.  This is
a false positive.

One such call chain is as follows, when a taskq needs more threads:
	taskq_dispatch->taskq_thread_spawn->taskq_dispatch

The initial taskq_dispatch() holds tq_lock on the taskq that needed more
worker threads.  The later call into taskq_dispatch() takes
dynamic_taskq->tq_lock.  Without subclassing, lockdep believes these
could potentially be the same lock and complains.  A similar case occurs
when taskq_dispatch() then calls task_alloc().

This patch uses spin_lock_irqsave_nested() when taking tq_lock, with one
of two new lock subclasses:

subclass              taskq
TQ_LOCK_DYNAMIC       dynamic_taskq
TQ_LOCK_GENERAL       any other

Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #480
@behlendorf
Copy link
Contributor

Merged as:

326172d Subclass tq_lock to eliminate a lockdep warning
628fc52 Fix lockdep warning in spl_inode_{lock,unlock}
692ae8d Add new lock types MUTEX_NOLOCKDEP, and RW_NOLOCKDEP

@behlendorf behlendorf closed this Dec 12, 2015
@ofaaland ofaaland deleted the crada_nolockdep_try_3 branch March 8, 2017 16:27
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants