[PATCH 4/4] target: re-use the command S/G list for single-task commands

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If we only have a single task per command (which at least in my testing
is the by far most common case) we do not have to allocate a new per-task
S/G list but can reuse the one from the command.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>

Index: lio-core/drivers/target/target_core_transport.c
===================================================================
--- lio-core.orig/drivers/target/target_core_transport.c	2011-10-18 12:28:49.444351865 +0200
+++ lio-core/drivers/target/target_core_transport.c	2011-10-18 12:28:53.465359432 +0200
@@ -3531,7 +3531,8 @@ static void transport_free_dev_tasks(str
 		 */
 		del_timer_sync(&task->task_timer);
 
-		kfree(task->task_sg);
+		if (task->task_sg != cmd->t_data_sg)
+			kfree(task->task_sg);
 
 		list_del(&task->t_list);
 
@@ -3810,7 +3811,33 @@ transport_allocate_data_tasks(struct se_
 	lba = cmd->t_task_lba;
 	sectors = DIV_ROUND_UP(cmd->data_length, sector_size);
 	task_count = DIV_ROUND_UP_SECTOR_T(sectors, dev_max_sectors);
-	
+
+	/*
+	 * If we need just a single task reuse the SG list in the command
+	 * and avoid a lot of work.
+	 */
+	if (task_count == 1) {
+		struct se_task *task;
+		unsigned long flags;
+
+		task = transport_generic_get_task(cmd, data_direction);
+		if (!task)
+			return -ENOMEM;
+
+		task->task_sg = cmd_sg;
+		task->task_sg_nents = sgl_nents;
+
+		task->task_lba = lba;
+		task->task_sectors = sectors;
+		task->task_size = task->task_sectors * sector_size;
+
+		spin_lock_irqsave(&cmd->t_state_lock, flags);
+		list_add_tail(&task->t_list, &cmd->t_task_list);
+		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+
+		return task_count;
+	}
+
 	for (i = 0; i < task_count; i++) {
 		struct se_task *task;
 		unsigned int task_size, task_sg_nents_padded;
@@ -3886,15 +3913,7 @@ transport_allocate_control_task(struct s
 	if (!task)
 		return -ENOMEM;
 
-	task->task_sg = kmalloc(sizeof(struct scatterlist) * cmd->t_data_nents,
-				GFP_KERNEL);
-	if (!task->task_sg) {
-		cmd->se_dev->transport->free_task(task);
-		return -ENOMEM;
-	}
-
-	memcpy(task->task_sg, cmd->t_data_sg,
-	       sizeof(struct scatterlist) * cmd->t_data_nents);
+	task->task_sg = cmd->t_data_sg;
 	task->task_size = cmd->data_length;
 	task->task_sg_nents = cmd->t_data_nents;
 

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux