提交 c7519dbf 编写于 作者: J Jarkko Lavinen 提交者: David Woodhouse

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: NJarkko Lavinen <jarkko.lavinen@nokia.com>
Tested-by: NArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: NDavid Woodhouse <David.Woodhouse@intel.com>
上级 13ce77f4
...@@ -119,11 +119,22 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, ...@@ -119,11 +119,22 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
} }
} }
int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev)
{
if (kthread_should_stop())
return 1;
return !elv_queue_empty(dev->rq);
}
EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background);
static int mtd_blktrans_thread(void *arg) static int mtd_blktrans_thread(void *arg)
{ {
struct mtd_blktrans_dev *dev = arg; struct mtd_blktrans_dev *dev = arg;
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;
int background_done = 0;
spin_lock_irq(rq->queue_lock); spin_lock_irq(rq->queue_lock);
...@@ -131,6 +142,19 @@ static int mtd_blktrans_thread(void *arg) ...@@ -131,6 +142,19 @@ static int mtd_blktrans_thread(void *arg)
int res; int res;
if (!req && !(req = blk_fetch_request(rq))) { if (!req && !(req = blk_fetch_request(rq))) {
if (tr->background && !background_done) {
spin_unlock_irq(rq->queue_lock);
mutex_lock(&dev->lock);
tr->background(dev);
mutex_unlock(&dev->lock);
spin_lock_irq(rq->queue_lock);
/*
* Do background processing just once per idle
* period.
*/
background_done = 1;
continue;
}
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (kthread_should_stop()) if (kthread_should_stop())
...@@ -152,6 +176,8 @@ static int mtd_blktrans_thread(void *arg) ...@@ -152,6 +176,8 @@ static int mtd_blktrans_thread(void *arg)
if (!__blk_end_request_cur(req, res)) if (!__blk_end_request_cur(req, res))
req = NULL; req = NULL;
background_done = 0;
} }
if (req) if (req)
......
...@@ -62,6 +62,7 @@ struct mtd_blktrans_ops { ...@@ -62,6 +62,7 @@ struct mtd_blktrans_ops {
unsigned long block, char *buffer); unsigned long block, char *buffer);
int (*discard)(struct mtd_blktrans_dev *dev, int (*discard)(struct mtd_blktrans_dev *dev,
unsigned long block, unsigned nr_blocks); unsigned long block, unsigned nr_blocks);
void (*background)(struct mtd_blktrans_dev *dev);
/* Block layer ioctls */ /* Block layer ioctls */
int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo); int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo);
...@@ -85,6 +86,7 @@ extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr); ...@@ -85,6 +86,7 @@ extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr);
extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr); extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr);
extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev);
#endif /* __MTD_TRANS_H__ */ #endif /* __MTD_TRANS_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册