--- /dev/null
+From 8c0bec2151a47906bf779c6715a10ce04453ab77 Mon Sep 17 00:00:00 2001
+From: Jiaying Zhang <jiayingz@google.com>
+Date: Wed, 31 Aug 2011 11:50:51 -0400
+Subject: ext4: remove i_mutex lock in ext4_evict_inode to fix lockdep complaining
+
+From: Jiaying Zhang <jiayingz@google.com>
+
+commit 8c0bec2151a47906bf779c6715a10ce04453ab77 upstream.
+
+The i_mutex lock and flush_completed_IO() added by commit 2581fdc810
+in ext4_evict_inode() causes lockdep complaining about potential
+deadlock in several places. In most/all of these LOCKDEP complaints
+it looks like it's a false positive, since many of the potential
+circular locking cases can't take place by the time the
+ext4_evict_inode() is called; but since at the very least it may mask
+real problems, we need to address this.
+
+This change removes the flush_completed_IO() and i_mutex lock in
+ext4_evict_inode(). Instead, we take a different approach to resolve
+the software lockup that commit 2581fdc810 intends to fix. Rather
+than having ext4-dio-unwritten thread wait for grabing the i_mutex
+lock of an inode, we use mutex_trylock() instead, and simply requeue
+the work item if we fail to grab the inode's i_mutex lock.
+
+This should speed up work queue processing in general and also
+prevents the following deadlock scenario: During page fault,
+shrink_icache_memory is called that in turn evicts another inode B.
+Inode B has some pending io_end work so it calls ext4_ioend_wait()
+that waits for inode B's i_ioend_count to become zero. However, inode
+B's ioend work was queued behind some of inode A's ioend work on the
+same cpu's ext4-dio-unwritten workqueue. As the ext4-dio-unwritten
+thread on that cpu is processing inode A's ioend work, it tries to
+grab inode A's i_mutex lock. Since the i_mutex lock of inode A is
+still hold before the page fault happened, we enter a deadlock.
+
+Signed-off-by: Jiaying Zhang <jiayingz@google.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/ext4.h | 1 +
+ fs/ext4/inode.c | 3 ---
+ fs/ext4/page-io.c | 18 +++++++++++++++++-
+ 3 files changed, 18 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -175,6 +175,7 @@ struct mpage_da_data {
+ */
+ #define EXT4_IO_END_UNWRITTEN 0x0001
+ #define EXT4_IO_END_ERROR 0x0002
++#define EXT4_IO_END_QUEUED 0x0004
+
+ struct ext4_io_page {
+ struct page *p_page;
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -190,9 +190,6 @@ void ext4_evict_inode(struct inode *inod
+
+ trace_ext4_evict_inode(inode);
+
+- mutex_lock(&inode->i_mutex);
+- ext4_flush_completed_IO(inode);
+- mutex_unlock(&inode->i_mutex);
+ ext4_ioend_wait(inode);
+
+ if (inode->i_nlink) {
+--- a/fs/ext4/page-io.c
++++ b/fs/ext4/page-io.c
+@@ -142,7 +142,23 @@ static void ext4_end_io_work(struct work
+ unsigned long flags;
+ int ret;
+
+- mutex_lock(&inode->i_mutex);
++ if (!mutex_trylock(&inode->i_mutex)) {
++ /*
++ * Requeue the work instead of waiting so that the work
++ * items queued after this can be processed.
++ */
++ queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work);
++ /*
++ * To prevent the ext4-dio-unwritten thread from keeping
++ * requeueing end_io requests and occupying cpu for too long,
++ * yield the cpu if it sees an end_io request that has already
++ * been requeued.
++ */
++ if (io->flag & EXT4_IO_END_QUEUED)
++ yield();
++ io->flag |= EXT4_IO_END_QUEUED;
++ return;
++ }
+ ret = ext4_end_io_nolock(io);
+ if (ret < 0) {
+ mutex_unlock(&inode->i_mutex);
--- /dev/null
+From 886486b792e4f6f96d4fbe8ec5bf20811cab7d6a Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu, 3 Nov 2011 23:39:18 +0100
+Subject: PM / Runtime: Automatically retry failed autosuspends
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 886486b792e4f6f96d4fbe8ec5bf20811cab7d6a upstream.
+
+Originally, the runtime PM core would send an idle notification
+whenever a suspend attempt failed. The idle callback routine could
+then schedule a delayed suspend for some time later.
+
+However this behavior was changed by commit
+f71648d73c1650b8b4aceb3856bebbde6daa3b86 (PM / Runtime: Remove idle
+notification after failing suspend). No notifications were sent, and
+there was no clear mechanism to retry failed suspends.
+
+This caused problems for the usbhid driver, because it fails
+autosuspend attempts as long as a key is being held down. Therefore
+this patch (as1492) adds a mechanism for retrying failed
+autosuspends. If the callback routine updates the last_busy field so
+that the next autosuspend expiration time is in the future, the
+autosuspend will automatically be rescheduled.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Henrik Rydberg <rydberg@euromail.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/power/runtime_pm.txt | 10 ++++++++++
+ drivers/base/power/runtime.c | 18 ++++++++++++++++--
+ 2 files changed, 26 insertions(+), 2 deletions(-)
+
+--- a/Documentation/power/runtime_pm.txt
++++ b/Documentation/power/runtime_pm.txt
+@@ -708,6 +708,16 @@ will behave normally, not taking the aut
+ Similarly, if the power.use_autosuspend field isn't set then the autosuspend
+ helper functions will behave just like the non-autosuspend counterparts.
+
++Under some circumstances a driver or subsystem may want to prevent a device
++from autosuspending immediately, even though the usage counter is zero and the
++autosuspend delay time has expired. If the ->runtime_suspend() callback
++returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is
++in the future (as it normally would be if the callback invoked
++pm_runtime_mark_last_busy()), the PM core will automatically reschedule the
++autosuspend. The ->runtime_suspend() callback can't do this rescheduling
++itself because no suspend requests of any kind are accepted while the device is
++suspending (i.e., while the callback is running).
++
+ The implementation is well suited for asynchronous use in interrupt contexts.
+ However such use inevitably involves races, because the PM core can't
+ synchronize ->runtime_suspend() callbacks with the arrival of I/O requests.
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -278,6 +278,9 @@ static int rpm_callback(int (*cb)(struct
+ * If a deferred resume was requested while the callback was running then carry
+ * it out; otherwise send an idle notification for the device (if the suspend
+ * failed) or for its parent (if the suspend succeeded).
++ * If ->runtime_suspend failed with -EAGAIN or -EBUSY, and if the RPM_AUTO
++ * flag is set and the next autosuspend-delay expiration time is in the
++ * future, schedule another autosuspend attempt.
+ *
+ * This function must be called under dev->power.lock with interrupts disabled.
+ */
+@@ -389,10 +392,21 @@ static int rpm_suspend(struct device *de
+ if (retval) {
+ __update_runtime_status(dev, RPM_ACTIVE);
+ dev->power.deferred_resume = 0;
+- if (retval == -EAGAIN || retval == -EBUSY)
++ if (retval == -EAGAIN || retval == -EBUSY) {
+ dev->power.runtime_error = 0;
+- else
++
++ /*
++ * If the callback routine failed an autosuspend, and
++ * if the last_busy time has been updated so that there
++ * is a new autosuspend expiration time, automatically
++ * reschedule another autosuspend.
++ */
++ if ((rpmflags & RPM_AUTO) &&
++ pm_runtime_autosuspend_expiration(dev) != 0)
++ goto repeat;
++ } else {
+ pm_runtime_cancel_pending(dev);
++ }
+ } else {
+ no_callback:
+ __update_runtime_status(dev, RPM_SUSPENDED);