mmcblk: Fix deadlock when cleanup is called from resume
PATCH 1/1 mmcblk: Fix deadlock when cleanup is called from resume
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 <[email protected]>
--- drivers/mmc/card/queue.c | 36 ++++++++++++++++++++++++++++++++++-- 1 files changed, 34 insertions(+), 2 deletions(-)
drivers/mmc/card/queue.c +34 -2
@@ -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 *lockvoid 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
Quoted 7 lines · On Tue, 8 Jul 2008 13:10:11 -0700 [email protected] (San Mehat) wrote:
When
CONFIG_UNSAFE_RESUMEis used, we may need to cleanup (and callkthread_stop) when threads are still frozen. To fix this deadlock, push cleanup off to a work-queue.Signed-off-by San Mehat <[email protected]>
I appreciate patches, but sending me something based on 2.6.21 is hardly helpful. This particular problem was solved over a year ago in mainline.
Rgds
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.