Commit 22a8578f authored by Ezequiel Garcia's avatar Ezequiel Garcia Committed by Artem Bityutskiy

mtd: mtd_blkdevs: Replace request handler kthread with a workqueue

By replacing a kthread with a workqueue, the code is now a bit clearer.
There's also a slight reduction of code size (numbers apply for x86):
Before:
   text	   data	    bss	    dec	    hex	filename
   3248	     36	      0	   3284	    cd4	drivers/mtd/mtd_blkdevs.o

After:
   text	   data	    bss	    dec	    hex	filename
   3150	     36	      0	   3186	    c72	drivers/mtd/mtd_blkdevs.o

Due to lack of real hardware, tests have been performed on an emulated
environment with mtdswap and mtdblock over nandsim devices.
Some real testing should be done, before merging this patch.
Signed-off-by: default avatarEzequiel Garcia <elezegarcia@gmail.com>
Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
parent 9329c5eb
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/kthread.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "mtdcore.h" #include "mtdcore.h"
...@@ -121,16 +120,14 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, ...@@ -121,16 +120,14 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev) int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev)
{ {
if (kthread_should_stop())
return 1;
return dev->bg_stop; return dev->bg_stop;
} }
EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background); EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background);
static int mtd_blktrans_thread(void *arg) static void mtd_blktrans_work(struct work_struct *work)
{ {
struct mtd_blktrans_dev *dev = arg; struct mtd_blktrans_dev *dev =
container_of(work, struct mtd_blktrans_dev, work);
struct mtd_blktrans_ops *tr = dev->tr; struct mtd_blktrans_ops *tr = dev->tr;
struct request_queue *rq = dev->rq; struct request_queue *rq = dev->rq;
struct request *req = NULL; struct request *req = NULL;
...@@ -138,7 +135,7 @@ static int mtd_blktrans_thread(void *arg) ...@@ -138,7 +135,7 @@ static int mtd_blktrans_thread(void *arg)
spin_lock_irq(rq->queue_lock); spin_lock_irq(rq->queue_lock);
while (!kthread_should_stop()) { while (1) {
int res; int res;
dev->bg_stop = false; dev->bg_stop = false;
...@@ -156,15 +153,7 @@ static int mtd_blktrans_thread(void *arg) ...@@ -156,15 +153,7 @@ static int mtd_blktrans_thread(void *arg)
background_done = !dev->bg_stop; background_done = !dev->bg_stop;
continue; continue;
} }
set_current_state(TASK_INTERRUPTIBLE); break;
if (kthread_should_stop())
set_current_state(TASK_RUNNING);
spin_unlock_irq(rq->queue_lock);
schedule();
spin_lock_irq(rq->queue_lock);
continue;
} }
spin_unlock_irq(rq->queue_lock); spin_unlock_irq(rq->queue_lock);
...@@ -185,8 +174,6 @@ static int mtd_blktrans_thread(void *arg) ...@@ -185,8 +174,6 @@ static int mtd_blktrans_thread(void *arg)
__blk_end_request_all(req, -EIO); __blk_end_request_all(req, -EIO);
spin_unlock_irq(rq->queue_lock); spin_unlock_irq(rq->queue_lock);
return 0;
} }
static void mtd_blktrans_request(struct request_queue *rq) static void mtd_blktrans_request(struct request_queue *rq)
...@@ -199,10 +186,8 @@ static void mtd_blktrans_request(struct request_queue *rq) ...@@ -199,10 +186,8 @@ static void mtd_blktrans_request(struct request_queue *rq)
if (!dev) if (!dev)
while ((req = blk_fetch_request(rq)) != NULL) while ((req = blk_fetch_request(rq)) != NULL)
__blk_end_request_all(req, -ENODEV); __blk_end_request_all(req, -ENODEV);
else { else
dev->bg_stop = true; queue_work(dev->wq, &dev->work);
wake_up_process(dev->thread);
}
} }
static int blktrans_open(struct block_device *bdev, fmode_t mode) static int blktrans_open(struct block_device *bdev, fmode_t mode)
...@@ -437,14 +422,13 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) ...@@ -437,14 +422,13 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
gd->queue = new->rq; gd->queue = new->rq;
/* Create processing thread */ /* Create processing workqueue */
/* TODO: workqueue ? */ new->wq = alloc_workqueue("%s%d", 0, 0,
new->thread = kthread_run(mtd_blktrans_thread, new, tr->name, new->mtd->index);
"%s%d", tr->name, new->mtd->index); if (!new->wq)
if (IS_ERR(new->thread)) {
ret = PTR_ERR(new->thread);
goto error4; goto error4;
} INIT_WORK(&new->work, mtd_blktrans_work);
gd->driverfs_dev = &new->mtd->dev; gd->driverfs_dev = &new->mtd->dev;
if (new->readonly) if (new->readonly)
...@@ -484,9 +468,8 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) ...@@ -484,9 +468,8 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
/* Stop new requests to arrive */ /* Stop new requests to arrive */
del_gendisk(old->disk); del_gendisk(old->disk);
/* Stop workqueue. This will perform any pending request. */
/* Stop the thread */ destroy_workqueue(old->wq);
kthread_stop(old->thread);
/* Kill current requests */ /* Kill current requests */
spin_lock_irqsave(&old->queue_lock, flags); spin_lock_irqsave(&old->queue_lock, flags);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/kref.h> #include <linux/kref.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/workqueue.h>
struct hd_geometry; struct hd_geometry;
struct mtd_info; struct mtd_info;
...@@ -43,7 +44,8 @@ struct mtd_blktrans_dev { ...@@ -43,7 +44,8 @@ struct mtd_blktrans_dev {
struct kref ref; struct kref ref;
struct gendisk *disk; struct gendisk *disk;
struct attribute_group *disk_attributes; struct attribute_group *disk_attributes;
struct task_struct *thread; struct workqueue_struct *wq;
struct work_struct work;
struct request_queue *rq; struct request_queue *rq;
spinlock_t queue_lock; spinlock_t queue_lock;
void *priv; void *priv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment