Commit 22a8578fca5a47e643bb4f70c232d0ec84db9e4e

Authored by Ezequiel Garcia
Committed by Artem Bityutskiy
1 parent 9329c5eb5b

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: Ezequiel Garcia <elezegarcia@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>

Showing 2 changed files with 18 additions and 33 deletions Side-by-side Diff

drivers/mtd/mtd_blkdevs.c
... ... @@ -32,7 +32,6 @@
32 32 #include <linux/hdreg.h>
33 33 #include <linux/init.h>
34 34 #include <linux/mutex.h>
35   -#include <linux/kthread.h>
36 35 #include <asm/uaccess.h>
37 36  
38 37 #include "mtdcore.h"
39 38  
40 39  
... ... @@ -121,16 +120,14 @@
121 120  
122 121 int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev)
123 122 {
124   - if (kthread_should_stop())
125   - return 1;
126   -
127 123 return dev->bg_stop;
128 124 }
129 125 EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background);
130 126  
131   -static int mtd_blktrans_thread(void *arg)
  127 +static void mtd_blktrans_work(struct work_struct *work)
132 128 {
133   - struct mtd_blktrans_dev *dev = arg;
  129 + struct mtd_blktrans_dev *dev =
  130 + container_of(work, struct mtd_blktrans_dev, work);
134 131 struct mtd_blktrans_ops *tr = dev->tr;
135 132 struct request_queue *rq = dev->rq;
136 133 struct request *req = NULL;
... ... @@ -138,7 +135,7 @@
138 135  
139 136 spin_lock_irq(rq->queue_lock);
140 137  
141   - while (!kthread_should_stop()) {
  138 + while (1) {
142 139 int res;
143 140  
144 141 dev->bg_stop = false;
... ... @@ -156,15 +153,7 @@
156 153 background_done = !dev->bg_stop;
157 154 continue;
158 155 }
159   - set_current_state(TASK_INTERRUPTIBLE);
160   -
161   - if (kthread_should_stop())
162   - set_current_state(TASK_RUNNING);
163   -
164   - spin_unlock_irq(rq->queue_lock);
165   - schedule();
166   - spin_lock_irq(rq->queue_lock);
167   - continue;
  156 + break;
168 157 }
169 158  
170 159 spin_unlock_irq(rq->queue_lock);
... ... @@ -185,8 +174,6 @@
185 174 __blk_end_request_all(req, -EIO);
186 175  
187 176 spin_unlock_irq(rq->queue_lock);
188   -
189   - return 0;
190 177 }
191 178  
192 179 static void mtd_blktrans_request(struct request_queue *rq)
... ... @@ -199,10 +186,8 @@
199 186 if (!dev)
200 187 while ((req = blk_fetch_request(rq)) != NULL)
201 188 __blk_end_request_all(req, -ENODEV);
202   - else {
203   - dev->bg_stop = true;
204   - wake_up_process(dev->thread);
205   - }
  189 + else
  190 + queue_work(dev->wq, &dev->work);
206 191 }
207 192  
208 193 static int blktrans_open(struct block_device *bdev, fmode_t mode)
209 194  
... ... @@ -437,14 +422,13 @@
437 422  
438 423 gd->queue = new->rq;
439 424  
440   - /* Create processing thread */
441   - /* TODO: workqueue ? */
442   - new->thread = kthread_run(mtd_blktrans_thread, new,
443   - "%s%d", tr->name, new->mtd->index);
444   - if (IS_ERR(new->thread)) {
445   - ret = PTR_ERR(new->thread);
  425 + /* Create processing workqueue */
  426 + new->wq = alloc_workqueue("%s%d", 0, 0,
  427 + tr->name, new->mtd->index);
  428 + if (!new->wq)
446 429 goto error4;
447   - }
  430 + INIT_WORK(&new->work, mtd_blktrans_work);
  431 +
448 432 gd->driverfs_dev = &new->mtd->dev;
449 433  
450 434 if (new->readonly)
... ... @@ -484,9 +468,8 @@
484 468 /* Stop new requests to arrive */
485 469 del_gendisk(old->disk);
486 470  
487   -
488   - /* Stop the thread */
489   - kthread_stop(old->thread);
  471 + /* Stop workqueue. This will perform any pending request. */
  472 + destroy_workqueue(old->wq);
490 473  
491 474 /* Kill current requests */
492 475 spin_lock_irqsave(&old->queue_lock, flags);
include/linux/mtd/blktrans.h
... ... @@ -23,6 +23,7 @@
23 23 #include <linux/mutex.h>
24 24 #include <linux/kref.h>
25 25 #include <linux/sysfs.h>
  26 +#include <linux/workqueue.h>
26 27  
27 28 struct hd_geometry;
28 29 struct mtd_info;
... ... @@ -43,7 +44,8 @@
43 44 struct kref ref;
44 45 struct gendisk *disk;
45 46 struct attribute_group *disk_attributes;
46   - struct task_struct *thread;
  47 + struct workqueue_struct *wq;
  48 + struct work_struct work;
47 49 struct request_queue *rq;
48 50 spinlock_t queue_lock;
49 51 void *priv;