summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-05-19 20:19:11 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-03 09:32:05 +0900
commitc20bc94058d10ee00a72490e05b9c314f2a75d4e (patch)
tree9f2b2ee9e44974663ff98594cf83f8c04a694a4d /include
parent26e45fbaec96c748f807925ea3855deb3c504118 (diff)
target: Fix bug with task_sg chained transport_free_dev_tasks release
commit f436677262a5b524ac87675014c6d4e8ee153029 upstream. This patch addresses a bug in the target core release path for HW operation where transport_free_dev_tasks() was incorrectly being called from transport_lun_remove_cmd() while releasing a se_cmd reference and calling struct target_core_fabric_ops->queue_data_in(). This would result in a OOPs with HW target mode when the release of se_task->task_sg[] would happen before pci_unmap_sg() can be called in HW target mode fabric module code. This patch addresses the issue by moving transport_free_dev_tasks() from transport_lun_remove_cmd() into transport_generic_free_cmd(), and adding TRANSPORT_FREE_CMD_INTR and transport_generic_free_cmd_intr() to allow se_cmd descriptor release to happen fromfrom within transport_processing_thread() process context when release of se_cmd is not possible from HW interrupt context. 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>
Diffstat (limited to 'include')
-rw-r--r--include/target/target_core_base.h1
-rw-r--r--include/target/target_core_transport.h1
2 files changed, 2 insertions, 0 deletions
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 1d3b5b2f0dbc..561ac99def5a 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -98,6 +98,7 @@ enum transport_state_table {
TRANSPORT_REMOVE = 14,
TRANSPORT_FREE = 15,
TRANSPORT_NEW_CMD_MAP = 16,
+ TRANSPORT_FREE_CMD_INTR = 17,
};
/* Used for struct se_cmd->se_cmd_flags */
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index 59aa464f6ee2..24a1c6cb83c3 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -172,6 +172,7 @@ extern int transport_generic_handle_cdb_map(struct se_cmd *);
extern int transport_generic_handle_data(struct se_cmd *);
extern void transport_new_cmd_failure(struct se_cmd *);
extern int transport_generic_handle_tmr(struct se_cmd *);
+extern void transport_generic_free_cmd_intr(struct se_cmd *);
extern void __transport_stop_task_timer(struct se_task *, unsigned long *);
extern unsigned char transport_asciihex_to_binaryhex(unsigned char val[2]);
extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32,