summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-05-19 20:19:10 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-03 10:34:04 +0900
commitc690d5d2e4f68f2203071118a423357ed108f2ea (patch)
tree6d4ccaa6fdf67cd075588b09bad0c186841d08b4
parentbaee56a2ef25317d47dbbb65eddaea25a1c46b99 (diff)
downloadlwn-c690d5d2e4f68f2203071118a423357ed108f2ea.tar.gz
lwn-c690d5d2e4f68f2203071118a423357ed108f2ea.zip
target: Fix interrupt context bug with stats_lock and core_tmr_alloc_req
commit 53ab6709b4d35b1924240854d794482fd7d33d4a upstream. 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> Signed-off-by: James Bottomley <jbottomley@parallels.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/target/target_core_device.c4
-rw-r--r--drivers/target/target_core_tmr.c7
2 files changed, 6 insertions, 5 deletions
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 5da051a07fa3..0e0257bf5b78 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -151,13 +151,13 @@ out:
{
struct se_device *dev = se_lun->lun_se_dev;
- spin_lock(&dev->stats_lock);
+ spin_lock_irq(&dev->stats_lock);
dev->num_cmds++;
if (se_cmd->data_direction == DMA_TO_DEVICE)
dev->write_bytes += se_cmd->data_length;
else if (se_cmd->data_direction == DMA_FROM_DEVICE)
dev->read_bytes += se_cmd->data_length;
- spin_unlock(&dev->stats_lock);
+ spin_unlock_irq(&dev->stats_lock);
}
/*
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",