lkml.org 
[lkml]   [2010]   [Aug]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[108/111] [SCSI] ibmvfc: Fix command completion handling
    2.6.32-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: Brian King <brking@linux.vnet.ibm.com>

    commit f5832fa2f8dc39adcf3ae348d2d6383163235e79 upstream.

    Commands which are completed by the VIOS are placed on a CRQ
    in kernel memory for the ibmvfc driver to process. Each CRQ
    entry is 16 bytes. The ibmvfc driver reads the first 8 bytes
    to check if the entry is valid, then reads the next 8 bytes to get
    the handle, which is a pointer the completed command. This fixes
    an issue seen on Power 7 where the processor reordered the
    loads from memory, resulting in processing command completion
    with a stale handle. This could result in command timeouts,
    and also early completion of commands.

    Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
    Signed-off-by: James Bottomley <James.Bottomley@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/scsi/ibmvscsi/ibmvfc.c | 6 ++++++
    1 file changed, 6 insertions(+)

    --- a/drivers/scsi/ibmvscsi/ibmvfc.c
    +++ b/drivers/scsi/ibmvscsi/ibmvfc.c
    @@ -2720,6 +2720,7 @@ static struct ibmvfc_async_crq *ibmvfc_n
    if (crq->valid & 0x80) {
    if (++async_crq->cur == async_crq->size)
    async_crq->cur = 0;
    + rmb();
    } else
    crq = NULL;

    @@ -2742,6 +2743,7 @@ static struct ibmvfc_crq *ibmvfc_next_cr
    if (crq->valid & 0x80) {
    if (++queue->cur == queue->size)
    queue->cur = 0;
    + rmb();
    } else
    crq = NULL;

    @@ -2790,12 +2792,14 @@ static void ibmvfc_tasklet(void *data)
    while ((async = ibmvfc_next_async_crq(vhost)) != NULL) {
    ibmvfc_handle_async(async, vhost);
    async->valid = 0;
    + wmb();
    }

    /* Pull all the valid messages off the CRQ */
    while ((crq = ibmvfc_next_crq(vhost)) != NULL) {
    ibmvfc_handle_crq(crq, vhost);
    crq->valid = 0;
    + wmb();
    }

    vio_enable_interrupts(vdev);
    @@ -2803,10 +2807,12 @@ static void ibmvfc_tasklet(void *data)
    vio_disable_interrupts(vdev);
    ibmvfc_handle_async(async, vhost);
    async->valid = 0;
    + wmb();
    } else if ((crq = ibmvfc_next_crq(vhost)) != NULL) {
    vio_disable_interrupts(vdev);
    ibmvfc_handle_crq(crq, vhost);
    crq->valid = 0;
    + wmb();
    } else
    done = 1;
    }



    \
     
     \ /
      Last update: 2010-08-12 02:03    [W:0.020 / U:2.036 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site