From 87598a2bd4c4ed19b91ef163f76297f305007304 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 13 Nov 2006 20:23:52 +0100 Subject: mmc: remove kernel_thread() Replace kernel_thread() with kthread_run()/kthread_stop(). Signed-off-by: Christoph Hellwig Signed-off-by: Pierre Ossman --- drivers/mmc/mmc_queue.c | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) (limited to 'drivers/mmc/mmc_queue.c') diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c index 4ccdd82b680..4e6a534e91d 100644 --- a/drivers/mmc/mmc_queue.c +++ b/drivers/mmc/mmc_queue.c @@ -10,13 +10,13 @@ */ #include #include +#include #include #include #include "mmc_queue.h" -#define MMC_QUEUE_EXIT (1 << 0) -#define MMC_QUEUE_SUSPENDED (1 << 1) +#define MMC_QUEUE_SUSPENDED (1 << 0) /* * Prepare a MMC request. Essentially, this means passing the @@ -59,7 +59,6 @@ static int mmc_queue_thread(void *d) { struct mmc_queue *mq = d; struct request_queue *q = mq->queue; - DECLARE_WAITQUEUE(wait, current); /* * Set iothread to ensure that we aren't put to sleep by @@ -67,12 +66,7 @@ static int mmc_queue_thread(void *d) */ current->flags |= PF_MEMALLOC|PF_NOFREEZE; - daemonize("mmcqd"); - - complete(&mq->thread_complete); - down(&mq->thread_sem); - add_wait_queue(&mq->thread_wq, &wait); do { struct request *req = NULL; @@ -84,7 +78,7 @@ static int mmc_queue_thread(void *d) spin_unlock_irq(q->queue_lock); if (!req) { - if (mq->flags & MMC_QUEUE_EXIT) + if (kthread_should_stop()) break; up(&mq->thread_sem); schedule(); @@ -95,10 +89,8 @@ static int mmc_queue_thread(void *d) mq->issue_fn(mq, req); } while (1); - remove_wait_queue(&mq->thread_wq, &wait); up(&mq->thread_sem); - complete_and_exit(&mq->thread_complete, 0); return 0; } @@ -113,7 +105,7 @@ static void mmc_request(request_queue_t *q) struct mmc_queue *mq = q->queuedata; if (!mq->req) - wake_up(&mq->thread_wq); + wake_up_process(mq->thread); } /** @@ -152,36 +144,31 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock GFP_KERNEL); if (!mq->sg) { ret = -ENOMEM; - goto cleanup; + goto cleanup_queue; } - init_completion(&mq->thread_complete); - init_waitqueue_head(&mq->thread_wq); init_MUTEX(&mq->thread_sem); - ret = kernel_thread(mmc_queue_thread, mq, CLONE_KERNEL); - if (ret >= 0) { - wait_for_completion(&mq->thread_complete); - init_completion(&mq->thread_complete); - ret = 0; - goto out; + mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd"); + if (IS_ERR(mq->thread)) { + ret = PTR_ERR(mq->thread); + goto free_sg; } - cleanup: + return 0; + + free_sg: kfree(mq->sg); mq->sg = NULL; - + cleanup_queue: blk_cleanup_queue(mq->queue); - out: return ret; } EXPORT_SYMBOL(mmc_init_queue); void mmc_cleanup_queue(struct mmc_queue *mq) { - mq->flags |= MMC_QUEUE_EXIT; - wake_up(&mq->thread_wq); - wait_for_completion(&mq->thread_complete); + kthread_stop(mq->thread); kfree(mq->sg); mq->sg = NULL; -- cgit v1.2.3-18-g5258 From 89b4e133afea9fce333054b94d89953583a55c19 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 14 Nov 2006 22:08:16 +0100 Subject: mmc: Flush block queue when removing card After mmc_block's remove function has exited, we must not touch the card structure in any way. This means we not only must remove the gendisk, we must also flush out any remaning requests already queued up. We previously removed the disk, but didn't flush it, causing oops:es when removing a card in the middle of a transfer. Signed-off-by: Pierre Ossman --- drivers/mmc/mmc_queue.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers/mmc/mmc_queue.c') diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c index 4e6a534e91d..5fa72ccb4fe 100644 --- a/drivers/mmc/mmc_queue.c +++ b/drivers/mmc/mmc_queue.c @@ -103,6 +103,19 @@ static int mmc_queue_thread(void *d) static void mmc_request(request_queue_t *q) { struct mmc_queue *mq = q->queuedata; + struct request *req; + int ret; + + if (!mq) { + printk(KERN_ERR "MMC: killing requests for dead queue\n"); + while ((req = elv_next_request(q)) != NULL) { + do { + ret = end_that_request_chunk(req, 0, + req->current_nr_sectors << 9); + } while (ret); + } + return; + } if (!mq->req) wake_up_process(mq->thread); @@ -168,6 +181,15 @@ EXPORT_SYMBOL(mmc_init_queue); void mmc_cleanup_queue(struct mmc_queue *mq) { + request_queue_t *q = mq->queue; + unsigned long flags; + + /* Mark that we should start throwing out stragglers */ + spin_lock_irqsave(q->queue_lock, flags); + q->queuedata = NULL; + spin_unlock_irqrestore(q->queue_lock, flags); + + /* Then terminate our worker thread */ kthread_stop(mq->thread); kfree(mq->sg); -- cgit v1.2.3-18-g5258