Prev: [31/54] USB: EHCI: remove PCI assumption
Next: [[PATCH 09/11]] viafb: add new output device management
From: Greg KH on 11 Aug 2010 20:10 2.6.34-stable review patch. If anyone has any objections, please let us know. ------------------ From: Brian King <brking(a)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(a)linux.vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley(a)suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh(a)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 @@ -3013,6 +3013,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; @@ -3035,6 +3036,7 @@ static struct ibmvfc_crq *ibmvfc_next_cr if (crq->valid & 0x80) { if (++queue->cur == queue->size) queue->cur = 0; + rmb(); } else crq = NULL; @@ -3083,12 +3085,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); @@ -3096,10 +3100,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; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ |