Re: [PATCH 02/10] aacraid: Fix RRQ overload

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

 



On Tue, 2015-12-01 at 04:39 -0800, Raghava Aditya Renukunta wrote:
> From: Raghava Aditya Renukunta <raghavaaditya.renukunta@xxxxxxxx>
> 
> The driver utilizes an array of atomic variables to keep track of
> IO submissions to each vector. To submit an IO multiple threads
> iterate through the array to find a vector which has empty slots
> to send an IO. The reading and updating of the variable is not atomic,
> causing race conditions when a thread uses a full vector to
> submit an IO.
> 
> Fixed by mapping each FIB to a vector, the submission path then uses
> said vector to submit IO thereby removing the possibly of a race
> condition.The vector assignment is started from 1 since vector 0 is
> reserved for the use of AIF management FIBS.If the number of MSIx
> vectors is 1 (MSI or INTx mode) then all the fibs are allocated to
> vector 0.
> 
> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renukunta@xxxxxxxx>
> ---
>  drivers/scsi/aacraid/aacraid.h |  1 +
>  drivers/scsi/aacraid/commsup.c | 12 ++++++++++++
>  drivers/scsi/aacraid/src.c     | 30 +++++++-----------------------
>  3 files changed, 20 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
> index da227e8..d133c4a 100644
> --- a/drivers/scsi/aacraid/aacraid.h
> +++ b/drivers/scsi/aacraid/aacraid.h
> @@ -944,6 +944,7 @@ struct fib {
>  	 */
>  	struct list_head	fiblink;
>  	void			*data;
> +	u32			vector_no;
>  	struct hw_fib		*hw_fib_va;		/* Actual
> shared object */
>  	dma_addr_t		hw_fib_pa;		/* physical
> address of hw_fib*/
>  };
> diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
> index b5b653c..b257d3b 100644
> --- a/drivers/scsi/aacraid/commsup.c
> +++ b/drivers/scsi/aacraid/commsup.c
> @@ -104,6 +104,7 @@ int aac_fib_setup(struct aac_dev * dev)
>  	struct hw_fib *hw_fib;
>  	dma_addr_t hw_fib_pa;
>  	int i;
> +	u32 vector = 1;
>  
>  	while (((i = fib_map_alloc(dev)) == -ENOMEM)
>  	 && (dev->scsi_host_ptr->can_queue > (64 - AAC_NUM_MGT_FIB))) {
> @@ -150,6 +151,17 @@ int aac_fib_setup(struct aac_dev * dev)
>  			dev->max_fib_size + sizeof(struct
> aac_fib_xporthdr));
>  		hw_fib_pa = hw_fib_pa +
>  			dev->max_fib_size + sizeof(struct aac_fib_xporthdr);
> +
> +		if ((dev->max_msix == 1) ||
> +		  (i > ((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB -
> 1)
> +			- dev->vector_cap))) {
> +			fibptr->vector_no = 0;
> +		} else {
> +			fibptr->vector_no = vector;
> +			vector++;
> +			if (vector == dev->max_msix)
> +				vector = 1;
> +		}
>  	}
>  	/*
>  	 *	Add the fib chain to the free list
> diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
> index 2aa34ea..bc0203f 100644
> --- a/drivers/scsi/aacraid/src.c
> +++ b/drivers/scsi/aacraid/src.c
> @@ -156,8 +156,8 @@ static irqreturn_t aac_src_intr_message(int irq, void
> *dev_id)
>  				break;
>  			if (dev->msi_enabled && dev->max_msix > 1)
>  				atomic_dec(&dev-
> >rrq_outstanding[vector_no]);
> -			aac_intr_normal(dev, handle-1, 0, isFastResponse,
> NULL);
>  			dev->host_rrq[index++] = 0;
> +			aac_intr_normal(dev, handle-1, 0, isFastResponse,
> NULL);
>  			if (index == (vector_no + 1) * dev->vector_cap)
>  				index = vector_no * dev->vector_cap;
>  			dev->host_rrq_idx[vector_no] = index;
> @@ -452,36 +452,20 @@ static int aac_src_deliver_message(struct fib *fib)
>  #endif
>  
>  	u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);
> +	u16 vector_no;
>  
>  	atomic_inc(&q->numpending);
>  
>  	if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest
> &&
>  	    dev->max_msix > 1) {
> -		u_int16_t vector_no, first_choice = 0xffff;
> -
> -		vector_no = dev->fibs_pushed_no % dev->max_msix;
> -		do {
> -			vector_no += 1;
> -			if (vector_no == dev->max_msix)
> -				vector_no = 1;
> -			if (atomic_read(&dev->rrq_outstanding[vector_no]) <
> -			    dev->vector_cap)
> -				break;
> -			if (0xffff == first_choice)
> -				first_choice = vector_no;
> -			else if (vector_no == first_choice)
> -				break;
> -		} while (1);
> -		if (vector_no == first_choice)
> -			vector_no = 0;
> -		atomic_inc(&dev->rrq_outstanding[vector_no]);
> -		if (dev->fibs_pushed_no == 0xffffffff)
> -			dev->fibs_pushed_no = 0;
> -		else
> -			dev->fibs_pushed_no++;
> +		vector_no = fib->vector_no;
>  		fib->hw_fib_va->header.Handle += (vector_no << 16);
> +	} else {
> +		vector_no = 0;
>  	}
>  
> +	atomic_inc(&dev->rrq_outstanding[vector_no]);
> +
>  	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
>  		/* Calculate the amount to the fibsize bits */
>  		fibsize = (hdr_size + 127) / 128 - 1;

Reviewed-by: Johannes Thumshirn <jthumshirn@xxxxxxx>
Fixes: 495c0217 "aacraid: MSI-x support"
Cc: stable@xxxxxxxxxxxxxxx # v4.1
--
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