Commit c7519dbf6f4b4408229d279d799c938ffdd06f21

Authored by Jarkko Lavinen
Committed by David Woodhouse
1 parent 13ce77f46c

mtd_blkdevs: Add background processing support

Add a new background method into mtd_blktrans_ops, add background support
into mtd_blktrans_thread(), and add mtd_blktrans_cease_background().

If the mtd blktrans dev has the background support, the thread will
call background function when the request queue becomes empty. The background
operation may run as long as needs to until
mtd_blktrans_cease_background() tells to stop.

Signed-off-by: Jarkko Lavinen <jarkko.lavinen@nokia.com>
Tested-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

Showing 2 changed files with 28 additions and 0 deletions Side-by-side Diff

drivers/mtd/mtd_blkdevs.c
... ... @@ -119,11 +119,22 @@
119 119 }
120 120 }
121 121  
  122 +int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev)
  123 +{
  124 + if (kthread_should_stop())
  125 + return 1;
  126 +
  127 + return !elv_queue_empty(dev->rq);
  128 +}
  129 +EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background);
  130 +
122 131 static int mtd_blktrans_thread(void *arg)
123 132 {
124 133 struct mtd_blktrans_dev *dev = arg;
  134 + struct mtd_blktrans_ops *tr = dev->tr;
125 135 struct request_queue *rq = dev->rq;
126 136 struct request *req = NULL;
  137 + int background_done = 0;
127 138  
128 139 spin_lock_irq(rq->queue_lock);
129 140  
... ... @@ -131,6 +142,19 @@
131 142 int res;
132 143  
133 144 if (!req && !(req = blk_fetch_request(rq))) {
  145 + if (tr->background && !background_done) {
  146 + spin_unlock_irq(rq->queue_lock);
  147 + mutex_lock(&dev->lock);
  148 + tr->background(dev);
  149 + mutex_unlock(&dev->lock);
  150 + spin_lock_irq(rq->queue_lock);
  151 + /*
  152 + * Do background processing just once per idle
  153 + * period.
  154 + */
  155 + background_done = 1;
  156 + continue;
  157 + }
134 158 set_current_state(TASK_INTERRUPTIBLE);
135 159  
136 160 if (kthread_should_stop())
... ... @@ -152,6 +176,8 @@
152 176  
153 177 if (!__blk_end_request_cur(req, res))
154 178 req = NULL;
  179 +
  180 + background_done = 0;
155 181 }
156 182  
157 183 if (req)
include/linux/mtd/blktrans.h
... ... @@ -62,6 +62,7 @@
62 62 unsigned long block, char *buffer);
63 63 int (*discard)(struct mtd_blktrans_dev *dev,
64 64 unsigned long block, unsigned nr_blocks);
  65 + void (*background)(struct mtd_blktrans_dev *dev);
65 66  
66 67 /* Block layer ioctls */
67 68 int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo);
... ... @@ -85,6 +86,7 @@
85 86 extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr);
86 87 extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
87 88 extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
  89 +extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev);
88 90  
89 91  
90 92 #endif /* __MTD_TRANS_H__ */