]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Oct 2013 21:51:01 +0000 (14:51 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Oct 2013 21:51:01 +0000 (14:51 -0700)
added patches:
dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch
dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch
usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch
xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch
xhci-fix-oops-happening-after-address-device-timeout.patch
xhci-fix-race-between-ep-halt-and-urb-cancellation.patch

queue-3.4/dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch [new file with mode: 0644]
queue-3.4/dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch [new file with mode: 0644]
queue-3.4/series
queue-3.4/usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch [new file with mode: 0644]
queue-3.4/xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch [new file with mode: 0644]
queue-3.4/xhci-fix-oops-happening-after-address-device-timeout.patch [new file with mode: 0644]
queue-3.4/xhci-fix-race-between-ep-halt-and-urb-cancellation.patch [new file with mode: 0644]

diff --git a/queue-3.4/dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch b/queue-3.4/dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch
new file mode 100644 (file)
index 0000000..c9cc485
--- /dev/null
@@ -0,0 +1,50 @@
+From 60e356f381954d79088d0455e357db48cfdd6857 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 18 Sep 2013 19:40:42 -0400
+Subject: dm-snapshot: fix performance degradation due to small hash size
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 60e356f381954d79088d0455e357db48cfdd6857 upstream.
+
+LVM2, since version 2.02.96, creates origin with zero size, then loads
+the snapshot driver and then loads the origin.  Consequently, the
+snapshot driver sees the origin size zero and sets the hash size to the
+lower bound 64.  Such small hash table causes performance degradation.
+
+This patch changes it so that the hash size is determined by the size of
+snapshot volume, not minimum of origin and snapshot size.  It doesn't
+make sense to set the snapshot size significantly larger than the origin
+size, so we do not need to take origin size into account when
+calculating the hash size.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-snap.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -721,17 +721,16 @@ static int calc_max_buckets(void)
+  */
+ static int init_hash_tables(struct dm_snapshot *s)
+ {
+-      sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets;
++      sector_t hash_size, cow_dev_size, max_buckets;
+       /*
+        * Calculate based on the size of the original volume or
+        * the COW volume...
+        */
+       cow_dev_size = get_dev_size(s->cow->bdev);
+-      origin_dev_size = get_dev_size(s->origin->bdev);
+       max_buckets = calc_max_buckets();
+-      hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
++      hash_size = cow_dev_size >> s->store->chunk_shift;
+       hash_size = min(hash_size, max_buckets);
+       if (hash_size < 64)
diff --git a/queue-3.4/dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch b/queue-3.4/dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch
new file mode 100644 (file)
index 0000000..4c9304d
--- /dev/null
@@ -0,0 +1,47 @@
+From 5ea330a75bd86b2b2a01d7b85c516983238306fb Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 18 Sep 2013 19:14:22 -0400
+Subject: dm snapshot: workaround for a false positive lockdep warning
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 5ea330a75bd86b2b2a01d7b85c516983238306fb upstream.
+
+The kernel reports a lockdep warning if a snapshot is invalidated because
+it runs out of space.
+
+The lockdep warning was triggered by commit 0976dfc1d0cd80a4e9dfaf87bd87
+("workqueue: Catch more locking problems with flush_work()") in v3.5.
+
+The warning is false positive.  The real cause for the warning is that
+the lockdep engine treats different instances of md->lock as a single
+lock.
+
+This patch is a workaround - we use flush_workqueue instead of flush_work.
+This code path is not performance sensitive (it is called only on
+initialization or invalidation), thus it doesn't matter that we flush the
+whole workqueue.
+
+The real fix for the problem would be to teach the lockdep engine to treat
+different instances of md->lock as separate locks.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Acked-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-snap-persistent.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/md/dm-snap-persistent.c
++++ b/drivers/md/dm-snap-persistent.c
+@@ -256,7 +256,7 @@ static int chunk_io(struct pstore *ps, v
+        */
+       INIT_WORK_ONSTACK(&req.work, do_metadata);
+       queue_work(ps->metadata_wq, &req.work);
+-      flush_work(&req.work);
++      flush_workqueue(ps->metadata_wq);
+       return req.result;
+ }
index c488386d1d04e36f274615fe9b90f80ae02ec5c3..8a9a9b2cc1f74f744e87ad132fb8eecfdbcb2545 100644 (file)
@@ -1,3 +1,9 @@
 x86-reboot-add-quirk-to-make-dell-c6100-use-reboot-pci-automatically.patch
 x86-efi-don-t-map-boot-services-on-i386.patch
 staging-vt6656-main_usb.c-oops-on-device_close-move-flag-earlier.patch
+xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch
+xhci-fix-oops-happening-after-address-device-timeout.patch
+xhci-fix-race-between-ep-halt-and-urb-cancellation.patch
+usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch
+dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch
+dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch
diff --git a/queue-3.4/usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch b/queue-3.4/usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch
new file mode 100644 (file)
index 0000000..843061d
--- /dev/null
@@ -0,0 +1,83 @@
+From 831abf76643555a99b80a3b54adfa7e4fa0a3259 Mon Sep 17 00:00:00 2001
+From: Kurt Garloff <kurt@garloff.de>
+Date: Tue, 24 Sep 2013 14:13:48 +0200
+Subject: usb/core/devio.c: Don't reject control message to endpoint with wrong direction bit
+
+From: Kurt Garloff <kurt@garloff.de>
+
+commit 831abf76643555a99b80a3b54adfa7e4fa0a3259 upstream.
+
+Trying to read data from the Pegasus Technologies NoteTaker (0e20:0101)
+[1] with the Windows App (EasyNote) works natively but fails when
+Windows is running under KVM (and the USB device handed to KVM).
+
+The reason is a USB control message
+ usb 4-2.2: control urb: bRequestType=22 bRequest=09 wValue=0200 wIndex=0001 wLength=0008
+This goes to endpoint address 0x01 (wIndex); however, endpoint address
+0x01 does not exist. There is an endpoint 0x81 though (same number,
+but other direction); the app may have meant that endpoint instead.
+
+The kernel thus rejects the IO and thus we see the failure.
+
+Apparently, Linux is more strict here than Windows ... we can't change
+the Win app easily, so that's a problem.
+
+It seems that the Win app/driver is buggy here and the driver does not
+behave fully according to the USB HID class spec that it claims to
+belong to.  The device seems to happily deal with that though (and
+seems to not really care about this value much).
+
+So the question is whether the Linux kernel should filter here.
+Rejecting has the risk that somewhat non-compliant userspace apps/
+drivers (most likely in a virtual machine) are prevented from working.
+Not rejecting has the risk of confusing an overly sensitive device with
+such a transfer. Given the fact that Windows does not filter it makes
+this risk rather small though.
+
+The patch makes the kernel more tolerant: If the endpoint address in
+wIndex does not exist, but an endpoint with toggled direction bit does,
+it will let the transfer through. (It does NOT change the message.)
+
+With attached patch, the app in Windows in KVM works.
+ usb 4-2.2: check_ctrlrecip: process 13073 (qemu-kvm) requesting ep 01 but needs 81
+
+I suspect this will mostly affect apps in virtual environments; as on
+Linux the apps would have been adapted to the stricter handling of the
+kernel. I have done that for mine[2].
+
+[1] http://www.pegatech.com/
+[2] https://sourceforge.net/projects/notetakerpen/
+
+Signed-off-by: Kurt Garloff <kurt@garloff.de>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/devio.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -684,6 +684,22 @@ static int check_ctrlrecip(struct dev_st
+               if ((index & ~USB_DIR_IN) == 0)
+                       return 0;
+               ret = findintfep(ps->dev, index);
++              if (ret < 0) {
++                      /*
++                       * Some not fully compliant Win apps seem to get
++                       * index wrong and have the endpoint number here
++                       * rather than the endpoint address (with the
++                       * correct direction). Win does let this through,
++                       * so we'll not reject it here but leave it to
++                       * the device to not break KVM. But we warn.
++                       */
++                      ret = findintfep(ps->dev, index ^ 0x80);
++                      if (ret >= 0)
++                              dev_info(&ps->dev->dev,
++                                      "%s: process %i (%s) requesting ep %02x but needs %02x\n",
++                                      __func__, task_pid_nr(current),
++                                      current->comm, index, index ^ 0x80);
++              }
+               if (ret >= 0)
+                       ret = checkintf(ps, ret);
+               break;
diff --git a/queue-3.4/xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch b/queue-3.4/xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch
new file mode 100644 (file)
index 0000000..f05d8f0
--- /dev/null
@@ -0,0 +1,144 @@
+From ec7e43e2d98173483866fe2e4e690143626b659c Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Fri, 30 Aug 2013 18:25:49 +0300
+Subject: xhci: Ensure a command structure points to the correct trb on the command ring
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit ec7e43e2d98173483866fe2e4e690143626b659c upstream.
+
+If a command on the command ring needs to be cancelled before it is handled
+it can be turned to a no-op operation when the ring is stopped.
+We want to store the command ring enqueue pointer in the command structure
+when the command in enqueued for the cancellation case.
+
+Some commands used to store the command ring dequeue pointers instead of enqueue
+(these often worked because enqueue happends to equal dequeue quite often)
+
+Other commands correctly used the enqueue pointer but did not check if it pointed
+to a valid trb or a link trb, this caused for example stop endpoint command to timeout in
+xhci_stop_device() in about 2% of suspend/resume cases.
+
+This should also solve some weird behavior happening in command cancellation cases.
+
+This patch is based on a patch submitted by Sarah Sharp to linux-usb, but
+then forgotten:
+    http://marc.info/?l=linux-usb&m=136269803207465&w=2
+
+This patch should be backported to kernels as old as 3.7, that contain
+the commit b92cc66c047ff7cf587b318fe377061a353c120f "xHCI: add aborting
+command ring function"
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-hub.c  |    2 +-
+ drivers/usb/host/xhci-ring.c |   10 ++++++++++
+ drivers/usb/host/xhci.c      |   25 +++++--------------------
+ drivers/usb/host/xhci.h      |    1 +
+ 4 files changed, 17 insertions(+), 21 deletions(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -287,7 +287,7 @@ static int xhci_stop_device(struct xhci_
+               if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue)
+                       xhci_queue_stop_endpoint(xhci, slot_id, i, suspend);
+       }
+-      cmd->command_trb = xhci->cmd_ring->enqueue;
++      cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring);
+       list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list);
+       xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend);
+       xhci_ring_cmd_db(xhci);
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -122,6 +122,16 @@ static int enqueue_is_link_trb(struct xh
+       return TRB_TYPE_LINK_LE32(link->control);
+ }
++union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring)
++{
++      /* Enqueue pointer can be left pointing to the link TRB,
++       * we must handle that
++       */
++      if (TRB_TYPE_LINK_LE32(ring->enqueue->link.control))
++              return ring->enq_seg->next->trbs;
++      return ring->enqueue;
++}
++
+ /* Updates trb to point to the next TRB in the ring, and updates seg if the next
+  * TRB is in a new segment.  This does not skip over link TRBs, and it does not
+  * effect the ring dequeue or enqueue pointers.
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -2582,15 +2582,7 @@ static int xhci_configure_endpoint(struc
+       if (command) {
+               cmd_completion = command->completion;
+               cmd_status = &command->status;
+-              command->command_trb = xhci->cmd_ring->enqueue;
+-
+-              /* Enqueue pointer can be left pointing to the link TRB,
+-               * we must handle that
+-               */
+-              if (TRB_TYPE_LINK_LE32(command->command_trb->link.control))
+-                      command->command_trb =
+-                              xhci->cmd_ring->enq_seg->next->trbs;
+-
++              command->command_trb = xhci_find_next_enqueue(xhci->cmd_ring);
+               list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
+       } else {
+               cmd_completion = &virt_dev->cmd_completion;
+@@ -2598,7 +2590,7 @@ static int xhci_configure_endpoint(struc
+       }
+       init_completion(cmd_completion);
+-      cmd_trb = xhci->cmd_ring->dequeue;
++      cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring);
+       if (!ctx_change)
+               ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
+                               udev->slot_id, must_succeed);
+@@ -3383,14 +3375,7 @@ int xhci_discover_or_reset_device(struct
+       /* Attempt to submit the Reset Device command to the command ring */
+       spin_lock_irqsave(&xhci->lock, flags);
+-      reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;
+-
+-      /* Enqueue pointer can be left pointing to the link TRB,
+-       * we must handle that
+-       */
+-      if (TRB_TYPE_LINK_LE32(reset_device_cmd->command_trb->link.control))
+-              reset_device_cmd->command_trb =
+-                      xhci->cmd_ring->enq_seg->next->trbs;
++      reset_device_cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring);
+       list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
+       ret = xhci_queue_reset_device(xhci, slot_id);
+@@ -3594,7 +3579,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd,
+       union xhci_trb *cmd_trb;
+       spin_lock_irqsave(&xhci->lock, flags);
+-      cmd_trb = xhci->cmd_ring->dequeue;
++      cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring);
+       ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0);
+       if (ret) {
+               spin_unlock_irqrestore(&xhci->lock, flags);
+@@ -3721,7 +3706,7 @@ int xhci_address_device(struct usb_hcd *
+       xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
+       spin_lock_irqsave(&xhci->lock, flags);
+-      cmd_trb = xhci->cmd_ring->dequeue;
++      cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring);
+       ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma,
+                                       udev->slot_id);
+       if (ret) {
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1811,6 +1811,7 @@ int xhci_cancel_cmd(struct xhci_hcd *xhc
+               union xhci_trb *cmd_trb);
+ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id,
+               unsigned int ep_index, unsigned int stream_id);
++union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring);
+ /* xHCI roothub code */
+ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,
diff --git a/queue-3.4/xhci-fix-oops-happening-after-address-device-timeout.patch b/queue-3.4/xhci-fix-oops-happening-after-address-device-timeout.patch
new file mode 100644 (file)
index 0000000..ba7d1af
--- /dev/null
@@ -0,0 +1,45 @@
+From 284d20552461466b04d6bfeafeb1c47a8891b591 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 5 Sep 2013 11:01:20 +0300
+Subject: xhci: Fix oops happening after address device timeout
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 284d20552461466b04d6bfeafeb1c47a8891b591 upstream.
+
+When a command times out, the command ring is first aborted,
+and then stopped. If the command ring is empty when it is stopped
+the stop event will point to next command which is not yet set.
+xHCI tries to handle this next event often causing an oops.
+
+Don't handle command completion events on stopped cmd ring if ring is
+empty.
+
+This patch should be backported to kernels as old as 3.7, that contain
+the commit b92cc66c047ff7cf587b318fe377061a353c120f "xHCI: add aborting
+command ring function"
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Reported-by: Giovanni <giovanni.nervi@yahoo.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1400,6 +1400,12 @@ static void handle_cmd_completion(struct
+                       inc_deq(xhci, xhci->cmd_ring);
+                       return;
+               }
++              /* There is no command to handle if we get a stop event when the
++               * command ring is empty, event->cmd_trb points to the next
++               * unset command
++               */
++              if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue)
++                      return;
+       }
+       switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])
diff --git a/queue-3.4/xhci-fix-race-between-ep-halt-and-urb-cancellation.patch b/queue-3.4/xhci-fix-race-between-ep-halt-and-urb-cancellation.patch
new file mode 100644 (file)
index 0000000..9b6ad5e
--- /dev/null
@@ -0,0 +1,41 @@
+From 526867c3ca0caa2e3e846cb993b0f961c33c2abb Mon Sep 17 00:00:00 2001
+From: Florian Wolter <wolly84@web.de>
+Date: Wed, 14 Aug 2013 10:33:16 +0200
+Subject: xhci: Fix race between ep halt and URB cancellation
+
+From: Florian Wolter <wolly84@web.de>
+
+commit 526867c3ca0caa2e3e846cb993b0f961c33c2abb upstream.
+
+The halted state of a endpoint cannot be cleared over CLEAR_HALT from a
+user process, because the stopped_td variable was overwritten in the
+handle_stopped_endpoint() function. So the xhci_endpoint_reset() function will
+refuse the reset and communication with device can not run over this endpoint.
+https://bugzilla.kernel.org/show_bug.cgi?id=60699
+
+Signed-off-by: Florian Wolter <wolly84@web.de>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Cc: Jonghwan Choi <jhbird.choi@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -857,8 +857,12 @@ remove_finished_td:
+               /* Otherwise ring the doorbell(s) to restart queued transfers */
+               ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
+       }
+-      ep->stopped_td = NULL;
+-      ep->stopped_trb = NULL;
++
++      /* Clear stopped_td and stopped_trb if endpoint is not halted */
++      if (!(ep->ep_state & EP_HALTED)) {
++              ep->stopped_td = NULL;
++              ep->stopped_trb = NULL;
++      }
+       /*
+        * Drop the lock and complete the URBs in the cancelled TD list.