linux-scsi.vger.kernel.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).