Move to blk-mq block interface.
Currently Open-CAS uses single queue block interface, which is removed in kernel in version 5.0. From this moment on Open-CAS supports only blk-mq, and single queue is not supported any longer. Signed-off-by: Michal Rakowski <michal.rakowski@intel.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/blkpg.h>
|
||||
#include <linux/elevator.h>
|
||||
#include <linux/blk-mq.h>
|
||||
|
||||
#include "cas_disk_defs.h"
|
||||
#include "cas_disk.h"
|
||||
@@ -65,47 +66,6 @@ void casdsk_deinit_exp_objs(void)
|
||||
kmem_cache_destroy(casdsk_module->exp_obj_cache);
|
||||
}
|
||||
|
||||
static int _casdsk_exp_obj_prep_rq_fn(struct request_queue *q, struct request *rq)
|
||||
{
|
||||
struct casdsk_disk *dsk;;
|
||||
|
||||
BUG_ON(!q);
|
||||
BUG_ON(!q->queuedata);
|
||||
dsk = q->queuedata;
|
||||
BUG_ON(!dsk->exp_obj);
|
||||
|
||||
if (likely(dsk->exp_obj->ops && dsk->exp_obj->ops->prep_rq_fn))
|
||||
return dsk->exp_obj->ops->prep_rq_fn(dsk, q, rq, dsk->private);
|
||||
else
|
||||
return CAS_BLKPREP_OK;
|
||||
}
|
||||
|
||||
static void _casdsk_exp_obj_request_fn(struct request_queue *q)
|
||||
{
|
||||
struct casdsk_disk *dsk;
|
||||
struct request *rq;
|
||||
|
||||
BUG_ON(!q);
|
||||
BUG_ON(!q->queuedata);
|
||||
dsk = q->queuedata;
|
||||
BUG_ON(!dsk);
|
||||
BUG_ON(!dsk->exp_obj);
|
||||
|
||||
if (likely(dsk->exp_obj->ops && dsk->exp_obj->ops->request_fn)) {
|
||||
dsk->exp_obj->ops->request_fn(dsk, q, dsk->private);
|
||||
} else {
|
||||
/*
|
||||
* request_fn() is required, as we can't do any default
|
||||
* action in attached mode. In PT mode we handle all bios
|
||||
* directly in make_request_fn(), so request_fn() will not
|
||||
* be called.
|
||||
*/
|
||||
|
||||
rq = blk_peek_request(q);
|
||||
BUG_ON(rq);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _casdsk_exp_obj_handle_bio_att(struct casdsk_disk *dsk,
|
||||
struct request_queue *q,
|
||||
struct bio *bio)
|
||||
@@ -468,6 +428,70 @@ static int _casdsk_exp_obj_init_kobject(struct casdsk_disk *dsk)
|
||||
return result;
|
||||
}
|
||||
|
||||
static CAS_BLK_STATUS_T _casdsk_exp_obj_queue_qr(struct blk_mq_hw_ctx *hctx,
|
||||
const struct blk_mq_queue_data *bd)
|
||||
{
|
||||
struct casdsk_disk *dsk = hctx->driver_data;
|
||||
struct casdsk_exp_obj *exp_obj = dsk->exp_obj;
|
||||
struct request *rq = bd->rq;
|
||||
int result = 0;
|
||||
|
||||
if (likely(exp_obj->ops && exp_obj->ops->queue_rq_fn)) {
|
||||
exp_obj->ops->pending_rq_inc(dsk, dsk->private);
|
||||
|
||||
result = exp_obj->ops->queue_rq_fn(dsk, rq, dsk->private);
|
||||
|
||||
exp_obj->ops->pending_rq_dec(dsk, dsk->private);
|
||||
} else {
|
||||
/*
|
||||
* queue_rq_fn() is required, as we can't do any default
|
||||
* action in attached mode. In PT mode we handle all bios
|
||||
* directly in make_request_fn(), so queue_rq_fn() will not
|
||||
* be called.
|
||||
*/
|
||||
BUG_ON(rq);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct blk_mq_ops casdsk_mq_ops = {
|
||||
.queue_rq = _casdsk_exp_obj_queue_qr,
|
||||
};
|
||||
|
||||
static void _casdsk_init_queues(struct casdsk_disk *dsk)
|
||||
{
|
||||
struct request_queue *q = dsk->exp_obj->queue;
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
int i;
|
||||
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
if (!hctx->nr_ctx || !hctx->tags)
|
||||
continue;
|
||||
|
||||
hctx->driver_data = dsk;
|
||||
}
|
||||
}
|
||||
|
||||
static int _casdsk_init_tag_set(struct casdsk_disk *dsk, struct blk_mq_tag_set *set)
|
||||
{
|
||||
BUG_ON(!dsk);
|
||||
BUG_ON(!set);
|
||||
|
||||
set->ops = &casdsk_mq_ops;
|
||||
set->nr_hw_queues = num_online_cpus();
|
||||
set->numa_node = NUMA_NO_NODE;
|
||||
/*TODO: Should we inherit qd from core device? */
|
||||
set->queue_depth = BLKDEV_MAX_RQ;
|
||||
|
||||
set->cmd_size = 0;
|
||||
set->flags = BLK_MQ_F_SHOULD_MERGE;
|
||||
|
||||
set->driver_data = dsk;
|
||||
|
||||
return blk_mq_alloc_tag_set(set);
|
||||
}
|
||||
|
||||
int casdsk_exp_obj_create(struct casdsk_disk *dsk, const char *dev_name,
|
||||
struct module *owner, struct casdsk_exp_obj_ops *ops)
|
||||
{
|
||||
@@ -524,30 +548,28 @@ int casdsk_exp_obj_create(struct casdsk_disk *dsk, const char *dev_name,
|
||||
if (result)
|
||||
goto error_dev_t;
|
||||
|
||||
spin_lock_init(&exp_obj->rq_lock);
|
||||
result = _casdsk_init_tag_set(dsk, &dsk->tag_set);
|
||||
if (result) {
|
||||
goto error_init_tag_set;
|
||||
}
|
||||
|
||||
queue = blk_init_queue(_casdsk_exp_obj_request_fn, &exp_obj->rq_lock);
|
||||
queue = blk_mq_init_queue(&dsk->tag_set);
|
||||
if (!queue) {
|
||||
result = -ENOMEM;
|
||||
goto error_init_queue;
|
||||
}
|
||||
|
||||
BUG_ON(queue->queuedata);
|
||||
queue->queuedata = dsk;
|
||||
exp_obj->queue = queue;
|
||||
|
||||
_casdsk_init_queues(dsk);
|
||||
|
||||
gd->fops = &_casdsk_exp_obj_ops;
|
||||
gd->queue = queue;
|
||||
gd->private_data = dsk;
|
||||
strlcpy(gd->disk_name, exp_obj->dev_name, sizeof(gd->disk_name));
|
||||
|
||||
if (exp_obj->ops->prepare_queue) {
|
||||
result = exp_obj->ops->prepare_queue(dsk, queue, dsk->private);
|
||||
if (result)
|
||||
goto error_prepare_queue;
|
||||
}
|
||||
|
||||
blk_queue_prep_rq(queue, _casdsk_exp_obj_prep_rq_fn);
|
||||
|
||||
dsk->exp_obj->mk_rq_fn = queue->make_request_fn;
|
||||
blk_queue_make_request(queue, _casdsk_exp_obj_make_rq_fn);
|
||||
|
||||
@@ -562,9 +584,9 @@ int casdsk_exp_obj_create(struct casdsk_disk *dsk, const char *dev_name,
|
||||
error_set_geometry:
|
||||
if (exp_obj->ops->cleanup_queue)
|
||||
exp_obj->ops->cleanup_queue(dsk, queue, dsk->private);
|
||||
error_prepare_queue:
|
||||
blk_cleanup_queue(queue);
|
||||
error_init_queue:
|
||||
blk_mq_free_tag_set(&dsk->tag_set);
|
||||
error_init_tag_set:
|
||||
_casdsk_exp_obj_clear_dev_t(dsk);
|
||||
error_dev_t:
|
||||
put_disk(gd);
|
||||
@@ -744,6 +766,8 @@ int casdsk_exp_obj_destroy(struct casdsk_disk *dsk)
|
||||
if (exp_obj->queue)
|
||||
blk_cleanup_queue(exp_obj->queue);
|
||||
|
||||
blk_mq_free_tag_set(&dsk->tag_set);
|
||||
|
||||
atomic_set(&dsk->mode, CASDSK_MODE_UNKNOWN);
|
||||
put_disk(exp_obj->gd);
|
||||
|
||||
@@ -786,40 +810,12 @@ static void _casdsk_exp_obj_wait_for_pending_rqs(struct casdsk_disk *dsk)
|
||||
schedule();
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 3, 0)
|
||||
static void _casdsk_exp_obj_drain_elevator(struct request_queue *q)
|
||||
{
|
||||
if (q->elevator && q->elevator->elevator_type)
|
||||
while (q->elevator->elevator_type->ops.
|
||||
elevator_dispatch_fn(q, 1))
|
||||
;
|
||||
}
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(4, 10, 0)
|
||||
static void _casdsk_exp_obj_drain_elevator(struct request_queue *q)
|
||||
{
|
||||
if (q->elevator && q->elevator->type)
|
||||
while (q->elevator->type->ops.elevator_dispatch_fn(q, 1))
|
||||
;
|
||||
}
|
||||
#else
|
||||
static void _casdsk_exp_obj_drain_elevator(struct request_queue *q)
|
||||
{
|
||||
if (q->elevator && q->elevator->type)
|
||||
while (q->elevator->type->ops.sq.elevator_dispatch_fn(q, 1))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void _casdsk_exp_obj_flush_queue(struct casdsk_disk *dsk)
|
||||
{
|
||||
struct casdsk_exp_obj *exp_obj = dsk->exp_obj;
|
||||
struct request_queue *q = exp_obj->queue;
|
||||
|
||||
spin_lock_irq(q->queue_lock);
|
||||
_casdsk_exp_obj_drain_elevator(q);
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
|
||||
blk_run_queue(q);
|
||||
blk_mq_run_hw_queues(q, false);
|
||||
blk_sync_queue(q);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user