diff --git a/configure.d/2_alloc_disk.conf b/configure.d/2_alloc_disk.conf index 719f14f..3f6e58d 100644 --- a/configure.d/2_alloc_disk.conf +++ b/configure.d/2_alloc_disk.conf @@ -1,7 +1,7 @@ #!/bin/bash # # Copyright(c) 2012-2022 Intel Corporation -# Copyright(c) 2024 Huawei Technologies +# Copyright(c) 2024-2025 Huawei Technologies # SPDX-License-Identifier: BSD-3-Clause # @@ -28,11 +28,12 @@ check() { apply() { case "$1" in "1") + add_typedef "struct queue_limits cas_queue_limits_t;" add_function " static inline int cas_alloc_mq_disk(struct gendisk **gd, struct request_queue **queue, - struct blk_mq_tag_set *tag_set) + struct blk_mq_tag_set *tag_set, cas_queue_limits_t *lim) { - *gd = blk_mq_alloc_disk(tag_set, NULL, NULL); + *gd = blk_mq_alloc_disk(tag_set, lim, NULL); if (IS_ERR(*gd)) return PTR_ERR(*gd); @@ -48,9 +49,10 @@ apply() { ;; "2") + add_typedef "void* cas_queue_limits_t;" add_function " static inline int cas_alloc_mq_disk(struct gendisk **gd, struct request_queue **queue, - struct blk_mq_tag_set *tag_set) + struct blk_mq_tag_set *tag_set, cas_queue_limits_t *lim) { *gd = blk_mq_alloc_disk(tag_set, NULL); if (IS_ERR(*gd)) @@ -68,10 +70,10 @@ apply() { ;; "3") - + add_typedef "void* cas_queue_limits_t;" add_function " static inline int cas_alloc_mq_disk(struct gendisk **gd, struct request_queue **queue, - struct blk_mq_tag_set *tag_set) + struct blk_mq_tag_set *tag_set, cas_queue_limits_t *lim) { *gd = alloc_disk(1); if (!(*gd)) diff --git a/modules/cas_cache/exp_obj.c b/modules/cas_cache/exp_obj.c index e44ae6b..8b53748 100644 --- a/modules/cas_cache/exp_obj.c +++ b/modules/cas_cache/exp_obj.c @@ -1,6 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation -* Copyright(c) 2024 Huawei Technologies +* Copyright(c) 2024-2025 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ #include @@ -417,6 +417,7 @@ int cas_exp_obj_create(struct cas_disk *dsk, const char *dev_name, struct cas_exp_obj *exp_obj; struct request_queue *queue; struct gendisk *gd; + cas_queue_limits_t queue_limits; int result = 0; BUG_ON(!owner); @@ -465,7 +466,15 @@ int cas_exp_obj_create(struct cas_disk *dsk, const char *dev_name, goto error_init_tag_set; } - result = cas_alloc_mq_disk(&gd, &queue, &exp_obj->tag_set); + if (exp_obj->ops->set_queue_limits) { + result = exp_obj->ops->set_queue_limits(dsk, priv, + &queue_limits); + if (result) + goto error_set_queue_limits; + } + + result = cas_alloc_mq_disk(&gd, &queue, &exp_obj->tag_set, + &queue_limits); if (result) { goto error_alloc_mq_disk; } @@ -521,6 +530,7 @@ error_exp_obj_set_dev_t: cas_cleanup_mq_disk(gd); exp_obj->gd = NULL; error_alloc_mq_disk: +error_set_queue_limits: blk_mq_free_tag_set(&exp_obj->tag_set); error_init_tag_set: module_put(owner); diff --git a/modules/cas_cache/exp_obj.h b/modules/cas_cache/exp_obj.h index be52f5a..b9b15c6 100644 --- a/modules/cas_cache/exp_obj.h +++ b/modules/cas_cache/exp_obj.h @@ -1,11 +1,12 @@ /* * Copyright(c) 2012-2022 Intel Corporation -* Copyright(c) 2024 Huawei Technologies +* Copyright(c) 2024-2025 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __CASDISK_EXP_OBJ_H__ #define __CASDISK_EXP_OBJ_H__ +#include "linux_kernel_version.h" #include struct cas_disk; @@ -17,6 +18,12 @@ struct cas_exp_obj_ops { */ int (*set_geometry)(struct cas_disk *dsk, void *private); + /** + * @brief Set queue limits of exported object (top) block device. + */ + int (*set_queue_limits)(struct cas_disk *dsk, void *private, + cas_queue_limits_t *lim); + /** * @brief submit_bio of exported object (top) block device. * diff --git a/modules/cas_cache/linux_kernel_version.h b/modules/cas_cache/linux_kernel_version.h index 41eda5b..80639b8 100644 --- a/modules/cas_cache/linux_kernel_version.h +++ b/modules/cas_cache/linux_kernel_version.h @@ -1,6 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation -* Copyright(c) 2024 Huawei Technologies +* Copyright(c) 2024-2025 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -40,7 +40,6 @@ #include #include #include -#include "exp_obj.h" #include "generated_defines.h" diff --git a/modules/cas_cache/volume/vol_block_dev_top.c b/modules/cas_cache/volume/vol_block_dev_top.c index 3e8d818..5be0f3c 100644 --- a/modules/cas_cache/volume/vol_block_dev_top.c +++ b/modules/cas_cache/volume/vol_block_dev_top.c @@ -1,6 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation -* Copyright(c) 2024 Huawei Technologies Co., Ltd. +* Copyright(c) 2024-2025 Huawei Technologies Co., Ltd. * SPDX-License-Identifier: BSD-3-Clause */ @@ -135,6 +135,36 @@ static int blkdev_core_set_geometry(struct cas_disk *dsk, void *private) return 0; } +static int blkdev_core_set_queue_limits(struct cas_disk *dsk, void *private, + cas_queue_limits_t *lim) +{ + ocf_core_t core = private; + ocf_cache_t cache = ocf_core_get_cache(core); + ocf_volume_t core_vol = ocf_core_get_volume(core); + struct bd_object *bd_core_vol; + struct request_queue *core_q; + bool flush, fua; + struct cache_priv *cache_priv = ocf_cache_get_priv(cache); + + bd_core_vol = bd_object(core_vol); + core_q = cas_disk_get_queue(bd_core_vol->dsk); + + flush = (CAS_CHECK_QUEUE_FLUSH(core_q) || + cache_priv->device_properties.flush); + fua = (CAS_CHECK_QUEUE_FUA(core_q) || + cache_priv->device_properties.fua); + + memset(lim, 0, sizeof(cas_queue_limits_t)); + + if (flush) + CAS_SET_QUEUE_LIMIT(lim, CAS_BLK_FEAT_WRITE_CACHE); + + if (fua) + CAS_SET_QUEUE_LIMIT(lim, CAS_BLK_FEAT_FUA); + + return 0; +} + struct defer_bio_context { struct work_struct io_work; void (*cb)(struct bd_object *bvol, struct bio *bio); @@ -429,6 +459,7 @@ static void blkdev_core_submit_bio(struct cas_disk *dsk, static struct cas_exp_obj_ops kcas_core_exp_obj_ops = { .set_geometry = blkdev_core_set_geometry, + .set_queue_limits = blkdev_core_set_queue_limits, .submit_bio = blkdev_core_submit_bio, }; @@ -471,6 +502,37 @@ static int blkdev_cache_set_geometry(struct cas_disk *dsk, void *private) return 0; } +static int blkdev_cache_set_queue_limits(struct cas_disk *dsk, void *private, + cas_queue_limits_t *lim) +{ + ocf_cache_t cache; + ocf_volume_t volume; + struct bd_object *bvol; + struct request_queue *cache_q; + struct block_device *bd; + + BUG_ON(!private); + cache = private; + volume = ocf_cache_get_volume(cache); + + bvol = bd_object(volume); + + bd = cas_disk_get_blkdev(bvol->dsk); + BUG_ON(!bd); + + cache_q = bd->bd_disk->queue; + + memset(lim, 0, sizeof(cas_queue_limits_t)); + + if (CAS_CHECK_QUEUE_FLUSH(cache_q)) + CAS_SET_QUEUE_LIMIT(lim, CAS_BLK_FEAT_WRITE_CACHE); + + if (CAS_CHECK_QUEUE_FUA(cache_q)) + CAS_SET_QUEUE_LIMIT(lim, CAS_BLK_FEAT_FUA); + + return 0; +} + static void blkdev_cache_submit_bio(struct cas_disk *dsk, struct bio *bio, void *private) { @@ -486,6 +548,7 @@ static void blkdev_cache_submit_bio(struct cas_disk *dsk, static struct cas_exp_obj_ops kcas_cache_exp_obj_ops = { .set_geometry = blkdev_cache_set_geometry, + .set_queue_limits = blkdev_cache_set_queue_limits, .submit_bio = blkdev_cache_submit_bio, };