lkml.org 
[lkml]   [2016]   [Mar]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.2.y-ckt 045/218] aacraid: Fix RRQ overload
    Date
    4.2.8-ckt7 -stable review patch.  If anyone has any objections, please let me know.

    ---8<------------------------------------------------------------

    From: Raghava Aditya Renukunta <raghavaaditya.renukunta@pmcs.com>

    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.

    Fixes: 495c0217 "aacraid: MSI-x support"

    Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renukunta@pmcs.com>
    Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
    Reviewed-by: Tomas Henzl <thenzl@redhat.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    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(-)

    diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
    index 40fe65c..18c9c06 100644
    --- a/drivers/scsi/aacraid/aacraid.h
    +++ b/drivers/scsi/aacraid/aacraid.h
    @@ -939,6 +939,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*/
    };
    @@ -2098,6 +2099,7 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor)
    #define AAC_OWNER_FIRMWARE 0x106

    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);
    diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
    index 4da5749..d8e1a54 100644
    --- a/drivers/scsi/aacraid/commsup.c
    +++ b/drivers/scsi/aacraid/commsup.c
    @@ -90,6 +90,28 @@ void aac_fib_map_free(struct aac_dev *dev)
    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
    */
    diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
    index e63cf9f..cf437bd 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;
    @@ -448,36 +448,20 @@ static int aac_src_deliver_message(struct fib *fib)
    dma_addr_t address;
    struct aac_fib_xporthdr *pFibX;
    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;
    --
    2.7.4
    \
     
     \ /
      Last update: 2016-03-31 23:41    [W:4.119 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site