From b82b338c53a5840611e607bbecca7755a7467b7f Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 17 May 2021 16:50:44 +0200 Subject: [PATCH] Remove blk request handling path Signed-off-by: Robert Baldyga --- configure.d/1_blk_status.conf | 4 +- modules/cas_cache/volume/vol_blk_utils.h | 11 - modules/cas_cache/volume/vol_block_dev_top.c | 423 ------------------- modules/cas_disk/cas_disk.h | 7 - modules/cas_disk/exp_obj.c | 25 +- 5 files changed, 4 insertions(+), 466 deletions(-) diff --git a/configure.d/1_blk_status.conf b/configure.d/1_blk_status.conf index 4db529c..e3197c4 100644 --- a/configure.d/1_blk_status.conf +++ b/configure.d/1_blk_status.conf @@ -21,10 +21,10 @@ apply() { case "$1" in "1") add_define "CAS_BLK_STATUS_T blk_status_t" - add_define "CAS_BLK_STS_OK BLK_STS_OK" ;; + add_define "CAS_BLK_STS_NOTSUPP BLK_STS_NOTSUPP" ;; "2") add_define "CAS_BLK_STATUS_T int" - add_define "CAS_BLK_STS_OK 0" ;; + add_define "CAS_BLK_STS_NOTSUPP -ENOTSUPP" ;; *) exit 1 diff --git a/modules/cas_cache/volume/vol_blk_utils.h b/modules/cas_cache/volume/vol_blk_utils.h index 151154f..0d069a5 100644 --- a/modules/cas_cache/volume/vol_blk_utils.h +++ b/modules/cas_cache/volume/vol_blk_utils.h @@ -9,17 +9,6 @@ #include "obj_blk.h" #include "context.h" -static inline bool cas_blk_is_flush_io(unsigned long flags) -{ - if ((flags & CAS_WRITE_FLUSH) == CAS_WRITE_FLUSH) - return true; - - if ((flags & CAS_WRITE_FLUSH_FUA) == CAS_WRITE_FLUSH_FUA) - return true; - - return false; -} - struct blkio { int error; atomic_t rq_remaning; diff --git a/modules/cas_cache/volume/vol_block_dev_top.c b/modules/cas_cache/volume/vol_block_dev_top.c index 01af060..4dae980 100644 --- a/modules/cas_cache/volume/vol_block_dev_top.c +++ b/modules/cas_cache/volume/vol_block_dev_top.c @@ -6,34 +6,6 @@ #include "cas_cache.h" #include "utils/cas_err.h" -#define BLK_RQ_POS(rq) (CAS_BIO_BISECTOR((rq)->bio)) -#define BLK_RQ_BYTES(rq) blk_rq_bytes(rq) - -static inline void _blockdev_end_request_all(struct request *rq, int error) -{ - CAS_END_REQUEST_ALL(rq, CAS_ERRNO_TO_BLK_STS( - map_cas_err_to_generic(error))); -} - -static inline bool _blockdev_can_handle_rq(struct request *rq) -{ - int error = 0; - - if (unlikely(!cas_is_rq_type_fs(rq))) - error = __LINE__; - - if (unlikely(CAS_BLK_BIDI_RQ(rq))) - error = __LINE__; - - if (error != 0) { - CAS_PRINT_RL(KERN_ERR "%s cannot handle request (ERROR %d)\n", - rq->rq_disk->disk_name, error); - return false; - } - - return true; -} - static void _blockdev_set_bio_data(struct blk_data *data, struct bio *bio) { #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) @@ -80,400 +52,6 @@ void block_dev_start_bio(struct ocf_io *io) data->start_time = _blockdev_start_io_acct(bio); } -void block_dev_complete_rq(struct ocf_io *io, int error) - -{ - struct blk_data *data = ocf_io_get_data(io); - struct request *rq = data->master_io_req; - - _blockdev_end_request_all(rq, error); - ocf_io_put(io); - cas_free_blk_data(data); -} - -void block_dev_complete_sub_rq(struct ocf_io *io, int error) -{ - struct blk_data *data = ocf_io_get_data(io); - struct ocf_io *master = data->master_io_req; - struct blk_data *master_data = ocf_io_get_data(master); - - if (error) - master_data->error = error; - - if (atomic_dec_return(&master_data->master_remaining) == 0) { - _blockdev_end_request_all(master_data->master_io_req, - master_data->error); - cas_free_blk_data(master_data); - ocf_io_put(master); - } - - ocf_io_put(io); - cas_free_blk_data(data); -} - -void block_dev_complete_flush(struct ocf_io *io, int error) -{ - struct request *rq = io->priv1; - - _blockdev_end_request_all(rq, error); - ocf_io_put(io); -} - -bool _blockdev_is_request_barier(struct request *rq) -{ - struct bio *i_bio = rq->bio; - - for_each_bio(i_bio) { - if (CAS_CHECK_BARRIER(i_bio)) - return true; - } - return false; -} - -static int _blockdev_alloc_many_requests(ocf_core_t core, - struct list_head *list, struct request *rq, - struct ocf_io *master) -{ - ocf_cache_t cache = ocf_core_get_cache(core); - struct cache_priv *cache_priv = ocf_cache_get_priv(cache); - int error = 0; - int flags = 0; - struct bio *bio; - struct ocf_io *sub_io; - struct blk_data *master_data = ocf_io_get_data(master); - struct blk_data *data; - - INIT_LIST_HEAD(list); - - /* Go over requests and allocate sub requests */ - bio = rq->bio; - for_each_bio(bio) { - /* Setup BIO flags */ - if (CAS_IS_WRITE_FLUSH_FUA(CAS_BIO_OP_FLAGS(bio))) { - /* FLUSH and FUA */ - flags = CAS_WRITE_FLUSH_FUA; - } else if (CAS_IS_WRITE_FUA(CAS_BIO_OP_FLAGS(bio))) { - /* FUA */ - flags = CAS_WRITE_FUA; - } else if (CAS_IS_WRITE_FLUSH(CAS_BIO_OP_FLAGS(bio))) { - /* FLUSH - It shall be handled in request handler */ - error = -EINVAL; - break; - } else { - flags = 0; - } - - data = cas_alloc_blk_data(bio_segments(bio), GFP_NOIO); - if (!data) { - CAS_PRINT_RL(KERN_CRIT "BIO data vector allocation error\n"); - error = -ENOMEM; - break; - } - - _blockdev_set_bio_data(data, bio); - - data->master_io_req = master; - - sub_io = ocf_core_new_io(core, - cache_priv->io_queues[smp_processor_id()], - CAS_BIO_BISECTOR(bio) << SECTOR_SHIFT, - CAS_BIO_BISIZE(bio), (bio_data_dir(bio) == READ) ? - OCF_READ : OCF_WRITE, - cas_cls_classify(cache, bio), flags); - - if (!sub_io) { - cas_free_blk_data(data); - error = -ENOMEM; - break; - } - - data->io = sub_io; - - error = ocf_io_set_data(sub_io, data, 0); - if (error) { - ocf_io_put(sub_io); - cas_free_blk_data(data); - break; - } - - ocf_io_set_cmpl(sub_io, NULL, NULL, block_dev_complete_sub_rq); - - list_add_tail(&data->list, list); - atomic_inc(&master_data->master_remaining); - } - - if (error) { - CAS_PRINT_RL(KERN_ERR "Cannot handle request (ERROR %d)\n", error); - - /* Go over list and free all */ - while (!list_empty(list)) { - data = list_first_entry(list, struct blk_data, list); - list_del(&data->list); - - sub_io = data->io; - ocf_io_put(sub_io); - cas_free_blk_data(data); - } - } - - return error; -} - -static void _blockdev_set_request_data(struct blk_data *data, struct request *rq) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) - struct req_iterator iter; - struct bio_vec *bvec; - uint32_t i = 0; - - rq_for_each_segment(bvec, rq, iter) { - BUG_ON(i >= data->size); - data->vec[i] = *bvec; - i++; - } -#else - struct req_iterator iter; - struct bio_vec bvec; - uint32_t i = 0; - - rq_for_each_segment(bvec, rq, iter) { - BUG_ON(i >= data->size); - data->vec[i] = bvec; - i++; - } -#endif -} - -/** - * @brief push flush request upon execution queue for given core device - */ -static int _blkdev_handle_flush_request(struct request *rq, ocf_core_t core) -{ - struct ocf_io *io; - ocf_cache_t cache = ocf_core_get_cache(core); - struct cache_priv *cache_priv = ocf_cache_get_priv(cache); - - io = ocf_core_new_io(core, cache_priv->io_queues[smp_processor_id()], - 0, 0, OCF_WRITE, 0, CAS_WRITE_FLUSH); - if (!io) - return -ENOMEM; - - ocf_io_set_cmpl(io, rq, NULL, block_dev_complete_flush); - - ocf_core_submit_flush(io); - - return 0; -} - -#ifdef RQ_CHECK_CONTINOUS -static inline bool _bvec_is_mergeable(struct bio_vec *bv1, struct bio_vec *bv2) -{ - if (bv1 == NULL) - return true; - - if (BIOVEC_PHYS_MERGEABLE(bv1, bv2)) - return true; - - return !bv2->bv_offset && !((bv1->bv_offset + bv1->bv_len) % PAGE_SIZE); -} -#endif - -static uint32_t _blkdev_scan_request(ocf_cache_t cache, struct request *rq, - struct ocf_io *io, bool *single_io) -{ - uint32_t size = 0; - struct req_iterator iter; - struct bio *bio_prev = NULL; - uint32_t io_class; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) - struct bio_vec bvec; -#ifdef RQ_CHECK_CONTINOUS - struct bio_vec bvec_prev = { NULL, }; -#endif -#else - struct bio_vec *bvec; -#ifdef RQ_CHECK_CONTINOUS - struct bio_vec *bvec_prev = NULL; -#endif -#endif - - *single_io = true; - - /* Scan BIOs in the request to: - * 1. Count the segments number - * 2. Check if requests contains many IO classes - * 3. Check if request is continuous (when process kernel stack is 8KB) - */ - rq_for_each_segment(bvec, rq, iter) { - /* Increase BIO data vector counter */ - size++; - - if (*single_io == false) { - /* Already detected complex request */ - continue; - } - -#ifdef RQ_CHECK_CONTINOUS - /* - * If request is not continous submit each bio as separate - * request, and prevent nvme driver from splitting requests. - * For large requests, nvme splitting causes stack overrun. - */ - if (!_bvec_is_mergeable(CAS_SEGMENT_BVEC(bvec_prev), - CAS_SEGMENT_BVEC(bvec))) { - *single_io = false; - continue; - } - bvec_prev = bvec; -#endif - - if (bio_prev == iter.bio) - continue; - - bio_prev = iter.bio; - - /* Get class ID for given BIO */ - io_class = cas_cls_classify(cache, iter.bio); - - if (io->io_class != io_class) { - /* - * Request contains BIO with different IO classes and - * need to handle BIO separately - */ - *single_io = false; - } - } - - return size; -} - -static int __block_dev_queue_rq(struct request *rq, ocf_core_t core) -{ - ocf_cache_t cache = ocf_core_get_cache(core); - struct cache_priv *cache_priv = ocf_cache_get_priv(cache); - struct ocf_io *io; - struct blk_data *data; - int master_flags = 0; - bool single_io; - uint32_t size; - int ret; - - if (_blockdev_is_request_barier(rq) || !_blockdev_can_handle_rq(rq)) { - CAS_PRINT_RL(KERN_WARNING - "special bio was sent,not supported!\n"); - return -ENOTSUPP; - } - - if ((rq->cmd_flags & REQ_FUA) && CAS_RQ_IS_FLUSH(rq)) { - /* FLUSH and FUA */ - master_flags = CAS_WRITE_FLUSH_FUA; - } else if (rq->cmd_flags & REQ_FUA) { - /* FUA */ - master_flags = CAS_WRITE_FUA; - } else if (CAS_RQ_IS_FLUSH(rq)) { - /* FLUSH */ - return _blkdev_handle_flush_request(rq, core); - } - - io = ocf_core_new_io(core, cache_priv->io_queues[smp_processor_id()], - BLK_RQ_POS(rq) << SECTOR_SHIFT, BLK_RQ_BYTES(rq), - (rq_data_dir(rq) == CAS_RQ_DATA_DIR_WR) ? - OCF_WRITE : OCF_READ, - cas_cls_classify(cache, rq->bio), master_flags); - if (!io) { - CAS_PRINT_RL(KERN_CRIT "Out of memory. Ending IO processing.\n"); - return -ENOMEM; - } - - - size = _blkdev_scan_request(cache, rq, io, &single_io); - - if (unlikely(size == 0)) { - CAS_PRINT_RL(KERN_ERR "Empty IO request\n"); - ocf_io_put(io); - return -EINVAL; - } - - if (single_io) { - data = cas_alloc_blk_data(size, GFP_NOIO); - if (data == NULL) { - CAS_PRINT_RL(KERN_CRIT - "Out of memory. Ending IO processing.\n"); - ocf_io_put(io); - return -ENOMEM; - } - - _blockdev_set_request_data(data, rq); - - data->master_io_req = rq; - - ret = ocf_io_set_data(io, data, 0); - if (ret) { - ocf_io_put(io); - cas_free_blk_data(data); - return -EINVAL; - } - - ocf_io_set_cmpl(io, NULL, NULL, block_dev_complete_rq); - - ocf_core_submit_io(io); - } else { - struct list_head list = LIST_HEAD_INIT(list); - - data = cas_alloc_blk_data(0, GFP_NOIO); - if (data == NULL) { - printk(KERN_CRIT - "Out of memory. Ending IO processing.\n"); - ocf_io_put(io); - return -ENOMEM; - } - data->master_io_req = rq; - - if (ocf_io_set_data(io, data, 0)) { - ocf_io_put(io); - cas_free_blk_data(data); - return -EINVAL; - } - - /* Allocate setup and setup */ - ret = _blockdev_alloc_many_requests(core, &list, rq, io); - if (ret < 0) { - printk(KERN_CRIT - "Out of memory. Ending IO processing.\n"); - cas_free_blk_data(data); - ocf_io_put(io); - return -ENOMEM; - } - - BUG_ON(list_empty(&list)); - - /* Go over list and push request to the engine */ - while (!list_empty(&list)) { - struct ocf_io *sub_io; - - data = list_first_entry(&list, struct blk_data, list); - list_del(&data->list); - - sub_io = data->io; - - ocf_core_submit_io(sub_io); - } - } - - return ret; -} - -static CAS_BLK_STATUS_T _block_dev_queue_request(struct casdsk_disk *dsk, struct request *rq, void *private) -{ - ocf_core_t core = private; - int ret = __block_dev_queue_rq(rq, core); - if (ret) - _blockdev_end_request_all(rq, ret); - - return CAS_ERRNO_TO_BLK_STS(ret); -} - static inline int _blkdev_can_hndl_bio(struct bio *bio) { if (CAS_CHECK_BARRIER(bio)) { @@ -847,7 +425,6 @@ static void _blockdev_submit_bio(struct casdsk_disk *dsk, static struct casdsk_exp_obj_ops _blockdev_exp_obj_ops = { .set_geometry = _blockdev_set_geometry, - .queue_rq_fn = _block_dev_queue_request, .submit_bio = _blockdev_submit_bio, .pending_rq_inc = _blockdev_pending_req_inc, .pending_rq_dec = _blockdev_pending_req_dec, diff --git a/modules/cas_disk/cas_disk.h b/modules/cas_disk/cas_disk.h index 78aecfb..17d2b6b 100644 --- a/modules/cas_disk/cas_disk.h +++ b/modules/cas_disk/cas_disk.h @@ -45,13 +45,6 @@ struct casdsk_exp_obj_ops { void (*submit_bio)(struct casdsk_disk *dsk, struct bio *bio, void *private); - /** - * @brief queue_rq_fn of exported object (top) block device. - * Called by cas_disk when cas_disk device is in attached mode. - */ - CAS_BLK_STATUS_T (*queue_rq_fn)(struct casdsk_disk *dsk, struct request *rq, - void *private); - /** * @brief Increment exported object pending request counter. */ diff --git a/modules/cas_disk/exp_obj.c b/modules/cas_disk/exp_obj.c index bfd309b..fee97fa 100644 --- a/modules/cas_disk/exp_obj.c +++ b/modules/cas_disk/exp_obj.c @@ -461,30 +461,9 @@ static int _casdsk_exp_obj_init_kobject(struct casdsk_disk *dsk) } static CAS_BLK_STATUS_T _casdsk_exp_obj_queue_rq(struct blk_mq_hw_ctx *hctx, - const struct blk_mq_queue_data *bd) + 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; - CAS_BLK_STATUS_T result = CAS_BLK_STS_OK; - - 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; + return CAS_BLK_STS_NOTSUPP; } static struct blk_mq_ops casdsk_mq_ops = {