Patch "aacraid: Fix RRQ overload" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
aacraid: Fix RRQ overload
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
aacraid-fix-rrq-overload.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
3f4ce057d51a9c0ed9b01ba693df685d230ffcaeMon Sep 17 00:00:00 2001
From: Raghava Aditya Renukunta <[email protected]>
Date: Wed, 3 Feb 2016 15:06:00 -0800
Subject: aacraid: Fix RRQ overload
From: Raghava Aditya Renukunta <[email protected]>
commit 3f4ce057d51a9c0ed9b01ba693df685d230ffcae upstream.
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.
--- drivers/scsi/aacraid/aacraid.h | 2 ++ drivers/scsi/aacraid/commsup.c | 28 ++++++++++++++++++++++++++++ drivers/scsi/aacraid/src.c | 30 +++++++----------------------- 3 files changed, 37 insertions(+), 23 deletions(-)
drivers/scsi/aacraid/aacraid.h +2 -0
@@ -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*/ };
@@ -2113,6 +2114,7 @@ static inline unsigned int cap_to_cyls(sint aac_acquire_irq (struct aac_dev *dev);void aac_free_irq (struct aac_dev *dev);const char *aac_driverinfo (struct Scsi_Host *); +void aac_fib_vector_assign (struct aac_dev *dev);struct fib *aac_fib_alloc (struct aac_dev *dev);int aac_fib_setup (struct aac_dev *dev);void aac_fib_map_free (struct aac_dev *dev);
drivers/scsi/aacraid/commsup.c +28 -0
@@ -90,6 +90,28 @@ void aac_fib_map_free(struct aac_dev *de dev->hw_fib_pa =0 ; } +void aac_fib_vector_assign (struct aac_dev *dev) +{ +u32 i =0 ; +u32 vector =1 ; +struct fib *fibptr =NULL ; + +for (i =0 , fibptr = &dev->fibs[i]; + i < (dev->scsi_host_ptr->can_queue +AAC_NUM_MGT_FIB ); + i++, fibptr++) { +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 ; + } + } +} +/** * aac_fib_setup - setup the fibs * @dev: Adapter to set up
@@ -151,6 +173,12 @@ int aac_fib_setup(struct aac_dev * dev) hw_fib_pa = hw_fib_pa + dev->max_fib_size +sizeof (struct aac_fib_xporthdr ); } + +/* +*Assign vector numbers to fibs +*/ +aac_fib_vector_assign (dev); +/* * Add the fib chain to the free list */
drivers/scsi/aacraid/src.c +7 -23
@@ -156,8 +156,8 @@ static irqreturn_t aac_src_intr_message(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(struc#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 ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/aacraid-fix-memory-leak-in-aac_fib_map_free.patch queue-4.4/aacraid-fix-rrq-overload.patch queue-4.4/aacraid-set-correct-msix-count-for-eeh-recovery.patch