Skip to content
  • Neil Horman's avatar
    libfc: extend ex_lock to protect all of fc_seq_send · fb00cc23
    Neil Horman authored
    
    
    This warning was reported recently:
    
    WARNING: at drivers/scsi/libfc/fc_exch.c:478 fc_seq_send+0x14f/0x160 [libfc]()
    (Not tainted)
    Hardware name: ProLiant DL120 G7
    Modules linked in: tcm_fc target_core_iblock target_core_file target_core_pscsi
    target_core_mod configfs dm_round_robin dm_multipath 8021q garp stp llc bnx2fc
    cnic uio fcoe libfcoe libfc scsi_transport_fc scsi_tgt autofs4 sunrpc
    pcc_cpufreq ipv6 hpilo hpwdt e1000e microcode iTCO_wdt iTCO_vendor_support
    serio_raw shpchp ixgbe dca mdio sg ext4 mbcache jbd2 sd_mod crc_t10dif pata_acpi
    ata_generic ata_piix hpsa dm_mirror dm_region_hash dm_log dm_mod [last unloaded:
    scsi_wait_scan]
    Pid: 5464, comm: target_completi Not tainted 2.6.32-272.el6.x86_64 #1
    Call Trace:
     [<ffffffff8106b747>] ? warn_slowpath_common+0x87/0xc0
     [<ffffffff8106b79a>] ? warn_slowpath_null+0x1a/0x20
     [<ffffffffa025f7df>] ? fc_seq_send+0x14f/0x160 [libfc]
     [<ffffffffa035cbce>] ? ft_queue_status+0x16e/0x210 [tcm_fc]
     [<ffffffffa030a660>] ? target_complete_ok_work+0x0/0x4b0 [target_core_mod]
     [<ffffffffa030a766>] ? target_complete_ok_work+0x106/0x4b0 [target_core_mod]
     [<ffffffffa030a660>] ? target_complete_ok_work+0x0/0x4b0 [target_core_mod]
     [<ffffffff8108c760>] ? worker_thread+0x170/0x2a0
     [<ffffffff810920d0>] ? autoremove_wake_function+0x0/0x40
     [<ffffffff8108c5f0>] ? worker_thread+0x0/0x2a0
     [<ffffffff81091d66>] ? kthread+0x96/0xa0
     [<ffffffff8100c14a>] ? child_rip+0xa/0x20
     [<ffffffff81091cd0>] ? kthread+0x0/0xa0
     [<ffffffff8100c140>] ? child_rip+0x0/0x20
    
    It occurs because fc_seq_send can have multiple contexts executing within it at
    the same time, and fc_seq_send doesn't consistently use the ep->ex_lock that
    protects this structure.  Because of that, its possible for one context to clear
    the INIT bit in the ep->esb_state field while another checks it, leading to the
    above stack trace generated by the WARN_ON in the function.
    
    We should probably undertake the effort to convert access to the fc_exch
    structures to use rcu, but that a larger work item.  To just fix this specific
    issue, we can just extend the ex_lock protection through the entire fc_seq_send
    path
    
    Signed-off-by: default avatarNeil Horman <nhorman@tuxdriver.com>
    Reported-by: default avatarGris Ge <fge@redhat.com>
    CC: Robert Love <robert.w.love@intel.com>
    Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
    fb00cc23