Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: RCU: Convert lockdep-splat.txt to ReST

- Add a SPDX header;
- Add a document title;
- Some whitespace fixes and new line breaks;
- Mark literal blocks as such;
- Add it to RCU/index.rst.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>

authored by

Mauro Carvalho Chehab and committed by
Paul E. McKenney
a3b0a79f 6b05dfac

+53 -47
+1
Documentation/RCU/index.rst
··· 11 11 12 12 arrayRCU 13 13 checklist 14 + lockdep-splat 14 15 rcubarrier 15 16 rcu_dereference 16 17 whatisRCU
+52 -47
Documentation/RCU/lockdep-splat.txt Documentation/RCU/lockdep-splat.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ================= 4 + Lockdep-RCU Splat 5 + ================= 6 + 1 7 Lockdep-RCU was added to the Linux kernel in early 2010 2 8 (http://lwn.net/Articles/371986/). This facility checks for some common 3 9 misuses of the RCU API, most notably using one of the rcu_dereference() ··· 18 12 being the real world and all that. 19 13 20 14 So let's look at an example RCU lockdep splat from 3.0-rc5, one that 21 - has long since been fixed: 15 + has long since been fixed:: 22 16 23 - ============================= 24 - WARNING: suspicious RCU usage 25 - ----------------------------- 26 - block/cfq-iosched.c:2776 suspicious rcu_dereference_protected() usage! 17 + ============================= 18 + WARNING: suspicious RCU usage 19 + ----------------------------- 20 + block/cfq-iosched.c:2776 suspicious rcu_dereference_protected() usage! 27 21 28 - other info that might help us debug this: 22 + other info that might help us debug this:: 29 23 24 + rcu_scheduler_active = 1, debug_locks = 0 25 + 3 locks held by scsi_scan_6/1552: 26 + #0: (&shost->scan_mutex){+.+.}, at: [<ffffffff8145efca>] 27 + scsi_scan_host_selected+0x5a/0x150 28 + #1: (&eq->sysfs_lock){+.+.}, at: [<ffffffff812a5032>] 29 + elevator_exit+0x22/0x60 30 + #2: (&(&q->__queue_lock)->rlock){-.-.}, at: [<ffffffff812b6233>] 31 + cfq_exit_queue+0x43/0x190 30 32 31 - rcu_scheduler_active = 1, debug_locks = 0 32 - 3 locks held by scsi_scan_6/1552: 33 - #0: (&shost->scan_mutex){+.+.}, at: [<ffffffff8145efca>] 34 - scsi_scan_host_selected+0x5a/0x150 35 - #1: (&eq->sysfs_lock){+.+.}, at: [<ffffffff812a5032>] 36 - elevator_exit+0x22/0x60 37 - #2: (&(&q->__queue_lock)->rlock){-.-.}, at: [<ffffffff812b6233>] 38 - cfq_exit_queue+0x43/0x190 33 + stack backtrace: 34 + Pid: 1552, comm: scsi_scan_6 Not tainted 3.0.0-rc5 #17 35 + Call Trace: 36 + [<ffffffff810abb9b>] lockdep_rcu_dereference+0xbb/0xc0 37 + [<ffffffff812b6139>] __cfq_exit_single_io_context+0xe9/0x120 38 + [<ffffffff812b626c>] cfq_exit_queue+0x7c/0x190 39 + [<ffffffff812a5046>] elevator_exit+0x36/0x60 40 + [<ffffffff812a802a>] blk_cleanup_queue+0x4a/0x60 41 + [<ffffffff8145cc09>] scsi_free_queue+0x9/0x10 42 + [<ffffffff81460944>] __scsi_remove_device+0x84/0xd0 43 + [<ffffffff8145dca3>] scsi_probe_and_add_lun+0x353/0xb10 44 + [<ffffffff817da069>] ? error_exit+0x29/0xb0 45 + [<ffffffff817d98ed>] ? _raw_spin_unlock_irqrestore+0x3d/0x80 46 + [<ffffffff8145e722>] __scsi_scan_target+0x112/0x680 47 + [<ffffffff812c690d>] ? trace_hardirqs_off_thunk+0x3a/0x3c 48 + [<ffffffff817da069>] ? error_exit+0x29/0xb0 49 + [<ffffffff812bcc60>] ? kobject_del+0x40/0x40 50 + [<ffffffff8145ed16>] scsi_scan_channel+0x86/0xb0 51 + [<ffffffff8145f0b0>] scsi_scan_host_selected+0x140/0x150 52 + [<ffffffff8145f149>] do_scsi_scan_host+0x89/0x90 53 + [<ffffffff8145f170>] do_scan_async+0x20/0x160 54 + [<ffffffff8145f150>] ? do_scsi_scan_host+0x90/0x90 55 + [<ffffffff810975b6>] kthread+0xa6/0xb0 56 + [<ffffffff817db154>] kernel_thread_helper+0x4/0x10 57 + [<ffffffff81066430>] ? finish_task_switch+0x80/0x110 58 + [<ffffffff817d9c04>] ? retint_restore_args+0xe/0xe 59 + [<ffffffff81097510>] ? __kthread_init_worker+0x70/0x70 60 + [<ffffffff817db150>] ? gs_change+0xb/0xb 39 61 40 - stack backtrace: 41 - Pid: 1552, comm: scsi_scan_6 Not tainted 3.0.0-rc5 #17 42 - Call Trace: 43 - [<ffffffff810abb9b>] lockdep_rcu_dereference+0xbb/0xc0 44 - [<ffffffff812b6139>] __cfq_exit_single_io_context+0xe9/0x120 45 - [<ffffffff812b626c>] cfq_exit_queue+0x7c/0x190 46 - [<ffffffff812a5046>] elevator_exit+0x36/0x60 47 - [<ffffffff812a802a>] blk_cleanup_queue+0x4a/0x60 48 - [<ffffffff8145cc09>] scsi_free_queue+0x9/0x10 49 - [<ffffffff81460944>] __scsi_remove_device+0x84/0xd0 50 - [<ffffffff8145dca3>] scsi_probe_and_add_lun+0x353/0xb10 51 - [<ffffffff817da069>] ? error_exit+0x29/0xb0 52 - [<ffffffff817d98ed>] ? _raw_spin_unlock_irqrestore+0x3d/0x80 53 - [<ffffffff8145e722>] __scsi_scan_target+0x112/0x680 54 - [<ffffffff812c690d>] ? trace_hardirqs_off_thunk+0x3a/0x3c 55 - [<ffffffff817da069>] ? error_exit+0x29/0xb0 56 - [<ffffffff812bcc60>] ? kobject_del+0x40/0x40 57 - [<ffffffff8145ed16>] scsi_scan_channel+0x86/0xb0 58 - [<ffffffff8145f0b0>] scsi_scan_host_selected+0x140/0x150 59 - [<ffffffff8145f149>] do_scsi_scan_host+0x89/0x90 60 - [<ffffffff8145f170>] do_scan_async+0x20/0x160 61 - [<ffffffff8145f150>] ? do_scsi_scan_host+0x90/0x90 62 - [<ffffffff810975b6>] kthread+0xa6/0xb0 63 - [<ffffffff817db154>] kernel_thread_helper+0x4/0x10 64 - [<ffffffff81066430>] ? finish_task_switch+0x80/0x110 65 - [<ffffffff817d9c04>] ? retint_restore_args+0xe/0xe 66 - [<ffffffff81097510>] ? __kthread_init_worker+0x70/0x70 67 - [<ffffffff817db150>] ? gs_change+0xb/0xb 68 - 69 - Line 2776 of block/cfq-iosched.c in v3.0-rc5 is as follows: 62 + Line 2776 of block/cfq-iosched.c in v3.0-rc5 is as follows:: 70 63 71 64 if (rcu_dereference(ioc->ioc_data) == cic) { 72 65 ··· 75 70 And maybe that lock really does protect this reference. If so, the fix 76 71 is to inform RCU, perhaps by changing __cfq_exit_single_io_context() to 77 72 take the struct request_queue "q" from cfq_exit_queue() as an argument, 78 - which would permit us to invoke rcu_dereference_protected as follows: 73 + which would permit us to invoke rcu_dereference_protected as follows:: 79 74 80 75 if (rcu_dereference_protected(ioc->ioc_data, 81 76 lockdep_is_held(&q->queue_lock)) == cic) { ··· 90 85 section. In this case, the critical section must span the use of the 91 86 return value from rcu_dereference(), or at least until there is some 92 87 reference count incremented or some such. One way to handle this is to 93 - add rcu_read_lock() and rcu_read_unlock() as follows: 88 + add rcu_read_lock() and rcu_read_unlock() as follows:: 94 89 95 90 rcu_read_lock(); 96 91 if (rcu_dereference(ioc->ioc_data) == cic) { ··· 107 102 But in this particular case, we don't actually dereference the pointer 108 103 returned from rcu_dereference(). Instead, that pointer is just compared 109 104 to the cic pointer, which means that the rcu_dereference() can be replaced 110 - by rcu_access_pointer() as follows: 105 + by rcu_access_pointer() as follows:: 111 106 112 107 if (rcu_access_pointer(ioc->ioc_data) == cic) { 113 108