Re: [PATCH] libsas: remove task_collector mode

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

 



On 11/24/2014 09:41 AM, Christoph Hellwig wrote:
> The task_collector mode (or "latency_injector", (C) Dan Willians) is an
> optional I/O path in libsas that queues up scsi commands instead of
> directly sending it to the hardware.  It generall increases latencies
> to in the optiomal case slightly reduce mmio traffic to the hardware.
> 
> Only the obsolete aic94xx driver and the mvsas driver allowed to use
> it without recompiling the kernel, and most drivers didn't support it
> at all.
> 
> Remove the giant blob of code to allow better optimizations for scsi-mq
> in the future.
> 
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
> ---
>  Documentation/scsi/libsas.txt       |  82 +----------------
>  drivers/scsi/aic94xx/aic94xx.h      |   2 +-
>  drivers/scsi/aic94xx/aic94xx_hwi.c  |   3 +-
>  drivers/scsi/aic94xx/aic94xx_init.c |  11 ---
>  drivers/scsi/aic94xx/aic94xx_task.c |  13 ++-
>  drivers/scsi/isci/init.c            |   2 -
>  drivers/scsi/isci/task.c            | 147 ++++++++++++++----------------
>  drivers/scsi/isci/task.h            |   1 -
>  drivers/scsi/libsas/sas_ata.c       |   9 +-
>  drivers/scsi/libsas/sas_expander.c  |   2 +-
>  drivers/scsi/libsas/sas_init.c      |  21 -----
>  drivers/scsi/libsas/sas_internal.h  |   2 -
>  drivers/scsi/libsas/sas_scsi_host.c | 176 +-----------------------------------
>  drivers/scsi/mvsas/mv_init.c        |  22 -----
>  drivers/scsi/mvsas/mv_sas.c         | 109 +---------------------
>  drivers/scsi/mvsas/mv_sas.h         |  10 +-
>  drivers/scsi/pm8001/pm8001_init.c   |   2 -
>  drivers/scsi/pm8001/pm8001_sas.c    |  22 +----
>  drivers/scsi/pm8001/pm8001_sas.h    |   3 +-
>  include/scsi/libsas.h               |  14 +--
>  20 files changed, 97 insertions(+), 556 deletions(-)
> 
> diff --git a/Documentation/scsi/libsas.txt b/Documentation/scsi/libsas.txt
> index 3cc9c78..8cac649 100644
> --- a/Documentation/scsi/libsas.txt
> +++ b/Documentation/scsi/libsas.txt
> @@ -226,9 +226,6 @@ static int register_sas_ha(struct my_sas_ha *my_ha)
>  	my_ha->sas_ha.lldd_dev_found = my_dev_found;
>  	my_ha->sas_ha.lldd_dev_gone = my_dev_gone;
>  
> -	my_ha->sas_ha.lldd_max_execute_num = lldd_max_execute_num; (1)
> -
> -	my_ha->sas_ha.lldd_queue_size = ha_can_queue;
>  	my_ha->sas_ha.lldd_execute_task = my_execute_task;
>  
>  	my_ha->sas_ha.lldd_abort_task     = my_abort_task;
> @@ -247,28 +244,6 @@ static int register_sas_ha(struct my_sas_ha *my_ha)
>  	return sas_register_ha(&my_ha->sas_ha);
>  }
>  
> -(1) This is normally a LLDD parameter, something of the
> -lines of a task collector.  What it tells the SAS Layer is
> -whether the SAS layer should run in Direct Mode (default:
> -value 0 or 1) or Task Collector Mode (value greater than 1).
> -
> -In Direct Mode, the SAS Layer calls Execute Task as soon as
> -it has a command to send to the SDS, _and_ this is a single
> -command, i.e. not linked.
> -
> -Some hardware (e.g. aic94xx) has the capability to DMA more
> -than one task at a time (interrupt) from host memory.  Task
> -Collector Mode is an optional feature for HAs which support
> -this in their hardware.  (Again, it is completely optional
> -even if your hardware supports it.)
> -
> -In Task Collector Mode, the SAS Layer would do _natural_
> -coalescing of tasks and at the appropriate moment it would
> -call your driver to DMA more than one task in a single HA
> -interrupt. DMBS may want to use this by insmod/modprobe
> -setting the lldd_max_execute_num to something greater than
> -1.
> -
>  (2) SAS 1.1 does not define I_T Nexus Reset TMF.
>  
>  Events
> @@ -325,71 +300,22 @@ PHYE_SPINUP_HOLD -- SATA is present, COMWAKE not sent.
>  
>  The Execute Command SCSI RPC:
>  
> -	int (*lldd_execute_task)(struct sas_task *, int num,
> -				 unsigned long gfp_flags);
> +	int (*lldd_execute_task)(struct sas_task *, gfp_t gfp_flags);
>  
> -Used to queue a task to the SAS LLDD.  @task is the tasks to
> -be executed.  @num should be the number of tasks being
> -queued at this function call (they are linked listed via
> -task::list), @gfp_mask should be the gfp_mask defining the
> -context of the caller.
> +Used to queue a task to the SAS LLDD.  @task is the task to be executed.
> +@gfp_mask is the gfp_mask defining the context of the caller.
>  
>  This function should implement the Execute Command SCSI RPC,
> -or if you're sending a SCSI Task as linked commands, you
> -should also use this function.
>  
> -That is, when lldd_execute_task() is called, the command(s)
> +That is, when lldd_execute_task() is called, the command
>  go out on the transport *immediately*.  There is *no*
>  queuing of any sort and at any level in a SAS LLDD.
>  
> -The use of task::list is two-fold, one for linked commands,
> -the other discussed below.
> -
> -It is possible to queue up more than one task at a time, by
> -initializing the list element of struct sas_task, and
> -passing the number of tasks enlisted in this manner in num.
> -
>  Returns: -SAS_QUEUE_FULL, -ENOMEM, nothing was queued;
>  	 0, the task(s) were queued.
>  
> -If you want to pass num > 1, then either
> -A) you're the only caller of this function and keep track
> -   of what you've queued to the LLDD, or
> -B) you know what you're doing and have a strategy of
> -   retrying.
> -
> -As opposed to queuing one task at a time (function call),
> -batch queuing of tasks, by having num > 1, greatly
> -simplifies LLDD code, sequencer code, and _hardware design_,
> -and has some performance advantages in certain situations
> -(DBMS).
> -
> -The LLDD advertises if it can take more than one command at
> -a time at lldd_execute_task(), by setting the
> -lldd_max_execute_num parameter (controlled by "collector"
> -module parameter in aic94xx SAS LLDD).
> -
> -You should leave this to the default 1, unless you know what
> -you're doing.
> -
> -This is a function of the LLDD, to which the SAS layer can
> -cater to.
> -
> -int lldd_queue_size
> -	The host adapter's queue size.  This is the maximum
> -number of commands the lldd can have pending to domain
> -devices on behalf of all upper layers submitting through
> -lldd_execute_task().
> -
> -You really want to set this to something (much) larger than
> -1.
> -
> -This _really_ has absolutely nothing to do with queuing.
> -There is no queuing in SAS LLDDs.
> -
>  struct sas_task {
>  	dev -- the device this task is destined to
> -	list -- must be initialized (INIT_LIST_HEAD)
>  	task_proto -- _one_ of enum sas_proto
>  	scatter -- pointer to scatter gather list array
>  	num_scatter -- number of elements in scatter
> diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h
> index 66cda66..26d4ad9 100644
> --- a/drivers/scsi/aic94xx/aic94xx.h
> +++ b/drivers/scsi/aic94xx/aic94xx.h
> @@ -78,7 +78,7 @@ void asd_dev_gone(struct domain_device *dev);
>  
>  void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id);
>  
> -int  asd_execute_task(struct sas_task *, int num, gfp_t gfp_flags);
> +int  asd_execute_task(struct sas_task *task, gfp_t gfp_flags);
>  
>  void asd_set_dmamode(struct domain_device *dev);
>  
> diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
> index 4df867e..9f636a3 100644
> --- a/drivers/scsi/aic94xx/aic94xx_hwi.c
> +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
> @@ -1200,8 +1200,7 @@ static void asd_start_scb_timers(struct list_head *list)
>   * Case A: we can send the whole batch at once.  Increment "pending"
>   * in the beginning of this function, when it is checked, in order to
>   * eliminate races when this function is called by multiple processes.
> - * Case B: should never happen if the managing layer considers
> - * lldd_queue_size.
> + * Case B: should never happen.
>   */
>  int asd_post_ascb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
>  		       int num)
> diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
> index 579dc2f..49e4465 100644
> --- a/drivers/scsi/aic94xx/aic94xx_init.c
> +++ b/drivers/scsi/aic94xx/aic94xx_init.c
> @@ -49,14 +49,6 @@ MODULE_PARM_DESC(use_msi, "\n"
>  	"\tEnable(1) or disable(0) using PCI MSI.\n"
>  	"\tDefault: 0");
>  
> -static int lldd_max_execute_num = 0;
> -module_param_named(collector, lldd_max_execute_num, int, S_IRUGO);
> -MODULE_PARM_DESC(collector, "\n"
> -	"\tIf greater than one, tells the SAS Layer to run in Task Collector\n"
> -	"\tMode.  If 1 or 0, tells the SAS Layer to run in Direct Mode.\n"
> -	"\tThe aic94xx SAS LLDD supports both modes.\n"
> -	"\tDefault: 0 (Direct Mode).\n");
> -
>  static struct scsi_transport_template *aic94xx_transport_template;
>  static int asd_scan_finished(struct Scsi_Host *, unsigned long);
>  static void asd_scan_start(struct Scsi_Host *);
> @@ -710,9 +702,6 @@ static int asd_register_sas_ha(struct asd_ha_struct *asd_ha)
>  	asd_ha->sas_ha.sas_port= sas_ports;
>  	asd_ha->sas_ha.num_phys= ASD_MAX_PHYS;
>  
> -	asd_ha->sas_ha.lldd_queue_size = asd_ha->seq.can_queue;
> -	asd_ha->sas_ha.lldd_max_execute_num = lldd_max_execute_num;
> -
>  	return sas_register_ha(&asd_ha->sas_ha);
>  }
>  
> diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
> index 59b86e2..5ff1ce7 100644
> --- a/drivers/scsi/aic94xx/aic94xx_task.c
> +++ b/drivers/scsi/aic94xx/aic94xx_task.c
> @@ -543,8 +543,7 @@ static int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
>  	return res;
>  }
>  
> -int asd_execute_task(struct sas_task *task, const int num,
> -		     gfp_t gfp_flags)
> +int asd_execute_task(struct sas_task *task, gfp_t gfp_flags)
>  {
>  	int res = 0;
>  	LIST_HEAD(alist);
> @@ -553,11 +552,11 @@ int asd_execute_task(struct sas_task *task, const int num,
>  	struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
>  	unsigned long flags;
>  
> -	res = asd_can_queue(asd_ha, num);
> +	res = asd_can_queue(asd_ha, 1);
>  	if (res)
>  		return res;
>  
> -	res = num;
> +	res = 1;
>  	ascb = asd_ascb_alloc_list(asd_ha, &res, gfp_flags);
>  	if (res) {
>  		res = -ENOMEM;
> @@ -568,7 +567,7 @@ int asd_execute_task(struct sas_task *task, const int num,
>  	list_for_each_entry(a, &alist, list) {
>  		a->uldd_task = t;
>  		t->lldd_task = a;
> -		t = list_entry(t->list.next, struct sas_task, list);
> +		break;
>  	}
>  	list_for_each_entry(a, &alist, list) {
>  		t = a->uldd_task;
> @@ -601,7 +600,7 @@ int asd_execute_task(struct sas_task *task, const int num,
>  	}
>  	list_del_init(&alist);
>  
> -	res = asd_post_ascb_list(asd_ha, ascb, num);
> +	res = asd_post_ascb_list(asd_ha, ascb, 1);
>  	if (unlikely(res)) {
>  		a = NULL;
>  		__list_add(&alist, ascb->list.prev, &ascb->list);
> @@ -639,6 +638,6 @@ out_err_unmap:
>  out_err:
>  	if (ascb)
>  		asd_ascb_free_list(ascb);
> -	asd_can_dequeue(asd_ha, num);
> +	asd_can_dequeue(asd_ha, 1);
>  	return res;
>  }
Why did you not remove the last argument from asd_can_queue() and
asd_can_dequeue(), too?
With that patch it's always '1' ...

[ .. ]
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 76570e6..b93f289 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -350,7 +350,7 @@ static int sas_find_local_port_id(struct domain_device *dev)
>    */
>  #define DEV_IS_GONE(pm8001_dev)	\
>  	((!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED)))
> -static int pm8001_task_exec(struct sas_task *task, const int num,
> +static int pm8001_task_exec(struct sas_task *task,
>  	gfp_t gfp_flags, int is_tmf, struct pm8001_tmf_task *tmf)
>  {
>  	struct domain_device *dev = task->dev;
> @@ -360,7 +360,6 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
>  	struct sas_task *t = task;
>  	struct pm8001_ccb_info *ccb;
>  	u32 tag = 0xdeadbeef, rc, n_elem = 0;
> -	u32 n = num;
>  	unsigned long flags = 0;
>  
>  	if (!dev->port) {
> @@ -387,18 +386,12 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
>  				spin_unlock_irqrestore(&pm8001_ha->lock, flags);
>  				t->task_done(t);
>  				spin_lock_irqsave(&pm8001_ha->lock, flags);
> -				if (n > 1)
> -					t = list_entry(t->list.next,
> -							struct sas_task, list);
>  				continue;
>  			} else {
>  				struct task_status_struct *ts = &t->task_status;
>  				ts->resp = SAS_TASK_UNDELIVERED;
>  				ts->stat = SAS_PHY_DOWN;
>  				t->task_done(t);
> -				if (n > 1)
> -					t = list_entry(t->list.next,
> -							struct sas_task, list);
>  				continue;
>  			}
>  		}
> @@ -460,9 +453,7 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
>  		t->task_state_flags |= SAS_TASK_AT_INITIATOR;
>  		spin_unlock(&t->task_state_lock);
>  		pm8001_dev->running_req++;
> -		if (n > 1)
> -			t = list_entry(t->list.next, struct sas_task, list);
> -	} while (--n);
> +	} while (0);
>  	rc = 0;
>  	goto out_done;
>  
This 'while' loop can go, too.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@xxxxxxx			      +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux