All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH-v2 0/4] Bugfixes for .39-rc8
@ 2011-05-11  4:35 Nicholas A. Bellinger
  2011-05-11  4:35 ` [PATCH-v2 1/4] target: Fix multi task->task_sg[] chaining logic bug Nicholas A. Bellinger
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Nicholas A. Bellinger @ 2011-05-11  4:35 UTC (permalink / raw)
  To: linux-kernel, linux-scsi, James Bottomley
  Cc: Linus Torvalds, Christoph Hellwig, Kiran Patil, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Hi James and Co,

This series is resend of four patches that should be considered critical
target core bugfixes for .39 that have been under stress testing in a
couple of different labs recently using lio-core-2.6.git/lio-4.1 (.39-rcX)
and /lio-4.0 (.38.3) branch code.

These are all important bugfixes that are required to run with in-flight
.40 HW target drivers in the upstream LIO tree.  This includes fixes for
the main transport_do_task_sg_chain() Data I/O mapping logic, and
task->task_sg[] shutdown path from MSI-X interrupt context.  These bugfixes
apply for all of the following HW fabric drivers:

   tcm_fc(openfcoe) w/ ddp offload, tcm_qla2xxx, ib_srpt and ibmvscsis.

These patches address issues that are able to easily produce OOPsen with
small backstore max_sectors values.  Please review+apply for .39 and
also queue into stable@kernel.org for .38.

The series is also available here for a direct pull:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/scsi-post-merge-2.6.git for-39-rc-fixes

and has been made against the following scsi-rc-fixes-2.6.git HEAD:

commit c055f5b2614b4f758ae6cc86733f31fa4c2c5844
Author: James Bottomley <James.Bottomley@suse.de>
Date:   Sun May 1 09:42:07 2011 -0500

    [SCSI] fix oops in scsi_run_queue()

Thanks!

--nab

Nicholas Bellinger (4):
  target: Fix multi task->task_sg[] chaining logic bug
  target: Fix interrupt context bug with stats_lock and
    core_tmr_alloc_req
  target: Fix bug with task_sg chained transport_free_dev_tasks release
  target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs

 drivers/target/target_core_device.c    |    4 +-
 drivers/target/target_core_tmr.c       |    7 +++--
 drivers/target/target_core_transport.c |   46 +++++++++++++++++++++++--------
 include/target/target_core_base.h      |    1 +
 include/target/target_core_transport.h |    1 +
 5 files changed, 42 insertions(+), 17 deletions(-)

-- 
1.7.5.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH-v2 1/4] target: Fix multi task->task_sg[] chaining logic bug
  2011-05-11  4:35 [PATCH-v2 0/4] Bugfixes for .39-rc8 Nicholas A. Bellinger
@ 2011-05-11  4:35 ` Nicholas A. Bellinger
  2011-05-17 21:27   ` Kiran Patil
  2011-05-11  4:35 ` [PATCH-v2 2/4] target: Fix interrupt context bug with stats_lock and core_tmr_alloc_req Nicholas A. Bellinger
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Nicholas A. Bellinger @ 2011-05-11  4:35 UTC (permalink / raw)
  To: linux-kernel, linux-scsi, James Bottomley
  Cc: Linus Torvalds, Christoph Hellwig, Kiran Patil, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch fixes a bug in transport_do_task_sg_chain() used by HW target
mode modules with sg_chain() to provide a single sg_next() walkable memory
layout for use with pci_map_sg() and friends.  This patch addresses an
issue with mapping multiple small block max_sector tasks across multiple
struct se_task->task_sg[] mappings for HW target mode operation.

This was causing OOPs with (cmd->t_task->t_tasks_no > 1) I/O traffic for
HW target drivers using transport_do_task_sg_chain(), and has been tested
so far with tcm_fc(openfcoe), tcm_qla2xxx, and ib_srpt fabrics with
t_tasks_no > 1 IBLOCK backends using a smaller max_sectors to trigger the
original issue.

Reported-by: Kiran Patil <kiran.patil@intel.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |   26 +++++++++++++++-----------
 1 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 9583b23..fefe10a 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -4776,18 +4776,20 @@ void transport_do_task_sg_chain(struct se_cmd *cmd)
 				sg_end_cur->page_link &= ~0x02;
 
 				sg_chain(sg_head, task_sg_num, sg_head_cur);
-				sg_count += (task->task_sg_num + 1);
-			} else
 				sg_count += task->task_sg_num;
+				task_sg_num = (task->task_sg_num + 1);
+			} else {
+				sg_chain(sg_head, task_sg_num, sg_head_cur);
+				sg_count += task->task_sg_num;
+				task_sg_num = task->task_sg_num;
+			}
 
 			sg_head = sg_head_cur;
 			sg_link = sg_link_cur;
-			task_sg_num = task->task_sg_num;
 			continue;
 		}
 		sg_head = sg_first = &task->task_sg[0];
 		sg_link = &task->task_sg[task->task_sg_num];
-		task_sg_num = task->task_sg_num;
 		/*
 		 * Check for single task..
 		 */
@@ -4798,9 +4800,12 @@ void transport_do_task_sg_chain(struct se_cmd *cmd)
 			 */
 			sg_end = &task->task_sg[task->task_sg_num - 1];
 			sg_end->page_link &= ~0x02;
-			sg_count += (task->task_sg_num + 1);
-		} else
 			sg_count += task->task_sg_num;
+			task_sg_num = (task->task_sg_num + 1);
+		} else {
+			sg_count += task->task_sg_num;
+			task_sg_num = task->task_sg_num;
+		}
 	}
 	/*
 	 * Setup the starting pointer and total t_tasks_sg_linked_no including
@@ -4809,21 +4814,20 @@ void transport_do_task_sg_chain(struct se_cmd *cmd)
 	T_TASK(cmd)->t_tasks_sg_chained = sg_first;
 	T_TASK(cmd)->t_tasks_sg_chained_no = sg_count;
 
-	DEBUG_CMD_M("Setup T_TASK(cmd)->t_tasks_sg_chained: %p and"
-		" t_tasks_sg_chained_no: %u\n", T_TASK(cmd)->t_tasks_sg_chained,
+	DEBUG_CMD_M("Setup cmd: %p T_TASK(cmd)->t_tasks_sg_chained: %p and"
+		" t_tasks_sg_chained_no: %u\n", cmd, T_TASK(cmd)->t_tasks_sg_chained,
 		T_TASK(cmd)->t_tasks_sg_chained_no);
 
 	for_each_sg(T_TASK(cmd)->t_tasks_sg_chained, sg,
 			T_TASK(cmd)->t_tasks_sg_chained_no, i) {
 
-		DEBUG_CMD_M("SG: %p page: %p length: %d offset: %d\n",
-			sg, sg_page(sg), sg->length, sg->offset);
+		DEBUG_CMD_M("SG[%d]: %p page: %p length: %d offset: %d, magic: 0x%08x\n",
+			i, sg, sg_page(sg), sg->length, sg->offset, sg->sg_magic);
 		if (sg_is_chain(sg))
 			DEBUG_CMD_M("SG: %p sg_is_chain=1\n", sg);
 		if (sg_is_last(sg))
 			DEBUG_CMD_M("SG: %p sg_is_last=1\n", sg);
 	}
-
 }
 EXPORT_SYMBOL(transport_do_task_sg_chain);
 
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH-v2 2/4] target: Fix interrupt context bug with stats_lock and core_tmr_alloc_req
  2011-05-11  4:35 [PATCH-v2 0/4] Bugfixes for .39-rc8 Nicholas A. Bellinger
  2011-05-11  4:35 ` [PATCH-v2 1/4] target: Fix multi task->task_sg[] chaining logic bug Nicholas A. Bellinger
@ 2011-05-11  4:35 ` Nicholas A. Bellinger
  2011-05-11  4:35 ` [PATCH-v2 3/4] target: Fix bug with task_sg chained transport_free_dev_tasks release Nicholas A. Bellinger
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Nicholas A. Bellinger @ 2011-05-11  4:35 UTC (permalink / raw)
  To: linux-kernel, linux-scsi, James Bottomley
  Cc: Linus Torvalds, Christoph Hellwig, Kiran Patil, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

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>
---
 drivers/target/target_core_device.c |    4 ++--
 drivers/target/target_core_tmr.c    |    7 ++++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index d25e208..fc10ed4 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -150,13 +150,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 4a10983..59b8b9c 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",
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH-v2 3/4] target: Fix bug with task_sg chained transport_free_dev_tasks release
  2011-05-11  4:35 [PATCH-v2 0/4] Bugfixes for .39-rc8 Nicholas A. Bellinger
  2011-05-11  4:35 ` [PATCH-v2 1/4] target: Fix multi task->task_sg[] chaining logic bug Nicholas A. Bellinger
  2011-05-11  4:35 ` [PATCH-v2 2/4] target: Fix interrupt context bug with stats_lock and core_tmr_alloc_req Nicholas A. Bellinger
@ 2011-05-11  4:35 ` Nicholas A. Bellinger
  2011-05-11  4:35 ` [PATCH-v2 4/4] target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs Nicholas A. Bellinger
  2011-05-14  0:05 ` [PATCH-v2 0/4] Bugfixes for .39-rc8 Nicholas A. Bellinger
  4 siblings, 0 replies; 7+ messages in thread
From: Nicholas A. Bellinger @ 2011-05-11  4:35 UTC (permalink / raw)
  To: linux-kernel, linux-scsi, James Bottomley
  Cc: Linus Torvalds, Christoph Hellwig, Kiran Patil, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

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>
---
 drivers/target/target_core_transport.c |   13 ++++++++++++-
 include/target/target_core_base.h      |    1 +
 include/target/target_core_transport.h |    1 +
 3 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index fefe10a..3eeb3e2 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -762,7 +762,6 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd)
 	transport_all_task_dev_remove_state(cmd);
 	spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
 
-	transport_free_dev_tasks(cmd);
 
 check_lun:
 	spin_lock_irqsave(&lun->lun_cmd_lock, flags);
@@ -2058,6 +2057,13 @@ int transport_generic_handle_tmr(
 }
 EXPORT_SYMBOL(transport_generic_handle_tmr);
 
+void transport_generic_free_cmd_intr(
+	struct se_cmd *cmd)
+{
+	transport_add_cmd_to_queue(cmd, TRANSPORT_FREE_CMD_INTR);
+}
+EXPORT_SYMBOL(transport_generic_free_cmd_intr);
+
 static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
 {
 	struct se_task *task, *task_tmp;
@@ -5301,6 +5307,8 @@ void transport_generic_free_cmd(
 		if (wait_for_tasks && cmd->transport_wait_for_tasks)
 			cmd->transport_wait_for_tasks(cmd, 0, 0);
 
+		transport_free_dev_tasks(cmd);
+
 		transport_generic_remove(cmd, release_to_pool,
 				session_reinstatement);
 	}
@@ -6136,6 +6144,9 @@ get_cmd:
 		case TRANSPORT_REMOVE:
 			transport_generic_remove(cmd, 1, 0);
 			break;
+		case TRANSPORT_FREE_CMD_INTR:
+			transport_generic_free_cmd(cmd, 0, 1, 0);
+			break;
 		case TRANSPORT_PROCESS_TMR:
 			transport_generic_do_tmr(cmd);
 			break;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 1d3b5b2..561ac99 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 59aa464..24a1c6c 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,
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH-v2 4/4] target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs
  2011-05-11  4:35 [PATCH-v2 0/4] Bugfixes for .39-rc8 Nicholas A. Bellinger
                   ` (2 preceding siblings ...)
  2011-05-11  4:35 ` [PATCH-v2 3/4] target: Fix bug with task_sg chained transport_free_dev_tasks release Nicholas A. Bellinger
@ 2011-05-11  4:35 ` Nicholas A. Bellinger
  2011-05-14  0:05 ` [PATCH-v2 0/4] Bugfixes for .39-rc8 Nicholas A. Bellinger
  4 siblings, 0 replies; 7+ messages in thread
From: Nicholas A. Bellinger @ 2011-05-11  4:35 UTC (permalink / raw)
  To: linux-kernel, linux-scsi, James Bottomley
  Cc: Linus Torvalds, Christoph Hellwig, Kiran Patil, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch fixes a bug where task->task_execute_queue=1 was not being
cleared once se_task had been removed from se_device->execute_task_list,
resulting in an OOPs in core_tmr_lun_reset() for the task->task_active=0
case where transport_remove_task_from_execute_queue() was incorrectly
being called.

This patch fixes two cases in transport_get_task_from_execute_queue()
and transport_remove_task_from_execute_queue() to properly clear
task->task_execute_queue=0 once list_del(&task->t_execute_list) has
been called.

It also adds an explict check in transport_remove_task_from_execute_queue()
to dump_stack + return if called with task->task_execute_queue=0.

Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 3eeb3e2..beaf8fa 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1194,6 +1194,7 @@ transport_get_task_from_execute_queue(struct se_device *dev)
 		break;
 
 	list_del(&task->t_execute_list);
+	atomic_set(&task->task_execute_queue, 0);
 	atomic_dec(&dev->execute_tasks);
 
 	return task;
@@ -1209,8 +1210,14 @@ void transport_remove_task_from_execute_queue(
 {
 	unsigned long flags;
 
+	if (atomic_read(&task->task_execute_queue) == 0) {
+		dump_stack();
+		return;
+	}
+
 	spin_lock_irqsave(&dev->execute_task_lock, flags);
 	list_del(&task->t_execute_list);
+	atomic_set(&task->task_execute_queue, 0);
 	atomic_dec(&dev->execute_tasks);
 	spin_unlock_irqrestore(&dev->execute_task_lock, flags);
 }
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH-v2 0/4] Bugfixes for .39-rc8
  2011-05-11  4:35 [PATCH-v2 0/4] Bugfixes for .39-rc8 Nicholas A. Bellinger
                   ` (3 preceding siblings ...)
  2011-05-11  4:35 ` [PATCH-v2 4/4] target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs Nicholas A. Bellinger
@ 2011-05-14  0:05 ` Nicholas A. Bellinger
  4 siblings, 0 replies; 7+ messages in thread
From: Nicholas A. Bellinger @ 2011-05-14  0:05 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-scsi, James Bottomley, Linus Torvalds, Christoph Hellwig,
	Kiran Patil, Love, Robert W

On Tue, 2011-05-10 at 21:35 -0700, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger <nab@linux-iscsi.org>
> 
> Hi James and Co,
> 
> This series is resend of four patches that should be considered critical
> target core bugfixes for .39 that have been under stress testing in a
> couple of different labs recently using lio-core-2.6.git/lio-4.1 (.39-rcX)
> and /lio-4.0 (.38.3) branch code.
> 
> These are all important bugfixes that are required to run with in-flight
> .40 HW target drivers in the upstream LIO tree.  This includes fixes for
> the main transport_do_task_sg_chain() Data I/O mapping logic, and
> task->task_sg[] shutdown path from MSI-X interrupt context.  These bugfixes
> apply for all of the following HW fabric drivers:
> 
>    tcm_fc(openfcoe) w/ ddp offload, tcm_qla2xxx, ib_srpt and ibmvscsis.
> 
> These patches address issues that are able to easily produce OOPsen with
> small backstore max_sectors values.  Please review+apply for .39 and
> also queue into stable@kernel.org for .38.
>
> The series is also available here for a direct pull:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/nab/scsi-post-merge-2.6.git for-39-rc-fixes
> 

Hi James,

Ping on getting these bugfixes merged into .39-final and .38 stable..? 

The tcm_fc(openfcoe) HW offload also in the queue for .40 from Kiran &
Co depends upon these fixes.

Thanks,

--nab

> and has been made against the following scsi-rc-fixes-2.6.git HEAD:
> 
> commit c055f5b2614b4f758ae6cc86733f31fa4c2c5844
> Author: James Bottomley <James.Bottomley@suse.de>
> Date:   Sun May 1 09:42:07 2011 -0500
> 
>     [SCSI] fix oops in scsi_run_queue()
> 
> Thanks!
> 
> --nab
> 
> Nicholas Bellinger (4):
>   target: Fix multi task->task_sg[] chaining logic bug
>   target: Fix interrupt context bug with stats_lock and
>     core_tmr_alloc_req
>   target: Fix bug with task_sg chained transport_free_dev_tasks release
>   target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs
> 
>  drivers/target/target_core_device.c    |    4 +-
>  drivers/target/target_core_tmr.c       |    7 +++--
>  drivers/target/target_core_transport.c |   46 +++++++++++++++++++++++--------
>  include/target/target_core_base.h      |    1 +
>  include/target/target_core_transport.h |    1 +
>  5 files changed, 42 insertions(+), 17 deletions(-)
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH-v2 1/4] target: Fix multi task->task_sg[] chaining logic bug
  2011-05-11  4:35 ` [PATCH-v2 1/4] target: Fix multi task->task_sg[] chaining logic bug Nicholas A. Bellinger
@ 2011-05-17 21:27   ` Kiran Patil
  0 siblings, 0 replies; 7+ messages in thread
From: Kiran Patil @ 2011-05-17 21:27 UTC (permalink / raw)
  To: Nicholas A. Bellinger
  Cc: linux-kernel, linux-scsi, James Bottomley, Linus Torvalds,
	Christoph Hellwig

Acked-by: Kiran Patil <kiran.patil@intel.com>

On 5/10/2011 9:35 PM, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger<nab@linux-iscsi.org>
>
> This patch fixes a bug in transport_do_task_sg_chain() used by HW target
> mode modules with sg_chain() to provide a single sg_next() walkable memory
> layout for use with pci_map_sg() and friends.  This patch addresses an
> issue with mapping multiple small block max_sector tasks across multiple
> struct se_task->task_sg[] mappings for HW target mode operation.
>
> This was causing OOPs with (cmd->t_task->t_tasks_no>  1) I/O traffic for
> HW target drivers using transport_do_task_sg_chain(), and has been tested
> so far with tcm_fc(openfcoe), tcm_qla2xxx, and ib_srpt fabrics with
> t_tasks_no>  1 IBLOCK backends using a smaller max_sectors to trigger the
> original issue.
>
> Reported-by: Kiran Patil<kiran.patil@intel.com>
> Signed-off-by: Nicholas Bellinger<nab@linux-iscsi.org>
> ---
>   drivers/target/target_core_transport.c |   26 +++++++++++++++-----------
>   1 files changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
> index 9583b23..fefe10a 100644
> --- a/drivers/target/target_core_transport.c
> +++ b/drivers/target/target_core_transport.c
> @@ -4776,18 +4776,20 @@ void transport_do_task_sg_chain(struct se_cmd *cmd)
>   				sg_end_cur->page_link&= ~0x02;
>
>   				sg_chain(sg_head, task_sg_num, sg_head_cur);
> -				sg_count += (task->task_sg_num + 1);
> -			} else
>   				sg_count += task->task_sg_num;
> +				task_sg_num = (task->task_sg_num + 1);
> +			} else {
> +				sg_chain(sg_head, task_sg_num, sg_head_cur);
> +				sg_count += task->task_sg_num;
> +				task_sg_num = task->task_sg_num;
> +			}
>
>   			sg_head = sg_head_cur;
>   			sg_link = sg_link_cur;
> -			task_sg_num = task->task_sg_num;
>   			continue;
>   		}
>   		sg_head = sg_first =&task->task_sg[0];
>   		sg_link =&task->task_sg[task->task_sg_num];
> -		task_sg_num = task->task_sg_num;
>   		/*
>   		 * Check for single task..
>   		 */
> @@ -4798,9 +4800,12 @@ void transport_do_task_sg_chain(struct se_cmd *cmd)
>   			 */
>   			sg_end =&task->task_sg[task->task_sg_num - 1];
>   			sg_end->page_link&= ~0x02;
> -			sg_count += (task->task_sg_num + 1);
> -		} else
>   			sg_count += task->task_sg_num;
> +			task_sg_num = (task->task_sg_num + 1);
> +		} else {
> +			sg_count += task->task_sg_num;
> +			task_sg_num = task->task_sg_num;
> +		}
>   	}
>   	/*
>   	 * Setup the starting pointer and total t_tasks_sg_linked_no including
> @@ -4809,21 +4814,20 @@ void transport_do_task_sg_chain(struct se_cmd *cmd)
>   	T_TASK(cmd)->t_tasks_sg_chained = sg_first;
>   	T_TASK(cmd)->t_tasks_sg_chained_no = sg_count;
>
> -	DEBUG_CMD_M("Setup T_TASK(cmd)->t_tasks_sg_chained: %p and"
> -		" t_tasks_sg_chained_no: %u\n", T_TASK(cmd)->t_tasks_sg_chained,
> +	DEBUG_CMD_M("Setup cmd: %p T_TASK(cmd)->t_tasks_sg_chained: %p and"
> +		" t_tasks_sg_chained_no: %u\n", cmd, T_TASK(cmd)->t_tasks_sg_chained,
>   		T_TASK(cmd)->t_tasks_sg_chained_no);
>
>   	for_each_sg(T_TASK(cmd)->t_tasks_sg_chained, sg,
>   			T_TASK(cmd)->t_tasks_sg_chained_no, i) {
>
> -		DEBUG_CMD_M("SG: %p page: %p length: %d offset: %d\n",
> -			sg, sg_page(sg), sg->length, sg->offset);
> +		DEBUG_CMD_M("SG[%d]: %p page: %p length: %d offset: %d, magic: 0x%08x\n",
> +			i, sg, sg_page(sg), sg->length, sg->offset, sg->sg_magic);
>   		if (sg_is_chain(sg))
>   			DEBUG_CMD_M("SG: %p sg_is_chain=1\n", sg);
>   		if (sg_is_last(sg))
>   			DEBUG_CMD_M("SG: %p sg_is_last=1\n", sg);
>   	}
> -
>   }
>   EXPORT_SYMBOL(transport_do_task_sg_chain);
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-05-17 21:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-11  4:35 [PATCH-v2 0/4] Bugfixes for .39-rc8 Nicholas A. Bellinger
2011-05-11  4:35 ` [PATCH-v2 1/4] target: Fix multi task->task_sg[] chaining logic bug Nicholas A. Bellinger
2011-05-17 21:27   ` Kiran Patil
2011-05-11  4:35 ` [PATCH-v2 2/4] target: Fix interrupt context bug with stats_lock and core_tmr_alloc_req Nicholas A. Bellinger
2011-05-11  4:35 ` [PATCH-v2 3/4] target: Fix bug with task_sg chained transport_free_dev_tasks release Nicholas A. Bellinger
2011-05-11  4:35 ` [PATCH-v2 4/4] target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs Nicholas A. Bellinger
2011-05-14  0:05 ` [PATCH-v2 0/4] Bugfixes for .39-rc8 Nicholas A. Bellinger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.