IB/qib: Fix lockdep splat in qib_alloc_lkey()
authorMike Marciniszyn <mike.marciniszyn@intel.com>
Fri, 17 May 2013 12:40:32 +0000 (12:40 +0000)
committerRoland Dreier <roland@purestorage.com>
Wed, 5 Jun 2013 00:05:20 +0000 (17:05 -0700)
The following backtrace is reported with CONFIG_PROVE_RCU:

    drivers/infiniband/hw/qib/qib_keys.c:64 suspicious rcu_dereference_check() usage!
    other info that might help us debug this:
    rcu_scheduler_active = 1, debug_locks = 1
    4 locks held by kworker/0:1/56:
    #0:  (events){.+.+.+}, at: [<ffffffff8107a4f5>] process_one_work+0x165/0x4a0
    #1:  ((&wfc.work)){+.+.+.}, at: [<ffffffff8107a4f5>] process_one_work+0x165/0x4a0
    #2:  (device_mutex){+.+.+.}, at: [<ffffffffa0148dd8>] ib_register_device+0x38/0x220 [ib_core]
    #3:  (&(&dev->lk_table.lock)->rlock){......}, at: [<ffffffffa017e81c>] qib_alloc_lkey+0x3c/0x1b0 [ib_qib]

    stack backtrace:
    Pid: 56, comm: kworker/0:1 Not tainted 3.10.0-rc1+ #6
    Call Trace:
    [<ffffffff810c0b85>] lockdep_rcu_suspicious+0xe5/0x130
    [<ffffffffa017e8e1>] qib_alloc_lkey+0x101/0x1b0 [ib_qib]
    [<ffffffffa0184886>] qib_get_dma_mr+0xa6/0xd0 [ib_qib]
    [<ffffffffa01461aa>] ib_get_dma_mr+0x1a/0x50 [ib_core]
    [<ffffffffa01678dc>] ib_mad_port_open+0x12c/0x390 [ib_mad]
    [<ffffffff810c2c55>] ?  trace_hardirqs_on_caller+0x105/0x190
    [<ffffffffa0167b92>] ib_mad_init_device+0x52/0x110 [ib_mad]
    [<ffffffffa01917c0>] ?  sl2vl_attr_show+0x30/0x30 [ib_qib]
    [<ffffffffa0148f49>] ib_register_device+0x1a9/0x220 [ib_core]
    [<ffffffffa01b1685>] qib_register_ib_device+0x735/0xa40 [ib_qib]
    [<ffffffff8106ba98>] ? mod_timer+0x118/0x220
    [<ffffffffa017d425>] qib_init_one+0x1e5/0x400 [ib_qib]
    [<ffffffff812ce86e>] local_pci_probe+0x4e/0x90
    [<ffffffff81078118>] work_for_cpu_fn+0x18/0x30
    [<ffffffff8107a566>] process_one_work+0x1d6/0x4a0
    [<ffffffff8107a4f5>] ?  process_one_work+0x165/0x4a0
    [<ffffffff8107c9c9>] worker_thread+0x119/0x370
    [<ffffffff8107c8b0>] ?  manage_workers+0x180/0x180
    [<ffffffff8108294e>] kthread+0xee/0x100
    [<ffffffff81082860>] ?  __init_kthread_worker+0x70/0x70
    [<ffffffff815c04ac>] ret_from_fork+0x7c/0xb0
    [<ffffffff81082860>] ?  __init_kthread_worker+0x70/0x70

Per Documentation/RCU/lockdep-splat.txt, the code now uses rcu_access_pointer()
vs. rcu_dereference().

Reported-by: Jay Fenlason <fenlason@redhat.com>
Reviewed-by: Dean Luick <dean.luick@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/qib/qib_keys.c

index 81c7b73695d26c4898735b7e58abcd49bca398d6..3b9afccaaade824370f5c0ea0d6d6ceb519e6090 100644 (file)
@@ -61,7 +61,7 @@ int qib_alloc_lkey(struct qib_mregion *mr, int dma_region)
        if (dma_region) {
                struct qib_mregion *tmr;
 
-               tmr = rcu_dereference(dev->dma_mr);
+               tmr = rcu_access_pointer(dev->dma_mr);
                if (!tmr) {
                        qib_get_mr(mr);
                        rcu_assign_pointer(dev->dma_mr, mr);