From: san@google.com (San Mehat)
To: drzeus-mmc@drzeus.cx
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 001/001] mmcblk: Fix deadlock when cleanup is called from resume
Date: Tue, 8 Jul 2008 13:10:11 -0700 [thread overview]
Message-ID: <20080708201011.GB16849@google.com> (raw)
When CONFIG_UNSAFE_RESUME is used, we may need to cleanup
(and call kthread_stop) when threads are still frozen. To fix this
deadlock, push cleanup off to a work-queue.
Signed-off-by: San Mehat <san@android.com>
---
drivers/mmc/card/queue.c | 36 ++++++++++++++++++++++++++++++++++--
1 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 972738f..908e3cf 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -14,6 +14,7 @@
#include <linux/freezer.h>
#include <linux/kthread.h>
#include <linux/scatterlist.h>
+#include <linux/workqueue.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -23,6 +24,11 @@
#define MMC_QUEUE_SUSPENDED (1 << 0)
+static void mq_cleanup_work(struct work_struct *work);
+static DECLARE_WORK(mq_cleanup_worker, mq_cleanup_work);
+static struct mmc_queue *cleanup_mq;
+static DEFINE_SPINLOCK(mq_cleanup_lock);
+
/*
* Prepare a MMC request. This just filters out odd stuff.
*/
@@ -217,9 +223,36 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
void mmc_cleanup_queue(struct mmc_queue *mq)
{
- struct request_queue *q = mq->queue;
unsigned long flags;
+ BUG_ON(!mq);
+
+ /*
+ * The actual cleanup is done from a work_queue because if you
+ * thread_stop() while resuming, you'll deadlock.
+ */
+ spin_lock_irqsave(&mq_cleanup_lock, flags);
+ cleanup_mq = mq;
+ schedule_work(&mq_cleanup_worker);
+ spin_unlock_irqrestore(&mq_cleanup_lock, flags);
+}
+EXPORT_SYMBOL(mmc_cleanup_queue);
+
+static void mq_cleanup_work(struct work_struct *work)
+{
+ struct mmc_queue *mq;
+ unsigned long flags;
+ struct request_queue *q;
+
+ spin_lock_irqsave(&mq_cleanup_lock, flags);
+ mq = cleanup_mq;
+ cleanup_mq = NULL;
+ spin_unlock_irqrestore(&mq_cleanup_lock, flags);
+
+ BUG_ON(!mq);
+
+ q = mq->queue;
+
/* Mark that we should start throwing out stragglers */
spin_lock_irqsave(q->queue_lock, flags);
q->queuedata = NULL;
@@ -246,7 +279,6 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
mq->card = NULL;
}
-EXPORT_SYMBOL(mmc_cleanup_queue);
/**
* mmc_queue_suspend - suspend a MMC request queue
next reply other threads:[~2008-07-08 20:10 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-08 20:10 San Mehat [this message]
2008-07-09 4:58 ` [PATCH 001/001] mmcblk: Fix deadlock when cleanup is called from resume Pierre Ossman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080708201011.GB16849@google.com \
--to=san@google.com \
--cc=drzeus-mmc@drzeus.cx \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.