diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-05-20 07:19:10 +0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-05-27 15:49:25 +0400 |
commit | 1e7de68c57daf75ec4b721f101f88cccf029e38c (patch) | |
tree | 730f6aa856ab971dfaea53a018a5fa61e67c1925 /drivers/target/target_core_tmr.c | |
parent | 4a8fcc2cc34b7546584bf9ebd8f0caf433e4736e (diff) | |
download | linux-1e7de68c57daf75ec4b721f101f88cccf029e38c.tar.xz |
[SCSI] target: Fix interrupt context bug with stats_lock and core_tmr_alloc_req
This patch fixes two bugs wrt to the interrupt context usage of target
core with HW target mode drivers. It first converts the usage of struct
se_device->stats_lock in transport_get_lun_for_cmd() and core_tmr_lun_reset()
to properly use spin_lock_irq() to address an BUG with CONFIG_LOCKDEP_SUPPORT=y
enabled.
This patch also adds a 'in_interrupt()' check to allow GFP_ATOMIC usage from
core_tmr_alloc_req() to fix a 'sleeping in interrupt context' BUG with HW
target fabrics that require this logic to function.
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Cc: stable@kernel.org
Signed-off-by: James Bottomley <jbottomley@parallels.com>
Diffstat (limited to 'drivers/target/target_core_tmr.c')
-rw-r--r-- | drivers/target/target_core_tmr.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 4a109835e420..59b8b9c5ad72 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -55,7 +55,8 @@ struct se_tmr_req *core_tmr_alloc_req( { struct se_tmr_req *tmr; - tmr = kmem_cache_zalloc(se_tmr_req_cache, GFP_KERNEL); + tmr = kmem_cache_zalloc(se_tmr_req_cache, (in_interrupt()) ? + GFP_ATOMIC : GFP_KERNEL); if (!(tmr)) { printk(KERN_ERR "Unable to allocate struct se_tmr_req\n"); return ERR_PTR(-ENOMEM); @@ -398,9 +399,9 @@ int core_tmr_lun_reset( printk(KERN_INFO "LUN_RESET: SCSI-2 Released reservation\n"); } - spin_lock(&dev->stats_lock); + spin_lock_irq(&dev->stats_lock); dev->num_resets++; - spin_unlock(&dev->stats_lock); + spin_unlock_irq(&dev->stats_lock); DEBUG_LR("LUN_RESET: %s for [%s] Complete\n", (preempt_and_abort_list) ? "Preempt" : "TMR", |