]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.34 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 11 Aug 2010 23:00:00 +0000 (16:00 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 11 Aug 2010 23:00:00 +0000 (16:00 -0700)
queue-2.6.34/ibmvfc-fix-command-completion-handling.patch [new file with mode: 0644]
queue-2.6.34/ibmvfc-reduce-error-recovery-timeout.patch [new file with mode: 0644]
queue-2.6.34/md-raid1-delay-reads-that-could-overtake-behind-writes.patch [new file with mode: 0644]
queue-2.6.34/series

diff --git a/queue-2.6.34/ibmvfc-fix-command-completion-handling.patch b/queue-2.6.34/ibmvfc-fix-command-completion-handling.patch
new file mode 100644 (file)
index 0000000..7bf2744
--- /dev/null
@@ -0,0 +1,73 @@
+From f5832fa2f8dc39adcf3ae348d2d6383163235e79 Mon Sep 17 00:00:00 2001
+From: Brian King <brking@linux.vnet.ibm.com>
+Date: Tue, 20 Apr 2010 14:21:33 -0500
+Subject: [SCSI] ibmvfc: Fix command completion handling
+
+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
+@@ -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;
+       }
diff --git a/queue-2.6.34/ibmvfc-reduce-error-recovery-timeout.patch b/queue-2.6.34/ibmvfc-reduce-error-recovery-timeout.patch
new file mode 100644 (file)
index 0000000..db8fb8d
--- /dev/null
@@ -0,0 +1,44 @@
+From daa142d1773dd3a986f02a8a4da929608d24daaa Mon Sep 17 00:00:00 2001
+From: Brian King <brking@linux.vnet.ibm.com>
+Date: Tue, 20 Apr 2010 14:21:35 -0500
+Subject: [SCSI] ibmvfc: Reduce error recovery timeout
+
+From: Brian King <brking@linux.vnet.ibm.com>
+
+commit daa142d1773dd3a986f02a8a4da929608d24daaa upstream.
+
+If a command times out resulting in EH getting invoked, we wait for the
+aborted commands to come back after sending the abort. Shorten
+the amount of time we wait for these responses, to ensure we don't
+get stuck in EH for several minutes.
+
+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 |    2 +-
+ drivers/scsi/ibmvscsi/ibmvfc.h |    1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/scsi/ibmvscsi/ibmvfc.c
++++ b/drivers/scsi/ibmvscsi/ibmvfc.c
+@@ -2245,7 +2245,7 @@ static int ibmvfc_wait_for_ops(struct ib
+       DECLARE_COMPLETION_ONSTACK(comp);
+       int wait;
+       unsigned long flags;
+-      signed long timeout = init_timeout * HZ;
++      signed long timeout = IBMVFC_ABORT_WAIT_TIMEOUT * HZ;
+       ENTER;
+       do {
+--- a/drivers/scsi/ibmvscsi/ibmvfc.h
++++ b/drivers/scsi/ibmvscsi/ibmvfc.h
+@@ -38,6 +38,7 @@
+ #define IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT      \
+               (IBMVFC_ADISC_TIMEOUT + IBMVFC_ADISC_CANCEL_TIMEOUT)
+ #define IBMVFC_INIT_TIMEOUT           120
++#define IBMVFC_ABORT_WAIT_TIMEOUT     40
+ #define IBMVFC_MAX_REQUESTS_DEFAULT   100
+ #define IBMVFC_DEBUG                  0
diff --git a/queue-2.6.34/md-raid1-delay-reads-that-could-overtake-behind-writes.patch b/queue-2.6.34/md-raid1-delay-reads-that-could-overtake-behind-writes.patch
new file mode 100644 (file)
index 0000000..95b9915
--- /dev/null
@@ -0,0 +1,111 @@
+From e555190d82c0f58e825e3cbd9e6ebe2e7ac713bd Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Wed, 31 Mar 2010 11:21:44 +1100
+Subject: md/raid1: delay reads that could overtake behind-writes.
+
+From: NeilBrown <neilb@suse.de>
+
+commit e555190d82c0f58e825e3cbd9e6ebe2e7ac713bd upstream.
+
+When a raid1 array is configured to support write-behind
+on some devices, it normally only reads from other devices.
+If all devices are write-behind (because the rest have failed)
+it is possible for a read request to be serviced before a
+behind-write request, which would appear as data corruption.
+
+So when forced to read from a WriteMostly device, wait for any
+write-behind to complete, and don't start any more behind-writes.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/bitmap.c |    4 +++-
+ drivers/md/bitmap.h |    1 +
+ drivers/md/raid1.c  |   25 ++++++++++++++++++-------
+ 3 files changed, 22 insertions(+), 8 deletions(-)
+
+--- a/drivers/md/bitmap.c
++++ b/drivers/md/bitmap.c
+@@ -1351,7 +1351,8 @@ void bitmap_endwrite(struct bitmap *bitm
+ {
+       if (!bitmap) return;
+       if (behind) {
+-              atomic_dec(&bitmap->behind_writes);
++              if (atomic_dec_and_test(&bitmap->behind_writes))
++                      wake_up(&bitmap->behind_wait);
+               PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n",
+                 atomic_read(&bitmap->behind_writes), bitmap->max_write_behind);
+       }
+@@ -1675,6 +1676,7 @@ int bitmap_create(mddev_t *mddev)
+       atomic_set(&bitmap->pending_writes, 0);
+       init_waitqueue_head(&bitmap->write_wait);
+       init_waitqueue_head(&bitmap->overflow_wait);
++      init_waitqueue_head(&bitmap->behind_wait);
+       bitmap->mddev = mddev;
+--- a/drivers/md/bitmap.h
++++ b/drivers/md/bitmap.h
+@@ -239,6 +239,7 @@ struct bitmap {
+       atomic_t pending_writes; /* pending writes to the bitmap file */
+       wait_queue_head_t write_wait;
+       wait_queue_head_t overflow_wait;
++      wait_queue_head_t behind_wait;
+       struct sysfs_dirent *sysfs_can_clear;
+ };
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -866,6 +866,15 @@ static int make_request(struct request_q
+               }
+               mirror = conf->mirrors + rdisk;
++              if (test_bit(WriteMostly, &mirror->rdev->flags) &&
++                  bitmap) {
++                      /* Reading from a write-mostly device must
++                       * take care not to over-take any writes
++                       * that are 'behind'
++                       */
++                      wait_event(bitmap->behind_wait,
++                                 atomic_read(&bitmap->behind_writes) == 0);
++              }
+               r1_bio->read_disk = rdisk;
+               read_bio = bio_clone(bio, GFP_NOIO);
+@@ -943,10 +952,14 @@ static int make_request(struct request_q
+               set_bit(R1BIO_Degraded, &r1_bio->state);
+       }
+-      /* do behind I/O ? */
++      /* do behind I/O ?
++       * Not if there are too many, or cannot allocate memory,
++       * or a reader on WriteMostly is waiting for behind writes
++       * to flush */
+       if (bitmap &&
+           (atomic_read(&bitmap->behind_writes)
+            < mddev->bitmap_info.max_write_behind) &&
++          !waitqueue_active(&bitmap->behind_wait) &&
+           (behind_pages = alloc_behind_pages(bio)) != NULL)
+               set_bit(R1BIO_BehindIO, &r1_bio->state);
+@@ -2153,15 +2166,13 @@ static int stop(mddev_t *mddev)
+ {
+       conf_t *conf = mddev->private;
+       struct bitmap *bitmap = mddev->bitmap;
+-      int behind_wait = 0;
+       /* wait for behind writes to complete */
+-      while (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
+-              behind_wait++;
+-              printk(KERN_INFO "raid1: behind writes in progress on device %s, waiting to stop (%d)\n", mdname(mddev), behind_wait);
+-              set_current_state(TASK_UNINTERRUPTIBLE);
+-              schedule_timeout(HZ); /* wait a second */
++      if (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
++              printk(KERN_INFO "raid1: behind writes in progress on device %s, waiting to stop.\n", mdname(mddev));
+               /* need to kick something here to make sure I/O goes? */
++              wait_event(bitmap->behind_wait,
++                         atomic_read(&bitmap->behind_writes) == 0);
+       }
+       raise_barrier(conf);
index 11303d349a906079c6e06a1cd42763e7949370c1..0ec314e2203d956b05d9b86158c04e1d6844d882 100644 (file)
@@ -49,3 +49,6 @@ irq-add-new-irq-flag-irqf_no_suspend.patch
 xen-do-not-suspend-ipi-irqs.patch
 drm-i915-use-rsen-instead-of-htplg-for-tfp410-monitor-detection.patch
 i915-fix-ironlake-edp-panel-setup-v4.patch
+ibmvfc-fix-command-completion-handling.patch
+ibmvfc-reduce-error-recovery-timeout.patch
+md-raid1-delay-reads-that-could-overtake-behind-writes.patch