├── doc ├── HOME.md ├── .gitignore ├── img │ ├── io-path.png │ ├── deployment-1.png │ └── deployment-2.png └── requirements │ └── disable_cleaner ├── .gitattributes ├── tests ├── unit │ ├── framework │ │ ├── .gitignore │ │ ├── README │ │ └── tests_config.py │ └── tests │ │ ├── header.c │ │ ├── .gitignore │ │ ├── ocf_env │ │ └── CMakeLists.txt │ │ ├── print_desc.h │ │ ├── add_new_test_file.py │ │ ├── utils │ │ └── utils_refcnt.c │ │ │ ├── utils_refcnt_inc.c │ │ │ ├── utils_refcnt_init.c │ │ │ ├── utils_refcnt_dec.c │ │ │ ├── utils_refcnt_unfreeze.c │ │ │ ├── utils_refcnt_register_zero_cb.c │ │ │ └── utils_refcnt_freeze.c │ │ └── metadata │ │ └── metadata_collision.c │ │ └── metadata_collision.c ├── functional │ ├── __init__.py │ ├── pyocf │ │ ├── __init__.py │ │ ├── types │ │ │ ├── __init__.py │ │ │ ├── stats │ │ │ │ ├── __init__.py │ │ │ │ ├── core.py │ │ │ │ ├── cache.py │ │ │ │ └── shared.py │ │ │ ├── volume_cache.py │ │ │ ├── ioclass.py │ │ │ ├── volume_core.py │ │ │ ├── cleaner.py │ │ │ └── cvolume.py │ │ ├── c │ │ │ ├── helpers │ │ │ │ ├── volume_type.c │ │ │ │ ├── metadata_helpers.h │ │ │ │ └── metadata_helpers.c │ │ │ └── wrappers │ │ │ │ ├── ocf_mngt_wrappers.c │ │ │ │ ├── ocf_volume_wrappers.c │ │ │ │ ├── ocf_core_wrappers.c │ │ │ │ ├── ocf_io_wrappers.c │ │ │ │ └── ocf_logger_wrappers.c │ │ ├── ocf.py │ │ └── helpers.py │ ├── tests │ │ ├── __init__.py │ │ ├── basic │ │ │ ├── __init__.py │ │ │ └── test_offset.py │ │ ├── flush │ │ │ └── __init__.py │ │ ├── engine │ │ │ ├── __init__.py │ │ │ ├── test_flush.py │ │ │ ├── test_d2c.py │ │ │ └── test_large_io.py │ │ ├── eviction │ │ │ └── __init__.py │ │ ├── management │ │ │ └── __init__.py │ │ ├── security │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ └── test_failover_security.py │ │ ├── failover │ │ │ └── test_standby_io.py │ │ └── utils │ │ │ └── random.py │ ├── config │ │ └── random.cfg │ ├── .gitignore │ ├── pytest.ini │ ├── utils │ │ └── configure_random.py │ ├── run_with_sanitizers.sh │ └── Makefile └── build │ └── Makefile ├── example └── simple │ ├── src │ ├── data.h │ ├── queue_thread.h │ ├── ctx.h │ └── volume.h │ └── Makefile ├── src ├── engine │ ├── engine_wa.h │ ├── engine_wi.h │ ├── engine_wt.h │ ├── engine_bf.h │ ├── engine_inv.h │ ├── engine_zero.h │ ├── engine_discard.h │ ├── engine_wb.h │ ├── engine_fast.h │ ├── engine_rd.h │ ├── engine_wo.h │ ├── engine_flush.h │ ├── engine_pt.h │ ├── engine_d2c.h │ ├── engine_io.h │ ├── cache_engine.h │ ├── engine_wa.c │ ├── engine_debug.h │ ├── engine_flush.c │ ├── engine_inv.c │ ├── engine_d2c.c │ └── engine_bf.c ├── metadata │ ├── metadata_common.h │ ├── metadata_eviction_policy.h │ ├── metadata_cleaning_policy.h │ ├── metadata_passive_update.h │ ├── metadata_raw_atomic.h │ ├── metadata_eviction_policy.c │ ├── metadata_cache_line.h │ ├── metadata_cleaning_policy.c │ ├── metadata_partition.h │ ├── metadata_core.h │ ├── metadata_partition.c │ ├── metadata_internal.h │ ├── metadata_misc.h │ ├── metadata_misc.c │ ├── metadata_segment_id.h │ ├── metadata_segment.h │ ├── metadata_raw_volatile.h │ ├── metadata_raw_volatile.c │ ├── metadata_structs.h │ ├── metadata_core.c │ ├── metadata_collision.h │ └── metadata_raw_dynamic.h ├── cleaning │ ├── nop.c │ ├── nop.h │ ├── nop_structs.h │ ├── cleaning_priv.h │ ├── acp_structs.h │ ├── alru_structs.h │ ├── cleaning.h │ ├── alru.h │ └── acp.h ├── ocf_composite_volume_priv.h ├── ocf_priv.h ├── mngt │ ├── ocf_mngt_core_pool_priv.h │ ├── ocf_mngt_core_priv.h │ ├── ocf_mngt_misc.c │ └── ocf_mngt_common.h ├── utils │ ├── utils_request.h │ ├── utils_generator.h │ ├── utils_request.c │ ├── utils_parallelize.h │ ├── utils_stats.h │ ├── utils_rbtree.h │ ├── utils_io.h │ ├── utils_async_lock.h │ ├── utils_list.c │ ├── utils_io_allocator.h │ ├── utils_realloc.h │ └── utils_realloc.c ├── promotion │ ├── nhit │ │ ├── nhit_structs.h │ │ ├── nhit_hash.h │ │ └── nhit.h │ └── ops.h ├── concurrency │ ├── ocf_pio_concurrency.h │ ├── ocf_concurrency.c │ ├── ocf_mio_concurrency.h │ └── ocf_concurrency.h ├── ocf_lru_structs.h ├── ocf_logger_priv.h ├── ocf_io_priv.h ├── ocf_space.h ├── ocf_seq_cutoff.h ├── ocf_logger.c ├── ocf_def_priv.h ├── ocf_lru.h ├── ocf_queue_priv.h ├── ocf_io_class.c ├── ocf_volume_priv.h ├── ocf_part.h └── ocf_metadata.c ├── .pep8speaks.yml ├── codecov.yml ├── .checkpatch.conf ├── env └── posix │ ├── ocf_env_headers.h │ ├── ocf_env_refcnt.h │ ├── ocf_env_refcnt.c │ └── utils_mpool.h ├── inc ├── promotion │ └── nhit.h ├── ocf_debug.h ├── ocf_cfg.h ├── ocf.h ├── ocf_logger.h ├── cleaning │ └── acp.h ├── ocf_cleaner.h ├── ocf_composite_volume.h └── ocf_types.h ├── .github ├── workflows │ ├── checkpatch.yml │ └── pullrequest.yml ├── ISSUE_TEMPLATE │ ├── question.md │ ├── enhancement.md │ └── bug.md └── verify_header.sh └── LICENSE /doc/HOME.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | html/ 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | tests/** -linguist-detectable 2 | -------------------------------------------------------------------------------- /tests/unit/framework/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | -------------------------------------------------------------------------------- /doc/img/io-path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-CAS/ocf/HEAD/doc/img/io-path.png -------------------------------------------------------------------------------- /doc/img/deployment-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-CAS/ocf/HEAD/doc/img/deployment-1.png -------------------------------------------------------------------------------- /doc/img/deployment-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-CAS/ocf/HEAD/doc/img/deployment-2.png -------------------------------------------------------------------------------- /tests/functional/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/functional/pyocf/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/functional/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/functional/tests/basic/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/functional/tests/flush/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/unit/tests/header.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | -------------------------------------------------------------------------------- /tests/functional/config/random.cfg: -------------------------------------------------------------------------------- 1 | # This file content will be generated by utils/configure_random.py 2 | # triggered from the Makefile 3 | -------------------------------------------------------------------------------- /tests/functional/tests/engine/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/functional/tests/eviction/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/functional/tests/management/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/functional/tests/security/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/stats/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | -------------------------------------------------------------------------------- /tests/unit/tests/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | ocf_env/ 3 | logs/ 4 | preprocessed_sources_repository/ 5 | sources_to_test_repository/ 6 | *generated_wraps.c 7 | -------------------------------------------------------------------------------- /tests/functional/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | pyocf/__pycache__ 3 | pyocf/libocf.so 4 | *.o 5 | pyocf/ocf/* 6 | *.pyc 7 | *.gcov 8 | *.gcda 9 | *.gcno 10 | -------------------------------------------------------------------------------- /tests/functional/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | markers = 3 | security: security objectives coverage 4 | long: long, do not run by default 5 | addopts = --ignore=tests/security -m "not long" 6 | -------------------------------------------------------------------------------- /tests/unit/tests/ocf_env/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(ocf_env ocf_env.c /usr/include/sys/types.h /usr/include/setjmp.h /usr/include/cmocka.h) 2 | add_definitions(-Dstatic= -Dinline= ) 3 | target_link_libraries(ocf_env pthread z) 4 | -------------------------------------------------------------------------------- /tests/unit/tests/print_desc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #define print_test_description(description) print_message("[ DESC ] %s\n", description); 7 | -------------------------------------------------------------------------------- /example/simple/src/data.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __DATA_H__ 7 | #define __DATA_H__ 8 | 9 | struct volume_data { 10 | void *ptr; 11 | int offset; 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/engine/engine_wa.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef ENGINE_WA_H_ 7 | #define ENGINE_WA_H_ 8 | 9 | int ocf_write_wa(struct ocf_request *req); 10 | 11 | #endif /* ENGINE_WA_H_ */ 12 | -------------------------------------------------------------------------------- /src/engine/engine_wi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef ENGINE_WI_H_ 7 | #define ENGINE_WI_H_ 8 | 9 | int ocf_write_wi(struct ocf_request *req); 10 | 11 | #endif /* ENGINE_WI_H_ */ 12 | -------------------------------------------------------------------------------- /src/engine/engine_wt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef ENGINE_WT_H_ 7 | #define ENGINE_WT_H_ 8 | 9 | int ocf_write_wt(struct ocf_request *req); 10 | 11 | #endif /* ENGINE_WT_H_ */ 12 | -------------------------------------------------------------------------------- /src/engine/engine_bf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef ENGINE_BF_H_ 7 | #define ENGINE_BF_H_ 8 | 9 | void ocf_engine_backfill(struct ocf_request *req); 10 | 11 | #endif /* ENGINE_BF_H_ */ 12 | -------------------------------------------------------------------------------- /src/engine/engine_inv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef ENGINE_INV_H_ 7 | #define ENGINE_INV_H_ 8 | 9 | void ocf_engine_invalidate(struct ocf_request *req); 10 | 11 | #endif /* ENGINE_INV_H_ */ 12 | -------------------------------------------------------------------------------- /src/engine/engine_zero.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef ENGINE_ZERO_H_ 7 | #define ENGINE_ZERO_H_ 8 | 9 | void ocf_engine_zero_line(struct ocf_request *req); 10 | 11 | #endif /* ENGINE_ZERO_H_ */ 12 | -------------------------------------------------------------------------------- /tests/functional/pyocf/c/helpers/volume_type.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2022-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf_composite_volume.h" 7 | 8 | int ocf_get_composite_volume_type_id_helper() 9 | { 10 | return OCF_VOLUME_TYPE_COMPOSITE; 11 | } 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/engine/engine_discard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __ENGINE_DISCARD_H__ 8 | #define __ENGINE_DISCARD_H__ 9 | 10 | int ocf_engine_discard(struct ocf_request *req); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/engine/engine_wb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | #ifndef ENGINE_WB_H_ 6 | #define ENGINE_WB_H_ 7 | 8 | int ocf_write_wb(struct ocf_request *req); 9 | 10 | int ocf_write_wb_do(struct ocf_request *req); 11 | 12 | #endif /* ENGINE_WI_H_ */ 13 | -------------------------------------------------------------------------------- /tests/functional/utils/configure_random.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # 4 | # Copyright(c) 2012-2021 Intel Corporation 5 | # SPDX-License-Identifier: BSD-3-Clause 6 | # 7 | 8 | import sys 9 | import random 10 | 11 | 12 | with open("config/random.cfg", "w") as f: 13 | f.write(str(random.randint(0, sys.maxsize))) 14 | -------------------------------------------------------------------------------- /src/engine/engine_fast.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef ENGINE_FAST_H_ 7 | #define ENGINE_FAST_H_ 8 | 9 | int ocf_read_fast(struct ocf_request *req); 10 | int ocf_write_fast(struct ocf_request *req); 11 | 12 | #endif /* ENGINE_WI_H_ */ 13 | -------------------------------------------------------------------------------- /src/metadata/metadata_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_COMMON_H__ 7 | #define __METADATA_COMMON_H__ 8 | 9 | typedef void (*ocf_metadata_end_t)(void *priv, int error); 10 | 11 | #endif /* __METADATA_COMMON_H__ */ 12 | 13 | -------------------------------------------------------------------------------- /.pep8speaks.yml: -------------------------------------------------------------------------------- 1 | # File : .pep8speaks.yml 2 | 3 | scanner: 4 | diff_only: True 5 | linter: pycodestyle 6 | 7 | pycodestyle: 8 | max-line-length: 100 9 | ignore: 10 | - E402 # module level import not at top of file 11 | - W503 # line break after binary operator 12 | 13 | no_blank_comment: True 14 | -------------------------------------------------------------------------------- /example/simple/src/queue_thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2021-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #pragma once 7 | 8 | int initialize_threads(struct ocf_queue *mngt_queue, struct ocf_queue *io_queue); 9 | void queue_thread_kick(ocf_queue_t q); 10 | void queue_thread_stop(ocf_queue_t q); 11 | -------------------------------------------------------------------------------- /src/engine/engine_rd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef ENGINE_RD_H_ 7 | #define ENGINE_RD_H_ 8 | 9 | int ocf_read_generic(struct ocf_request *req); 10 | 11 | void ocf_read_generic_submit_hit(struct ocf_request *req); 12 | 13 | #endif /* ENGINE_RD_H_ */ 14 | -------------------------------------------------------------------------------- /tests/functional/pyocf/c/wrappers/ocf_mngt_wrappers.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright(c) 2022 Intel Corporation 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include "ocf/ocf_mngt.h" 8 | 9 | void ocf_mngt_cache_config_set_default_wrapper(struct ocf_mngt_cache_config *cfg) 10 | { 11 | ocf_mngt_cache_config_set_default(cfg); 12 | } 13 | -------------------------------------------------------------------------------- /src/engine/engine_wo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef ENGINE_WO_H_ 8 | #define ENGINE_WO_H_ 9 | 10 | #include "engine_common.h" 11 | 12 | int ocf_read_wo(struct ocf_request *req); 13 | 14 | #endif /* ENGINE_WO_H_ */ 15 | -------------------------------------------------------------------------------- /src/engine/engine_flush.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __CACHE_ENGINE_FLUSH_H_ 8 | #define __CACHE_ENGINE_FLUSH_H_ 9 | 10 | int ocf_engine_flush(struct ocf_request *req); 11 | 12 | #endif /* __CACHE_ENGINE_FLUSH_H_ */ 13 | -------------------------------------------------------------------------------- /tests/functional/pyocf/c/wrappers/ocf_volume_wrappers.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright(c) 2012-2021 Intel Corporation 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include "ocf/ocf_io.h" 8 | #include "ocf/ocf_volume.h" 9 | 10 | const char *ocf_uuid_to_str_wrapper(const struct ocf_volume_uuid *uuid) { 11 | return ocf_uuid_to_str(uuid); 12 | } 13 | -------------------------------------------------------------------------------- /src/cleaning/nop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf.h" 7 | #include "nop.h" 8 | #include "../ocf_cache_priv.h" 9 | 10 | void cleaning_nop_perform_cleaning(ocf_cache_t cache, ocf_cleaner_end_t cmpl) 11 | { 12 | cmpl(&cache->cleaner, OCF_CLEANER_DISABLE); 13 | } 14 | -------------------------------------------------------------------------------- /tests/functional/pyocf/c/wrappers/ocf_core_wrappers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2021-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf_io.h" 7 | #include "ocf/ocf_core.h" 8 | 9 | const struct ocf_volume_uuid *ocf_core_get_uuid_wrapper(ocf_core_t core) 10 | { 11 | return ocf_core_get_uuid(core); 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/ocf_composite_volume_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause-Clear 4 | */ 5 | 6 | #ifndef __OCF_COMPOSITE_VOLUME_PRIV_H__ 7 | #define __OCF_COMPOSITE_VOLUME_PRIV_H__ 8 | 9 | #include "ocf/ocf.h" 10 | 11 | int ocf_composite_volume_type_init(ocf_ctx_t ctx); 12 | 13 | #endif /* __OCF_COMPOSITE_VOLUME_H__ */ 14 | -------------------------------------------------------------------------------- /src/metadata/metadata_eviction_policy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_EVICTION_H__ 7 | #define __METADATA_EVICTION_H__ 8 | 9 | struct ocf_lru_meta * 10 | ocf_metadata_get_lru( 11 | struct ocf_cache *cache, ocf_cache_line_t line); 12 | 13 | #endif /* METADATA_EVICTION_H_ */ 14 | -------------------------------------------------------------------------------- /src/cleaning/nop.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __LAYER_CLEANING_POLICY_NOP_H__ 7 | #define __LAYER_CLEANING_POLICY_NOP_H__ 8 | 9 | #include "cleaning.h" 10 | #include "nop_structs.h" 11 | 12 | void cleaning_nop_perform_cleaning(ocf_cache_t cache, ocf_cleaner_end_t cmpl); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/cleaning/nop_structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | #ifndef __LAYER_CLEANING_POLICY_NOP_STRUCTS_H__ 6 | 7 | #define __LAYER_CLEANING_POLICY_NOP_STRUCTS_H__ 8 | 9 | struct nop_cleaning_policy_meta { 10 | } __attribute__((packed)); 11 | 12 | struct nop_cleaning_policy { 13 | }; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/ocf_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | #ifndef __OCF_PRIV_H__ 6 | #define __OCF_PRIV_H__ 7 | 8 | #include "ocf_env.h" 9 | #include "ocf_def_priv.h" 10 | 11 | #define OCF_CHECK_NULL(p) ENV_BUG_ON(!(p)) 12 | 13 | #define OCF_CMPL_RET(args...) ({ \ 14 | cmpl(args); \ 15 | return; \ 16 | }) 17 | 18 | #endif /* __OCF_PRIV_H__ */ 19 | -------------------------------------------------------------------------------- /src/metadata/metadata_cleaning_policy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_CLEANING_POLICY_H__ 7 | #define __METADATA_CLEANING_POLICY_H__ 8 | 9 | struct cleaning_policy_meta * 10 | ocf_metadata_get_cleaning_policy(struct ocf_cache *cache, 11 | ocf_cache_line_t line); 12 | 13 | 14 | #endif /* METADATA_CLEANING_POLICY_H_ */ 15 | -------------------------------------------------------------------------------- /src/mngt/ocf_mngt_core_pool_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __OCF_MNGT_CORE_POOL_PRIV_H__ 7 | #define __OCF_MNGT_CORE_POOL_PRIV_H__ 8 | 9 | #include "ocf/ocf.h" 10 | 11 | void ocf_mngt_core_pool_init(ocf_ctx_t ctx); 12 | 13 | void ocf_mngt_core_pool_deinit(ocf_ctx_t ctx); 14 | 15 | #endif /* __OCF_MNGT_CORE_POOL_PRIV_H__ */ 16 | -------------------------------------------------------------------------------- /src/utils/utils_request.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "../ocf_request.h" 7 | #include "../ocf_cache_priv.h" 8 | 9 | typedef int (*ocf_req_actor_t)(struct ocf_request *req, uint32_t map_idx); 10 | 11 | int ocf_req_actor(struct ocf_request *req, ocf_req_actor_t actor); 12 | 13 | void ocf_req_set_cleaning_hot(struct ocf_request *req); 14 | -------------------------------------------------------------------------------- /src/engine/engine_pt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef ENGINE_OFF_H_ 8 | #define ENGINE_OFF_H_ 9 | 10 | int ocf_read_pt(struct ocf_request *req); 11 | 12 | int ocf_read_pt_do(struct ocf_request *req); 13 | 14 | void ocf_queue_push_req_pt(struct ocf_request *req); 15 | 16 | #endif /* ENGINE_OFF_H_ */ 17 | -------------------------------------------------------------------------------- /example/simple/src/ctx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __CTX_H__ 7 | #define __CTX_H__ 8 | 9 | #include 10 | 11 | #define VOL_TYPE 1 12 | 13 | ctx_data_t *ctx_data_alloc(uint32_t pages); 14 | void ctx_data_free(ctx_data_t *ctx_data); 15 | 16 | int ctx_init(ocf_ctx_t *ocf_ctx); 17 | void ctx_cleanup(ocf_ctx_t ctx); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/promotion/nhit/nhit_structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | #ifndef __PROMOTION_NHIT_STRUCTS_H_ 6 | #define __PROMOTION_NHIT_STRUCTS_H_ 7 | 8 | struct nhit_promotion_policy_config { 9 | uint32_t insertion_threshold; 10 | /*!< Number of hits */ 11 | 12 | uint32_t trigger_threshold; 13 | /*!< Cache occupancy (percentage value) */ 14 | }; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/engine/engine_d2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef ENGINE_2DC_H_ 8 | #define ENGINE_2DC_H_ 9 | 10 | int ocf_d2c_io_fast(struct ocf_request *req); 11 | 12 | int ocf_d2c_flush_fast(struct ocf_request *req); 13 | 14 | int ocf_d2c_discard_fast(struct ocf_request *req); 15 | 16 | #endif /* ENGINE_2DC_H_ */ 17 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: yes 3 | 4 | coverage: 5 | precision: 2 6 | round: down 7 | range: "60...100" 8 | 9 | status: 10 | project: yes 11 | patch: yes 12 | changes: no 13 | 14 | parsers: 15 | gcov: 16 | branch_detection: 17 | conditional: yes 18 | loop: yes 19 | method: no 20 | macro: no 21 | 22 | comment: 23 | layout: "diff,flags,tree" 24 | behavior: default 25 | require_changes: no 26 | -------------------------------------------------------------------------------- /src/metadata/metadata_passive_update.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __OCF_METADATA_PASSIVE_IO_H__ 8 | #define __OCF_METADATA_PASSIVE_IO_H__ 9 | 10 | int ocf_metadata_passive_update(struct ocf_request *master); 11 | 12 | int ocf_metadata_passive_io_ctx_init(ocf_cache_t cache); 13 | 14 | void ocf_metadata_passive_io_ctx_deinit(ocf_cache_t cache); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /.checkpatch.conf: -------------------------------------------------------------------------------- 1 | --max-line-length=80 2 | --no-tree 3 | 4 | --ignore AVOID_BUG 5 | --ignore COMMIT_MESSAGE 6 | --ignore FILE_PATH_CHANGES 7 | --ignore PREFER_PR_LEVEL 8 | --ignore SPDX_LICENSE_TAG 9 | --ignore SPLIT_STRING 10 | --ignore UNSPECIFIED_INT 11 | --ignore NEW_TYPEDEFS 12 | --ignore PREFER_DEFINED_ATTRIBUTE_MACRO 13 | 14 | --exclude .github 15 | --exclude doc 16 | --exclude tests 17 | --exclude .pep8speaks.yml 18 | --exclude LICENSE 19 | --exclude Makefile 20 | --exclude README.md 21 | --exclude codecov.yml 22 | -------------------------------------------------------------------------------- /example/simple/src/volume.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __VOLUME_H__ 8 | #define __VOLUME_H__ 9 | 10 | #include 11 | #include "ocf_env.h" 12 | #include "ctx.h" 13 | #include "data.h" 14 | 15 | struct myvolume { 16 | uint8_t *mem; 17 | const char *name; 18 | }; 19 | 20 | int volume_init(ocf_ctx_t ocf_ctx); 21 | void volume_cleanup(ocf_ctx_t ocf_ctx); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/mngt/ocf_mngt_core_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __OCF_MNGT_CORE_PRIV_H__ 8 | #define __OCF_MNGT_CORE_PRIV_H__ 9 | 10 | #include "../ocf_core_priv.h" 11 | 12 | int ocf_mngt_core_init_front_volume(ocf_core_t core); 13 | 14 | void ocf_mngt_core_clear_uuid_metadata(ocf_core_t core); 15 | 16 | ocf_seq_no_t ocf_mngt_get_core_seq_no(ocf_cache_t cache); 17 | 18 | #endif /* __OCF_MNGT_CORE_PRIV_H__ */ 19 | -------------------------------------------------------------------------------- /src/metadata/metadata_raw_atomic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_RAW_ATOMIC_H__ 7 | #define __METADATA_RAW_ATOMIC_H__ 8 | 9 | void raw_atomic_flush_mark(struct ocf_cache *cache, struct ocf_request *req, 10 | uint32_t map_idx, int to_state, uint8_t start, uint8_t stop); 11 | 12 | int raw_atomic_flush_do_asynch(struct ocf_cache *cache, struct ocf_request *req, 13 | struct ocf_metadata_raw *raw, ocf_req_end_t complete); 14 | 15 | #endif /* __METADATA_RAW_ATOMIC_H__ */ 16 | -------------------------------------------------------------------------------- /src/utils/utils_generator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __UTILS_GENERATOR_H__ 7 | #define __UTILS_GENERATOR_H__ 8 | 9 | #include "ocf/ocf.h" 10 | 11 | struct ocf_generator_bisect_state { 12 | uint32_t curr; 13 | uint32_t limit; 14 | }; 15 | 16 | void ocf_generator_bisect_init( 17 | struct ocf_generator_bisect_state *generator, 18 | uint32_t limit, uint32_t offset); 19 | 20 | uint32_t ocf_generator_bisect_next( 21 | struct ocf_generator_bisect_state *generator); 22 | 23 | #endif /* __UTILS_GENERATOR_H__ */ 24 | -------------------------------------------------------------------------------- /env/posix/ocf_env_headers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __OCF_ENV_HEADERS_H__ 7 | #define __OCF_ENV_HEADERS_H__ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | /* TODO: Move prefix printing to context logger. */ 14 | #define OCF_LOGO "OCF" 15 | #define OCF_PREFIX_SHORT "[" OCF_LOGO "] " 16 | #define OCF_PREFIX_LONG "Open CAS Framework" 17 | 18 | #define OCF_VERSION_MAIN 20 19 | #define OCF_VERSION_MAJOR 3 20 | #define OCF_VERSION_MINOR 0 21 | 22 | #endif /* __OCF_ENV_HEADERS_H__ */ 23 | -------------------------------------------------------------------------------- /inc/promotion/nhit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __OCF_PROMOTION_NHIT_H__ 7 | #define __OCF_PROMOTION_NHIT_H__ 8 | 9 | enum ocf_nhit_param { 10 | ocf_nhit_insertion_threshold, 11 | ocf_nhit_trigger_threshold, 12 | ocf_nhit_param_max 13 | }; 14 | 15 | #define OCF_NHIT_MIN_THRESHOLD 2 16 | #define OCF_NHIT_MAX_THRESHOLD 1000 17 | #define OCF_NHIT_THRESHOLD_DEFAULT 3 18 | 19 | #define OCF_NHIT_MIN_TRIGGER 0 20 | #define OCF_NHIT_MAX_TRIGGER 100 21 | #define OCF_NHIT_TRIGGER_DEFAULT 80 22 | 23 | #endif /* __OCF_PROMOTION_NHIT_H__ */ 24 | -------------------------------------------------------------------------------- /src/concurrency/ocf_pio_concurrency.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2021-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __OCF_PIO_CONCURRENCY_H_ 7 | #define __OCF_PIO_CONCURRENCY_H_ 8 | 9 | #include "../utils/utils_alock.h" 10 | 11 | int ocf_pio_async_lock(struct ocf_alock *alock, struct ocf_request *req, 12 | ocf_req_async_lock_cb cmpl); 13 | 14 | void ocf_pio_async_unlock(struct ocf_alock *alock, struct ocf_request *req); 15 | 16 | int ocf_pio_concurrency_init(struct ocf_alock **self, ocf_cache_t cache); 17 | 18 | void ocf_pio_concurrency_deinit(struct ocf_alock **self); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /.github/workflows/checkpatch.yml: -------------------------------------------------------------------------------- 1 | name: checkpatch review 2 | permissions: 3 | contents: read 4 | pull-requests: read 5 | on: [pull_request] 6 | jobs: 7 | my_review: 8 | name: checkpatch review 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: 'Calculate PR commits + 1' 12 | run: echo "PR_FETCH_DEPTH=$(( ${{ github.event.pull_request.commits }} + 1 ))" >> $GITHUB_ENV 13 | - uses: actions/checkout@v3 14 | with: 15 | ref: ${{ github.event.pull_request.head.sha }} 16 | fetch-depth: ${{ env.PR_FETCH_DEPTH }} 17 | - name: Run checkpatch review 18 | uses: webispy/checkpatch-action@v9 19 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/stats/core.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2021 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | from ctypes import c_uint32, c_uint64, Structure 7 | 8 | from .shared import OcfStatsReq, OcfStatsBlock, OcfStatsDebug, OcfStatsError 9 | 10 | 11 | class CoreInfo(Structure): 12 | _fields_ = [ 13 | ("core_size", c_uint64), 14 | ("core_size_bytes", c_uint64), 15 | ("dirty", c_uint32), 16 | ("flushed", c_uint32), 17 | ("dirty_for", c_uint64), 18 | ("seq_cutoff_threshold", c_uint32), 19 | ("seq_cutoff_policy", c_uint32), 20 | ] 21 | -------------------------------------------------------------------------------- /inc/ocf_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __OCF_DEBUG_H__ 8 | #define __OCF_DEBUG_H__ 9 | 10 | struct ocf_dbg_seq_cutoff_status { 11 | struct { 12 | uint64_t last; 13 | uint64_t bytes; 14 | uint32_t rw : 1; 15 | uint32_t active : 1; 16 | } streams[OCF_SEQ_CUTOFF_PERCORE_STREAMS]; 17 | }; 18 | 19 | void ocf_dbg_get_seq_cutoff_status(ocf_core_t core, 20 | struct ocf_dbg_seq_cutoff_status *status); 21 | 22 | bool ocf_dbg_cache_is_settled(ocf_cache_t cache); 23 | 24 | #endif /* __OCF_DEBUG_H__ */ 25 | -------------------------------------------------------------------------------- /src/metadata/metadata_eviction_policy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2020-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf.h" 7 | #include "metadata.h" 8 | #include "metadata_eviction_policy.h" 9 | #include "metadata_internal.h" 10 | 11 | /* 12 | * Eviction policy - Get 13 | */ 14 | struct ocf_lru_meta * ocf_metadata_get_lru(struct ocf_cache *cache, 15 | ocf_cache_line_t line) 16 | { 17 | struct ocf_metadata_ctrl *ctrl 18 | = (struct ocf_metadata_ctrl *) cache->metadata.priv; 19 | 20 | return ocf_metadata_raw_wr_access(cache, 21 | &(ctrl->raw_desc[metadata_segment_lru]), line); 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/cleaning/cleaning_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | static inline void cleaning_policy_param_error(ocf_cache_t cache, 7 | const char *param_name, uint32_t min, uint32_t max) 8 | { 9 | ocf_cache_log(cache, log_err, "Refusing setting flush " 10 | "parameters because parameter %s is not within range " 11 | "of <%d-%d>\n", param_name, min, max); 12 | } 13 | 14 | #define OCF_CLEANING_CHECK_PARAM(CACHE, VAL, MIN, MAX, NAME) ({ \ 15 | if (VAL < MIN || VAL > MAX) { \ 16 | cleaning_policy_param_error(CACHE, NAME, MIN, MAX); \ 17 | return -OCF_ERR_INVAL; \ 18 | } \ 19 | }) 20 | -------------------------------------------------------------------------------- /tests/functional/pyocf/c/helpers/metadata_helpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #pragma once 7 | 8 | uint64_t ocf_get_metadata_segment_start_page(ocf_cache_t cache, int segment); 9 | uint64_t ocf_get_metadata_segment_page_count(ocf_cache_t cache, int segment); 10 | uint64_t ocf_get_metadata_segment_elems_count(ocf_cache_t cache, int segment); 11 | uint64_t ocf_get_metadata_segment_elems_per_page(ocf_cache_t cache, int segment); 12 | uint64_t ocf_get_metadata_segment_elem_size(ocf_cache_t cache, int segment); 13 | bool ocf_get_metadata_segment_is_flapped(ocf_cache_t cache, int segment); 14 | -------------------------------------------------------------------------------- /src/cleaning/acp_structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2023-2025 Huawei Technologies Co., Ltd. 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef __CLEANING_AGGRESSIVE_STRUCTS_H__ 7 | #define __CLEANING_AGGRESSIVE_STRUCTS_H__ 8 | 9 | #include "ocf_env_headers.h" 10 | 11 | /* TODO: remove acp metadata */ 12 | struct acp_cleaning_policy_meta { 13 | uint8_t dirty : 1; 14 | }; 15 | 16 | /* cleaning policy per partition metadata */ 17 | struct acp_cleaning_policy_config { 18 | uint32_t thread_wakeup_time; /* in milliseconds*/ 19 | uint32_t flush_max_buffers; /* in lines */ 20 | }; 21 | 22 | #endif 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/ocf_lru_structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | #ifndef __EVICTION_LRU_STRUCTS_H__ 6 | 7 | #define __EVICTION_LRU_STRUCTS_H__ 8 | 9 | struct ocf_lru_meta { 10 | uint32_t prev; 11 | uint32_t next; 12 | uint8_t hot; 13 | } __attribute__((packed)); 14 | 15 | struct ocf_lru_list { 16 | uint32_t num_nodes; 17 | uint32_t head; 18 | uint32_t tail; 19 | uint32_t num_hot; 20 | uint32_t last_hot; 21 | bool track_hot; 22 | }; 23 | 24 | struct ocf_lru_part_meta { 25 | struct ocf_lru_list clean; 26 | struct ocf_lru_list dirty; 27 | }; 28 | 29 | #define OCF_LRU_HOT_RATIO 2 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tests/unit/framework/README: -------------------------------------------------------------------------------- 1 | GENERATING NEW TEST 2 | To add new test, run "add_new_test_file.py" with two parameters: 3 | - tested file path (path must be relative to your current working dir) 4 | - tested function name 5 | Generated file name may be changed without any consequences. 6 | 7 | Good practise is to use "add_new_test_file.py" script from test directory (not framework), 8 | because it prepend appropriate license header. 9 | 10 | RUNNING SINGLE TEST 11 | Executable tests files are stored by default in 'UT_dir/build/sources_to_test_repository/' 12 | 13 | REQUIREMENTS FOR BUILD: 14 | - cmocka 15 | - cmake 16 | - ctags (Exuberant version) 17 | - nm, gcc, make 18 | -------------------------------------------------------------------------------- /src/metadata/metadata_cache_line.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_CACHE_LINE_H__ 7 | #define __METADATA_CACHE_LINE_H__ 8 | 9 | static inline ocf_cache_line_size_t ocf_line_size(struct ocf_cache *cache) 10 | { 11 | return cache->metadata.line_size; 12 | } 13 | 14 | static inline uint64_t ocf_line_sectors(struct ocf_cache *cache) 15 | { 16 | return BYTES_TO_SECTORS(cache->metadata.line_size); 17 | } 18 | 19 | static inline uint64_t ocf_line_end_sector(struct ocf_cache *cache) 20 | { 21 | return ocf_line_sectors(cache) - 1; 22 | } 23 | 24 | #endif /* __METADATA_CACHE_LINE_H__ */ 25 | -------------------------------------------------------------------------------- /src/concurrency/ocf_concurrency.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf_concurrency.h" 7 | #include "../metadata/metadata.h" 8 | 9 | int ocf_concurrency_init(struct ocf_cache *cache) 10 | { 11 | int result = 0; 12 | 13 | result = ocf_cache_line_concurrency_init( 14 | &cache->device->concurrency.cache_line, 15 | ocf_metadata_collision_table_entries(cache), 16 | cache); 17 | 18 | if (result) 19 | ocf_concurrency_deinit(cache); 20 | 21 | return result; 22 | } 23 | 24 | void ocf_concurrency_deinit(struct ocf_cache *cache) 25 | { 26 | ocf_cache_line_concurrency_deinit( 27 | &cache->device->concurrency.cache_line); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/metadata/metadata_cleaning_policy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2020-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf.h" 7 | #include "metadata.h" 8 | #include "metadata_cleaning_policy.h" 9 | #include "metadata_internal.h" 10 | 11 | /* 12 | * Cleaning policy - Get 13 | */ 14 | struct cleaning_policy_meta * 15 | ocf_metadata_get_cleaning_policy(struct ocf_cache *cache, 16 | ocf_cache_line_t line) 17 | { 18 | struct ocf_metadata_ctrl *ctrl 19 | = (struct ocf_metadata_ctrl *) cache->metadata.priv; 20 | 21 | ENV_BUG_ON(cache->conf_meta->cleaner_disabled); 22 | 23 | return ocf_metadata_raw_wr_access(cache, 24 | &(ctrl->raw_desc[metadata_segment_cleaning]), line); 25 | } 26 | -------------------------------------------------------------------------------- /src/mngt/ocf_mngt_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf.h" 7 | #include "ocf_mngt_common.h" 8 | #include "../ocf_priv.h" 9 | #include "../metadata/metadata.h" 10 | #include "../engine/cache_engine.h" 11 | #include "../ocf_ctx_priv.h" 12 | 13 | uint32_t ocf_mngt_cache_get_count(ocf_ctx_t ctx) 14 | { 15 | struct ocf_cache *cache; 16 | uint32_t count = 0; 17 | 18 | OCF_CHECK_NULL(ctx); 19 | 20 | env_rmutex_lock(&ctx->lock); 21 | 22 | /* currently, there are no macros in list.h to get list size.*/ 23 | list_for_each_entry(cache, &ctx->caches, list) 24 | count++; 25 | 26 | env_rmutex_unlock(&ctx->lock); 27 | 28 | return count; 29 | } 30 | -------------------------------------------------------------------------------- /src/concurrency/ocf_mio_concurrency.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2021-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef OCF_MIO_CONCURRENCY_H_ 7 | #define OCF_MIO_CONCURRENCY_H_ 8 | 9 | #include "../utils/utils_alock.h" 10 | 11 | struct metadata_io_request; 12 | 13 | int ocf_mio_async_lock(struct ocf_alock *alock, 14 | struct metadata_io_request *m_req, 15 | ocf_req_async_lock_cb cmpl); 16 | 17 | void ocf_mio_async_unlock(struct ocf_alock *alock, 18 | struct metadata_io_request *m_req); 19 | 20 | int ocf_mio_concurrency_init(struct ocf_alock **self, 21 | unsigned first_page, unsigned num_pages, 22 | ocf_cache_t cache); 23 | 24 | void ocf_mio_concurrency_deinit(struct ocf_alock **self); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask the question that is bothering you 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | --- 8 | 9 | ## Question 10 | 11 | 12 | ## Motivation 13 | 14 | 15 | ## Your Environment 16 | 17 | 18 | * OCF version (commit hash or tag): 19 | * Operating System: 20 | * Kernel version: 21 | * Cache device type (NAND/Optane/other): 22 | * Core device type (HDD/SSD/other): 23 | * Configuration: 24 | * * Cache mode: (default: wt) 25 | * * Cache line size: (default: 4) 26 | * Other (e.g. _lsblk_, _lsscsi_) 27 | -------------------------------------------------------------------------------- /src/promotion/nhit/nhit_hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef NHIT_HASH_H_ 7 | #define NHIT_HASH_H_ 8 | 9 | #include "ocf/ocf.h" 10 | 11 | typedef struct nhit_hash *nhit_hash_t; 12 | 13 | uint64_t nhit_hash_sizeof(uint64_t hash_size); 14 | 15 | ocf_error_t nhit_hash_init(uint64_t hash_size, nhit_hash_t *ctx); 16 | 17 | void nhit_hash_deinit(nhit_hash_t ctx); 18 | 19 | void nhit_hash_insert(nhit_hash_t ctx, ocf_core_id_t core_id, uint64_t core_lba); 20 | 21 | bool nhit_hash_query(nhit_hash_t ctx, ocf_core_id_t core_id, uint64_t core_lba, 22 | int32_t *counter); 23 | 24 | void nhit_hash_set_occurences(nhit_hash_t ctx, ocf_core_id_t core_id, 25 | uint64_t core_lba, int32_t occurences); 26 | #endif /* NHIT_HASH_H_ */ 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement proposal 3 | about: Create an enhancement proposal to help us improve 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | --- 8 | 9 | ## Description 10 | 11 | 12 | ## Reason 13 | 14 | 15 | ## Your Environment 16 | 17 | * OCF version (commit hash or tag): 18 | * Operating System: 19 | * Kernel version: 20 | * Cache device type (NAND/Optane/other): 21 | * Core device type (HDD/SSD/other): 22 | * Configuration: 23 | * * Cache mode: (default: wt) 24 | * * Cache line size: (default: 4) 25 | * Other (e.g. _lsblk_, _lsscsi_) 26 | -------------------------------------------------------------------------------- /src/metadata/metadata_partition.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies Co., Ltd. 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __METADATA_PARTITION_H__ 8 | #define __METADATA_PARTITION_H__ 9 | 10 | #include "../ocf_cache_priv.h" 11 | 12 | #define PARTITION_DEFAULT 0 13 | #define PARTITION_UNSPECIFIED ((ocf_part_id_t)-1) 14 | #define PARTITION_FREELIST OCF_USER_IO_CLASS_MAX + 1 15 | #define PARTITION_SIZE_MIN 0 16 | #define PARTITION_SIZE_MAX 100 17 | 18 | ocf_part_id_t ocf_metadata_get_partition_id(struct ocf_cache *cache, 19 | ocf_cache_line_t line); 20 | 21 | void ocf_metadata_set_partition_id( 22 | struct ocf_cache *cache, ocf_cache_line_t line, 23 | ocf_part_id_t part_id); 24 | 25 | #endif /* __METADATA_PARTITION_H__ */ 26 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/volume_cache.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2022 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | from ctypes import cast, POINTER 7 | 8 | from .cache import Cache 9 | from .io import Io 10 | from .io import IoDir 11 | from .volume_exp_obj import OcfInternalVolume 12 | from .volume import Volume 13 | 14 | 15 | class CacheVolume(OcfInternalVolume): 16 | def __init__(self, cache, uuid=None): 17 | super().__init__(cache, uuid) 18 | self.cache = cache 19 | self.lib = cache.owner.lib 20 | 21 | def get_c_handle(self): 22 | return self.cache.get_c_front_volume() 23 | 24 | def md5(self): 25 | out = self.cache.get_conf() 26 | cache_line_size = int(out["cache_line_size"]) 27 | return self._exp_obj_md5(cache_line_size) 28 | -------------------------------------------------------------------------------- /example/simple/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2021 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | OCFDIR=../../ 7 | SRCDIR=src/ 8 | INCDIR=include/ 9 | 10 | SRC=$(shell find ${SRCDIR} -name \*.c) 11 | OBJS = $(patsubst %.c, %.o, $(SRC)) 12 | PROGRAM=simple 13 | 14 | CC = gcc 15 | CFLAGS = -g -Wall -I${INCDIR} -I${SRCDIR}/ocf/env/ 16 | LDFLAGS = -lm -lz -pthread 17 | 18 | all: sync 19 | $(MAKE) $(PROGRAM) 20 | 21 | $(PROGRAM): $(OBJS) 22 | $(CC) -o $@ $^ $(LDFLAGS) 23 | 24 | sync: 25 | @$(MAKE) -C ${OCFDIR} inc O=$(PWD) 26 | @$(MAKE) -C ${OCFDIR} src O=$(PWD) 27 | @$(MAKE) -C ${OCFDIR} env O=$(PWD) OCF_ENV=posix 28 | 29 | clean: 30 | @rm -rf $(PROGRAM) $(OBJS) 31 | 32 | distclean: 33 | @rm -rf $(PROGRAM) $(OBJS) 34 | @rm -rf src/ocf 35 | @rm -rf include/ocf 36 | 37 | .PHONY: all clean 38 | -------------------------------------------------------------------------------- /src/concurrency/ocf_concurrency.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef OCF_CONCURRENCY_H_ 7 | #define OCF_CONCURRENCY_H_ 8 | 9 | #include "../ocf_cache_priv.h" 10 | 11 | /** 12 | * @file utils_req.h 13 | * @brief OCF concurrency 14 | */ 15 | 16 | /** 17 | * @brief Initialize OCF concurrency module 18 | * 19 | * @param cache - OCF cache instance 20 | * @return 0 - Initialization successful, otherwise ERROR 21 | */ 22 | int ocf_concurrency_init(struct ocf_cache *cache); 23 | 24 | /** 25 | * @biref De-Initialize OCF concurrency module 26 | * 27 | * @param cache - OCF cache instance 28 | */ 29 | void ocf_concurrency_deinit(struct ocf_cache *cache); 30 | 31 | #include "ocf_cache_line_concurrency.h" 32 | 33 | #endif /* OCF_CONCURRENCY_H_ */ 34 | -------------------------------------------------------------------------------- /src/ocf_logger_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __OCF_LOGGER_PRIV_H__ 7 | #define __OCF_LOGGER_PRIV_H__ 8 | 9 | #include "ocf/ocf_logger.h" 10 | 11 | struct ocf_logger { 12 | const struct ocf_logger_ops *ops; 13 | void *priv; 14 | }; 15 | 16 | __attribute__((format(printf, 3, 4))) 17 | int ocf_log_raw(ocf_logger_t logger, ocf_logger_lvl_t lvl, 18 | const char *fmt, ...); 19 | 20 | int ocf_log_raw_rl(ocf_logger_t logger, const char *func_name); 21 | 22 | int ocf_log_stack_trace_raw(ocf_logger_t logger); 23 | 24 | void ocf_logger_init(ocf_logger_t logger, 25 | const struct ocf_logger_ops *ops, void *priv); 26 | 27 | int ocf_logger_open(ocf_logger_t logger); 28 | 29 | void ocf_logger_close(ocf_logger_t logger); 30 | 31 | #endif /* __OCF_LOGGER_PRIV_H__ */ 32 | -------------------------------------------------------------------------------- /inc/ocf_cfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | 7 | #ifndef __OCF_CFG_H__ 8 | #define __OCF_CFG_H__ 9 | 10 | /** 11 | * @file 12 | * @brief OCF configuration file 13 | */ 14 | 15 | /** 16 | * Configure maximum numbers of cores in cache instance 17 | */ 18 | #ifndef OCF_CONFIG_MAX_CORES 19 | #define OCF_CONFIG_MAX_CORES 4096 20 | #endif 21 | 22 | /** Maximum number of IO classes that can be configured */ 23 | #ifndef OCF_CONFIG_MAX_IO_CLASSES 24 | #define OCF_CONFIG_MAX_IO_CLASSES 33 25 | #endif 26 | 27 | #if OCF_CONFIG_MAX_IO_CLASSES > 256 28 | #error "Limit of maximum number of IO classes exceeded" 29 | #endif 30 | 31 | /** Enabling debug statistics */ 32 | #ifndef OCF_CONFIG_DEBUG_STATS 33 | #define OCF_CONFIG_DEBUG_STATS 0 34 | #endif 35 | 36 | #endif /* __OCF_CFG_H__ */ 37 | -------------------------------------------------------------------------------- /inc/ocf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __OCF_H__ 7 | #define __OCF_H__ 8 | 9 | /** 10 | * @file 11 | * @brief Main OCF header 12 | * This file doesn't contain any functions or structures. 13 | * It's simply collective include file to allow OCF user include 14 | * everything at once. 15 | */ 16 | 17 | #include "ocf_def.h" 18 | #include "ocf_types.h" 19 | #include "ocf_io.h" 20 | #include "ocf_volume.h" 21 | #include "ocf_composite_volume.h" 22 | #include "ocf_cache.h" 23 | #include "ocf_core.h" 24 | #include "ocf_queue.h" 25 | #include "ocf_cleaner.h" 26 | #include "cleaning/alru.h" 27 | #include "cleaning/acp.h" 28 | #include "promotion/nhit.h" 29 | #include "ocf_metadata.h" 30 | #include "ocf_io_class.h" 31 | #include "ocf_stats.h" 32 | #include "ocf_mngt.h" 33 | #include "ocf_ctx.h" 34 | #include "ocf_err.h" 35 | 36 | #endif /* __OCF_H__ */ 37 | -------------------------------------------------------------------------------- /src/promotion/nhit/nhit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef NHIT_PROMOTION_POLICY_H_ 7 | #define NHIT_PROMOTION_POLICY_H_ 8 | 9 | #include "ocf/ocf.h" 10 | #include "../../ocf_request.h" 11 | #include "../promotion.h" 12 | #include "nhit_structs.h" 13 | 14 | void nhit_setup(ocf_cache_t cache); 15 | 16 | ocf_error_t nhit_init(ocf_cache_t cache); 17 | 18 | void nhit_deinit(ocf_promotion_policy_t policy); 19 | 20 | ocf_error_t nhit_set_param(ocf_cache_t cache, uint8_t param_id, 21 | uint32_t param_value); 22 | 23 | ocf_error_t nhit_get_param(ocf_cache_t cache, uint8_t param_id, 24 | uint32_t *param_value); 25 | 26 | void nhit_req_purge(ocf_promotion_policy_t policy, 27 | struct ocf_request *req); 28 | 29 | bool nhit_req_should_promote(ocf_promotion_policy_t policy, 30 | struct ocf_request *req); 31 | 32 | #endif /* NHIT_PROMOTION_POLICY_H_ */ 33 | -------------------------------------------------------------------------------- /src/metadata/metadata_core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_CORE_H__ 7 | #define __METADATA_CORE_H__ 8 | 9 | #include 10 | 11 | void ocf_metadata_get_core_info(struct ocf_cache *cache, 12 | ocf_cache_line_t line, ocf_core_id_t *core_id, 13 | uint64_t *core_sector); 14 | 15 | void ocf_metadata_set_core_info(struct ocf_cache *cache, 16 | ocf_cache_line_t line, ocf_core_id_t core_id, 17 | uint64_t core_sector); 18 | 19 | ocf_core_id_t ocf_metadata_get_core_id( 20 | struct ocf_cache *cache, ocf_cache_line_t line); 21 | 22 | struct ocf_metadata_uuid *ocf_metadata_get_core_uuid( 23 | struct ocf_cache *cache, ocf_core_id_t core_id); 24 | 25 | void ocf_metadata_get_core_and_part_id( 26 | struct ocf_cache *cache, ocf_cache_line_t line, 27 | ocf_core_id_t *core_id, ocf_part_id_t *part_id); 28 | 29 | #endif /* METADATA_CORE_H_ */ 30 | -------------------------------------------------------------------------------- /tests/functional/pyocf/c/wrappers/ocf_io_wrappers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include "ocf/ocf_io.h" 8 | #include "ocf/ocf_core.h" 9 | 10 | void ocf_io_set_cmpl_wrapper(ocf_io_t io, void *context, 11 | void *context2, ocf_end_io_t fn) 12 | { 13 | ocf_io_set_cmpl(io, context, context2, fn); 14 | } 15 | 16 | void ocf_io_set_start_wrapper(ocf_io_t io, ocf_start_io_t fn) 17 | { 18 | ocf_io_set_start(io, fn); 19 | } 20 | 21 | void ocf_io_set_handle_wrapper(ocf_io_t io, ocf_handle_io_t fn) 22 | { 23 | ocf_io_set_handle(io, fn); 24 | } 25 | 26 | void ocf_core_submit_io_wrapper(ocf_io_t io) 27 | { 28 | ocf_core_submit_io(io); 29 | } 30 | 31 | 32 | void ocf_core_submit_flush_wrapper(ocf_io_t io) 33 | { 34 | ocf_core_submit_flush(io); 35 | } 36 | 37 | void ocf_core_submit_discard_wrapper(ocf_io_t io) 38 | { 39 | ocf_core_submit_discard(io); 40 | } 41 | -------------------------------------------------------------------------------- /src/ocf_io_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __OCF_IO_PRIV_H__ 8 | #define __OCF_IO_PRIV_H__ 9 | 10 | #include "ocf/ocf.h" 11 | #include "utils/utils_io_allocator.h" 12 | 13 | int ocf_io_allocator_default_init(ocf_io_allocator_t allocator, 14 | const char *name); 15 | 16 | void ocf_io_allocator_default_deinit(ocf_io_allocator_t allocator); 17 | 18 | void *ocf_io_allocator_default_new(ocf_io_allocator_t allocator, 19 | ocf_volume_t volume, ocf_queue_t queue, 20 | uint64_t addr, uint32_t bytes, uint32_t dir); 21 | 22 | void ocf_io_allocator_default_del(ocf_io_allocator_t allocator, void *obj); 23 | 24 | ocf_io_t ocf_io_new(ocf_volume_t volume, ocf_queue_t queue, 25 | uint64_t addr, uint32_t bytes, uint32_t dir, 26 | uint32_t io_class, uint64_t flags); 27 | 28 | void ocf_io_end_func(ocf_io_t io, int error); 29 | 30 | #endif /* __OCF_IO_PRIV_H__ */ 31 | -------------------------------------------------------------------------------- /tests/build/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2021 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | # 7 | # This Makefile performs basic build test of OCF with posix environment. 8 | # It doesn't generate any final executable, but just compiles every 9 | # single *.c file into *.o object, to check if compilation succeeds. 10 | # 11 | # It's intended to be used as part of CI process. 12 | # 13 | 14 | OCFDIR=../../ 15 | SRCDIR=src/ 16 | INCDIR=include/ 17 | 18 | SRC=$(shell find ${SRCDIR} -name \*.c) 19 | OBJS = $(patsubst %.c, %.o, $(SRC)) 20 | CFLAGS = -Wall -Werror -I${INCDIR} -I${SRCDIR}/ocf/env/ 21 | 22 | all: sync 23 | $(MAKE) build 24 | 25 | build: $(OBJS) 26 | 27 | sync: 28 | @$(MAKE) -C ${OCFDIR} inc O=$(PWD) 29 | @$(MAKE) -C ${OCFDIR} src O=$(PWD) 30 | @$(MAKE) -C ${OCFDIR} env O=$(PWD) OCF_ENV=posix 31 | 32 | clean: 33 | @rm -rf $(OBJS) 34 | 35 | distclean: 36 | @rm -rf $(OBJS) 37 | @rm -rf src/ocf 38 | @rm -rf include/ocf 39 | 40 | .PHONY: all build sync clean distclean 41 | -------------------------------------------------------------------------------- /src/utils/utils_request.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2020 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef UTILS_REQUEST_H_ 7 | #define UTILS_REQUEST_H_ 8 | 9 | #include "utils_request.h" 10 | #include "utils_cache_line.h" 11 | 12 | int ocf_req_actor(struct ocf_request *req, ocf_req_actor_t actor) 13 | { 14 | uint32_t count = req->core_line_count; 15 | uint32_t map_idx = 0; 16 | int result = 0; 17 | 18 | for (map_idx = 0; map_idx < count; map_idx++) { 19 | result = actor(req, map_idx); 20 | if (result) 21 | break; 22 | } 23 | 24 | return result; 25 | } 26 | 27 | static int _set_cleaning_hot_actor(struct ocf_request *req, uint32_t map_idx) 28 | { 29 | ocf_cache_t cache = req->cache; 30 | ocf_cache_line_t line = req->map[map_idx].coll_idx; 31 | 32 | ocf_cleaning_set_hot_cache_line(cache, line); 33 | 34 | return 0; 35 | } 36 | 37 | void ocf_req_set_cleaning_hot(struct ocf_request *req) 38 | { 39 | ocf_req_actor(req, _set_cleaning_hot_actor); 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/engine/engine_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2024 Huawei Technologies 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef ENGINE_IO_H_ 7 | #define ENGINE_IO_H_ 8 | 9 | #include "../ocf_request.h" 10 | 11 | void ocf_engine_forward_cache_io(struct ocf_request *req, int dir, 12 | uint64_t offset, uint64_t size, ocf_req_end_t callback); 13 | 14 | void ocf_engine_forward_cache_io_req(struct ocf_request *req, int dir, 15 | ocf_req_end_t callback); 16 | 17 | void ocf_engine_forward_cache_flush_req(struct ocf_request *req, 18 | ocf_req_end_t callback); 19 | 20 | void ocf_engine_forward_cache_discard_req(struct ocf_request *req, 21 | ocf_req_end_t callback); 22 | 23 | void ocf_engine_forward_core_io_req(struct ocf_request *req, 24 | ocf_req_end_t callback); 25 | 26 | void ocf_engine_forward_core_flush_req(struct ocf_request *req, 27 | ocf_req_end_t callback); 28 | 29 | void ocf_engine_forward_core_discard_req(struct ocf_request *req, 30 | ocf_req_end_t callback); 31 | 32 | #endif /* ENGINE_IO_H_ */ 33 | -------------------------------------------------------------------------------- /tests/functional/pyocf/c/wrappers/ocf_logger_wrappers.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright(c) 2012-2021 Intel Corporation 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "ocf_env.h" 11 | 12 | #define LOG_BUFFER_SIZE 4096 13 | 14 | struct pyocf_logger_priv { 15 | int (*pyocf_log)(void *pyocf_logger, ocf_logger_lvl_t lvl, char *msg); 16 | }; 17 | 18 | int pyocf_printf_helper(ocf_logger_t logger, ocf_logger_lvl_t lvl, 19 | const char *fmt, va_list args) 20 | { 21 | char *buffer = env_zalloc(LOG_BUFFER_SIZE, ENV_MEM_NORMAL); 22 | struct pyocf_logger_priv *priv = ocf_logger_get_priv(logger); 23 | int ret; 24 | 25 | if (!buffer) { 26 | ret = -ENOMEM; 27 | goto out; 28 | } 29 | 30 | ret = vsnprintf(buffer, LOG_BUFFER_SIZE, fmt, args); 31 | if (ret < 0) { 32 | env_free(buffer); 33 | goto out; 34 | } 35 | 36 | ret = priv->pyocf_log(logger, lvl, buffer); 37 | 38 | env_free(buffer); 39 | 40 | out: 41 | return ret; 42 | } 43 | -------------------------------------------------------------------------------- /tests/functional/pyocf/ocf.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2021 Intel Corporation 3 | # Copyright(c) 2024 Huawei Technologies 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | # 6 | from ctypes import c_int, c_void_p, cdll 7 | import inspect 8 | import os 9 | 10 | 11 | class OcfLib: 12 | __lib__ = None 13 | 14 | @classmethod 15 | def getInstance(cls): 16 | if cls.__lib__ is None: 17 | lib = cdll.LoadLibrary( 18 | os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), "libocf.so",) 19 | ) 20 | lib.ocf_volume_get_uuid.restype = c_void_p 21 | lib.ocf_volume_get_uuid.argtypes = [c_void_p] 22 | 23 | lib.ocf_core_get_front_volume.restype = c_void_p 24 | lib.ocf_core_get_front_volume.argtypes = [c_void_p] 25 | 26 | lib.ocf_queue_create_mngt.restype = c_int 27 | lib.ocf_queue_create_mngt.argtypes = [c_void_p, c_void_p, c_void_p] 28 | 29 | cls.__lib__ = lib 30 | 31 | return cls.__lib__ 32 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/ioclass.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2021 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | from ctypes import c_uint8, c_uint32, c_int, c_int16, c_uint16, c_char, c_char_p, Structure 7 | 8 | 9 | class IoClassInfo(Structure): 10 | MAX_IO_CLASS_NAME_SIZE = 1024 11 | _fields_ = [ 12 | ("_name", c_char * MAX_IO_CLASS_NAME_SIZE), 13 | ("_cache_mode", c_int), 14 | ("_priority", c_int16), 15 | ("_curr_size", c_uint32), 16 | ("_min_size", c_uint32), 17 | ("_max_size", c_uint32), 18 | ("_cleaning_policy_type", c_int), 19 | ] 20 | 21 | 22 | class IoClassConfig(Structure): 23 | _fields_ = [ 24 | ("_class_id", c_uint32), 25 | ("_max_size", c_uint32), 26 | ("_name", c_char_p), 27 | ("_cache_mode", c_int), 28 | ("_priority", c_uint16), 29 | ] 30 | 31 | 32 | class IoClassesInfo(Structure): 33 | MAX_IO_CLASSES = 33 34 | _fields_ = [("_config", IoClassConfig * MAX_IO_CLASSES)] 35 | -------------------------------------------------------------------------------- /inc/ocf_logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __OCF_LOGGER_H__ 7 | #define __OCF_LOGGER_H__ 8 | 9 | /** 10 | * @file 11 | * @brief Logger API 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | /** 18 | * @brief Verbosity levels of context log 19 | */ 20 | typedef enum { 21 | log_emerg, 22 | log_alert, 23 | log_crit, 24 | log_err, 25 | log_warn, 26 | log_notice, 27 | log_info, 28 | log_debug, 29 | } ocf_logger_lvl_t; 30 | 31 | struct ocf_logger_ops { 32 | int (*open)(ocf_logger_t logger); 33 | void (*close)(ocf_logger_t logger); 34 | int (*print)(ocf_logger_t logger, ocf_logger_lvl_t lvl, 35 | const char *fmt, va_list args); 36 | int (*print_rl)(ocf_logger_t logger, const char *func_name); 37 | int (*dump_stack)(ocf_logger_t logger); 38 | }; 39 | 40 | void ocf_logger_set_priv(ocf_logger_t logger, void *priv); 41 | 42 | void *ocf_logger_get_priv(ocf_logger_t logger); 43 | 44 | #endif /* __OCF_LOGGER_H__ */ 45 | -------------------------------------------------------------------------------- /src/ocf_space.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __LAYER_EVICTION_POLICY_H__ 7 | #define __LAYER_EVICTION_POLICY_H__ 8 | 9 | #include "ocf/ocf.h" 10 | #include "ocf_lru.h" 11 | #include "ocf_lru_structs.h" 12 | 13 | #define OCF_NUM_LRU_LISTS 32 14 | 15 | struct ocf_part; 16 | struct ocf_user_part; 17 | struct ocf_part_runtime; 18 | struct ocf_part_cleaning_ctx; 19 | struct ocf_request; 20 | 21 | /* 22 | * Deallocates space according to eviction priorities. 23 | * 24 | * @returns: 25 | * 'LOOKUP_HIT' if evicted enough cachelines to serve @req 26 | * 'LOOKUP_MISS' otherwise 27 | */ 28 | int ocf_space_managment_remap_do(struct ocf_request *req); 29 | 30 | typedef void (*ocf_metadata_actor_t)(struct ocf_cache *cache, 31 | ocf_cache_line_t cache_line); 32 | 33 | int ocf_metadata_actor(struct ocf_cache *cache, 34 | ocf_part_id_t part_id, ocf_core_id_t core_id, 35 | uint64_t start_byte, uint64_t end_byte, 36 | ocf_metadata_actor_t actor); 37 | #endif 38 | -------------------------------------------------------------------------------- /src/cleaning/alru_structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2022 David Lee 4 | * Copyright(c) 2025 Huawei Technologies 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #ifndef __CLEANING_ALRU_STRUCTS_H__ 8 | #define __CLEANING_ALRU_STRUCTS_H__ 9 | 10 | #include "ocf/ocf.h" 11 | #include "ocf_env.h" 12 | 13 | struct alru_cleaning_policy_meta { 14 | /* Lru pointers 2*4=8 bytes */ 15 | uint32_t timestamp; 16 | uint32_t lru_prev; 17 | uint32_t lru_next; 18 | } __attribute__((packed)); 19 | 20 | struct alru_cleaning_policy_config { 21 | uint32_t thread_wakeup_time; /* in seconds */ 22 | uint32_t stale_buffer_time; /* in seconds */ 23 | uint32_t flush_max_buffers; /* in lines */ 24 | uint32_t activity_threshold; /* in milliseconds */ 25 | uint32_t dirty_ratio_threshold; /* percent */ 26 | uint32_t dirty_ratio_inertia; /* bytes */ 27 | }; 28 | 29 | struct alru_cleaning_policy { 30 | env_atomic size; 31 | uint32_t lru_head; 32 | uint32_t lru_tail; 33 | }; 34 | 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/volume_core.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2022 Intel Corporation 3 | # Copyright(c) 2024 Huawei Technologies 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | # 6 | 7 | from .volume_exp_obj import OcfInternalVolume 8 | from .queue import Queue 9 | from .io import Sync, IoDir 10 | from .data import Data 11 | 12 | 13 | class CoreVolume(OcfInternalVolume): 14 | def __init__(self, core, uuid=None): 15 | super().__init__(core, uuid) 16 | self.core = core 17 | self.lib = core.cache.owner.lib 18 | 19 | def get_c_handle(self): 20 | return self.core.get_c_front_volume() 21 | 22 | def md5(self): 23 | return self._exp_obj_md5(4096) 24 | 25 | def sync_io( 26 | self, 27 | queue: Queue, 28 | address: int, 29 | data: Data, 30 | direction: IoDir, 31 | io_class=0, 32 | flags=0, 33 | submit_func=Sync.submit, 34 | ): 35 | super().sync_io(queue, address, data, direction, io_class, flags, submit_func) 36 | self.core.cache.settle() 37 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/cleaner.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2021 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | from ctypes import c_void_p, CFUNCTYPE, Structure, c_int 7 | from .shared import SharedOcfObject 8 | 9 | 10 | class CleanerOps(Structure): 11 | INIT = CFUNCTYPE(c_int, c_void_p) 12 | KICK = CFUNCTYPE(None, c_void_p) 13 | STOP = CFUNCTYPE(None, c_void_p) 14 | 15 | _fields_ = [("init", INIT), ("kick", KICK), ("stop", STOP)] 16 | 17 | 18 | class Cleaner(SharedOcfObject): 19 | _instances_ = {} 20 | _fields_ = [("cleaner", c_void_p)] 21 | 22 | def __init__(self): 23 | self._as_parameter_ = self.cleaner 24 | super().__init__() 25 | 26 | @classmethod 27 | def get_ops(cls): 28 | return CleanerOps(init=cls._init, kick=cls._kick, stop=cls._stop) 29 | 30 | @staticmethod 31 | @CleanerOps.INIT 32 | def _init(cleaner): 33 | return 0 34 | 35 | @staticmethod 36 | @CleanerOps.KICK 37 | def _kick(cleaner): 38 | pass 39 | 40 | @staticmethod 41 | @CleanerOps.STOP 42 | def _stop(cleaner): 43 | pass 44 | -------------------------------------------------------------------------------- /src/utils/utils_parallelize.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2022 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __UTILS_PARALLELIZE_H__ 8 | #define __UTILS_PARALLELIZE_H__ 9 | 10 | #include "ocf/ocf.h" 11 | 12 | typedef struct ocf_parallelize *ocf_parallelize_t; 13 | 14 | typedef int (*ocf_parallelize_handle_t)(ocf_parallelize_t parallelize, 15 | void *priv, unsigned shard_id, unsigned shards_cnt); 16 | 17 | typedef void (*ocf_parallelize_finish_t)(ocf_parallelize_t parallelize, 18 | void *priv, int error); 19 | 20 | int ocf_parallelize_create(ocf_parallelize_t *parallelize, 21 | ocf_cache_t cache, unsigned shards_cnt, uint32_t priv_size, 22 | ocf_parallelize_handle_t handle, 23 | ocf_parallelize_finish_t finish, 24 | bool use_mngt_queue); 25 | 26 | void ocf_parallelize_destroy(ocf_parallelize_t parallelize); 27 | 28 | void ocf_parallelize_set_priv(ocf_parallelize_t parallelize, void *priv); 29 | 30 | void *ocf_parallelize_get_priv(ocf_parallelize_t parallelize); 31 | 32 | void ocf_parallelize_run(ocf_parallelize_t parallelize); 33 | 34 | #endif /* __UTILS_PARALLELIZE_H__ */ 35 | -------------------------------------------------------------------------------- /src/metadata/metadata_partition.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf.h" 7 | #include "metadata.h" 8 | #include "metadata_internal.h" 9 | #include "../utils/utils_user_part.h" 10 | 11 | ocf_part_id_t ocf_metadata_get_partition_id(struct ocf_cache *cache, 12 | ocf_cache_line_t line) 13 | { 14 | const struct ocf_metadata_list_info *info; 15 | struct ocf_metadata_ctrl *ctrl = 16 | (struct ocf_metadata_ctrl *) cache->metadata.priv; 17 | 18 | info = ocf_metadata_raw_rd_access(cache, 19 | &(ctrl->raw_desc[metadata_segment_list_info]), line); 20 | 21 | ENV_BUG_ON(!info); 22 | 23 | return info->partition_id; 24 | } 25 | 26 | void ocf_metadata_set_partition_id(struct ocf_cache *cache, 27 | ocf_cache_line_t line, ocf_part_id_t part_id) 28 | { 29 | struct ocf_metadata_list_info *info; 30 | struct ocf_metadata_ctrl *ctrl = 31 | (struct ocf_metadata_ctrl *) cache->metadata.priv; 32 | 33 | info = ocf_metadata_raw_wr_access(cache, 34 | &(ctrl->raw_desc[metadata_segment_list_info]), line); 35 | 36 | if (info) 37 | info->partition_id = part_id; 38 | else 39 | ocf_metadata_error(cache); 40 | } 41 | -------------------------------------------------------------------------------- /tests/unit/tests/add_new_test_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # 4 | # Copyright(c) 2012-2021 Intel Corporation 5 | # SPDX-License-Identifier: BSD-3-Clause 6 | # 7 | 8 | import subprocess 9 | import sys 10 | import os 11 | 12 | 13 | args = ' '.join(sys.argv[1:]) 14 | script_path = os.path.dirname(os.path.realpath(__file__)) 15 | framework_script_path = os.path.join(script_path, "../framework/add_new_test_file.py") 16 | framework_script_path = os.path.normpath(framework_script_path) 17 | result = subprocess.run(framework_script_path + " " + args, shell=True, 18 | stdout=subprocess.PIPE, stderr=subprocess.PIPE) 19 | status = result.returncode 20 | output = result.stdout.decode("ASCII", errors='ignore') 21 | 22 | print(output) 23 | 24 | if status == 0: 25 | path = output.split(" ", 1)[0] 26 | with open(script_path + os.sep + "header.c", "r") as header_file: 27 | with open(path, "r+") as source_file: 28 | source = source_file.readlines() 29 | 30 | source_file.seek(0, os.SEEK_SET) 31 | source_file.truncate() 32 | 33 | source_file.writelines(header_file.readlines()) 34 | source_file.writelines(source) 35 | -------------------------------------------------------------------------------- /src/utils/utils_stats.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef UTILS_STATS_H_ 7 | #define UTILS_STATS_H_ 8 | 9 | #define _ocf_stats_zero(stats) \ 10 | do { \ 11 | if (stats) { \ 12 | typeof(*stats) zero = { { 0 } }; \ 13 | *stats = zero; \ 14 | } \ 15 | } while (0) 16 | 17 | static inline uint64_t _fraction(uint64_t numerator, uint64_t denominator) 18 | { 19 | uint64_t result; 20 | if (denominator) { 21 | result = 10000 * numerator / denominator; 22 | } else { 23 | result = 0; 24 | } 25 | return result; 26 | } 27 | 28 | static inline uint64_t _lines4k(uint64_t size, 29 | ocf_cache_line_size_t cache_line_size) 30 | { 31 | long unsigned int result; 32 | 33 | result = size * (cache_line_size / 4096); 34 | 35 | return result; 36 | } 37 | 38 | static inline uint64_t _bytes4k(uint64_t bytes) 39 | { 40 | return (bytes + 4095UL) >> 12; 41 | } 42 | 43 | static inline void _set(struct ocf_stat *stat, uint64_t value, 44 | uint64_t denominator) 45 | { 46 | stat->value = value; 47 | stat->fraction = _fraction(value, denominator); 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | ## Description 10 | 11 | 12 | ## Expected Behavior 13 | 14 | 15 | ## Actual Behavior 16 | 17 | 18 | ## Steps to Reproduce 19 | 20 | 1. 21 | 2. 22 | 3. 23 | 4. 24 | 25 | ## Context 26 | 27 | 28 | ## Possible Fix 29 | 30 | 31 | ## Logs 32 | 33 | 34 | ## Your Environment 35 | 36 | * OCF version (commit hash or tag): 37 | * Operating System: 38 | * Kernel version: 39 | * Cache device type (NAND/Optane/other): 40 | * Core device type (HDD/SSD/other): 41 | * Configuration: 42 | * * Cache mode: (default: wt) 43 | * * Cache line size: (default: 4) 44 | * Other (e.g. _lsblk_, _lsscsi_) 45 | -------------------------------------------------------------------------------- /src/metadata/metadata_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2020-2021 Intel Corporation 3 | * Copyright(c) 2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __METADATA_INTERNAL_H__ 8 | #define __METADATA_INTERNAL_H__ 9 | 10 | #include 11 | #include "../ocf_cache_priv.h" 12 | #include "metadata_segment.h" 13 | #include "metadata_segment_id.h" 14 | #include "metadata_raw.h" 15 | 16 | #define METADATA_MEM_POOL(ctrl, section) ctrl->raw_desc[section].mem_pool 17 | 18 | /* 19 | * Metadata control structure 20 | */ 21 | struct ocf_metadata_ctrl { 22 | ocf_cache_line_t cachelines; 23 | ocf_cache_line_t start_page; 24 | uint32_t count_pages_fixed; 25 | uint32_t count_pages_variable; 26 | uint32_t device_lines; 27 | size_t mapping_size; 28 | struct ocf_metadata_raw raw_desc[metadata_segment_max]; 29 | struct ocf_metadata_segment *segment[metadata_segment_max]; 30 | }; 31 | 32 | struct ocf_metadata_context { 33 | ocf_metadata_end_t cmpl; 34 | void *priv; 35 | ocf_pipeline_t pipeline; 36 | ocf_cache_t cache; 37 | struct ocf_metadata_ctrl *ctrl; 38 | struct ocf_metadata_raw segment_copy[metadata_segment_fixed_size_max]; 39 | }; 40 | 41 | extern const char * const ocf_metadata_segment_names[]; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/stats/cache.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2021 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | from ctypes import c_uint8, c_uint32, c_uint64, c_bool, c_int, Structure 7 | from pyocf.types.stats.shared import _Stat 8 | 9 | 10 | class _Inactive(Structure): 11 | _fields_ = [("occupancy", _Stat), ("clean", _Stat), ("dirty", _Stat)] 12 | 13 | 14 | class _FallbackPt(Structure): 15 | _fields_ = [("error_counter", c_int), ("status", c_bool)] 16 | 17 | 18 | class CacheInfo(Structure): 19 | _fields_ = [ 20 | ("attached", c_bool), 21 | ("volume_type", c_uint8), 22 | ("state", c_uint8), 23 | ("size", c_uint32), 24 | ("inactive", _Inactive), 25 | ("occupancy", c_uint32), 26 | ("dirty", c_uint32), 27 | ("dirty_for", c_uint64), 28 | ("dirty_initial", c_uint32), 29 | ("cache_mode", c_uint32), 30 | ("fallback_pt", _FallbackPt), 31 | ("cleaning_policy", c_uint32), 32 | ("promotion_policy", c_uint32), 33 | ("cache_line_size", c_uint64), 34 | ("flushed", c_uint32), 35 | ("core_count", c_uint32), 36 | ("metadata_footprint", c_uint64), 37 | ("metadata_end_offset", c_uint32), 38 | ] 39 | -------------------------------------------------------------------------------- /src/metadata/metadata_misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_MISC_H__ 7 | #define __METADATA_MISC_H__ 8 | 9 | /* Hash function intentionally returns consecutive (modulo @hash_table_entries) 10 | * values for consecutive @core_line_num. This way it is trivial to sort all 11 | * core lines within a single request in ascending hash value order. This kind 12 | * of sorting is required to assure that (future) hash bucket metadata locks are 13 | * always acquired in fixed order, eliminating the risk of dead locks. 14 | */ 15 | static inline ocf_cache_line_t ocf_metadata_hash_func(ocf_cache_t cache, 16 | uint64_t core_line_num, ocf_core_id_t core_id) 17 | { 18 | const unsigned int entries = cache->device->hash_table_entries; 19 | 20 | return (ocf_cache_line_t) ((core_line_num + (core_id * (entries / 32))) 21 | % entries); 22 | } 23 | 24 | void ocf_metadata_remove_cache_line(struct ocf_cache *cache, 25 | ocf_cache_line_t cache_line); 26 | 27 | void ocf_metadata_sparse_cache_line(struct ocf_cache *cache, 28 | ocf_cache_line_t cache_line); 29 | 30 | int ocf_metadata_sparse_range(struct ocf_cache *cache, int core_id, 31 | uint64_t start_byte, uint64_t end_byte); 32 | 33 | #endif /* __METADATA_MISC_H__ */ 34 | -------------------------------------------------------------------------------- /inc/cleaning/acp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | #ifndef __OCF_CLEANING_ACP_H__ 6 | #define __OCF_CLEANING_ACP_H__ 7 | 8 | /** 9 | * @file 10 | * @brief ACP cleaning policy API 11 | */ 12 | 13 | enum ocf_cleaning_acp_parameters { 14 | ocf_acp_wake_up_time, 15 | ocf_acp_flush_max_buffers, 16 | }; 17 | 18 | /** 19 | * @name ACP cleaning policy parameters 20 | * @{ 21 | */ 22 | 23 | /** 24 | * ACP cleaning policy time between flushing cycles (in ms) 25 | */ 26 | 27 | /**< Wake up time minimum value */ 28 | #define OCF_ACP_MIN_WAKE_UP 0 29 | /**< Wake up time maximum value */ 30 | #define OCF_ACP_MAX_WAKE_UP 10000 31 | /**< Wake up time default value */ 32 | #define OCF_ACP_DEFAULT_WAKE_UP 10 33 | 34 | /** 35 | * ACP cleaning thread number of dirty cache lines to be flushed in one cycle 36 | */ 37 | 38 | /** Dirty cache lines to be flushed in one cycle minimum value */ 39 | #define OCF_ACP_MIN_FLUSH_MAX_BUFFERS 1 40 | /** Dirty cache lines to be flushed in one cycle maximum value */ 41 | #define OCF_ACP_MAX_FLUSH_MAX_BUFFERS 10000 42 | /** Dirty cache lines to be flushed in one cycle default value */ 43 | #define OCF_ACP_DEFAULT_FLUSH_MAX_BUFFERS 128 44 | 45 | /** 46 | * @} 47 | */ 48 | 49 | #endif /* __OCF_CLEANING_ACP_H__ */ 50 | -------------------------------------------------------------------------------- /.github/workflows/pullrequest.yml: -------------------------------------------------------------------------------- 1 | name: Licence-date-verification 2 | permissions: 3 | contents: read 4 | pull-requests: read 5 | on: 6 | pull_request: 7 | branches: 8 | - master 9 | - v* 10 | 11 | env: 12 | EXTENSIONS: "c h cpp py go sh mk spec service" 13 | FILES: "*Makefile" 14 | jobs: 15 | verify-date: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | fetch-depth: 0 21 | - name: Get changed files 22 | id: changed-files 23 | uses: tj-actions/changed-files@v47.0.0 24 | with: 25 | files_ignore: '.github/**' 26 | - name: List all changed files 27 | run: | 28 | files_to_check=(${{ steps.changed-files.outputs.added_files }}) 29 | files_to_check+=(${{ steps.changed-files.outputs.modified_files }}) 30 | 31 | for file in ${files_to_check[@]}; do 32 | for file_in_list in $FILES; do 33 | if [[ "$file" == $file_in_list ]]; then 34 | .github/verify_header.sh "$file" 35 | continue 2 36 | fi 37 | done 38 | 39 | extension=${file##*.} 40 | if [[ "$EXTENSIONS" =~ $extension ]]; then 41 | .github/verify_header.sh "$file" 42 | fi 43 | done 44 | -------------------------------------------------------------------------------- /src/engine/cache_engine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __CACHE_ENGINE_H_ 8 | #define __CACHE_ENGINE_H_ 9 | 10 | #include "../ocf_request.h" 11 | 12 | struct ocf_thread_priv; 13 | 14 | #define LOOKUP_HIT 5 15 | #define LOOKUP_MISS 6 16 | #define LOOKUP_REMAPPED 8 17 | 18 | static inline ocf_req_cache_mode_t ocf_cache_mode_to_req_cache_mode( 19 | ocf_cache_mode_t mode) 20 | { 21 | return (ocf_req_cache_mode_t)mode; 22 | } 23 | 24 | struct ocf_io_if { 25 | ocf_req_cb cbs[2]; /* READ and WRITE */ 26 | 27 | const char *name; 28 | }; 29 | 30 | void ocf_resolve_effective_cache_mode(ocf_cache_t cache, 31 | ocf_core_t core, struct ocf_request *req); 32 | 33 | const char *ocf_get_io_iface_name(ocf_req_cache_mode_t cache_mode); 34 | 35 | bool ocf_req_cache_mode_has_lazy_write(ocf_req_cache_mode_t mode); 36 | 37 | bool ocf_fallback_pt_is_on(ocf_cache_t cache); 38 | 39 | int ocf_engine_hndl_req(struct ocf_request *req); 40 | 41 | #define OCF_FAST_PATH_YES 7 42 | #define OCF_FAST_PATH_NO 13 43 | 44 | int ocf_engine_hndl_fast_req(struct ocf_request *req); 45 | 46 | void ocf_engine_hndl_flush_req(struct ocf_request *req); 47 | 48 | void ocf_engine_hndl_discard_req(struct ocf_request *req); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/utils/utils_rbtree.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2020-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __UTILS_RBTREE_H__ 7 | #define __UTILS_RBTREE_H__ 8 | 9 | #include "../ocf_priv.h" 10 | 11 | struct ocf_rb_node { 12 | bool red; 13 | struct ocf_rb_node *left; 14 | struct ocf_rb_node *right; 15 | struct ocf_rb_node *parent; 16 | struct list_head list; 17 | }; 18 | 19 | typedef int (*ocf_rb_tree_node_cmp_cb)(struct ocf_rb_node *n1, 20 | struct ocf_rb_node *n2); 21 | 22 | typedef struct ocf_rb_node *(*ocf_rb_tree_list_find_cb)( 23 | struct list_head *node_list); 24 | 25 | struct ocf_rb_tree { 26 | struct ocf_rb_node *root; 27 | ocf_rb_tree_node_cmp_cb cmp; 28 | ocf_rb_tree_list_find_cb find; 29 | }; 30 | 31 | void ocf_rb_tree_init(struct ocf_rb_tree *tree, ocf_rb_tree_node_cmp_cb cmp, 32 | ocf_rb_tree_list_find_cb find); 33 | 34 | void ocf_rb_tree_insert(struct ocf_rb_tree *tree, struct ocf_rb_node *node); 35 | 36 | void ocf_rb_tree_remove(struct ocf_rb_tree *tree, struct ocf_rb_node *node); 37 | 38 | bool ocf_rb_tree_can_update(struct ocf_rb_tree *tree, 39 | struct ocf_rb_node *node, struct ocf_rb_node *new_node); 40 | 41 | struct ocf_rb_node *ocf_rb_tree_find(struct ocf_rb_tree *tree, 42 | struct ocf_rb_node *node); 43 | 44 | #endif /* __UTILS_RBTREE_H__ */ 45 | -------------------------------------------------------------------------------- /src/engine/engine_wa.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #include "ocf/ocf.h" 7 | #include "../ocf_cache_priv.h" 8 | #include "engine_wa.h" 9 | #include "engine_wt.h" 10 | #include "engine_wi.h" 11 | #include "engine_common.h" 12 | #include "engine_io.h" 13 | #include "cache_engine.h" 14 | #include "../ocf_request.h" 15 | #include "../metadata/metadata.h" 16 | 17 | #define OCF_ENGINE_DEBUG_IO_NAME "wa" 18 | #include "engine_debug.h" 19 | 20 | int ocf_write_wa(struct ocf_request *req) 21 | { 22 | 23 | /* Get OCF request - increase reference counter */ 24 | ocf_req_get(req); 25 | 26 | ocf_req_hash(req); 27 | 28 | ocf_hb_req_prot_lock_rd(req); /*- Metadata RD access -----------------------*/ 29 | 30 | /* Traverse request to check if there are mapped cache lines */ 31 | ocf_engine_traverse(req); 32 | 33 | ocf_hb_req_prot_unlock_rd(req); /*- END Metadata RD access -----------------*/ 34 | 35 | if (ocf_engine_is_hit(req)) { 36 | ocf_req_clear(req); 37 | 38 | /* There is HIT, do WT */ 39 | ocf_write_wt(req); 40 | 41 | } else { 42 | ocf_req_clear(req); 43 | 44 | /* MISS, do WI */ 45 | ocf_write_wi(req); 46 | } 47 | 48 | /* Put OCF request - decrease reference counter */ 49 | ocf_req_put(req); 50 | 51 | return 0; 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/mngt/ocf_mngt_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | 8 | #ifndef __OCF_MNGT_COMMON_H__ 9 | #define __OCF_MNGT_COMMON_H__ 10 | 11 | #include "ocf_env_refcnt.h" 12 | #include "../utils/utils_pipeline.h" 13 | 14 | void cache_mngt_core_deinit(ocf_core_t core); 15 | 16 | void cache_mngt_core_remove_from_meta(ocf_core_t core); 17 | 18 | void cache_mngt_core_remove_from_cache(ocf_core_t core); 19 | 20 | void cache_mngt_core_deinit_attached_meta(ocf_core_t core); 21 | 22 | void cache_mngt_core_remove_from_cleaning_pol(ocf_core_t core); 23 | 24 | int _ocf_cleaning_thread(void *priv); 25 | 26 | int cache_mngt_thread_io_requests(void *data); 27 | 28 | int ocf_mngt_add_partition_to_cache(struct ocf_cache *cache, 29 | ocf_part_id_t part_id, const char *name, uint32_t min_size, 30 | uint32_t max_size, uint8_t priority, bool valid); 31 | 32 | int ocf_mngt_cache_lock_init(ocf_cache_t cache); 33 | void ocf_mngt_cache_lock_deinit(ocf_cache_t cache); 34 | 35 | bool ocf_mngt_cache_is_locked(ocf_cache_t cache); 36 | 37 | void __set_cleaning_policy(ocf_cache_t cache, 38 | ocf_cleaning_t new_cleaning_policy); 39 | 40 | void ocf_mngt_continue_pipeline_on_zero_refcnt(struct env_refcnt *refcnt, 41 | ocf_pipeline_t pipeline); 42 | 43 | #endif /* __OCF_MNGT_COMMON_H__ */ 44 | -------------------------------------------------------------------------------- /tests/functional/pyocf/helpers.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2022 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | # 6 | from .ocf import OcfLib 7 | 8 | 9 | def get_metadata_segment_page_location(cache, segment): 10 | lib = OcfLib.getInstance() 11 | return int(lib.ocf_get_metadata_segment_start_page(cache, segment)) 12 | 13 | 14 | def get_metadata_segment_size(cache, segment): 15 | lib = OcfLib.getInstance() 16 | return int(lib.ocf_get_metadata_segment_page_count(cache, segment)) 17 | 18 | 19 | def get_metadata_segment_elems_count(cache, segment): 20 | lib = OcfLib.getInstance() 21 | return int(lib.ocf_get_metadata_segment_elems_count(cache, segment)) 22 | 23 | 24 | def get_metadata_segment_elems_per_page(cache, segment): 25 | lib = OcfLib.getInstance() 26 | return int(lib.ocf_get_metadata_segment_elems_per_page(cache, segment)) 27 | 28 | 29 | def get_metadata_segment_elem_size(cache, segment): 30 | lib = OcfLib.getInstance() 31 | return int(lib.ocf_get_metadata_segment_elem_size(cache, segment)) 32 | 33 | 34 | def get_metadata_segment_is_flapped(cache, segment): 35 | lib = OcfLib.getInstance() 36 | return bool(lib.ocf_get_metadata_segment_is_flapped(cache, segment)) 37 | 38 | 39 | def get_composite_volume_type_id(): 40 | lib = OcfLib.getInstance() 41 | return int(lib.ocf_get_composite_volume_type_id_helper()) 42 | -------------------------------------------------------------------------------- /tests/unit/tests/utils/utils_refcnt.c/utils_refcnt_inc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | /* 7 | * src/utils/utils_refcnt.c 8 | * ocf_refcnt_inc 9 | * 10 | * ocf_refcnt_init 11 | * ocf_refcnt_dec 12 | * 13 | */ 14 | 15 | #undef static 16 | 17 | #undef inline 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "print_desc.h" 25 | 26 | #include "../utils/utils_refcnt.h" 27 | 28 | #include "utils/utils_refcnt.c/utils_refcnt_inc_generated_wraps.c" 29 | 30 | static void ocf_refcnt_inc_test(void **state) 31 | { 32 | struct ocf_refcnt rc; 33 | int val; 34 | 35 | print_test_description("Increment adds 1 and returns proper value"); 36 | 37 | ocf_refcnt_init(&rc); 38 | 39 | val = ocf_refcnt_inc(&rc); 40 | assert_int_equal(1, val); 41 | assert_int_equal(1, env_atomic_read(&rc.counter)); 42 | 43 | val = ocf_refcnt_inc(&rc); 44 | assert_int_equal(2, val); 45 | assert_int_equal(2, env_atomic_read(&rc.counter)); 46 | } 47 | 48 | int main(void) 49 | { 50 | const struct CMUnitTest tests[] = { 51 | cmocka_unit_test(ocf_refcnt_inc_test) 52 | }; 53 | 54 | print_message("Unit test of src/utils/utils_refcnt.c"); 55 | 56 | return cmocka_run_group_tests(tests, NULL, NULL); 57 | } 58 | -------------------------------------------------------------------------------- /src/utils/utils_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef UTILS_IO_H_ 8 | #define UTILS_IO_H_ 9 | 10 | #include "../ocf_request.h" 11 | 12 | typedef void (*ocf_submit_end_t)(void *priv, int error); 13 | 14 | void ocf_submit_cache_flush(ocf_cache_t cache, 15 | ocf_submit_end_t cmpl, void *priv); 16 | 17 | void ocf_submit_cache_discard(ocf_cache_t cache, uint64_t addr, 18 | uint64_t length, ocf_submit_end_t cmpl, void *priv); 19 | 20 | void ocf_submit_cache_write_zeros(ocf_cache_t cache, uint64_t addr, 21 | uint64_t length, ocf_submit_end_t cmpl, void *priv); 22 | 23 | void ocf_submit_cache_page(ocf_cache_t cache, uint64_t addr, int dir, 24 | void *buffer, ocf_submit_end_t cmpl, void *priv); 25 | 26 | static inline ocf_io_t ocf_new_cache_io(ocf_cache_t cache, 27 | ocf_queue_t queue, uint64_t addr, uint32_t bytes, 28 | uint32_t dir, uint32_t io_class, uint64_t flags) 29 | 30 | { 31 | return ocf_volume_new_io(ocf_cache_get_volume(cache), queue, 32 | addr, bytes, dir, io_class, flags); 33 | } 34 | 35 | static inline ocf_io_t ocf_new_core_io(ocf_core_t core, 36 | ocf_queue_t queue, uint64_t addr, uint32_t bytes, 37 | uint32_t dir, uint32_t io_class, uint64_t flags) 38 | { 39 | return ocf_volume_new_io(ocf_core_get_volume(core), queue, 40 | addr, bytes, dir, io_class, flags); 41 | } 42 | 43 | #endif /* UTILS_IO_H_ */ 44 | -------------------------------------------------------------------------------- /.github/verify_header.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Copyright(c) 2022 Intel Corporation 5 | # SPDX-License-Identifier: BSD-3-Clause 6 | # 7 | 8 | # COPYRIGHT_REGEX is lowercase, because the whole line is 9 | # converted to lowercase before test against this regex. 10 | COPYRIGHT_REGEX="(copyright|\(c\))\s*([0-9]{4}(\s*-\s*([0-9]{4}))?)" 11 | LICENSE_REGEX="SPDX-License-Identifier: BSD-3-Clause$" 12 | YEAR=$(date +"%Y") 13 | 14 | unset copyright_header license_header 15 | 16 | # Read lines until proper copyright and license headers are found. 17 | while read -r line && [[ ! "$copyright_header" || ! "$license_header" ]]; do 18 | if [[ "${line,,}" =~ $COPYRIGHT_REGEX ]]; then 19 | # If the fourth regex group (from year range) doesn't exist, 20 | # use the second regex group instead (from a single year). 21 | copyright_year=${BASH_REMATCH[4]:-${BASH_REMATCH[2]}} 22 | 23 | if [[ $copyright_year == $YEAR ]]; then 24 | copyright_header="correct_copyright_header_found" 25 | fi 26 | elif [[ "$line" =~ $LICENSE_REGEX ]]; then 27 | license_header="correct_license_header_found" 28 | fi 29 | done < "$1" 30 | 31 | # Proper copyright and license info were found - all good. 32 | [[ "$copyright_header" && "$license_header" ]] && exit 0 33 | 34 | [[ ! "$copyright_header" ]] && echo >&2 "error: file '$1' does not contain any appropriate copyright info" 35 | [[ ! "$license_header" ]] && echo >&2 "error: file '$1' does not contain appropriate license identifier" 36 | exit 1 37 | -------------------------------------------------------------------------------- /src/ocf_seq_cutoff.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2020-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __OCF_SEQ_CUTOFF_H__ 7 | #define __OCF_SEQ_CUTOFF_H__ 8 | 9 | #include "ocf/ocf.h" 10 | #include "ocf_request.h" 11 | #include "utils/utils_rbtree.h" 12 | 13 | struct ocf_seq_cutoff_stream { 14 | uint64_t last; 15 | uint64_t bytes; 16 | uint32_t rw : 1; 17 | uint32_t valid : 1; 18 | uint32_t req_count : 16; 19 | struct ocf_rb_node node; 20 | struct list_head list; 21 | }; 22 | 23 | struct ocf_seq_cutoff { 24 | ocf_core_t core; 25 | env_rwlock lock; 26 | struct ocf_rb_tree tree; 27 | struct list_head lru; 28 | struct ocf_seq_cutoff_stream streams[]; 29 | }; 30 | 31 | struct ocf_seq_cutoff_percore { 32 | struct ocf_seq_cutoff base; 33 | struct ocf_seq_cutoff_stream streams[OCF_SEQ_CUTOFF_PERCORE_STREAMS]; 34 | }; 35 | 36 | struct ocf_seq_cutoff_perqueue { 37 | struct ocf_seq_cutoff base; 38 | struct ocf_seq_cutoff_stream streams[OCF_SEQ_CUTOFF_PERQUEUE_STREAMS]; 39 | }; 40 | 41 | int ocf_core_seq_cutoff_init(ocf_core_t core); 42 | 43 | void ocf_core_seq_cutoff_deinit(ocf_core_t core); 44 | 45 | int ocf_queue_seq_cutoff_init(ocf_queue_t queue); 46 | 47 | void ocf_queue_seq_cutoff_deinit(ocf_queue_t queue); 48 | 49 | bool ocf_core_seq_cutoff_check(ocf_core_t core, struct ocf_request *req); 50 | 51 | void ocf_core_seq_cutoff_update(ocf_core_t core, struct ocf_request *req); 52 | 53 | #endif /* __OCF_SEQ_CUTOFF_H__ */ 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright(c) 2019-2021 Intel Corporation 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /src/metadata/metadata_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf.h" 7 | #include "metadata.h" 8 | #include "../utils/utils_cache_line.h" 9 | 10 | /* the caller must hold the relevant cache block concurrency reader lock 11 | * and the metadata lock 12 | */ 13 | void ocf_metadata_remove_cache_line(struct ocf_cache *cache, 14 | ocf_cache_line_t cache_line) 15 | { 16 | ocf_part_id_t partition_id = 17 | ocf_metadata_get_partition_id(cache, cache_line); 18 | 19 | ocf_metadata_remove_from_collision(cache, cache_line, partition_id); 20 | } 21 | 22 | void ocf_metadata_sparse_cache_line(struct ocf_cache *cache, 23 | ocf_cache_line_t cache_line) 24 | { 25 | ocf_metadata_start_collision_shared_access(cache, cache_line); 26 | 27 | set_cache_line_invalid_no_flush(cache, 0, ocf_line_end_sector(cache), 28 | cache_line); 29 | 30 | /* 31 | * This is especially for removing inactive core 32 | */ 33 | metadata_clear_dirty(cache, cache_line); 34 | 35 | ocf_metadata_end_collision_shared_access(cache, cache_line); 36 | } 37 | 38 | /* caller must hold metadata lock 39 | * set core_id to -1 to clean the whole cache device 40 | */ 41 | int ocf_metadata_sparse_range(struct ocf_cache *cache, int core_id, 42 | uint64_t start_byte, uint64_t end_byte) 43 | { 44 | return ocf_metadata_actor(cache, PARTITION_UNSPECIFIED, core_id, 45 | start_byte, end_byte, ocf_metadata_sparse_cache_line); 46 | } 47 | -------------------------------------------------------------------------------- /tests/functional/run_with_sanitizers.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Copyright(c) 2019-2022 Intel Corporation 5 | # Copyright(c) 2025 Huawei Technologies 6 | # SPDX-License-Identifier: BSD-3-Clause 7 | # 8 | 9 | LIB_DIR="/lib/x86_64-linux-gnu/" 10 | 11 | ASAN_LIB="$LIB_DIR/libasan.so.6" 12 | TSAN_LIB="$LIB_DIR/libtsan.so.0" 13 | UBSAN_LIB="$LIB_DIR/libubsan.so.1" 14 | 15 | # Path to test file/directory 16 | PYOCF_TESTS_PATH="tests/" 17 | 18 | echo "Cleaning and building with Address Sanitizer" 19 | make distclean 20 | OPT_CFLAGS="-fsanitize=address" make -j >/dev/null 21 | echo "Running tests, please wait..." 22 | LD_PRELOAD=$ASAN_LIB ASAN_OPTIONS=log_output=asan_log.txt PYTHONMALLOC=malloc pytest $PYOCF_TESTS_PATH 2>&1 | tee asan_output.txt 23 | echo "Done, check asan_log.txt" 24 | 25 | echo "Cleaning and building with Thread Sanitizer" 26 | make distclean 27 | OPT_CFLAGS="-fsanitize=thread -fno-omit-frame-pointer" make -j >/dev/null 28 | echo "Running tests, please wait..." 29 | LD_PRELOAD=$TSAN_LIB TSAN_OPTIONS=log_output=tsan_log.txt pytest -s $PYOCF_TESTS_PATH 2>&1 | tee tsan_output.txt 30 | echo "Done, check tsan_log.txt" 31 | 32 | echo "Cleaning and building with Undefined Behaviour Sanitizer" 33 | make distclean 34 | OPT_CFLAGS="-fsanitize=undefined -fno-sanitize=alignment" make -j >/dev/null 35 | echo "Running tests, please wait..." 36 | LD_PRELOAD=$UBSAN_LIB UBSAN_OPTIONS=log_output=ubsan_log.txt pytest -s $PYOCF_TESTS_PATH 2>&1 | tee ubsan_output.txt 37 | echo "Done, check ubsan_output.txt" 38 | -------------------------------------------------------------------------------- /tests/unit/tests/utils/utils_refcnt.c/utils_refcnt_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | /* 7 | * src/utils/utils_refcnt.c 8 | * ocf_refcnt_init 9 | * 10 | * INSERT HERE LIST OF FUNCTIONS YOU WANT TO LEAVE 11 | * ONE FUNCTION PER LINE 12 | * 13 | */ 14 | 15 | #undef static 16 | 17 | #undef inline 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "print_desc.h" 25 | 26 | #include "../utils/utils_refcnt.h" 27 | 28 | #include "utils/utils_refcnt.c/utils_refcnt_init_generated_wraps.c" 29 | 30 | static void ocf_refcnt_init_test(void **state) 31 | { 32 | struct ocf_refcnt rc; 33 | 34 | print_test_description("Reference counter is properly initialized"); 35 | 36 | env_atomic_set(&rc.counter, 1); 37 | env_atomic_set(&rc.freeze, 1); 38 | env_atomic_set(&rc.callback, 1); 39 | 40 | ocf_refcnt_init(&rc); 41 | 42 | assert_int_equal(0, env_atomic_read(&rc.counter)); 43 | assert_int_equal(0, env_atomic_read(&rc.freeze)); 44 | assert_int_equal(0, env_atomic_read(&rc.cb)); 45 | } 46 | 47 | int main(void) 48 | { 49 | const struct CMUnitTest tests[] = { 50 | cmocka_unit_test(ocf_refcnt_init_test) 51 | }; 52 | 53 | print_message("Unit test of src/utils/utils_refcnt.c"); 54 | 55 | return cmocka_run_group_tests(tests, NULL, NULL); 56 | } 57 | -------------------------------------------------------------------------------- /src/engine/engine_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef ENGINE_DEBUG_H_ 8 | #define ENGINE_DEBUG_H_ 9 | 10 | #ifndef OCF_ENGINE_DEBUG 11 | #define OCF_ENGINE_DEBUG 0 12 | #endif 13 | 14 | #if 1 == OCF_ENGINE_DEBUG 15 | 16 | #ifndef OCF_ENGINE_DEBUG_IO_NAME 17 | #define OCF_ENGINE_DEBUG_IO_NAME "null" 18 | #endif 19 | 20 | #define OCF_DEBUG_PREFIX "[Engine][%s] %s " 21 | 22 | #define OCF_DEBUG_LOG(cache, format, ...) \ 23 | ocf_cache_log_prefix(cache, log_info, OCF_DEBUG_PREFIX, \ 24 | format"\n", OCF_ENGINE_DEBUG_IO_NAME, __func__, \ 25 | ##__VA_ARGS__) 26 | 27 | #define OCF_DEBUG_TRACE(cache) OCF_DEBUG_LOG(cache, "") 28 | 29 | #define OCF_DEBUG_MSG(cache, msg) OCF_DEBUG_LOG(cache, "- %s", msg) 30 | 31 | #define OCF_DEBUG_PARAM(cache, format, ...) OCF_DEBUG_LOG(cache, "- "format, \ 32 | ##__VA_ARGS__) 33 | 34 | #define OCF_DEBUG_RQ(req, format, ...) \ 35 | ocf_cache_log(req->cache, log_info, "[Engine][%s][%s, %llu, %u] %s - " \ 36 | format"\n", OCF_ENGINE_DEBUG_IO_NAME, \ 37 | OCF_READ == (req)->rw ? "RD" : "WR", req->addr, \ 38 | req->bytes, __func__, ##__VA_ARGS__) 39 | 40 | #else 41 | #define OCF_DEBUG_PREFIX 42 | #define OCF_DEBUG_LOG(cache, format, ...) 43 | #define OCF_DEBUG_TRACE(cache) 44 | #define OCF_DEBUG_MSG(cache, msg) 45 | #define OCF_DEBUG_PARAM(cache, format, ...) 46 | #define OCF_DEBUG_RQ(req, format, ...) 47 | #endif 48 | 49 | #endif /* ENGINE_DEBUG_H_ */ 50 | -------------------------------------------------------------------------------- /tests/functional/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2022 Intel Corporation 3 | # Copyright(c) 2025 Huawei Technologies 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | # 6 | 7 | PWD=$(shell pwd) 8 | OCFDIR=$(PWD)/../../ 9 | ADAPTERDIR=$(PWD)/pyocf 10 | SRCDIR=$(ADAPTERDIR)/ocf/src 11 | INCDIR=$(ADAPTERDIR)/ocf/include 12 | WRAPDIR=$(ADAPTERDIR)/c/wrappers 13 | HELPDIR=$(ADAPTERDIR)/c/helpers 14 | 15 | CFLAGS=-g -Wall -I$(INCDIR) -I$(SRCDIR)/ocf/env $(OPT_CFLAGS) 16 | LDFLAGS=-pthread #-lz 17 | 18 | SRC=$(shell find $(SRCDIR) $(WRAPDIR) $(HELPDIR) -name \*.c) 19 | OBJS=$(patsubst %.c, %.o, $(SRC)) 20 | OCFLIB=$(ADAPTERDIR)/libocf.so 21 | 22 | all: | sync config_random 23 | $(MAKE) $(OCFLIB) 24 | 25 | $(OCFLIB): $(OBJS) 26 | @echo "Building $@" 27 | @$(CC) -coverage -shared -o $@ $(CFLAGS) $^ -fPIC $(LDFLAGS) 28 | 29 | %.o: %.c 30 | @echo "Compiling $@" 31 | @$(CC) -coverage -c $(CFLAGS) -o $@ -fPIC $^ $(LDFLAGS) 32 | 33 | sync: 34 | @echo "Syncing OCF sources" 35 | @mkdir -p $(ADAPTERDIR)/ocf 36 | @$(MAKE) -C $(OCFDIR) inc O=$(ADAPTERDIR)/ocf 37 | @$(MAKE) -C $(OCFDIR) src O=$(ADAPTERDIR)/ocf 38 | @$(MAKE) -C $(OCFDIR) env O=$(ADAPTERDIR)/ocf OCF_ENV=posix 39 | 40 | config_random: 41 | @python3 utils/configure_random.py 42 | 43 | clean: 44 | @rm -rf $(OCFLIB) $(OBJS) 45 | @echo " CLEAN " 46 | 47 | distclean: clean 48 | @rm -rf $(OCFLIB) $(OBJS) 49 | @rm -rf $(SRCDIR)/ocf 50 | @rm -rf $(INCDIR)/ocf 51 | @find . -name *.gc* -delete 52 | @echo " DISTCLEAN " 53 | 54 | .PHONY: all clean sync config_random distclean 55 | -------------------------------------------------------------------------------- /src/cleaning/cleaning.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2023-2025 Huawei Technologies Co., Ltd. 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __LAYER_CLEANING_POLICY_H__ 8 | #define __LAYER_CLEANING_POLICY_H__ 9 | 10 | #include "alru_structs.h" 11 | #include "nop_structs.h" 12 | #include "acp_structs.h" 13 | #include "ocf_env_refcnt.h" 14 | #include "ocf/ocf_cleaner.h" 15 | 16 | #define CLEANING_POLICY_CONFIG_BYTES 256 17 | #define CLEANING_POLICY_TYPE_MAX 4 18 | 19 | #define SLEEP_TIME_MS (1000) 20 | 21 | struct ocf_request; 22 | 23 | struct cleaning_policy_config { 24 | uint8_t data[CLEANING_POLICY_CONFIG_BYTES]; 25 | }; 26 | 27 | struct cleaning_policy { 28 | union { 29 | struct nop_cleaning_policy nop; 30 | struct alru_cleaning_policy alru; 31 | } policy; 32 | }; 33 | 34 | /* Cleaning policy metadata per cache line */ 35 | struct cleaning_policy_meta { 36 | union { 37 | struct nop_cleaning_policy_meta nop; 38 | struct alru_cleaning_policy_meta alru; 39 | struct acp_cleaning_policy_meta acp; 40 | } meta; 41 | }; 42 | 43 | struct ocf_cleaner { 44 | struct env_refcnt refcnt; 45 | ocf_cleaning_t policy; 46 | void *cleaning_policy_context; 47 | ocf_queue_t io_queue; 48 | ocf_cleaner_end_t end; 49 | void *priv; 50 | }; 51 | 52 | int ocf_start_cleaner(ocf_cache_t cache); 53 | 54 | void ocf_kick_cleaner(ocf_cache_t cache); 55 | 56 | void ocf_stop_cleaner(ocf_cache_t cache); 57 | 58 | typedef void (*ocf_cleaning_op_end_t)(void *priv, int error); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/utils/utils_async_lock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __UTILS_ASYNC_LOCK_H__ 7 | #define __UTILS_ASYNC_LOCK_H__ 8 | 9 | #include "ocf_env.h" 10 | 11 | struct ocf_async_lock { 12 | struct list_head waiters; 13 | env_spinlock waiters_lock; 14 | uint32_t rd; 15 | uint32_t wr; 16 | uint32_t waiter_priv_size; 17 | }; 18 | 19 | typedef struct ocf_async_lock *ocf_async_lock_t; 20 | 21 | typedef struct ocf_async_lock_waiter *ocf_async_lock_waiter_t; 22 | 23 | typedef void (*ocf_async_lock_end_t)(ocf_async_lock_waiter_t waiter, int error); 24 | 25 | int ocf_async_lock_init(ocf_async_lock_t lock, uint32_t waiter_priv_size); 26 | 27 | void ocf_async_lock_deinit(ocf_async_lock_t lock); 28 | 29 | ocf_async_lock_waiter_t ocf_async_lock_new_waiter(ocf_async_lock_t lock, 30 | ocf_async_lock_end_t cmpl); 31 | 32 | ocf_async_lock_t ocf_async_lock_waiter_get_lock(ocf_async_lock_waiter_t waiter); 33 | 34 | void *ocf_async_lock_waiter_get_priv(ocf_async_lock_waiter_t waiter); 35 | 36 | void ocf_async_lock(ocf_async_lock_waiter_t waiter); 37 | 38 | int ocf_async_trylock(struct ocf_async_lock *lock); 39 | 40 | void ocf_async_unlock(struct ocf_async_lock *lock); 41 | 42 | void ocf_async_read_lock(ocf_async_lock_waiter_t waiter); 43 | 44 | int ocf_async_read_trylock(struct ocf_async_lock *lock); 45 | 46 | void ocf_async_read_unlock(struct ocf_async_lock *lock); 47 | 48 | bool ocf_async_is_locked(struct ocf_async_lock *lock); 49 | 50 | #endif /* __UTILS_ASYNC_LOCK_H__ */ 51 | -------------------------------------------------------------------------------- /src/cleaning/alru.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef __LAYER_CLEANING_POLICY_ALRU_H__ 7 | 8 | #define __LAYER_CLEANING_POLICY_ALRU_H__ 9 | 10 | #include "cleaning.h" 11 | #include "alru_structs.h" 12 | 13 | void cleaning_policy_alru_setup(ocf_cache_t cache); 14 | int cleaning_policy_alru_initialize(ocf_cache_t cache, int kick_cleaner); 15 | void cleaning_policy_alru_populate(ocf_cache_t cache, 16 | ocf_cleaning_op_end_t cmpl, void *priv); 17 | void cleaning_policy_alru_prepopulate(ocf_cache_t cache, 18 | ocf_cleaning_op_end_t cmpl, void *priv); 19 | void cleaning_policy_alru_update(ocf_cache_t cache, 20 | ocf_cleaning_op_end_t cmpl, void *priv); 21 | void cleaning_policy_alru_deinitialize(ocf_cache_t cache); 22 | void cleaning_policy_alru_init_cache_block(ocf_cache_t cache, 23 | uint32_t cache_line); 24 | void cleaning_policy_alru_purge_cache_block(ocf_cache_t cache, 25 | uint32_t cache_line); 26 | int cleaning_policy_alru_purge_range(ocf_cache_t cache, int core_id, 27 | uint64_t start_byte, uint64_t end_byte); 28 | void cleaning_policy_alru_set_hot_cache_line(ocf_cache_t cache, 29 | uint32_t cache_line); 30 | int cleaning_policy_alru_set_cleaning_param(ocf_cache_t cache, 31 | uint32_t param_id, uint32_t param_value); 32 | int cleaning_policy_alru_get_cleaning_param(ocf_cache_t cache, 33 | uint32_t param_id, uint32_t *param_value); 34 | void cleaning_alru_perform_cleaning(ocf_cache_t cache, ocf_cleaner_end_t cmpl); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/metadata/metadata_segment_id.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_HASH_H__ 7 | #define __METADATA_HASH_H__ 8 | 9 | /** 10 | * @file metadata_.h 11 | * @brief Metadata Service - Hash Implementation 12 | */ 13 | 14 | #include "../ocf_request.h" 15 | /** 16 | * @brief Metada hash elements type 17 | */ 18 | enum ocf_metadata_segment_id { 19 | metadata_segment_sb_config = 0, /*!< Super block conf */ 20 | metadata_segment_sb_runtime, /*!< Super block runtime */ 21 | metadata_segment_reserved, /*!< Reserved space on disk */ 22 | metadata_segment_part_config, /*!< Part Config Metadata */ 23 | metadata_segment_part_runtime, /*!< Part Runtime Metadata */ 24 | metadata_segment_core_config, /*!< Core Config Metadata */ 25 | metadata_segment_core_runtime, /*!< Core Runtime Metadata */ 26 | metadata_segment_core_uuid, /*!< Core UUID */ 27 | /* .... new fixed size sections go here */ 28 | 29 | metadata_segment_fixed_size_max, 30 | metadata_segment_variable_size_start = metadata_segment_fixed_size_max, 31 | 32 | /* sections with size dependent on cache device size go here: */ 33 | metadata_segment_cleaning = /*!< Cleaning policy */ 34 | metadata_segment_variable_size_start, 35 | metadata_segment_lru, /*!< Eviction policy */ 36 | metadata_segment_collision, /*!< Collision */ 37 | metadata_segment_list_info, /*!< Collision */ 38 | metadata_segment_hash, /*!< Hash */ 39 | /* .... new variable size sections go here */ 40 | 41 | metadata_segment_max, /*!< MAX */ 42 | }; 43 | 44 | #endif /* METADATA_HASH_H_ */ 45 | -------------------------------------------------------------------------------- /src/engine/engine_flush.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #include "ocf/ocf.h" 7 | #include "../ocf_cache_priv.h" 8 | #include "engine_common.h" 9 | #include "engine_io.h" 10 | #include "cache_engine.h" 11 | #include "engine_flush.h" 12 | #include "../ocf_request.h" 13 | 14 | #define OCF_ENGINE_DEBUG_IO_NAME "flush" 15 | #include "engine_debug.h" 16 | 17 | static void _ocf_engine_flush_complete(struct ocf_request *req, int error) 18 | { 19 | if (error) 20 | req->error = req->error ?: error; 21 | 22 | if (env_atomic_dec_return(&req->req_remaining)) 23 | return; 24 | 25 | OCF_DEBUG_RQ(req, "Completion"); 26 | 27 | if (req->error) { 28 | /* An error occured */ 29 | ocf_engine_error(req, false, "Core operation failure"); 30 | } 31 | 32 | /* Complete requests - both to cache and to core*/ 33 | req->complete(req, req->error); 34 | 35 | /* Release OCF request */ 36 | ocf_req_put(req); 37 | } 38 | 39 | int ocf_engine_flush(struct ocf_request *req) 40 | { 41 | /* Get OCF request - increase reference counter */ 42 | ocf_req_get(req); 43 | 44 | /* IO to the core device and to the cache device */ 45 | env_atomic_set(&req->req_remaining, 2); 46 | 47 | /* Submit operation into core device */ 48 | ocf_engine_forward_core_flush_req(req, _ocf_engine_flush_complete); 49 | 50 | /* submit flush to cache device */ 51 | ocf_engine_forward_cache_flush_req(req, _ocf_engine_flush_complete); 52 | 53 | /* Put OCF request - decrease reference counter */ 54 | ocf_req_put(req); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /src/metadata/metadata_segment.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2020-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __METADATA_SEGMENT_OPS_H__ 8 | #define __METADATA_SEGMENT_OPS_H__ 9 | 10 | #include "../utils/utils_pipeline.h" 11 | #include "metadata_raw.h" 12 | #include 13 | 14 | struct ocf_metadata_segment 15 | { 16 | struct ocf_metadata_raw *raw; 17 | struct ocf_metadata_segment *superblock; 18 | }; 19 | 20 | int ocf_metadata_segment_init_in_place( 21 | struct ocf_metadata_segment *segment, 22 | struct ocf_cache *cache, 23 | struct ocf_metadata_raw *raw, 24 | ocf_flush_page_synch_t lock_page_pfn, 25 | ocf_flush_page_synch_t unlock_page_pfn, 26 | struct ocf_metadata_segment *superblock); 27 | 28 | int ocf_metadata_segment_init( 29 | struct ocf_metadata_segment **self, 30 | struct ocf_cache *cache, 31 | struct ocf_metadata_raw *raw, 32 | ocf_flush_page_synch_t lock_page_pfn, 33 | ocf_flush_page_synch_t unlock_page_pfn, 34 | struct ocf_metadata_segment *superblock); 35 | 36 | void ocf_metadata_segment_destroy(struct ocf_cache *cache, 37 | struct ocf_metadata_segment *self); 38 | 39 | void ocf_metadata_check_crc(ocf_pipeline_t pipeline, 40 | void *priv, ocf_pipeline_arg_t arg); 41 | 42 | void ocf_metadata_calculate_crc(ocf_pipeline_t pipeline, 43 | void *priv, ocf_pipeline_arg_t arg); 44 | 45 | void ocf_metadata_flush_segment(ocf_pipeline_t pipeline, 46 | void *priv, ocf_pipeline_arg_t arg); 47 | 48 | void ocf_metadata_load_segment(ocf_pipeline_t pipeline, 49 | void *priv, ocf_pipeline_arg_t arg); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/promotion/ops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef PROMOTION_OPS_H_ 7 | #define PROMOTION_OPS_H_ 8 | 9 | #include "../metadata/metadata.h" 10 | #include "promotion.h" 11 | 12 | struct ocf_promotion_policy { 13 | ocf_cache_t owner; 14 | 15 | ocf_promotion_t type; 16 | 17 | void *config; 18 | /* Pointer to config values stored in cache superblock */ 19 | 20 | void *ctx; 21 | }; 22 | 23 | struct promotion_policy_ops { 24 | const char *name; 25 | /*!< Promotion policy name */ 26 | 27 | void (*setup)(ocf_cache_t cache); 28 | /*!< initialize promotion policy default config */ 29 | 30 | ocf_error_t (*init)(ocf_cache_t cache); 31 | /*!< Allocate and initialize promotion policy */ 32 | 33 | void (*deinit)(ocf_promotion_policy_t policy); 34 | /*!< Deinit and free promotion policy */ 35 | 36 | ocf_error_t (*set_param)(ocf_cache_t cache, uint8_t param_id, 37 | uint32_t param_value); 38 | /*!< Set promotion policy parameter */ 39 | 40 | ocf_error_t (*get_param)(ocf_cache_t cache, uint8_t param_id, 41 | uint32_t *param_value); 42 | /*!< Get promotion policy parameter */ 43 | 44 | void (*req_purge)(ocf_promotion_policy_t policy, 45 | struct ocf_request *req); 46 | /*!< Call when request core lines have been inserted or it is 47 | * a discard request */ 48 | 49 | bool (*req_should_promote)(ocf_promotion_policy_t policy, 50 | struct ocf_request *req); 51 | /*!< Should request lines be inserted into cache */ 52 | }; 53 | 54 | extern struct promotion_policy_ops ocf_promotion_policies[ocf_promotion_max]; 55 | 56 | #endif /* PROMOTION_OPS_H_ */ 57 | 58 | -------------------------------------------------------------------------------- /inc/ocf_cleaner.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef OCF_CLEANER_H_ 7 | #define OCF_CLEANER_H_ 8 | 9 | /** 10 | * @file 11 | * @brief OCF cleaner API for synchronization dirty data 12 | * 13 | */ 14 | 15 | /** 16 | * @brief OCF Cleaner completion 17 | * 18 | * @note Completion function for cleaner 19 | * 20 | * @param[in] cleaner Cleaner instance 21 | * @param[in] interval Time to sleep before next cleaner iteration 22 | */ 23 | typedef void (*ocf_cleaner_end_t)(ocf_cleaner_t cleaner, uint32_t interval); 24 | 25 | /** 26 | * @brief Set cleaner completion function 27 | * 28 | * @param[in] cleaner Cleaner instance 29 | * @param[in] fn Completion function 30 | */ 31 | void ocf_cleaner_set_cmpl(ocf_cleaner_t cleaner, ocf_cleaner_end_t fn); 32 | 33 | /** 34 | * @brief Run cleaner 35 | * 36 | * @param[in] c Cleaner instance to run 37 | * @param[in] queue IO queue handle 38 | */ 39 | void ocf_cleaner_run(ocf_cleaner_t c, ocf_queue_t queue); 40 | 41 | /** 42 | * @brief Set cleaner private data 43 | * 44 | * @param[in] c Cleaner handle 45 | * @param[in] priv Private data 46 | */ 47 | void ocf_cleaner_set_priv(ocf_cleaner_t c, void *priv); 48 | 49 | /** 50 | * @brief Get cleaner private data 51 | * 52 | * @param[in] c Cleaner handle 53 | * 54 | * @retval Cleaner private data 55 | */ 56 | void *ocf_cleaner_get_priv(ocf_cleaner_t c); 57 | 58 | /** 59 | * @brief Get cache instance to which cleaner belongs 60 | * 61 | * @param[in] c Cleaner handle 62 | * 63 | * @retval Cache instance 64 | */ 65 | ocf_cache_t ocf_cleaner_get_cache(ocf_cleaner_t c); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/engine/engine_inv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include "ocf/ocf.h" 8 | #include "../ocf_cache_priv.h" 9 | #include "engine_inv.h" 10 | #include "engine_common.h" 11 | #include "cache_engine.h" 12 | #include "../ocf_request.h" 13 | #include "../utils/utils_cache_line.h" 14 | #include "../metadata/metadata.h" 15 | #include "../concurrency/ocf_concurrency.h" 16 | 17 | #define OCF_ENGINE_DEBUG_IO_NAME "inv" 18 | #include "engine_debug.h" 19 | 20 | static void _ocf_invalidate_req(struct ocf_request *req, int error) 21 | { 22 | OCF_DEBUG_RQ(req, "Completion"); 23 | 24 | if (error) { 25 | ocf_core_stats_cache_error_update(req->core, OCF_WRITE); 26 | ocf_engine_error(req, true, "Failed to flush metadata to cache"); 27 | } 28 | 29 | ocf_req_unlock_wr(ocf_cache_line_concurrency(req->cache), req); 30 | 31 | /* Put OCF request - decrease reference counter */ 32 | ocf_req_put(req); 33 | } 34 | 35 | static int _ocf_invalidate_do(struct ocf_request *req) 36 | { 37 | struct ocf_cache *cache = req->cache; 38 | 39 | ocf_hb_req_prot_lock_wr(req); 40 | ocf_purge_map_info(req); 41 | ocf_hb_req_prot_unlock_wr(req); 42 | 43 | if (ocf_volume_is_atomic(&cache->device->volume) && 44 | req->info.flush_metadata) { 45 | /* Metadata flush IO */ 46 | ocf_metadata_flush_do_asynch(cache, req, _ocf_invalidate_req); 47 | } else { 48 | _ocf_invalidate_req(req, 0); 49 | } 50 | 51 | return 0; 52 | } 53 | 54 | void ocf_engine_invalidate(struct ocf_request *req) 55 | { 56 | ocf_queue_push_req_cb(req, _ocf_invalidate_do, 57 | OCF_QUEUE_ALLOW_SYNC | OCF_QUEUE_PRIO_HIGH); 58 | } 59 | -------------------------------------------------------------------------------- /tests/unit/tests/utils/utils_refcnt.c/utils_refcnt_dec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | /* 7 | * src/utils/utils_refcnt.c 8 | * ocf_refcnt_dec 9 | * 10 | * ocf_refcnt_init 11 | * ocf_refcnt_inc 12 | * 13 | */ 14 | 15 | #undef static 16 | 17 | #undef inline 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "print_desc.h" 25 | 26 | #include "../utils/utils_refcnt.h" 27 | 28 | #include "utils/utils_refcnt.c/utils_refcnt_dec_generated_wraps.c" 29 | 30 | static void ocf_refcnt_dec_test01(void **state) 31 | { 32 | struct ocf_refcnt rc; 33 | int val, val2; 34 | 35 | print_test_description("Decrement subtracts 1 and returns proper value"); 36 | 37 | ocf_refcnt_init(&rc); 38 | 39 | ocf_refcnt_inc(&rc); 40 | ocf_refcnt_inc(&rc); 41 | ocf_refcnt_inc(&rc); 42 | 43 | val = ocf_refcnt_dec(&rc); 44 | assert_int_equal(2, val); 45 | val2 = env_atomic_read(&rc.counter); 46 | assert_int_equal(2, val2); 47 | 48 | val = ocf_refcnt_dec(&rc); 49 | assert_int_equal(1, val); 50 | val2 = env_atomic_read(&rc.counter); 51 | assert_int_equal(1, val2); 52 | 53 | val = ocf_refcnt_dec(&rc); 54 | assert_int_equal(0, val); 55 | val2 = env_atomic_read(&rc.counter); 56 | assert_int_equal(0, val2); 57 | } 58 | 59 | int main(void) 60 | { 61 | const struct CMUnitTest tests[] = { 62 | cmocka_unit_test(ocf_refcnt_dec_test01) 63 | }; 64 | 65 | print_message("Unit test of src/utils/utils_refcnt.c"); 66 | 67 | return cmocka_run_group_tests(tests, NULL, NULL); 68 | } 69 | -------------------------------------------------------------------------------- /src/utils/utils_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf.h" 7 | #include "utils_list.h" 8 | 9 | void ocf_lst_sort(struct ocf_lst *lst) 10 | { 11 | ocf_cache_line_t iter_idx; 12 | ocf_cache_line_t next_idx; 13 | struct ocf_lst_entry *iter; 14 | 15 | if (!lst->cmp) { 16 | /* No comparator, no needed to sort */ 17 | return; 18 | } 19 | 20 | if (ocf_lst_empty(lst)) { 21 | /* List is empty nothing to do */ 22 | return; 23 | } 24 | 25 | /* Get iterator - first element on the list, and one after */ 26 | iter_idx = lst->head->next; 27 | iter = lst->getter(lst->cache, iter_idx); 28 | next_idx = iter->next; 29 | lst->getter(lst->cache, iter->next); 30 | 31 | /* Initialize list to initial empty state, it will be empty */ 32 | lst->head->next = lst->invalid; 33 | lst->head->prev = lst->invalid; 34 | 35 | while (iter_idx != lst->invalid) { 36 | ocf_lst_init_entry(lst, iter); 37 | 38 | if (ocf_lst_empty(lst)) { 39 | /* Put first at the the list */ 40 | ocf_lst_add(lst, iter_idx); 41 | } else { 42 | /* search for place where put element at the list */ 43 | struct ocf_lst_entry *pos; 44 | ocf_cache_line_t pos_idx; 45 | 46 | for_each_lst(lst, pos, pos_idx) 47 | if (lst->cmp(lst->cache, pos, iter) > 0) 48 | break; 49 | 50 | if (lst->invalid == pos_idx) { 51 | /* Put at the end of list */ 52 | ocf_lst_add_tail(lst, iter_idx); 53 | } else { 54 | /* Position is known, put it before */ 55 | ocf_lst_add_before(lst, pos_idx, iter_idx); 56 | } 57 | } 58 | 59 | /* Switch to next */ 60 | iter_idx = next_idx; 61 | iter = lst->getter(lst->cache, iter_idx); 62 | next_idx = iter->next; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/cleaning/acp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef __LAYER_CLEANING_POLICY_AGGRESSIVE_H__ 7 | 8 | #define __LAYER_CLEANING_POLICY_AGGRESSIVE_H__ 9 | 10 | #include "cleaning.h" 11 | 12 | void cleaning_policy_acp_setup(ocf_cache_t cache); 13 | 14 | int cleaning_policy_acp_initialize(ocf_cache_t cache, int kick_cleaner); 15 | 16 | void cleaning_policy_acp_populate(ocf_cache_t cache, 17 | ocf_cleaning_op_end_t cmpl, void *priv); 18 | 19 | void cleaning_policy_acp_prepopulate(ocf_cache_t cache, 20 | ocf_cleaning_op_end_t cmpl, void *priv); 21 | 22 | void cleaning_policy_acp_update(ocf_cache_t cache, 23 | ocf_cleaning_op_end_t cmpl, void *priv); 24 | 25 | void cleaning_policy_acp_deinitialize(ocf_cache_t cache); 26 | 27 | void cleaning_policy_acp_perform_cleaning(ocf_cache_t cache, 28 | ocf_cleaner_end_t cmpl); 29 | 30 | void cleaning_policy_acp_init_cache_block(ocf_cache_t cache, 31 | uint32_t cache_line); 32 | 33 | void cleaning_policy_acp_set_hot_cache_line(ocf_cache_t cache, 34 | uint32_t cache_line); 35 | 36 | void cleaning_policy_acp_purge_block(ocf_cache_t cache, uint32_t cache_line); 37 | 38 | int cleaning_policy_acp_purge_range(ocf_cache_t cache, 39 | int core_id, uint64_t start_byte, uint64_t end_byte); 40 | 41 | int cleaning_policy_acp_set_cleaning_param(ocf_cache_t cache, 42 | uint32_t param_id, uint32_t param_value); 43 | 44 | int cleaning_policy_acp_get_cleaning_param(ocf_cache_t cache, 45 | uint32_t param_id, uint32_t *param_value); 46 | 47 | int cleaning_policy_acp_add_core(ocf_cache_t cache, ocf_core_id_t core_id); 48 | 49 | void cleaning_policy_acp_remove_core(ocf_cache_t cache, 50 | ocf_core_id_t core_id); 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /src/ocf_logger.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf_env.h" 7 | #include "ocf/ocf_logger.h" 8 | #include "ocf_logger_priv.h" 9 | #include "ocf_priv.h" 10 | 11 | /* 12 | * 13 | */ 14 | __attribute__((format(printf, 3, 4))) 15 | int ocf_log_raw(ocf_logger_t logger, ocf_logger_lvl_t lvl, 16 | const char *fmt, ...) 17 | { 18 | va_list args; 19 | int ret = 0; 20 | 21 | if (!logger->ops->print) 22 | return -ENOTSUP; 23 | 24 | va_start(args, fmt); 25 | ret = logger->ops->print(logger, lvl, fmt, args); 26 | va_end(args); 27 | 28 | return ret; 29 | } 30 | 31 | int ocf_log_raw_rl(ocf_logger_t logger, const char *func_name) 32 | { 33 | if (!logger->ops->print_rl) 34 | return -ENOTSUP; 35 | 36 | return logger->ops->print_rl(logger, func_name); 37 | } 38 | 39 | /* 40 | * 41 | */ 42 | int ocf_log_stack_trace_raw(ocf_logger_t logger) 43 | { 44 | if (!logger->ops->dump_stack) 45 | return -ENOTSUP; 46 | 47 | return logger->ops->dump_stack(logger); 48 | } 49 | 50 | void ocf_logger_init(ocf_logger_t logger, 51 | const struct ocf_logger_ops *ops, void *priv) 52 | { 53 | logger->ops = ops; 54 | logger->priv = priv; 55 | } 56 | 57 | int ocf_logger_open(ocf_logger_t logger) 58 | { 59 | if (!logger->ops->open) 60 | return 0; 61 | 62 | return logger->ops->open(logger); 63 | } 64 | 65 | void ocf_logger_close(ocf_logger_t logger) 66 | { 67 | if (!logger->ops->close) 68 | return; 69 | 70 | logger->ops->close(logger); 71 | } 72 | 73 | void ocf_logger_set_priv(ocf_logger_t logger, void *priv) 74 | { 75 | OCF_CHECK_NULL(logger); 76 | 77 | logger->priv = priv; 78 | } 79 | 80 | void *ocf_logger_get_priv(ocf_logger_t logger) 81 | { 82 | OCF_CHECK_NULL(logger); 83 | 84 | return logger->priv; 85 | } 86 | 87 | -------------------------------------------------------------------------------- /src/ocf_def_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __OCF_DEF_PRIV_H__ 8 | #define __OCF_DEF_PRIV_H__ 9 | 10 | #include "ocf/ocf.h" 11 | #include "ocf_env.h" 12 | 13 | #define BYTES_TO_SECTORS(x) ((x) >> ENV_SECTOR_SHIFT) 14 | #define SECTORS_TO_BYTES(x) ((x) << ENV_SECTOR_SHIFT) 15 | 16 | #define BYTES_TO_PAGES(x) ((((uint64_t)x) + (PAGE_SIZE - 1)) / PAGE_SIZE) 17 | #define PAGES_TO_BYTES(x) (((uint64_t)x) * PAGE_SIZE) 18 | 19 | #define OCF_DIV_ROUND_UP(x, y) \ 20 | ({ \ 21 | __typeof__ (x) __x = (x); \ 22 | __typeof__ (y) __y = (y); \ 23 | (__x + __y - 1) / __y; \ 24 | }) 25 | 26 | #define OCF_MAX(x,y) \ 27 | ({ \ 28 | __typeof__ (x) __x = (x); \ 29 | __typeof__ (y) __y = (y); \ 30 | __x > __y ? __x : __y; \ 31 | }) 32 | 33 | #define OCF_MIN(x,y) \ 34 | ({ \ 35 | __typeof__ (x) __x = (x); \ 36 | __typeof__ (y) __y = (y); \ 37 | __x < __y ? __x : __y; \ 38 | }) 39 | 40 | #define METADATA_VERSION() ((OCF_VERSION_MAIN << 16) + \ 41 | (OCF_VERSION_MAJOR << 8) + OCF_VERSION_MINOR) 42 | 43 | /* call conditional reschedule every 'iterations' calls */ 44 | #define OCF_COND_RESCHED(cnt, iterations) \ 45 | if (unlikely(++(cnt) == (iterations))) { \ 46 | env_cond_resched(); \ 47 | (cnt) = 0; \ 48 | } 49 | 50 | /* call conditional reschedule with default interval */ 51 | #define OCF_COND_RESCHED_DEFAULT(cnt) OCF_COND_RESCHED(cnt, 1000000) 52 | 53 | static inline unsigned long long 54 | ocf_rotate_right(unsigned long long bits, unsigned shift, unsigned width) 55 | { 56 | return ((bits >> shift) | (bits << (width - shift))) & 57 | ((1ULL << width) - 1); 58 | } 59 | 60 | struct ocf_request; 61 | 62 | typedef void (*ocf_req_end_t)(struct ocf_request *req, int error); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /env/posix/ocf_env_refcnt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * Copyright(c) 2024-2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __OCF_ENV_REFCNT_H__ 8 | #define __OCF_ENV_REFCNT_H__ 9 | 10 | #include "ocf_env.h" 11 | 12 | typedef void (*env_refcnt_cb_t)(void *priv); 13 | 14 | struct env_refcnt 15 | { 16 | env_atomic counter __attribute__((aligned(64))); 17 | env_atomic freeze; 18 | env_atomic callback; 19 | env_refcnt_cb_t cb; 20 | void *priv; 21 | }; 22 | 23 | /* Initialize reference counter */ 24 | int env_refcnt_init(struct env_refcnt *rc, const char *name, size_t name_len); 25 | 26 | void env_refcnt_deinit(struct env_refcnt *rc); 27 | 28 | /* Try to increment counter. Returns true if successfull, false 29 | * if counter is frozen */ 30 | bool env_refcnt_inc(struct env_refcnt *rc); 31 | 32 | /* Decrement reference counter */ 33 | void env_refcnt_dec(struct env_refcnt *rc); 34 | 35 | /* Disallow incrementing of underlying counter - attempts to increment counter 36 | * will be failing until env_refcnt_unfreeze is calleed. 37 | * It's ok to call freeze multiple times, in which case counter is frozen 38 | * until all freeze calls are offset by a corresponding unfreeze.*/ 39 | void env_refcnt_freeze(struct env_refcnt *rc); 40 | 41 | /* Cancel the effect of single env_refcnt_freeze call */ 42 | void env_refcnt_unfreeze(struct env_refcnt *rc); 43 | 44 | bool env_refcnt_frozen(struct env_refcnt *rc); 45 | 46 | bool env_refcnt_zeroed(struct env_refcnt *rc); 47 | 48 | /* Register callback to be called when reference counter drops to 0. 49 | * Must be called after counter is frozen. 50 | * Cannot be called until previously regsitered callback had fired. */ 51 | void env_refcnt_register_zero_cb(struct env_refcnt *rc, env_refcnt_cb_t cb, 52 | void *priv); 53 | 54 | #endif // __OCF_ENV_REFCNT_H__ 55 | -------------------------------------------------------------------------------- /src/metadata/metadata_raw_volatile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_RAW_VOLATILE_H__ 7 | #define __METADATA_RAW_VOLATILE_H__ 8 | 9 | /* 10 | * RAW volatile Implementation - Size on SSD 11 | */ 12 | uint32_t raw_volatile_size_on_ssd(struct ocf_metadata_raw *raw); 13 | 14 | /* 15 | * RAW volatile Implementation - Checksum 16 | */ 17 | uint32_t raw_volatile_checksum(ocf_cache_t cache, 18 | struct ocf_metadata_raw *raw); 19 | 20 | /* 21 | * RAW volatile Implementation - Update 22 | */ 23 | int raw_volatile_update(ocf_cache_t cache, 24 | struct ocf_metadata_raw *raw, ctx_data_t *data, 25 | uint64_t page, uint64_t count); 26 | 27 | /* 28 | * RAW volatile Implementation - Zero 29 | */ 30 | void raw_volatile_zero(ocf_cache_t cache, struct ocf_metadata_raw *raw, 31 | ocf_metadata_end_t cmpl, void *context); 32 | /* 33 | * RAW volatile Implementation - Load all metadata elements from SSD 34 | */ 35 | void raw_volatile_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, 36 | ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx); 37 | 38 | /* 39 | * RAW volatile Implementation - Flush all elements 40 | */ 41 | void raw_volatile_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, 42 | ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx); 43 | 44 | /* 45 | * RAM RAW volatile Implementation - Mark to Flush 46 | */ 47 | void raw_volatile_flush_mark(ocf_cache_t cache, struct ocf_request *req, 48 | uint32_t map_idx, int to_state, uint8_t start, uint8_t stop); 49 | 50 | /* 51 | * RAM RAW volatile Implementation - Do Flush asynchronously 52 | */ 53 | int raw_volatile_flush_do_asynch(ocf_cache_t cache, 54 | struct ocf_request *req, struct ocf_metadata_raw *raw, 55 | ocf_req_end_t complete); 56 | 57 | #endif /* __METADATA_RAW_VOLATILE_H__ */ 58 | -------------------------------------------------------------------------------- /src/ocf_lru.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | #ifndef __EVICTION_LRU_H__ 6 | #define __EVICTION_LRU_H__ 7 | 8 | #include "ocf_space.h" 9 | #include "ocf_lru_structs.h" 10 | 11 | struct ocf_part; 12 | struct ocf_user_part; 13 | struct ocf_part_runtime; 14 | struct ocf_part_cleaning_ctx; 15 | struct ocf_request; 16 | 17 | void ocf_lru_init_cline(ocf_cache_t cache, ocf_cache_line_t cline); 18 | void ocf_lru_rm_cline(struct ocf_cache *cache, ocf_cache_line_t cline); 19 | bool ocf_lru_can_evict(struct ocf_cache *cache); 20 | uint32_t ocf_lru_req_clines(struct ocf_request *req, 21 | struct ocf_part *src_part, uint32_t cline_no); 22 | void ocf_lru_hot_cline(struct ocf_cache *cache, ocf_cache_line_t cline); 23 | void ocf_lru_add(ocf_cache_t cache, ocf_cache_line_t cline); 24 | void ocf_lru_init(struct ocf_cache *cache, struct ocf_part *part); 25 | void ocf_lru_dirty_cline(struct ocf_cache *cache, struct ocf_part *part, 26 | ocf_cache_line_t cline); 27 | void ocf_lru_clean_cline(struct ocf_cache *cache, struct ocf_part *part, 28 | ocf_cache_line_t cline); 29 | void ocf_lru_clean(ocf_cache_t cache, struct ocf_user_part *user_part, 30 | ocf_queue_t io_queue, uint32_t count); 31 | void ocf_lru_repart(ocf_cache_t cache, ocf_cache_line_t cline, 32 | struct ocf_part *src_upart, struct ocf_part *dst_upart); 33 | void ocf_lru_add_free(ocf_cache_t cache, ocf_cache_line_t cline); 34 | uint32_t ocf_lru_num_free(ocf_cache_t cache); 35 | struct ocf_lru_list *ocf_lru_get_list(struct ocf_part *part, 36 | uint32_t lru_idx, bool clean); 37 | void ocf_lru_remove_locked(ocf_cache_t cache, struct ocf_lru_list *list, 38 | ocf_cache_line_t cline); 39 | 40 | typedef void (*ocf_lru_populate_end_t)(void *priv, int error); 41 | 42 | void ocf_lru_populate(ocf_cache_t cache, 43 | ocf_lru_populate_end_t cmpl, void *priv); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /tests/functional/tests/engine/test_flush.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2022-2022 Intel Corporation 3 | # Copyright(c) 2024 Huawei Technologies 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | # 6 | 7 | from pyocf.types.cache import Cache 8 | from pyocf.types.data import Data 9 | from pyocf.types.core import Core 10 | from pyocf.types.io import Io, IoDir, Sync 11 | from pyocf.types.volume import RamVolume, IoFlags, TraceDevice 12 | from pyocf.types.volume_core import CoreVolume 13 | from pyocf.utils import Size 14 | 15 | 16 | def test_flush_propagation(pyocf_ctx): 17 | flushes = {} 18 | 19 | pyocf_ctx.register_volume_type(TraceDevice) 20 | 21 | def trace_flush(vol, io_type, rw, addr, nbytes, flags): 22 | nonlocal flushes 23 | 24 | if io_type == TraceDevice.IoType.Flush: 25 | if vol.uuid not in flushes: 26 | flushes[vol.uuid] = [] 27 | flushes[vol.uuid].append((addr, nbytes)) 28 | 29 | return True 30 | 31 | cache_device = TraceDevice(RamVolume(Size.from_MiB(50)), trace_fcn=trace_flush) 32 | core_device = TraceDevice(RamVolume(Size.from_MiB(100)), trace_fcn=trace_flush) 33 | 34 | cache = Cache.start_on_device(cache_device) 35 | core = Core.using_device(core_device) 36 | cache.add_core(core) 37 | 38 | queue = cache.get_default_queue() 39 | vol = CoreVolume(core) 40 | 41 | flushes = {} 42 | 43 | vol.open() 44 | io = vol.new_io(queue, 0, 0, IoDir.WRITE, 0, 0) 45 | 46 | completion = Sync(io).submit_flush() 47 | vol.close() 48 | 49 | assert int(completion.results["err"]) == 0 50 | 51 | assert cache_device.uuid in flushes 52 | assert core_device.uuid in flushes 53 | 54 | cache_flushes = flushes[cache_device.uuid] 55 | core_flushes = flushes[core_device.uuid] 56 | 57 | assert len(cache_flushes) == 1 58 | assert len(core_flushes) == 1 59 | 60 | cache.stop() 61 | -------------------------------------------------------------------------------- /env/posix/ocf_env_refcnt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include "ocf_env_refcnt.h" 8 | 9 | int env_refcnt_init(struct env_refcnt *rc, const char *name, size_t name_len) 10 | { 11 | env_atomic_set(&rc->counter, 0); 12 | env_atomic_set(&rc->freeze, 0); 13 | env_atomic_set(&rc->callback, 0); 14 | rc->cb = NULL; 15 | 16 | return 0; 17 | } 18 | 19 | void env_refcnt_deinit(struct env_refcnt *rc) 20 | { 21 | 22 | } 23 | 24 | void env_refcnt_dec(struct env_refcnt *rc) 25 | { 26 | int val = env_atomic_dec_return(&rc->counter); 27 | ENV_BUG_ON(val < 0); 28 | 29 | if (!val && env_atomic_cmpxchg(&rc->callback, 1, 0)) 30 | rc->cb(rc->priv); 31 | } 32 | 33 | bool env_refcnt_inc(struct env_refcnt *rc) 34 | { 35 | int val; 36 | 37 | if (!env_atomic_read(&rc->freeze)) { 38 | val = env_atomic_inc_return(&rc->counter); 39 | if (!env_atomic_read(&rc->freeze)) 40 | return !!val; 41 | else 42 | env_refcnt_dec(rc); 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | 49 | void env_refcnt_freeze(struct env_refcnt *rc) 50 | { 51 | env_atomic_inc(&rc->freeze); 52 | } 53 | 54 | void env_refcnt_register_zero_cb(struct env_refcnt *rc, env_refcnt_cb_t cb, 55 | void *priv) 56 | { 57 | ENV_BUG_ON(!env_atomic_read(&rc->freeze)); 58 | ENV_BUG_ON(env_atomic_read(&rc->callback)); 59 | 60 | env_atomic_inc(&rc->counter); 61 | rc->cb = cb; 62 | rc->priv = priv; 63 | env_atomic_set(&rc->callback, 1); 64 | env_refcnt_dec(rc); 65 | } 66 | 67 | void env_refcnt_unfreeze(struct env_refcnt *rc) 68 | { 69 | int val = env_atomic_dec_return(&rc->freeze); 70 | ENV_BUG_ON(val < 0); 71 | } 72 | 73 | bool env_refcnt_frozen(struct env_refcnt *rc) 74 | { 75 | return !!env_atomic_read(&rc->freeze); 76 | } 77 | 78 | bool env_refcnt_zeroed(struct env_refcnt *rc) 79 | { 80 | return (env_atomic_read(&rc->counter) == 0); 81 | } 82 | -------------------------------------------------------------------------------- /src/utils/utils_io_allocator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __UTILS_IO_ALLOCATOR_H__ 8 | #define __UTILS_IO_ALLOCATOR_H__ 9 | 10 | #include "ocf/ocf_types.h" 11 | 12 | typedef struct ocf_io_allocator *ocf_io_allocator_t; 13 | 14 | struct ocf_io_allocator_ops { 15 | int (*allocator_init)(ocf_io_allocator_t allocator, const char *name); 16 | void (*allocator_deinit)(ocf_io_allocator_t allocator); 17 | void *(*allocator_new)(ocf_io_allocator_t allocator, 18 | ocf_volume_t volume, ocf_queue_t queue, 19 | uint64_t addr, uint32_t bytes, uint32_t dir); 20 | void (*allocator_del)(ocf_io_allocator_t allocator, void *obj); 21 | }; 22 | 23 | struct ocf_io_allocator_type { 24 | struct ocf_io_allocator_ops ops; 25 | }; 26 | 27 | typedef const struct ocf_io_allocator_type *ocf_io_allocator_type_t; 28 | 29 | struct ocf_io_allocator { 30 | const struct ocf_io_allocator_type *type; 31 | void *priv; 32 | }; 33 | 34 | static inline void *ocf_io_allocator_new(ocf_io_allocator_t allocator, 35 | ocf_volume_t volume, ocf_queue_t queue, 36 | uint64_t addr, uint32_t bytes, uint32_t dir) 37 | { 38 | return allocator->type->ops.allocator_new(allocator, volume, queue, 39 | addr, bytes, dir); 40 | } 41 | 42 | static inline void ocf_io_allocator_del(ocf_io_allocator_t allocator, void *obj) 43 | { 44 | allocator->type->ops.allocator_del(allocator, obj); 45 | } 46 | 47 | static inline int ocf_io_allocator_init(ocf_io_allocator_t allocator, 48 | ocf_io_allocator_type_t type, const char *name) 49 | { 50 | allocator->type = type; 51 | return allocator->type->ops.allocator_init(allocator, name); 52 | } 53 | 54 | static inline void ocf_io_allocator_deinit(ocf_io_allocator_t allocator) 55 | { 56 | allocator->type->ops.allocator_deinit(allocator); 57 | } 58 | 59 | ocf_io_allocator_type_t ocf_io_allocator_get_type_default(void); 60 | 61 | #endif /* __UTILS_IO_ALLOCATOR__ */ 62 | -------------------------------------------------------------------------------- /src/ocf_queue_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef OCF_QUEUE_PRIV_H_ 8 | #define OCF_QUEUE_PRIV_H_ 9 | 10 | #include "ocf_env.h" 11 | #include "ocf_request.h" 12 | 13 | /* ocf_queue_push_req flags */ 14 | #define OCF_QUEUE_ALLOW_SYNC 0x01 /* Request can run immediately in caller context */ 15 | #define OCF_QUEUE_PRIO_HIGH 0x02 /* Push to the high priority queue */ 16 | 17 | struct ocf_queue { 18 | ocf_cache_t cache; 19 | 20 | void *priv; 21 | 22 | struct list_head io_list_high; 23 | struct list_head io_list_low; 24 | 25 | /* per-queue free running global metadata lock index */ 26 | unsigned lock_idx; 27 | 28 | /* per-queue free running lru list index */ 29 | unsigned lru_idx; 30 | 31 | struct ocf_seq_cutoff *seq_cutoff; 32 | 33 | struct list_head list; 34 | 35 | const struct ocf_queue_ops *ops; 36 | 37 | /* Tracing reference counter */ 38 | env_atomic64 trace_ref_cntr; 39 | 40 | /* Tracing stop request */ 41 | env_atomic trace_stop; 42 | env_atomic io_no; 43 | 44 | env_atomic ref_count; 45 | env_spinlock io_list_lock; 46 | } __attribute__((__aligned__(64))); 47 | 48 | static inline void ocf_queue_kick(ocf_queue_t queue, bool allow_sync) 49 | { 50 | if (allow_sync && queue->ops->kick_sync) 51 | queue->ops->kick_sync(queue); 52 | else 53 | queue->ops->kick(queue); 54 | } 55 | 56 | /** 57 | * @brief Push OCF request to the OCF thread worker queue 58 | * 59 | * @param req OCF request 60 | * @param flags See ocf_queue_push_req flags above 61 | */ 62 | void ocf_queue_push_req(struct ocf_request *req, uint flags); 63 | 64 | /** 65 | * @brief Set interface and push from request to the OCF thread worker queue 66 | * 67 | * @param req OCF request 68 | * @param req_cb IO engine handler callback 69 | * @param flags See ocf_queue_push_req flags above 70 | */ 71 | void ocf_queue_push_req_cb(struct ocf_request *req, 72 | ocf_req_cb req_cb, uint flags); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /tests/functional/pyocf/c/helpers/metadata_helpers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf_io.h" 7 | #include "ocf/ocf_cache.h" 8 | #include "../src/ocf/ocf_cache_priv.h" 9 | #include "../src/ocf/metadata/metadata_raw.h" 10 | #include "../src/ocf/metadata/metadata_internal.h" 11 | #include "../src/ocf/metadata/metadata_superblock.h" 12 | 13 | uint64_t ocf_get_metadata_segment_start_page(ocf_cache_t cache, int segment) 14 | { 15 | struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; 16 | struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; 17 | 18 | return raw->ssd_pages_offset; 19 | } 20 | 21 | uint64_t ocf_get_metadata_segment_page_count(ocf_cache_t cache, int segment) 22 | { 23 | struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; 24 | struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; 25 | 26 | return raw->ssd_pages; 27 | } 28 | 29 | uint64_t ocf_get_metadata_segment_elems_count(ocf_cache_t cache, int segment) 30 | { 31 | struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; 32 | struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; 33 | 34 | return raw->entries; 35 | } 36 | 37 | uint64_t ocf_get_metadata_segment_elems_per_page(ocf_cache_t cache, int segment) 38 | { 39 | struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; 40 | struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; 41 | 42 | return raw->entries_in_page; 43 | } 44 | 45 | uint64_t ocf_get_metadata_segment_elem_size(ocf_cache_t cache, int segment) 46 | { 47 | struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; 48 | struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; 49 | 50 | if (segment == metadata_segment_sb_config) 51 | return offsetof(struct ocf_superblock_config, checksum); 52 | 53 | return raw->entry_size; 54 | } 55 | 56 | bool ocf_get_metadata_segment_is_flapped(ocf_cache_t cache, int segment) 57 | { 58 | struct ocf_metadata_ctrl *ctrl = cache->metadata.priv; 59 | struct ocf_metadata_raw *raw = &ctrl->raw_desc[segment]; 60 | 61 | return raw->flapping; 62 | } 63 | -------------------------------------------------------------------------------- /src/metadata/metadata_raw_volatile.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "metadata.h" 7 | #include "metadata_segment_id.h" 8 | #include "metadata_raw.h" 9 | #include "metadata_io.h" 10 | #include "metadata_raw_volatile.h" 11 | 12 | /* 13 | * RAW volatile Implementation - Size on SSD 14 | */ 15 | uint32_t raw_volatile_size_on_ssd(struct ocf_metadata_raw *raw) 16 | { 17 | return 0; 18 | } 19 | 20 | /* 21 | * RAW volatile Implementation - Checksum 22 | */ 23 | uint32_t raw_volatile_checksum(ocf_cache_t cache, 24 | struct ocf_metadata_raw *raw) 25 | { 26 | return 0; 27 | } 28 | 29 | /* 30 | * RAW volatile Implementation - Update 31 | */ 32 | int raw_volatile_update(ocf_cache_t cache, 33 | struct ocf_metadata_raw *raw, ctx_data_t *data, 34 | uint64_t page, uint64_t count) 35 | { 36 | /* Do nothing on purpose. */ 37 | return 0; 38 | } 39 | 40 | /* 41 | * RAW volatile Implementation - Zero - implemented as noop 42 | */ 43 | void raw_volatile_zero(ocf_cache_t cache, struct ocf_metadata_raw *raw, 44 | ocf_metadata_end_t cmpl, void *context) 45 | { 46 | cmpl(context, 0); 47 | } 48 | 49 | /* 50 | * RAW volatile Implementation - Load all metadata elements from SSD 51 | */ 52 | void raw_volatile_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, 53 | ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx) 54 | { 55 | cmpl(priv, -OCF_ERR_NOT_SUPP); 56 | } 57 | 58 | /* 59 | * RAM Implementation - Flush all elements 60 | */ 61 | void raw_volatile_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, 62 | ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx) 63 | { 64 | cmpl(priv, 0); 65 | } 66 | 67 | /* 68 | * RAM RAM Implementation - Mark to Flush 69 | */ 70 | void raw_volatile_flush_mark(ocf_cache_t cache, struct ocf_request *req, 71 | uint32_t map_idx, int to_state, uint8_t start, uint8_t stop) 72 | { 73 | } 74 | 75 | /* 76 | * RAM RAM Implementation - Do Flush asynchronously 77 | */ 78 | int raw_volatile_flush_do_asynch(ocf_cache_t cache, 79 | struct ocf_request *req, struct ocf_metadata_raw *raw, 80 | ocf_req_end_t complete) 81 | { 82 | complete(req, 0); 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /inc/ocf_composite_volume.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2022 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __OCF_COMPOSITE_VOLUME_H__ 8 | #define __OCF_COMPOSITE_VOLUME_H__ 9 | 10 | /** 11 | * @file 12 | * @brief OCF composite volume API 13 | */ 14 | 15 | #include "ocf_types.h" 16 | #include "ocf_env_headers.h" 17 | #include "ocf_err.h" 18 | #include "ocf_volume.h" 19 | 20 | #define OCF_VOLUME_TYPE_COMPOSITE 10 21 | 22 | /** 23 | * @brief handle to object designating composite volume 24 | */ 25 | typedef ocf_volume_t ocf_composite_volume_t; 26 | 27 | /** 28 | * @brief Allocate and initialize composite volume 29 | * 30 | * @param[out] cvolume pointer to volume handle 31 | * @param[in] ctx OCF context 32 | * 33 | * @return Zero when success, othewise an error 34 | */ 35 | int ocf_composite_volume_create(ocf_composite_volume_t *cvolume, ocf_ctx_t ctx); 36 | 37 | /** 38 | * @brief Deinitialize and free composite volume 39 | * 40 | * @param[in] volume volume handle 41 | */ 42 | void ocf_composite_volume_destroy(ocf_composite_volume_t cvolume); 43 | 44 | /** 45 | * @brief Add subvolume to composite volume 46 | * 47 | * @param[in] cvolume composite volume handle 48 | * @param[in] type type of added subvolume 49 | * @param[in] uuid UUID of added subvolume 50 | * @param[in] volume_params params to be passed to subvolume open 51 | * 52 | * @return Zero when success, othewise an error 53 | */ 54 | int ocf_composite_volume_add(ocf_composite_volume_t cvolume, 55 | ocf_volume_type_t type, struct ocf_volume_uuid *uuid, 56 | void *volume_params); 57 | 58 | typedef int (*ocf_composite_volume_member_visitor_t)(ocf_volume_t subvolume, 59 | void *priv); 60 | 61 | /** 62 | * @brief Call @visitor on every valid member of composite volume 63 | * 64 | * @param[in] cvolume composite volume handle 65 | * @param[in] visitor function callback 66 | * @param[in] priv pointer to be passed to the callback 67 | * 68 | * @return subvolume in composite volume 69 | */ 70 | int ocf_composite_volume_member_visit(ocf_composite_volume_t cvolume, 71 | ocf_composite_volume_member_visitor_t visitor, void *priv); 72 | 73 | #endif /* __OCF_COMPOSITE_VOLUME_H__ */ 74 | -------------------------------------------------------------------------------- /src/ocf_io_class.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf.h" 7 | #include "ocf_priv.h" 8 | #include "metadata/metadata.h" 9 | #include "engine/cache_engine.h" 10 | #include "utils/utils_user_part.h" 11 | 12 | int ocf_cache_io_class_get_info(ocf_cache_t cache, uint32_t io_class, 13 | struct ocf_io_class_info *info) 14 | { 15 | ocf_part_id_t part_id = io_class; 16 | struct ocf_part *part; 17 | 18 | OCF_CHECK_NULL(cache); 19 | 20 | if (ocf_cache_is_standby(cache)) 21 | return -OCF_ERR_CACHE_STANDBY; 22 | 23 | if (!info) 24 | return -OCF_ERR_INVAL; 25 | 26 | if (io_class >= OCF_USER_IO_CLASS_MAX) 27 | return -OCF_ERR_INVAL; 28 | 29 | if (!ocf_user_part_is_valid(&cache->user_parts[part_id])) { 30 | /* Partition does not exist */ 31 | return -OCF_ERR_IO_CLASS_NOT_EXIST; 32 | } 33 | 34 | if (env_strncpy(info->name, OCF_IO_CLASS_NAME_MAX - 1, 35 | cache->user_parts[part_id].config->name, 36 | sizeof(cache->user_parts[part_id].config->name))) { 37 | return -OCF_ERR_INVAL; 38 | } 39 | 40 | part = &cache->user_parts[part_id].part; 41 | 42 | info->priority = cache->user_parts[part_id].config->priority; 43 | info->curr_size = ocf_cache_is_device_attached(cache) ? 44 | env_atomic_read(&part->runtime->curr_size) : 0; 45 | info->min_size = cache->user_parts[part_id].config->min_size; 46 | info->max_size = cache->user_parts[part_id].config->max_size; 47 | 48 | info->cleaning_policy_type = cache->cleaner.policy; 49 | 50 | info->cache_mode = cache->user_parts[part_id].config->cache_mode; 51 | 52 | return 0; 53 | } 54 | 55 | int ocf_io_class_visit(ocf_cache_t cache, ocf_io_class_visitor_t visitor, 56 | void *cntx) 57 | { 58 | struct ocf_user_part *user_part; 59 | ocf_part_id_t part_id; 60 | int result = 0; 61 | 62 | OCF_CHECK_NULL(cache); 63 | 64 | if (ocf_cache_is_standby(cache)) 65 | return -OCF_ERR_CACHE_STANDBY; 66 | 67 | if (!visitor) 68 | return -OCF_ERR_INVAL; 69 | 70 | for_each_user_part(cache, user_part, part_id) { 71 | if (!ocf_user_part_is_valid(user_part)) 72 | continue; 73 | 74 | result = visitor(cache, part_id, cntx); 75 | if (result) 76 | break; 77 | } 78 | 79 | return result; 80 | } 81 | -------------------------------------------------------------------------------- /tests/functional/tests/security/conftest.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2022 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | import os 7 | import sys 8 | from ctypes import c_uint64, c_uint32, c_uint16, c_int 9 | from tests.utils.random import RandomStringGenerator, RandomGenerator, DefaultRanges, Range 10 | 11 | from pyocf.types.cache import CacheMode, MetadataLayout, PromotionPolicy 12 | from pyocf.types.shared import CacheLineSize 13 | 14 | import pytest 15 | 16 | sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir)) 17 | 18 | 19 | def enum_min(enum): 20 | return list(enum)[0].value 21 | 22 | 23 | def enum_max(enum): 24 | return list(enum)[-1].value 25 | 26 | 27 | def enum_range(enum): 28 | return Range(enum_min(enum), enum_max(enum)) 29 | 30 | 31 | @pytest.fixture(params=RandomGenerator(DefaultRanges.UINT16)) 32 | def c_uint16_randomize(request): 33 | return request.param 34 | 35 | 36 | @pytest.fixture(params=RandomGenerator(DefaultRanges.UINT32)) 37 | def c_uint32_randomize(request): 38 | return request.param 39 | 40 | 41 | @pytest.fixture(params=RandomGenerator(DefaultRanges.UINT64)) 42 | def c_uint64_randomize(request): 43 | return request.param 44 | 45 | 46 | @pytest.fixture(params=RandomGenerator(DefaultRanges.INT)) 47 | def c_int_randomize(request): 48 | return request.param 49 | 50 | 51 | @pytest.fixture(params=RandomGenerator(DefaultRanges.INT)) 52 | def c_int_sector_randomize(request): 53 | return request.param // 512 * 512 54 | 55 | 56 | @pytest.fixture(params=RandomStringGenerator()) 57 | def string_randomize(request): 58 | return request.param 59 | 60 | 61 | @pytest.fixture(params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(CacheMode))) 62 | def not_cache_mode_randomize(request): 63 | return request.param 64 | 65 | 66 | @pytest.fixture( 67 | params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(CacheLineSize)) 68 | ) 69 | def not_cache_line_size_randomize(request): 70 | return request.param 71 | 72 | 73 | @pytest.fixture( 74 | params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(PromotionPolicy)) 75 | ) 76 | def not_promotion_policy_randomize(request): 77 | return request.param 78 | -------------------------------------------------------------------------------- /tests/unit/framework/tests_config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # 4 | # Copyright(c) 2012-2021 Intel Corporation 5 | # SPDX-License-Identifier: BSD-3-Clause 6 | # 7 | 8 | # ALL PATHS SHOULD BE ENDED WITH "/" CHARACTER 9 | 10 | MAIN_DIRECTORY_OF_TESTED_PROJECT = "../../../" 11 | 12 | MAIN_DIRECTORY_OF_ENV_FILES = MAIN_DIRECTORY_OF_TESTED_PROJECT + "env/posix/" 13 | 14 | MAIN_DIRECTORY_OF_UNIT_TESTS = "../tests/" 15 | 16 | # Paths to all directories, in which tests are stored. All paths should be relative to 17 | # MAIN_DIRECTORY_OF_UNIT_TESTS 18 | DIRECTORIES_WITH_TESTS_LIST = ["cleaning/", "metadata/", "mngt/", "concurrency/", "engine/", 19 | "ocf_space.c/", "ocf_lru.c/", "utils/", "promotion/"] 20 | 21 | # Paths to all directories containing files with sources. All paths should be relative to 22 | # MAIN_DIRECTORY_OF_TESTED_PROJECT 23 | DIRECTORIES_TO_INCLUDE_FROM_PROJECT_LIST = ["src/", "src/cleaning/", "src/engine/", "src/metadata/", 24 | "src/eviction/", "src/mngt/", "src/concurrency/", 25 | "src/utils/", "inc/", "src/promotion/", 26 | "src/promotion/nhit/"] 27 | 28 | # Paths to all directories from directory with tests, which should also be included 29 | DIRECTORIES_TO_INCLUDE_FROM_UT_LIST = ["ocf_env/"] 30 | 31 | # Paths to include, required by cmake, cmocka, cunit 32 | FRAMEWORK_DIRECTORIES_TO_INCLUDE_LIST = ["${CMOCKA_PUBLIC_INCLUDE_DIRS}", "${CMAKE_BINARY_DIR}", 33 | "${CMAKE_CURRENT_SOURCE_DIR}"] 34 | 35 | # Path to directory containing all sources after preprocessing. Should be relative to 36 | # MAIN_DIRECTORY_OF_UNIT_TESTS 37 | PREPROCESSED_SOURCES_REPOSITORY = "preprocessed_sources_repository/" 38 | 39 | # Path to directory containing all sources after removing unneeded functions and cmake files for 40 | # tests 41 | SOURCES_TO_TEST_REPOSITORY = "sources_to_test_repository/" 42 | 43 | # List of includes. 44 | # Directories will be recursively copied to given destinations in directory with tests. 45 | # key - destination in dir with tests 46 | # value - path in tested project to dir which should be copied 47 | INCLUDES_TO_COPY_DICT = {'ocf_env/ocf/': "inc/"} 48 | -------------------------------------------------------------------------------- /src/metadata/metadata_structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __METADATA_STRUCTS_H__ 8 | #define __METADATA_STRUCTS_H__ 9 | 10 | #include "metadata_common.h" 11 | #include "../ocf_space.h" 12 | #include "../cleaning/cleaning.h" 13 | #include "../ocf_request.h" 14 | 15 | 16 | /** 17 | * @file metadata_priv.h 18 | * @brief Metadata private structures 19 | */ 20 | 21 | /** 22 | * @brief Metadata shutdown status 23 | */ 24 | enum ocf_metadata_shutdown_status { 25 | ocf_metadata_dirty_shutdown = 0, /*!< Dirty OCF shutdown*/ 26 | ocf_metadata_clean_shutdown = 1, /*!< OCF shutdown graceful*/ 27 | }; 28 | 29 | /** 30 | * @brief Query cores completion callback 31 | * 32 | * @param priv - Caller private data 33 | * @param error - Operation error status 34 | * @param num_cores - Number of cores in metadata 35 | */ 36 | typedef void (*ocf_metadata_query_cores_end_t)(void *priv, int error, 37 | unsigned int num_cores); 38 | 39 | #define OCF_METADATA_GLOBAL_LOCK_IDX_BITS 2 40 | #define OCF_NUM_GLOBAL_META_LOCKS (1 << (OCF_METADATA_GLOBAL_LOCK_IDX_BITS)) 41 | 42 | struct ocf_metadata_global_lock { 43 | env_rwsem sem; 44 | } __attribute__((aligned(64))); 45 | 46 | struct ocf_metadata_lock 47 | { 48 | struct ocf_metadata_global_lock global[OCF_NUM_GLOBAL_META_LOCKS]; 49 | /*!< global metadata lock (GML) */ 50 | env_rwlock lru[OCF_NUM_LRU_LISTS]; /*!< Fast locks for lru list */ 51 | env_spinlock partition[OCF_USER_IO_CLASS_MAX]; /* partition lock */ 52 | env_rwsem *hash; /*!< Hash bucket locks */ 53 | env_rwsem *collision_pages; /*!< Collision table page locks */ 54 | ocf_cache_t cache; /*!< Parent cache object */ 55 | uint32_t num_hash_entries; /*!< Hash bucket count */ 56 | uint32_t num_collision_pages; /*!< Collision table page count */ 57 | }; 58 | 59 | /** 60 | * @brief Metadata control structure 61 | */ 62 | struct ocf_metadata { 63 | void *priv; 64 | /*!< Private data of metadata service interface */ 65 | 66 | ocf_cache_line_size_t line_size; 67 | /*!< Cache line size */ 68 | 69 | bool is_volatile; 70 | /*!< true if metadata used in volatile mode (RAM only) */ 71 | 72 | struct ocf_metadata_lock lock; 73 | }; 74 | 75 | #endif /* __METADATA_STRUCTS_H__ */ 76 | -------------------------------------------------------------------------------- /src/utils/utils_realloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef UTILS_REALLOC_H_ 7 | #define UTILS_REALLOC_H_ 8 | 9 | /** 10 | * @file utils_realloc.h 11 | * @brief OCF realloc 12 | */ 13 | 14 | void ocf_realloc_init(void **mem, size_t *limit); 15 | 16 | int ocf_realloc(void **mem, size_t size, size_t count, size_t *limit); 17 | 18 | int ocf_realloc_cp(void **mem, size_t size, size_t count, size_t *limit); 19 | 20 | /** 21 | * @brief Initialize memory pointer and limit before reallocator usage 22 | * 23 | * @param[inout] mem - Pointer to the memory 24 | * @param[inout] limit - Variable used internally by reallocator and indicates 25 | * last allocation size 26 | */ 27 | #define OCF_REALLOC_INIT(mem, limit) \ 28 | ocf_realloc_init((void **)mem, limit) 29 | 30 | /** 31 | * @brief De-Initialize memory pointer and limit, free memory 32 | * 33 | * @param[inout] mem - Pointer to the memory 34 | * @param[inout] limit - Variable used internally by reallocator and indicates 35 | * last allocation size 36 | */ 37 | #define OCF_REALLOC_DEINIT(mem, limit) \ 38 | ocf_realloc((void **)mem, 0, 0, limit) 39 | 40 | /** 41 | * @brief Reallocate referenced memory if it is required. 42 | * 43 | * @param[inout] mem - Pointer to the memory 44 | * @param[in] size - Size of particular element 45 | * @param[in] count - Counts of element 46 | * @param[inout] limit - Variable used internally by reallocator and indicates 47 | * last allocation size 48 | * 49 | * @return 0 - Reallocation successful, Non zero - Realocation ERROR 50 | */ 51 | #define OCF_REALLOC(mem, size, count, limit) \ 52 | ocf_realloc((void **)mem, size, count, limit) 53 | 54 | /** 55 | * @brief Reallocate referenced memory if it is required and copy old content 56 | * into new memory space, new memory space is set to '0' 57 | * 58 | * @param[inout] mem - Pointer to the memory 59 | * @param[in] size - Size of particular element 60 | * @param[in] count - Counts of element 61 | * @param[inout] limit - Variable used internally by reallocator and indicates 62 | * last allocation size 63 | * 64 | * @return 0 - Reallocation successful, Non zero - Realocation ERROR 65 | */ 66 | #define OCF_REALLOC_CP(mem, size, count, limit) \ 67 | ocf_realloc_cp((void **)mem, size, count, limit) 68 | 69 | #endif /* UTILS_REALLOC_H_ */ 70 | -------------------------------------------------------------------------------- /tests/unit/tests/metadata/metadata_collision.c/metadata_collision.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | /* 7 | * src/metadata/metadata_collision.c 8 | * ocf_metadata_hash_func 9 | * 10 | * ocf_metadata_get_hash 11 | * 12 | */ 13 | 14 | #undef static 15 | 16 | #undef inline 17 | 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "print_desc.h" 24 | 25 | #include "ocf/ocf.h" 26 | #include "metadata.h" 27 | #include "../utils/utils_cache_line.h" 28 | 29 | #include "metadata/metadata_collision.c/metadata_collision_generated_wraps.c" 30 | 31 | static void metadata_hash_func_test01(void **state) 32 | { 33 | struct ocf_cache *cache; 34 | bool wrap = false; 35 | ocf_cache_line_t i; 36 | ocf_cache_line_t hash_cur, hash_next; 37 | unsigned c; 38 | ocf_core_id_t core_ids[] = {0, 1, 2, 100, OCF_CORE_MAX}; 39 | ocf_core_id_t core_id; 40 | 41 | print_test_description("Verify that hash function increments by 1 and generates" 42 | "collision after 'hash_table_entries' successive core lines"); 43 | 44 | cache = test_malloc(sizeof(*cache)); 45 | cache->device = test_malloc(sizeof(*cache->device)); 46 | cache->device->hash_table_entries = 10; 47 | 48 | for (c = 0; c < sizeof(core_ids) / sizeof(core_ids[0]); c++) { 49 | core_id = core_ids[c]; 50 | for (i = 0; i < cache->device->hash_table_entries + 1; i++) { 51 | hash_cur = ocf_metadata_hash_func(cache, i, core_id); 52 | hash_next = ocf_metadata_hash_func(cache, i + 1, core_id); 53 | /* make sure hash value is within expected range */ 54 | assert(hash_cur < cache->device->hash_table_entries); 55 | assert(hash_next < cache->device->hash_table_entries); 56 | /* hash should either increment by 1 or overflow to 0 */ 57 | assert(hash_next == (hash_cur + 1) % cache->device->hash_table_entries); 58 | } 59 | } 60 | 61 | test_free(cache->device); 62 | test_free(cache); 63 | } 64 | 65 | int main(void) 66 | { 67 | const struct CMUnitTest tests[] = { 68 | cmocka_unit_test(metadata_hash_func_test01) 69 | }; 70 | 71 | print_message("Unit test of src/metadata/metadata_collision.c"); 72 | 73 | return cmocka_run_group_tests(tests, NULL, NULL); 74 | } 75 | -------------------------------------------------------------------------------- /src/metadata/metadata_core.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2020-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #include "ocf/ocf.h" 7 | #include "../ocf_priv.h" 8 | #include "metadata.h" 9 | #include "metadata_core.h" 10 | #include "metadata_internal.h" 11 | #include "metadata_raw.h" 12 | 13 | void ocf_metadata_get_core_info(struct ocf_cache *cache, 14 | ocf_cache_line_t line, ocf_core_id_t *core_id, 15 | uint64_t *core_sector) 16 | { 17 | const struct ocf_metadata_map *collision; 18 | struct ocf_metadata_ctrl *ctrl = 19 | (struct ocf_metadata_ctrl *) cache->metadata.priv; 20 | 21 | collision = ocf_metadata_raw_rd_access(cache, 22 | &(ctrl->raw_desc[metadata_segment_collision]), line); 23 | 24 | ENV_BUG_ON(!collision); 25 | 26 | if (core_id) 27 | *core_id = collision->core_id; 28 | if (core_sector) 29 | *core_sector = collision->core_line; 30 | } 31 | 32 | void ocf_metadata_set_core_info(struct ocf_cache *cache, 33 | ocf_cache_line_t line, ocf_core_id_t core_id, 34 | uint64_t core_sector) 35 | { 36 | struct ocf_metadata_map *collision; 37 | struct ocf_metadata_ctrl *ctrl = 38 | (struct ocf_metadata_ctrl *) cache->metadata.priv; 39 | 40 | collision = ocf_metadata_raw_wr_access(cache, 41 | &(ctrl->raw_desc[metadata_segment_collision]), line); 42 | 43 | if (collision) { 44 | collision->core_id = core_id; 45 | collision->core_line = core_sector; 46 | } else { 47 | ocf_metadata_error(cache); 48 | } 49 | } 50 | 51 | ocf_core_id_t ocf_metadata_get_core_id(struct ocf_cache *cache, 52 | ocf_cache_line_t line) 53 | { 54 | const struct ocf_metadata_map *collision; 55 | struct ocf_metadata_ctrl *ctrl = 56 | (struct ocf_metadata_ctrl *) cache->metadata.priv; 57 | 58 | collision = ocf_metadata_raw_rd_access(cache, 59 | &(ctrl->raw_desc[metadata_segment_collision]), line); 60 | 61 | if (collision) 62 | return collision->core_id; 63 | 64 | ocf_metadata_error(cache); 65 | return OCF_CORE_MAX; 66 | } 67 | 68 | struct ocf_metadata_uuid *ocf_metadata_get_core_uuid( 69 | struct ocf_cache *cache, ocf_core_id_t core_id) 70 | { 71 | struct ocf_metadata_uuid *muuid; 72 | struct ocf_metadata_ctrl *ctrl = 73 | (struct ocf_metadata_ctrl *) cache->metadata.priv; 74 | 75 | muuid = ocf_metadata_raw_wr_access(cache, 76 | &(ctrl->raw_desc[metadata_segment_core_uuid]), core_id); 77 | 78 | if (!muuid) 79 | ocf_metadata_error(cache); 80 | 81 | return muuid; 82 | } 83 | -------------------------------------------------------------------------------- /tests/functional/tests/security/test_failover_security.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2022 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | import pytest 7 | import logging 8 | from datetime import datetime 9 | 10 | from pyocf.types.volume_cache import CacheVolume 11 | from pyocf.types.volume import RamVolume 12 | from pyocf.types.cache import Cache, CacheMetadataSegment, CacheMode 13 | from pyocf.utils import Size 14 | from pyocf.types.shared import CacheLineSize, OcfError, OcfErrorCode 15 | from pyocf.types.ctx import OcfCtx 16 | from pyocf.rio import Rio, ReadWrite 17 | from pyocf.helpers import get_metadata_segment_size, get_metadata_segment_page_location 18 | from tests.utils.random import RandomGenerator 19 | 20 | logger = logging.getLogger(__name__) 21 | 22 | 23 | @pytest.mark.security 24 | @pytest.mark.parametrize("cache_line_size", CacheLineSize) 25 | @pytest.mark.parametrize( 26 | "bs", 27 | [ 28 | Size.from_B(512), 29 | Size.from_KiB(1), 30 | Size.from_KiB(18), 31 | Size.from_KiB(128), 32 | ], 33 | ) 34 | @pytest.mark.parametrize( 35 | "io_size", 36 | [ 37 | Size.from_B(512), 38 | Size.from_KiB(10), 39 | Size.from_MiB(1), 40 | Size.from_MiB(10), 41 | Size.from_GiB(1), 42 | ], 43 | ) 44 | @pytest.mark.parametrize("section", CacheMetadataSegment) 45 | def test_garbage_on_cache_exported_object(pyocf_ctx, cache_line_size, bs, io_size, section): 46 | num_jobs = 1 47 | qd = 64 48 | 49 | vol_size = Size.from_MiB(100) 50 | cache_vol = RamVolume(vol_size) 51 | secondary_cache_volume = RamVolume(vol_size) 52 | 53 | cache = Cache(owner=OcfCtx.get_default(), cache_line_size=cache_line_size) 54 | 55 | cache.start_cache(init_default_io_queue=False) 56 | 57 | for i in range(num_jobs): 58 | cache.add_io_queue(f"io-queue-{i}") 59 | 60 | cache.standby_attach(cache_vol) 61 | 62 | cache_exp_vol = CacheVolume(cache) 63 | 64 | seed = next(RandomGenerator()) 65 | r = ( 66 | Rio() 67 | .target(cache_exp_vol) 68 | .njobs(num_jobs) 69 | .readwrite(ReadWrite.RANDWRITE) 70 | .io_size(io_size) 71 | .randseed(seed) 72 | .bs(bs) 73 | .qd(qd) 74 | .norandommap() 75 | .run(cache.io_queues) 76 | ) 77 | 78 | cache.standby_detach() 79 | with pytest.raises(OcfError): 80 | cache.standby_activate(secondary_cache_volume, open_cores=False) 81 | -------------------------------------------------------------------------------- /tests/functional/tests/engine/test_d2c.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2024 Huawei Technologies 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | 7 | from time import sleep 8 | import pytest 9 | 10 | 11 | from pyocf.types.cache import Cache 12 | from pyocf.types.core import Core 13 | from pyocf.types.data import Data 14 | from pyocf.types.io import IoDir, Sync 15 | from pyocf.types.volume import RamVolume 16 | from pyocf.types.volume_core import CoreVolume 17 | from pyocf.utils import Size 18 | 19 | CORE_SIZE = 4096 20 | 21 | 22 | def test_d2c_io(pyocf_ctx): 23 | """ 24 | Start cache in D2C 25 | prepare an IO in D2C 26 | attach cache 27 | submit and complete an IO in WT 28 | submit the D2C IO 29 | read data from core 30 | verify the data read from core matches with content of the core disk 31 | """ 32 | cache_device = RamVolume(Size.from_MiB(50)) 33 | core_device = RamVolume(Size(CORE_SIZE)) 34 | 35 | cache = Cache(owner=pyocf_ctx) 36 | cache.start_cache() 37 | core = Core.using_device(core_device) 38 | cache.add_core(core) 39 | 40 | queue = cache.get_default_queue() 41 | vol = CoreVolume(core) 42 | vol.open() 43 | 44 | d2c_io = vol.new_io(queue, 0, CORE_SIZE, IoDir.WRITE, 0, 0) 45 | d2c_data = Data(CORE_SIZE) 46 | d2c_data.write(b"a" * CORE_SIZE, CORE_SIZE) 47 | d2c_io.set_data(d2c_data) 48 | 49 | c = cache.attach_device_async(cache_device) 50 | sleep(1) 51 | 52 | wt_io = vol.new_io(queue, 0, CORE_SIZE, IoDir.WRITE, 0, 0) 53 | wt_data = Data(CORE_SIZE) 54 | wt_data.write(b"b" * CORE_SIZE, CORE_SIZE) 55 | wt_io.set_data(wt_data) 56 | 57 | wt_completion = Sync(wt_io).submit() 58 | assert int(wt_completion.results["err"]) == 0 59 | 60 | d2c_completion = Sync(d2c_io).submit() 61 | assert int(d2c_completion.results["err"]) == 0 62 | 63 | c.wait() 64 | 65 | if c.results["error"]: 66 | raise OcfError( 67 | f"Attaching cache device failed", 68 | c.results["error"], 69 | ) 70 | 71 | assert cache.get_stats()["req"]["wr_pt"]["value"] == 2 72 | 73 | read_io = vol.new_io(queue, 0, CORE_SIZE, IoDir.READ, 0, 0) 74 | read_data = Data(CORE_SIZE) 75 | read_io.set_data(read_data) 76 | 77 | read_completion = Sync(read_io).submit() 78 | assert int(read_completion.results["err"]) == 0 79 | assert cache.get_stats()["req"]["rd_full_misses"]["value"] == 1 80 | 81 | cache.stop() 82 | 83 | assert core_device.md5() == read_data.md5() 84 | -------------------------------------------------------------------------------- /tests/functional/tests/engine/test_large_io.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2022 Intel Corporation 3 | # Copyright(c) 2024 Huawei Technologies 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | # 6 | 7 | from ctypes import c_int 8 | 9 | from pyocf.types.cache import Cache 10 | from pyocf.types.data import Data 11 | from pyocf.types.core import Core 12 | from pyocf.types.io import IoDir, Sync 13 | from pyocf.types.volume import RamVolume, IoFlags 14 | from pyocf.types.volume_core import CoreVolume 15 | from pyocf.utils import Size 16 | 17 | 18 | def test_large_flush(pyocf_ctx): 19 | cache_device = RamVolume(Size.from_MiB(50)) 20 | core_device = RamVolume(Size.from_MiB(100)) 21 | 22 | cache = Cache.start_on_device(cache_device) 23 | core = Core.using_device(core_device) 24 | cache.add_core(core) 25 | 26 | queue = cache.get_default_queue() 27 | vol = CoreVolume(core) 28 | vol.open() 29 | 30 | io = vol.new_io(queue, 0, core_device.size.bytes, IoDir.WRITE, 0, IoFlags.FLUSH) 31 | data = Data(byte_count=0) 32 | io.set_data(data, 0) 33 | completion = Sync(io).submit_flush() 34 | vol.close() 35 | 36 | assert int(completion.results["err"]) == 0 37 | 38 | cache.stop() 39 | 40 | 41 | def test_large_discard(pyocf_ctx): 42 | cache_device = RamVolume(Size.from_MiB(50)) 43 | core_device = RamVolume(Size.from_MiB(100)) 44 | 45 | cache = Cache.start_on_device(cache_device) 46 | core = Core.using_device(core_device) 47 | cache.add_core(core) 48 | 49 | queue = cache.get_default_queue() 50 | vol = CoreVolume(core) 51 | vol.open() 52 | 53 | io = vol.new_io(queue, 0, core_device.size.bytes, IoDir.WRITE, 0, 0) 54 | data = Data(byte_count=0) 55 | io.set_data(data, 0) 56 | completion = Sync(io).submit_discard() 57 | vol.close() 58 | 59 | assert int(completion.results["err"]) == 0 60 | 61 | cache.stop() 62 | 63 | 64 | def test_large_io(pyocf_ctx): 65 | cache_device = RamVolume(Size.from_MiB(50)) 66 | core_device = RamVolume(Size.from_MiB(100)) 67 | 68 | cache = Cache.start_on_device(cache_device) 69 | core = Core.using_device(core_device) 70 | cache.add_core(core) 71 | 72 | queue = cache.get_default_queue() 73 | vol = CoreVolume(core) 74 | vol.open() 75 | 76 | io = vol.new_io(queue, 0, core_device.size.bytes, IoDir.WRITE, 0, 0) 77 | data = Data(byte_count=core_device.size.bytes) 78 | io.set_data(data) 79 | completion = Sync(io).submit() 80 | 81 | vol.close() 82 | 83 | assert int(completion.results["err"]) == 0 84 | 85 | cache.stop() 86 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/stats/shared.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2021 Intel Corporation 3 | # Copyright(c) 2024 Huawei Technologies 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | # 6 | 7 | from ctypes import c_uint64, c_uint32, Structure 8 | 9 | 10 | class _Stat(Structure): 11 | _fields_ = [("value", c_uint64), ("fraction", c_uint64)] 12 | 13 | 14 | class OcfStatsReq(Structure): 15 | _fields_ = [ 16 | ("partial_miss", c_uint64), 17 | ("full_miss", c_uint64), 18 | ("total", c_uint64), 19 | ("pass_through", c_uint64), 20 | ] 21 | 22 | 23 | class OcfStatsBlock(Structure): 24 | _fields_ = [("read", c_uint64), ("write", c_uint64)] 25 | 26 | 27 | class OcfStatsError(Structure): 28 | _fields_ = [("read", c_uint32), ("write", c_uint32)] 29 | 30 | 31 | class OcfStatsDebug(Structure): 32 | _fields_ = [ 33 | ("read_size", c_uint64 * 12), 34 | ("write_size", c_uint64 * 12), 35 | ("read_align", c_uint64 * 4), 36 | ("write_align", c_uint64 * 4), 37 | ] 38 | 39 | 40 | class UsageStats(Structure): 41 | _fields_ = [ 42 | ("occupancy", _Stat), 43 | ("free", _Stat), 44 | ("clean", _Stat), 45 | ("dirty", _Stat), 46 | ] 47 | 48 | 49 | class RequestsStats(Structure): 50 | _fields_ = [ 51 | ("rd_hits", _Stat), 52 | ("rd_partial_misses", _Stat), 53 | ("rd_full_misses", _Stat), 54 | ("rd_total", _Stat), 55 | ("wr_hits", _Stat), 56 | ("wr_partial_misses", _Stat), 57 | ("wr_full_misses", _Stat), 58 | ("wr_total", _Stat), 59 | ("rd_pt", _Stat), 60 | ("wr_pt", _Stat), 61 | ("serviced", _Stat), 62 | ("total", _Stat), 63 | ] 64 | 65 | 66 | class BlocksStats(Structure): 67 | _fields_ = [ 68 | ("core_volume_rd", _Stat), 69 | ("core_volume_wr", _Stat), 70 | ("core_volume_total", _Stat), 71 | ("cache_volume_rd", _Stat), 72 | ("cache_volume_wr", _Stat), 73 | ("cache_volume_total", _Stat), 74 | ("volume_rd", _Stat), 75 | ("volume_wr", _Stat), 76 | ("volume_total", _Stat), 77 | ("pt_rd", _Stat), 78 | ("pt_wr", _Stat), 79 | ("pt_total", _Stat), 80 | ] 81 | 82 | 83 | class ErrorsStats(Structure): 84 | _fields_ = [ 85 | ("core_volume_rd", _Stat), 86 | ("core_volume_wr", _Stat), 87 | ("core_volume_total", _Stat), 88 | ("cache_volume_rd", _Stat), 89 | ("cache_volume_wr", _Stat), 90 | ("cache_volume_total", _Stat), 91 | ("total", _Stat), 92 | ] 93 | -------------------------------------------------------------------------------- /src/engine/engine_d2c.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2024-2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #include "ocf/ocf.h" 7 | #include "../ocf_cache_priv.h" 8 | #include "engine_d2c.h" 9 | #include "engine_common.h" 10 | #include "engine_io.h" 11 | #include "cache_engine.h" 12 | #include "../ocf_request.h" 13 | #include "../metadata/metadata.h" 14 | 15 | #define OCF_ENGINE_DEBUG_IO_NAME "d2c" 16 | #include "engine_debug.h" 17 | 18 | static void _ocf_d2c_completion(struct ocf_request *req, int error) 19 | { 20 | OCF_DEBUG_RQ(req, "Completion"); 21 | 22 | if (error) 23 | ocf_core_stats_core_error_update(req->core, req->rw); 24 | 25 | /* Complete request */ 26 | req->complete(req, error); 27 | 28 | /* Release OCF request */ 29 | ocf_req_put(req); 30 | } 31 | 32 | int ocf_d2c_io_fast(struct ocf_request *req) 33 | { 34 | OCF_DEBUG_TRACE(req->cache); 35 | 36 | /* Increase reference counter - once for submission and second time to 37 | * avoid freeing the request before updating stats 38 | */ 39 | ocf_req_get(req); 40 | ocf_req_get(req); 41 | 42 | ocf_engine_forward_core_io_req(req, _ocf_d2c_completion); 43 | 44 | ocf_engine_update_block_stats(req); 45 | 46 | ocf_core_stats_pt_block_update(req->core, req->part_id, req->rw, 47 | req->bytes); 48 | 49 | ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw, 50 | req->info.hit_no, req->core_line_count); 51 | 52 | ocf_req_put(req); 53 | 54 | return 0; 55 | } 56 | 57 | int ocf_d2c_flush_fast(struct ocf_request *req) 58 | { 59 | OCF_DEBUG_TRACE(req->cache); 60 | 61 | /* Get OCF request - increase reference counter */ 62 | ocf_req_get(req); 63 | 64 | ocf_engine_forward_core_flush_req(req, _ocf_d2c_completion); 65 | 66 | ocf_engine_update_block_stats(req); 67 | 68 | ocf_core_stats_pt_block_update(req->core, req->part_id, req->rw, 69 | req->bytes); 70 | 71 | ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw, 72 | req->info.hit_no, req->core_line_count); 73 | 74 | return 0; 75 | } 76 | 77 | int ocf_d2c_discard_fast(struct ocf_request *req) 78 | { 79 | OCF_DEBUG_TRACE(req->cache); 80 | 81 | /* Get OCF request - increase reference counter */ 82 | ocf_req_get(req); 83 | 84 | ocf_engine_forward_core_discard_req(req, _ocf_d2c_completion); 85 | 86 | ocf_engine_update_block_stats(req); 87 | 88 | ocf_core_stats_pt_block_update(req->core, req->part_id, req->rw, 89 | req->bytes); 90 | 91 | ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw, 92 | req->info.hit_no, req->core_line_count); 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /tests/functional/pyocf/types/cvolume.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2022 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | from ctypes import ( 7 | c_int, 8 | c_uint32, 9 | c_uint64, 10 | c_void_p, 11 | c_char_p, 12 | byref, 13 | cast, 14 | create_string_buffer, 15 | ) 16 | 17 | from ..ocf import OcfLib 18 | from .ctx import OcfCtx 19 | from .io import Io, IoDir 20 | from .queue import Queue 21 | from .shared import OcfError, Uuid 22 | from .volume_exp_obj import OcfInternalVolume 23 | 24 | 25 | class CVolume(OcfInternalVolume): 26 | def __init__(self, ctx): 27 | super().__init__(None) 28 | self.ctx = ctx 29 | self.lib = ctx.lib 30 | 31 | self.cvol = c_void_p() 32 | ret = lib.ocf_composite_volume_create(byref(self.cvol), self.ctx.ctx_handle) 33 | 34 | if ret != 0: 35 | raise OcfError("Composite volume creation failed", ret) 36 | 37 | self.handle = self.cvol.value 38 | 39 | def destroy(self): 40 | self.lib.ocf_composite_volume_destroy(self.cvol) 41 | self.cvol = None 42 | self.handle = 0 43 | 44 | def add(self, vol): 45 | uuid = Uuid( 46 | _data=cast(create_string_buffer(vol.uuid.encode("ascii")), c_char_p), 47 | _size=len(vol.uuid) + 1, 48 | ) 49 | 50 | volume = c_void_p() 51 | ocf_vol_type = self.ctx.ocf_volume_type[type(vol)] 52 | 53 | ret = self.lib.ocf_composite_volume_add(self.cvol, ocf_vol_type, byref(uuid), c_void_p()) 54 | 55 | if ret != 0: 56 | raise OcfError("Failed to add volume to a composite volume", ret) 57 | 58 | def get_c_handle(self): 59 | return self.cvol.value 60 | 61 | def open(self): 62 | ret = super().open() 63 | if ret == 0: 64 | ret = self.lib.ocf_volume_open(self.handle, c_void_p()) 65 | 66 | if ret: 67 | raise OcfError("opening composite volume failed", ret) 68 | 69 | return ret 70 | 71 | def close(self): 72 | self.lib.ocf_volume_close(self.handle) 73 | super().close() 74 | 75 | 76 | 77 | lib = OcfLib.getInstance() 78 | lib.ocf_composite_volume_create.restype = c_int 79 | lib.ocf_composite_volume_create.argtypes = [c_void_p, c_void_p] 80 | lib.ocf_composite_volume_destroy.argtypes = [c_void_p] 81 | lib.ocf_composite_volume_add.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p] 82 | lib.ocf_composite_volume_add.restype = c_int 83 | lib.ocf_volume_open.restype = c_int 84 | lib.ocf_volume_open.argtypes = [c_void_p, c_void_p] 85 | lib.ocf_volume_close.argtypes = [c_void_p] 86 | -------------------------------------------------------------------------------- /tests/functional/tests/basic/test_offset.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2024 Huawei Technologies 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | from pyocf.types.cache import Cache 7 | from pyocf.types.core import Core 8 | from pyocf.types.data import Data, DataSeek 9 | from pyocf.types.io import IoDir, Sync 10 | from pyocf.types.volume import RamVolume 11 | from pyocf.types.volume_core import CoreVolume 12 | from pyocf.utils import Size 13 | 14 | 15 | def test_data_with_offset(pyocf_ctx): 16 | cache_device = RamVolume(Size.from_MiB(50)) 17 | core_device = RamVolume(Size.from_MiB(50)) 18 | 19 | cache = Cache.start_on_device(cache_device) 20 | core = Core.using_device(core_device) 21 | queue = cache.get_default_queue() 22 | 23 | cache.add_core(core) 24 | core_volume = CoreVolume(core) 25 | core_volume.open() 26 | 27 | # Populate core backend volume 28 | CL = cache.cache_line_size 29 | data_1 = Data(CL) 30 | for addr in range(0, CL, Size._SECTOR_SIZE): 31 | data_1.seek(DataSeek.BEGIN, addr) 32 | data_1.write(b"I\x00\x00\x00\x00", 5) 33 | core_device.sync_io(queue, CL * 0, data_1, IoDir.WRITE) 34 | core_device.sync_io(queue, CL * 1, data_1, IoDir.WRITE) 35 | core_device.sync_io(queue, CL * 2, data_1, IoDir.WRITE) 36 | core_device.sync_io(queue, CL * 3, data_1, IoDir.WRITE) 37 | 38 | # write using data with offset 39 | B1 = b"12345" 40 | B2 = b"67890" 41 | data = Data(8192) 42 | data.seek(DataSeek.BEGIN, 0) 43 | data.write(B1, len(B1)) 44 | data.seek(DataSeek.BEGIN, 4096) 45 | data.write(B2, len(B2)) 46 | 47 | address = CL 48 | length = CL 49 | offset = CL 50 | io = core_volume.new_io(queue, address, length, IoDir.WRITE, 0, 0) 51 | io.set_data(data, offset) 52 | Sync(io).submit() 53 | 54 | s = core_device.read_sync(queue, 0, 2 * CL) 55 | for addr in range(0, CL, Size._SECTOR_SIZE): 56 | assert chr(s[addr]) == "I", f"addr {addr}" 57 | assert s[CL:CL + len(B2)] == B2 58 | 59 | s = core_volume.read_sync(queue, 0, 2 * CL) 60 | for addr in range(0, CL, Size._SECTOR_SIZE): 61 | assert chr(s[addr]) == "I", f"addr {addr}" 62 | assert s[CL:CL + len(B2)] == B2 63 | 64 | # read using data with offset 65 | data1 = Data(10000) 66 | offset1 = 10 67 | io1 = core_volume.new_io(queue, address, length, IoDir.READ, 0, 0) 68 | io1.set_data(data1, offset1) 69 | Sync(io1).submit() 70 | 71 | s0 = data1.buffer[:offset1] 72 | assert s0 == bytes([Data.DATA_POISON] * offset1) 73 | s1 = data1.buffer[offset1:(offset1 + len(B2))] 74 | assert s1 == B2 75 | -------------------------------------------------------------------------------- /src/metadata/metadata_collision.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_COLLISION_H__ 7 | #define __METADATA_COLLISION_H__ 8 | 9 | /** 10 | * @brief Metadata map structure 11 | */ 12 | 13 | struct ocf_metadata_list_info { 14 | ocf_cache_line_t prev_col; 15 | /*!< Previous cache line in collision list */ 16 | ocf_cache_line_t next_col; 17 | /*!< Next cache line in collision list*/ 18 | ocf_part_id_t partition_id : 8; 19 | /*!< ID of partition where is assigned this cache line*/ 20 | } __attribute__((packed)); 21 | 22 | /** 23 | * @brief Metadata map structure 24 | */ 25 | 26 | struct ocf_metadata_map { 27 | uint64_t core_line; 28 | /*!< Core line addres on cache mapped by this strcture */ 29 | 30 | uint16_t core_id; 31 | /*!< ID of core where is assigned this cache line*/ 32 | 33 | uint8_t status[]; 34 | /*!< Entry status structure e.g. valid, dirty...*/ 35 | } __attribute__((packed)); 36 | 37 | void ocf_metadata_set_collision_info( 38 | struct ocf_cache *cache, ocf_cache_line_t line, 39 | ocf_cache_line_t next, ocf_cache_line_t prev); 40 | 41 | void ocf_metadata_set_collision_next( 42 | struct ocf_cache *cache, ocf_cache_line_t line, 43 | ocf_cache_line_t next); 44 | 45 | void ocf_metadata_set_collision_prev( 46 | struct ocf_cache *cache, ocf_cache_line_t line, 47 | ocf_cache_line_t prev); 48 | 49 | void ocf_metadata_get_collision_info( 50 | struct ocf_cache *cache, ocf_cache_line_t line, 51 | ocf_cache_line_t *next, ocf_cache_line_t *prev); 52 | 53 | static inline ocf_cache_line_t ocf_metadata_get_collision_next( 54 | struct ocf_cache *cache, ocf_cache_line_t line) 55 | { 56 | ocf_cache_line_t next; 57 | 58 | ocf_metadata_get_collision_info(cache, line, &next, NULL); 59 | return next; 60 | } 61 | 62 | static inline ocf_cache_line_t ocf_metadata_get_collision_prev( 63 | struct ocf_cache *cache, ocf_cache_line_t line) 64 | { 65 | ocf_cache_line_t prev; 66 | 67 | ocf_metadata_get_collision_info(cache, line, NULL, &prev); 68 | return prev; 69 | } 70 | 71 | void ocf_metadata_add_to_collision(struct ocf_cache *cache, 72 | ocf_core_id_t core_id, uint64_t core_line, 73 | ocf_cache_line_t hash, ocf_cache_line_t cache_line); 74 | 75 | void ocf_metadata_remove_from_collision(struct ocf_cache *cache, 76 | ocf_cache_line_t line, ocf_part_id_t part_id); 77 | 78 | void ocf_metadata_start_collision_shared_access( 79 | struct ocf_cache *cache, ocf_cache_line_t line); 80 | 81 | void ocf_metadata_end_collision_shared_access( 82 | struct ocf_cache *cache, ocf_cache_line_t line); 83 | 84 | #endif /* METADATA_COLLISION_H_ */ 85 | -------------------------------------------------------------------------------- /env/posix/utils_mpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef UTILS_MPOOL_H_ 7 | #define UTILS_MPOOL_H_ 8 | 9 | #include 10 | #include 11 | 12 | #define MPOOL_ALLOCATOR_NAME_MAX 128 13 | 14 | enum { 15 | env_mpool_1, 16 | env_mpool_2, 17 | env_mpool_4, 18 | env_mpool_8, 19 | env_mpool_16, 20 | env_mpool_32, 21 | env_mpool_64, 22 | env_mpool_128, 23 | 24 | env_mpool_max 25 | }; 26 | 27 | struct env_mpool; 28 | 29 | /** 30 | * @brief Create CAS memory pool 31 | * 32 | * @param hdr_size size of constant allocation part 33 | * @param elem_size size increment for each element 34 | * @param flags Allocation flags 35 | * @param mpool_max Maximal allocator size (power of two) 36 | * @param fallback Should allocations fall back to vmalloc if allocator fails 37 | * @param limits Array of rpool preallocation limits per each mpool allocation 38 | * order or NULL if defaults are to be used. Array should have 39 | * mpool_max elements 40 | * @param name_prefix Format name prefix 41 | * 42 | * @return CAS memory pool 43 | */ 44 | struct env_mpool *env_mpool_create(uint32_t hdr_size, uint32_t elem_size, 45 | int flags, int mpool_max, bool fallback, 46 | const uint32_t limits[env_mpool_max], 47 | const char *name_perfix, bool zero); 48 | 49 | /** 50 | * @brief Destroy existing memory pool 51 | * 52 | * @param mpool memory pool 53 | */ 54 | void env_mpool_destroy(struct env_mpool *mpool); 55 | 56 | /** 57 | * @brief Allocate new items of memory pool 58 | * 59 | * @note Allocation based on ATOMIC memory pool and this function can be called 60 | * when IRQ disable 61 | * 62 | * @param mpool CAS memory pool reference 63 | * @param count Count of elements to be allocated 64 | * 65 | * @return Pointer to the new items 66 | */ 67 | void *env_mpool_new(struct env_mpool *mpool, uint32_t count); 68 | 69 | /** 70 | * @brief Allocate new items of memory pool with specified allocation flag 71 | * 72 | * @param mpool CAS memory pool reference 73 | * @param count Count of elements to be allocated 74 | * @param flags Kernel allocation falgs 75 | * 76 | * @return Pointer to the new items 77 | */ 78 | void *env_mpool_new_f(struct env_mpool *mpool, uint32_t count, int flags); 79 | 80 | /** 81 | * @brief Free existing items of memory pool 82 | * 83 | * @param mpool CAS memory pool reference 84 | * @param items Items to be freed 85 | * @param count - Count of elements to be free 86 | * 87 | * @return Allocation was freed 88 | */ 89 | bool env_mpool_del(struct env_mpool *mpool, void *items, uint32_t count); 90 | 91 | #endif /* UTILS_MPOOL_H_ */ 92 | -------------------------------------------------------------------------------- /src/metadata/metadata_raw_dynamic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | #ifndef __METADATA_RAW_DYNAMIC_H__ 7 | #define __METADATA_RAW_DYNAMIC_H__ 8 | 9 | /** 10 | * @file metadata_raw_dynamic.h 11 | * @brief Metadata RAW container implementation for dynamic numbers of elements 12 | */ 13 | 14 | /* 15 | * RAW DYNAMIC - Initialize 16 | */ 17 | int raw_dynamic_init(ocf_cache_t cache, 18 | ocf_flush_page_synch_t lock_page_pfn, 19 | ocf_flush_page_synch_t unlock_page_pfn, 20 | struct ocf_metadata_raw *raw); 21 | 22 | /* 23 | * RAW DYNAMIC - De-Initialize 24 | */ 25 | int raw_dynamic_deinit(ocf_cache_t cache, 26 | struct ocf_metadata_raw *raw); 27 | 28 | /* 29 | * RAW DYNAMIC - Get size of memory footprint of this RAW metadata container 30 | */ 31 | size_t raw_dynamic_size_of(ocf_cache_t cache, 32 | struct ocf_metadata_raw *raw); 33 | 34 | /* 35 | * RAW DYNAMIC Implementation - Size on SSD 36 | */ 37 | uint32_t raw_dynamic_size_on_ssd(struct ocf_metadata_raw *raw); 38 | 39 | /* 40 | * RAW DYNAMIC Implementation - Checksum 41 | */ 42 | uint32_t raw_dynamic_checksum(ocf_cache_t cache, 43 | struct ocf_metadata_raw *raw); 44 | 45 | /* 46 | * RAM DYNAMIC Implementation - Entry page number 47 | */ 48 | uint32_t raw_dynamic_page(struct ocf_metadata_raw *raw, uint32_t entry); 49 | 50 | /* 51 | * RAW DYNAMIC - Write access for specified entry 52 | */ 53 | void *raw_dynamic_access(ocf_cache_t cache, 54 | struct ocf_metadata_raw *raw, uint32_t entry); 55 | 56 | /* 57 | * RAW DYNAMIC - Update metadata based on cache volume io 58 | */ 59 | int raw_dynamic_update(ocf_cache_t cache, 60 | struct ocf_metadata_raw *raw, ctx_data_t *data, 61 | uint64_t page, uint64_t count); 62 | 63 | /* 64 | * RAW DYNAMIC - Load all metadata of this RAW metadata container 65 | * from cache device 66 | */ 67 | void raw_dynamic_load_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, 68 | ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx); 69 | 70 | /* 71 | * RAW DYNAMIC - Flush all metadata of this RAW metadata container 72 | * to cache device 73 | */ 74 | void raw_dynamic_flush_all(ocf_cache_t cache, struct ocf_metadata_raw *raw, 75 | ocf_metadata_end_t cmpl, void *priv, unsigned flapping_idx); 76 | 77 | /* 78 | * RAW DYNAMIC - Mark specified entry to be flushed 79 | */ 80 | void raw_dynamic_flush_mark(ocf_cache_t cache, struct ocf_request *req, 81 | uint32_t map_idx, int to_state, uint8_t start, uint8_t stop); 82 | 83 | /* 84 | * DYNAMIC Implementation - Do Flush Asynchronously 85 | */ 86 | int raw_dynamic_flush_do_asynch(ocf_cache_t cache, struct ocf_request *req, 87 | struct ocf_metadata_raw *raw, ocf_req_end_t complete); 88 | 89 | 90 | #endif /* METADATA_RAW_H_ */ 91 | -------------------------------------------------------------------------------- /tests/unit/tests/utils/utils_refcnt.c/utils_refcnt_unfreeze.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | /* 7 | * src/utils/utils_refcnt.c 8 | * ocf_refcnt_unfreeze 9 | * 10 | * ocf_refcnt_init 11 | * ocf_refcnt_inc 12 | * ocf_refcnt_dec 13 | * ocf_refcnt_freeze 14 | * 15 | */ 16 | 17 | #undef static 18 | 19 | #undef inline 20 | 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "print_desc.h" 27 | 28 | #include "../utils/utils_refcnt.h" 29 | 30 | #include "utils/utils_refcnt.c/utils_refcnt_unfreeze_generated_wraps.c" 31 | 32 | static void ocf_refcnt_unfreeze_test01(void **state) 33 | { 34 | struct ocf_refcnt rc; 35 | int val, val2; 36 | 37 | print_test_description("Unfreeze decrements freeze counter"); 38 | 39 | ocf_refcnt_init(&rc); 40 | 41 | ocf_refcnt_freeze(&rc); 42 | ocf_refcnt_freeze(&rc); 43 | val = env_atomic_read(&rc.freeze); 44 | 45 | ocf_refcnt_unfreeze(&rc); 46 | val2 = env_atomic_read(&rc.freeze); 47 | assert_int_equal(val2, val - 1); 48 | 49 | ocf_refcnt_unfreeze(&rc); 50 | val2 = env_atomic_read(&rc.freeze); 51 | assert_int_equal(val2, val - 2); 52 | 53 | } 54 | 55 | static void ocf_refcnt_unfreeze_test02(void **state) 56 | { 57 | struct ocf_refcnt rc; 58 | int val, val2; 59 | 60 | print_test_description("Unfreezed counter can be incremented"); 61 | 62 | ocf_refcnt_init(&rc); 63 | 64 | val = ocf_refcnt_inc(&rc); 65 | ocf_refcnt_freeze(&rc); 66 | ocf_refcnt_unfreeze(&rc); 67 | val2 = ocf_refcnt_inc(&rc); 68 | 69 | assert_int_equal(val2, val + 1); 70 | } 71 | 72 | static void ocf_refcnt_unfreeze_test03(void **state) 73 | { 74 | struct ocf_refcnt rc; 75 | int val, val2; 76 | 77 | print_test_description("Two freezes require two unfreezes"); 78 | 79 | ocf_refcnt_init(&rc); 80 | 81 | val = ocf_refcnt_inc(&rc); 82 | ocf_refcnt_freeze(&rc); 83 | ocf_refcnt_freeze(&rc); 84 | ocf_refcnt_unfreeze(&rc); 85 | val2 = ocf_refcnt_inc(&rc); 86 | 87 | assert_int_equal(0, val2); 88 | 89 | ocf_refcnt_unfreeze(&rc); 90 | val2 = ocf_refcnt_inc(&rc); 91 | 92 | assert_int_equal(val2, val + 1); 93 | } 94 | 95 | int main(void) 96 | { 97 | const struct CMUnitTest tests[] = { 98 | cmocka_unit_test(ocf_refcnt_unfreeze_test01), 99 | cmocka_unit_test(ocf_refcnt_unfreeze_test02), 100 | cmocka_unit_test(ocf_refcnt_unfreeze_test03), 101 | }; 102 | 103 | print_message("Unit test of src/utils/utils_refcnt.c"); 104 | 105 | return cmocka_run_group_tests(tests, NULL, NULL); 106 | } 107 | -------------------------------------------------------------------------------- /tests/unit/tests/utils/utils_refcnt.c/utils_refcnt_register_zero_cb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | /* 7 | * src/utils/utils_refcnt.c 8 | * ocf_refcnt_register_zero_cb 9 | * 10 | * ocf_refcnt_init 11 | * ocf_refcnt_inc 12 | * ocf_refcnt_dec 13 | * ocf_refcnt_freeze 14 | * 15 | */ 16 | 17 | #undef static 18 | 19 | #undef inline 20 | 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "print_desc.h" 27 | 28 | #include "../utils/utils_refcnt.h" 29 | 30 | #include "utils/utils_refcnt.c/utils_refcnt_register_zero_cb_generated_wraps.c" 31 | 32 | static void zero_cb(void *ctx) 33 | { 34 | function_called(); 35 | check_expected_ptr(ctx); 36 | } 37 | 38 | static void ocf_refcnt_register_zero_cb_test01(void **state) 39 | { 40 | struct ocf_refcnt rc; 41 | int val; 42 | void *ptr = 0x12345678; 43 | 44 | print_test_description("Callback fires when counter drops to 0"); 45 | 46 | /* cnt = 2 */ 47 | ocf_refcnt_init(&rc); 48 | ocf_refcnt_inc(&rc); 49 | ocf_refcnt_inc(&rc); 50 | 51 | /* freeze and register cb */ 52 | ocf_refcnt_freeze(&rc); 53 | ocf_refcnt_register_zero_cb(&rc, zero_cb, ptr); 54 | 55 | /* 2 -> 1 */ 56 | ocf_refcnt_dec(&rc); 57 | 58 | val = env_atomic_read(&rc.callback); 59 | assert_int_equal(1, val); 60 | 61 | /* expect callback now */ 62 | expect_function_calls(zero_cb, 1); 63 | expect_value(zero_cb, ctx, ptr); 64 | 65 | /* 1 -> 0 */ 66 | ocf_refcnt_dec(&rc); 67 | 68 | val = env_atomic_read(&rc.callback); 69 | assert_int_equal(0, val); 70 | } 71 | 72 | static void ocf_refcnt_register_zero_cb_test02(void **state) 73 | { 74 | struct ocf_refcnt rc; 75 | int val; 76 | void *ptr = 0x12345678; 77 | 78 | print_test_description("Callback fires when counter is already 0"); 79 | 80 | /* cnt = 0 */ 81 | ocf_refcnt_init(&rc); 82 | 83 | /* freeze */ 84 | ocf_refcnt_freeze(&rc); 85 | 86 | /* expect callback now */ 87 | expect_function_calls(zero_cb, 1); 88 | expect_value(zero_cb, ctx, ptr); 89 | 90 | /* register callback */ 91 | ocf_refcnt_register_zero_cb(&rc, zero_cb, ptr); 92 | 93 | val = env_atomic_read(&rc.callback); 94 | assert_int_equal(0, val); 95 | } 96 | 97 | int main(void) 98 | { 99 | const struct CMUnitTest tests[] = { 100 | cmocka_unit_test(ocf_refcnt_register_zero_cb_test01), 101 | cmocka_unit_test(ocf_refcnt_register_zero_cb_test02), 102 | }; 103 | 104 | print_message("Unit test of src/utils/utils_refcnt.c"); 105 | 106 | return cmocka_run_group_tests(tests, NULL, NULL); 107 | } 108 | -------------------------------------------------------------------------------- /src/utils/utils_realloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | #include "ocf/ocf.h" 6 | #include "utils_realloc.h" 7 | #include "ocf_env.h" 8 | 9 | #define OCF_REALLOC_K_MAX (128 * KiB) 10 | 11 | static int _ocf_realloc_with_cp(void **mem, size_t size, size_t count, 12 | size_t *limit, bool cp) 13 | { 14 | size_t alloc_size = size * count; 15 | 16 | ENV_BUG_ON(!mem); 17 | ENV_BUG_ON(!limit); 18 | 19 | if (size && count) { 20 | /* Memory reallocation request */ 21 | 22 | if (alloc_size > *limit) { 23 | /* The space is not enough, we need allocate new one */ 24 | 25 | void *new_mem; 26 | 27 | if (alloc_size > OCF_REALLOC_K_MAX) 28 | new_mem = env_vzalloc(alloc_size); 29 | else 30 | new_mem = env_zalloc(alloc_size, ENV_MEM_NOIO); 31 | 32 | if (!new_mem) { 33 | /* Allocation error */ 34 | return -1; 35 | } 36 | 37 | /* Free previous memory */ 38 | if (*mem) { 39 | if (cp) { 40 | /* copy previous content into new allocated 41 | * memory 42 | */ 43 | ENV_BUG_ON(env_memcpy(new_mem, alloc_size, *mem, *limit)); 44 | 45 | } 46 | 47 | if (*limit > OCF_REALLOC_K_MAX) 48 | env_vfree(*mem); 49 | else 50 | env_free(*mem); 51 | } 52 | 53 | /* Update limit */ 54 | *limit = alloc_size; 55 | 56 | /* Update memory pointer */ 57 | *mem = new_mem; 58 | 59 | return 0; 60 | } 61 | 62 | /* 63 | * The memory space is enough, no action required. 64 | * Space after allocation set to '0' 65 | */ 66 | if (cp) 67 | ENV_BUG_ON(env_memset(*mem + alloc_size, *limit - alloc_size, 0)); 68 | 69 | return 0; 70 | 71 | } 72 | 73 | if ((size == 0) && (count == 0)) { 74 | 75 | if ((*mem) && (*limit)) { 76 | /* Need to free memory */ 77 | if (*limit > OCF_REALLOC_K_MAX) 78 | env_vfree(*mem); 79 | else 80 | env_free(*mem); 81 | 82 | /* Update limit */ 83 | *((size_t *)limit) = 0; 84 | *mem = NULL; 85 | 86 | return 0; 87 | } 88 | 89 | if ((!*mem) && (*limit == 0)) { 90 | /* No allocation before do nothing */ 91 | return 0; 92 | 93 | } 94 | } 95 | 96 | ENV_BUG(); 97 | return -1; 98 | } 99 | 100 | int ocf_realloc(void **mem, size_t size, size_t count, size_t *limit) 101 | { 102 | return _ocf_realloc_with_cp(mem, size, count, limit, false); 103 | } 104 | 105 | int ocf_realloc_cp(void **mem, size_t size, size_t count, size_t *limit) 106 | { 107 | return _ocf_realloc_with_cp(mem, size, count, limit, true); 108 | } 109 | 110 | void ocf_realloc_init(void **mem, size_t *limit) 111 | { 112 | ENV_BUG_ON(!mem); 113 | ENV_BUG_ON(!limit); 114 | 115 | *mem = NULL; 116 | *((size_t *)limit) = 0; 117 | } 118 | -------------------------------------------------------------------------------- /src/ocf_volume_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024-2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __OCF_VOLUME_PRIV_H__ 8 | #define __OCF_VOLUME_PRIV_H__ 9 | 10 | #include "ocf_env.h" 11 | #include "ocf_env_refcnt.h" 12 | #include "ocf_io_priv.h" 13 | #include "utils/utils_io_allocator.h" 14 | 15 | struct ocf_volume_extended { 16 | ocf_io_allocator_type_t allocator_type; 17 | }; 18 | 19 | struct ocf_volume_type { 20 | const struct ocf_volume_properties *properties; 21 | struct ocf_io_allocator allocator; 22 | }; 23 | 24 | struct ocf_volume { 25 | ocf_volume_type_t type; 26 | struct ocf_volume_uuid uuid; 27 | struct { 28 | unsigned discard_zeroes:1; 29 | /* true if reading discarded pages returns 0 */ 30 | } features; 31 | bool opened; 32 | 33 | bool uuid_copy; 34 | /* @brief True if OCF shall free UUID on volume deinit */ 35 | 36 | void *priv; 37 | ocf_cache_t cache; 38 | struct list_head core_pool_item; 39 | struct env_refcnt refcnt; 40 | } __attribute__((aligned(64))); 41 | 42 | int ocf_volume_type_init(struct ocf_volume_type **type, 43 | const struct ocf_volume_properties *properties, 44 | const struct ocf_volume_extended *extended); 45 | 46 | void ocf_volume_type_deinit(struct ocf_volume_type *type); 47 | 48 | void ocf_volume_move(ocf_volume_t volume, ocf_volume_t from); 49 | 50 | void ocf_volume_set_uuid(ocf_volume_t volume, 51 | const struct ocf_volume_uuid *uuid); 52 | 53 | void ocf_volume_forward_io(ocf_volume_t volume, ocf_forward_token_t token, 54 | int dir, uint64_t addr, uint64_t bytes, uint64_t offset); 55 | 56 | void ocf_volume_forward_flush(ocf_volume_t volume, ocf_forward_token_t token); 57 | 58 | void ocf_volume_forward_discard(ocf_volume_t volume, ocf_forward_token_t token, 59 | uint64_t addr, uint64_t bytes); 60 | 61 | void ocf_volume_forward_write_zeros(ocf_volume_t volume, 62 | ocf_forward_token_t token, uint64_t addr, uint64_t bytes); 63 | 64 | void ocf_volume_forward_metadata(ocf_volume_t volume, ocf_forward_token_t token, 65 | int dir, uint64_t addr, uint64_t bytes, uint64_t offset); 66 | 67 | void ocf_volume_forward_io_simple(ocf_volume_t volume, 68 | ocf_forward_token_t token, int dir, 69 | uint64_t addr, uint64_t bytes); 70 | 71 | static inline void ocf_volume_submit_metadata(ocf_io_t io) 72 | { 73 | ocf_volume_t volume = ocf_io_get_volume(io); 74 | 75 | ENV_BUG_ON(!volume->type->properties->ops.submit_metadata); 76 | 77 | volume->type->properties->ops.submit_metadata(io); 78 | } 79 | 80 | static inline void ocf_volume_submit_write_zeroes(ocf_io_t io) 81 | { 82 | ocf_volume_t volume = ocf_io_get_volume(io); 83 | 84 | ENV_BUG_ON(!volume->type->properties->ops.submit_write_zeroes); 85 | 86 | volume->type->properties->ops.submit_write_zeroes(io); 87 | } 88 | 89 | #endif /*__OCF_VOLUME_PRIV_H__ */ 90 | -------------------------------------------------------------------------------- /src/ocf_part.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2023-2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __METADATA_PARTITION_STRUCTS_H__ 8 | #define __METADATA_PARTITION_STRUCTS_H__ 9 | 10 | #include "utils/utils_list.h" 11 | #include "utils/utils_cleaner.h" 12 | #include "cleaning/cleaning.h" 13 | #include "ocf_space.h" 14 | #include "ocf_env_refcnt.h" 15 | 16 | #define OCF_NUM_PARTITIONS OCF_USER_IO_CLASS_MAX + 2 17 | 18 | struct ocf_user_part_config { 19 | char name[OCF_IO_CLASS_NAME_MAX]; 20 | uint32_t min_size; 21 | uint32_t max_size; 22 | struct { 23 | uint8_t valid : 1; 24 | uint8_t added : 1; 25 | uint8_t eviction : 1; 26 | /*!< This bits is setting during partition sorting, 27 | * and means that can evict from this partition 28 | */ 29 | } flags; 30 | int16_t priority; 31 | ocf_cache_mode_t cache_mode; 32 | }; 33 | 34 | struct ocf_part_runtime { 35 | env_atomic curr_size; 36 | struct ocf_lru_part_meta lru[OCF_NUM_LRU_LISTS]; 37 | }; 38 | 39 | typedef bool ( *_lru_hash_locked_pfn)(struct ocf_request *req, 40 | ocf_core_id_t core_id, uint64_t core_line); 41 | 42 | /* Iterator state, visiting all lru lists within a partition 43 | in round robin order */ 44 | struct ocf_lru_iter 45 | { 46 | /* per-partition cacheline iterator */ 47 | ocf_cache_line_t curr_cline[OCF_NUM_LRU_LISTS]; 48 | /* cache object */ 49 | ocf_cache_t cache; 50 | /* cacheline concurrency */ 51 | struct ocf_alock *c; 52 | /* target partition */ 53 | struct ocf_part *part; 54 | /* available (non-empty) lru list bitmap rotated so that current 55 | @lru_idx is on the most significant bit */ 56 | unsigned long long next_avail_lru; 57 | /* number of available lru lists */ 58 | uint32_t num_avail_lrus; 59 | /* current lru list index */ 60 | uint32_t lru_idx; 61 | /* callback to determine whether given hash bucket is already 62 | * locked by the caller */ 63 | _lru_hash_locked_pfn hash_locked; 64 | /* optional caller request */ 65 | struct ocf_request *req; 66 | /* 1 if iterating over clean lists, 0 if over dirty */ 67 | bool clean : 1; 68 | }; 69 | 70 | #define OCF_EVICTION_CLEAN_SIZE 32U 71 | 72 | struct ocf_part_cleaning_ctx { 73 | ocf_cache_t cache; 74 | struct env_refcnt counter; 75 | env_atomic cleaner_running; 76 | struct flush_data entries[OCF_EVICTION_CLEAN_SIZE]; 77 | }; 78 | 79 | /* common partition data for both user-deined partitions as 80 | * well as freelist 81 | */ 82 | struct ocf_part { 83 | struct ocf_part_runtime *runtime; 84 | ocf_part_id_t id; 85 | }; 86 | 87 | struct ocf_user_part { 88 | struct ocf_user_part_config *config; 89 | struct cleaning_policy *clean_pol; 90 | struct ocf_part part; 91 | struct ocf_part_cleaning_ctx cleaning; 92 | struct ocf_lst_entry lst_valid; 93 | }; 94 | 95 | 96 | #endif /* __METADATA_PARTITION_STRUCTS_H__ */ 97 | -------------------------------------------------------------------------------- /tests/functional/tests/failover/test_standby_io.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2022 Intel Corporation 3 | # Copyright(c) 2024 Huawei Technologies 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | # 6 | 7 | import pytest 8 | from datetime import timedelta 9 | 10 | from pyocf.types.volume import RamVolume 11 | from pyocf.types.volume_cache import CacheVolume 12 | from pyocf.types.cache import Cache, CacheMetadataSegment 13 | from pyocf.types.queue import Queue 14 | from pyocf.utils import Size 15 | from pyocf.types.shared import CacheLineSize 16 | from pyocf.types.ctx import OcfCtx 17 | from pyocf.rio import Rio, ReadWrite 18 | from pyocf.helpers import get_metadata_segment_page_location, get_metadata_segment_size 19 | 20 | 21 | @pytest.mark.parametrize("cacheline_size", CacheLineSize) 22 | def test_test_standby_io(pyocf_ctx, cacheline_size): 23 | num_jobs = 8 24 | qd = 16 25 | runtime = 5 26 | 27 | vol_size = Size.from_MiB(100) 28 | cache_vol = RamVolume(vol_size) 29 | 30 | cache = Cache(owner=OcfCtx.get_default(), cache_line_size=cacheline_size) 31 | 32 | cache.start_cache(init_default_io_queue=False) 33 | 34 | for i in range(num_jobs): 35 | cache.add_io_queue(f"io-queue-{i}") 36 | 37 | cache.standby_attach(cache_vol) 38 | cache_vol = CacheVolume(cache) 39 | 40 | r = ( 41 | Rio() 42 | .target(cache_vol) 43 | .njobs(num_jobs) 44 | .readwrite(ReadWrite.RANDWRITE) 45 | .size(vol_size) 46 | .io_size(Size.from_GiB(100)) 47 | .bs(Size.from_KiB(4)) 48 | .qd(qd) 49 | .time(timedelta(seconds=runtime)) 50 | .time_based() 51 | .run(cache.io_queues) 52 | ) 53 | 54 | 55 | @pytest.mark.parametrize("cacheline_size", CacheLineSize) 56 | def test_test_standby_io_metadata(pyocf_ctx, cacheline_size): 57 | num_jobs = 8 58 | qd = 16 59 | runtime = 10 60 | 61 | vol_size = Size.from_MiB(200) 62 | cache_vol = RamVolume(vol_size) 63 | 64 | cache = Cache(owner=OcfCtx.get_default(), cache_line_size=cacheline_size) 65 | 66 | cache.start_cache(init_default_io_queue=False) 67 | 68 | for i in range(num_jobs): 69 | cache.add_io_queue(f"io-queue-{i}") 70 | 71 | cache.standby_attach(cache_vol) 72 | 73 | start = get_metadata_segment_page_location(cache, CacheMetadataSegment.COLLISION) 74 | count = get_metadata_segment_size(cache, CacheMetadataSegment.COLLISION) 75 | io_offset = Size.from_page(start) 76 | io_size = Size.from_page(count) 77 | 78 | cache_vol = CacheVolume(cache) 79 | 80 | r = ( 81 | Rio() 82 | .target(cache_vol) 83 | .njobs(num_jobs) 84 | .readwrite(ReadWrite.RANDWRITE) 85 | .size(io_size) 86 | .bs(Size.from_KiB(16)) 87 | .offset(io_offset) 88 | .qd(qd) 89 | .time(timedelta(seconds=runtime)) 90 | .time_based() 91 | .norandommap() 92 | .run(cache.io_queues) 93 | ) 94 | -------------------------------------------------------------------------------- /inc/ocf_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2021 Intel Corporation 3 | * Copyright(c) 2024 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | /** 8 | * @file 9 | * @brief OCF types 10 | */ 11 | #ifndef __OCF_TYPES_H_ 12 | #define __OCF_TYPES_H_ 13 | 14 | #include "ocf_env_headers.h" 15 | 16 | /** 17 | * @brief cache line type (by default designated as 32 bit unsigned integer) 18 | */ 19 | typedef uint32_t ocf_cache_line_t; 20 | 21 | /** 22 | * @brief core id type (by default designated as 16 bit unsigned integer) 23 | */ 24 | typedef uint16_t ocf_core_id_t; 25 | 26 | /** 27 | * @brief core sequence number type (by default designated as 16 bit unsigned integer) 28 | */ 29 | typedef uint16_t ocf_seq_no_t; 30 | 31 | /** 32 | * @brief partition id type (by default designated as 16 bit unsigned integer) 33 | */ 34 | typedef uint16_t ocf_part_id_t; 35 | 36 | /** 37 | * @brief handle to object designating ocf context 38 | */ 39 | typedef struct ocf_ctx *ocf_ctx_t; 40 | 41 | struct ocf_cache; 42 | /** 43 | * @brief handle to object designating ocf cache device 44 | */ 45 | typedef struct ocf_cache *ocf_cache_t; 46 | 47 | struct ocf_core; 48 | /** 49 | * @brief handle to object designating ocf core object 50 | */ 51 | typedef struct ocf_core *ocf_core_t; 52 | 53 | struct ocf_volume; 54 | /** 55 | * @brief handle to object designating ocf volume 56 | */ 57 | typedef struct ocf_volume *ocf_volume_t; 58 | 59 | 60 | struct ocf_volume_type; 61 | /** 62 | * @brief handle to volume type 63 | */ 64 | typedef struct ocf_volume_type *ocf_volume_type_t; 65 | 66 | /** 67 | * @brief handle to volume uuid 68 | */ 69 | typedef struct ocf_volume_uuid *ocf_uuid_t; 70 | 71 | /** 72 | * @brief handle to object designating ocf context object 73 | */ 74 | typedef void ctx_data_t; 75 | 76 | struct ocf_request; 77 | /** 78 | * @brief handle to io 79 | */ 80 | typedef struct ocf_request *ocf_io_t; 81 | 82 | /** 83 | * @brief IO forward token 84 | * 85 | * The token is associated with IO that is being forwarded. It allows 86 | * OCF to keep track of which IO has been forwarded where. It also has 87 | * refcount which can be increased/decreased on each forward level, so 88 | * that there is no need to introduce additional counters if at some 89 | * level the forward needs to be splitted into several sub-forwards. 90 | */ 91 | typedef uint64_t ocf_forward_token_t; 92 | 93 | /** 94 | * @brief handle to I/O queue 95 | */ 96 | typedef struct ocf_queue *ocf_queue_t; 97 | 98 | /** 99 | * @brief handle to cleaner 100 | */ 101 | typedef struct ocf_cleaner *ocf_cleaner_t; 102 | 103 | /** 104 | * @brief handle to metadata_updater 105 | */ 106 | typedef struct ocf_metadata_updater *ocf_metadata_updater_t; 107 | 108 | /** 109 | * @brief handle to logger 110 | */ 111 | typedef struct ocf_logger *ocf_logger_t; 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /doc/requirements/disable_cleaner: -------------------------------------------------------------------------------- 1 | --- 2 | group: disable_cleaner 3 | --- 4 | 5 | Disabling cleaner is a feature that is intented to be used with read cache 6 | (Write-Thourgh and Write-Around modes), where no dirty data is produced, so 7 | the cleaning is not necessary. Its major benefit is metadata memory footprint 8 | reduction, which is result of not allocating "cleaning" metatada section, 9 | that constitutes about 20% of total metadata capacity. 10 | 11 | While it is possible to use disable_cleaner option Write-Back and Write-Only 12 | modes, it may result in performance degradation due to necessity to perform 13 | cleaning on eviction. 14 | 15 | -------------------------------------------------------------------------------- 16 | -------------------------------------------------------------------------------- 17 | title: Setting cleaner_disabled mode 18 | id: set_cleaner_disabled 19 | --- 20 | 21 | It shall be possible to select cleaner_disabled mode during cache attach 22 | operation by setting apropirate field in attach config. 23 | 24 | -------------------------------------------------------------------------------- 25 | -------------------------------------------------------------------------------- 26 | title: Loading cache cleaner_disabled mode 27 | id: load_cleaner_disabled 28 | --- 29 | 30 | The cleaner_disabled setting should be preserved in cache metadata, i.e. on the 31 | cache load/recovery the setting should be restored to the value it had before 32 | the cache stop. 33 | 34 | -------------------------------------------------------------------------------- 35 | -------------------------------------------------------------------------------- 36 | title: Metadata "cleaning" section allocation 37 | id: cleaning_section_alocation 38 | --- 39 | 40 | When disable_cleaner option is selected the "cleaning" section in OCF metadata 41 | shall not be allocated neither in DRAM nor on the cache drive. 42 | 43 | -------------------------------------------------------------------------------- 44 | -------------------------------------------------------------------------------- 45 | title: Starting with NOP cleaning policy 46 | id: starting_with_nop_policy 47 | --- 48 | 49 | When attaching/loading cache with disable_cleaner option selected, the cleaning 50 | policy shall always be NOP. 51 | 52 | -------------------------------------------------------------------------------- 53 | -------------------------------------------------------------------------------- 54 | title: NOP cleaning policy enforcement 55 | id: nop_enforcement 56 | --- 57 | 58 | When disable_cleaner option is selected it shall not be possible to change the 59 | cleaning policy to other than NOP. 60 | 61 | -------------------------------------------------------------------------------- 62 | -------------------------------------------------------------------------------- 63 | title: Default setting 64 | id: default_setting 65 | --- 66 | 67 | By default the disable_cleaner option shall not be selected. 68 | -------------------------------------------------------------------------------- /tests/unit/tests/utils/utils_refcnt.c/utils_refcnt_freeze.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2019-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | /* 7 | * src/utils/utils_refcnt.c 8 | * ocf_refcnt_freeze 9 | * 10 | * ocf_refcnt_init 11 | * ocf_refcnt_inc 12 | * ocf_refcnt_dec 13 | * 14 | */ 15 | 16 | #undef static 17 | 18 | #undef inline 19 | 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "print_desc.h" 26 | 27 | #include "../utils/utils_refcnt.h" 28 | 29 | #include "utils/utils_refcnt.c/utils_refcnt_freeze_generated_wraps.c" 30 | 31 | static void ocf_refcnt_freeze_test01(void **state) 32 | { 33 | struct ocf_refcnt rc; 34 | int val; 35 | 36 | print_test_description("Freeze increments freeze counter"); 37 | 38 | ocf_refcnt_init(&rc); 39 | 40 | ocf_refcnt_freeze(&rc); 41 | assert_int_equal(1, env_atomic_read(&rc.freeze)); 42 | 43 | ocf_refcnt_freeze(&rc); 44 | assert_int_equal(2, env_atomic_read(&rc.freeze)); 45 | } 46 | 47 | static void ocf_refcnt_freeze_test02(void **state) 48 | { 49 | struct ocf_refcnt rc; 50 | int val; 51 | 52 | print_test_description("Increment returns 0 for frozen counter"); 53 | 54 | ocf_refcnt_init(&rc); 55 | 56 | ocf_refcnt_inc(&rc); 57 | ocf_refcnt_inc(&rc); 58 | ocf_refcnt_inc(&rc); 59 | 60 | ocf_refcnt_freeze(&rc); 61 | 62 | val = ocf_refcnt_inc(&rc); 63 | 64 | assert_int_equal(0, val); 65 | } 66 | 67 | static void ocf_refcnt_freeze_test03(void **state) 68 | { 69 | struct ocf_refcnt rc; 70 | int val, val2; 71 | 72 | print_test_description("Freeze bocks increment"); 73 | 74 | ocf_refcnt_init(&rc); 75 | 76 | val = ocf_refcnt_inc(&rc); 77 | val = ocf_refcnt_inc(&rc); 78 | val = ocf_refcnt_inc(&rc); 79 | 80 | ocf_refcnt_freeze(&rc); 81 | 82 | ocf_refcnt_inc(&rc); 83 | 84 | val2 = env_atomic_read(&rc.counter); 85 | 86 | assert_int_equal(val, val2); 87 | } 88 | 89 | static void ocf_refcnt_freeze_test04(void **state) 90 | { 91 | struct ocf_refcnt rc; 92 | int val, val2; 93 | 94 | print_test_description("Freeze allows decrement"); 95 | 96 | ocf_refcnt_init(&rc); 97 | 98 | val = ocf_refcnt_inc(&rc); 99 | val = ocf_refcnt_inc(&rc); 100 | val = ocf_refcnt_inc(&rc); 101 | 102 | ocf_refcnt_freeze(&rc); 103 | 104 | val2 = ocf_refcnt_dec(&rc); 105 | assert_int_equal(val2, val - 1); 106 | 107 | val2 = ocf_refcnt_dec(&rc); 108 | assert_int_equal(val2, val - 2); 109 | } 110 | int main(void) 111 | { 112 | const struct CMUnitTest tests[] = { 113 | cmocka_unit_test(ocf_refcnt_freeze_test01), 114 | cmocka_unit_test(ocf_refcnt_freeze_test02), 115 | cmocka_unit_test(ocf_refcnt_freeze_test03), 116 | cmocka_unit_test(ocf_refcnt_freeze_test04), 117 | }; 118 | 119 | print_message("Unit test of src/utils/utils_refcnt.c"); 120 | 121 | return cmocka_run_group_tests(tests, NULL, NULL); 122 | } 123 | -------------------------------------------------------------------------------- /src/ocf_metadata.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | #include "ocf_priv.h" 6 | #include "ocf_cache_priv.h" 7 | #include "utils/utils_cache_line.h" 8 | 9 | static inline ocf_cache_line_t ocf_atomic_addr2line( 10 | struct ocf_cache *cache, uint64_t addr) 11 | { 12 | addr -= cache->device->metadata_offset; 13 | return ocf_bytes_2_lines(cache, addr); 14 | } 15 | 16 | static inline uint8_t ocf_atomic_addr2pos(struct ocf_cache *cache, 17 | uint64_t addr) 18 | { 19 | addr -= cache->device->metadata_offset; 20 | addr = BYTES_TO_SECTORS(addr); 21 | addr %= ocf_line_sectors(cache); 22 | 23 | return addr; 24 | } 25 | 26 | int ocf_metadata_get_atomic_entry(ocf_cache_t cache, 27 | uint64_t addr, struct ocf_atomic_metadata *entry) 28 | { 29 | OCF_CHECK_NULL(cache); 30 | OCF_CHECK_NULL(entry); 31 | 32 | if (addr > ocf_volume_get_length(&cache->device->volume)) 33 | return -OCF_ERR_INVAL; 34 | 35 | if (addr < cache->device->metadata_offset) { 36 | /* Metadata IO of OCF */ 37 | ENV_BUG_ON(env_memset(entry, sizeof(*entry), 0)); 38 | } else { 39 | ocf_cache_line_t line = ocf_atomic_addr2line(cache, addr); 40 | uint8_t pos = ocf_atomic_addr2pos(cache, addr); 41 | ocf_core_id_t core_id = OCF_CORE_MAX; 42 | ocf_core_t core; 43 | uint64_t core_line = 0; 44 | 45 | ocf_metadata_get_core_info(cache, line, &core_id, &core_line); 46 | core = ocf_cache_get_core(cache, core_id); 47 | 48 | entry->core_seq_no = core->conf_meta->seq_no; 49 | entry->core_line = core_line; 50 | 51 | entry->valid = metadata_test_valid_one(cache, line, pos); 52 | entry->dirty = metadata_test_dirty_one(cache, line, pos); 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | int ocf_metadata_check_invalid_before(ocf_cache_t cache, uint64_t addr) 59 | { 60 | ocf_cache_line_t line; 61 | uint8_t pos; 62 | int i; 63 | 64 | OCF_CHECK_NULL(cache); 65 | 66 | if (ocf_cache_is_standby(cache)) 67 | return -OCF_ERR_CACHE_STANDBY; 68 | 69 | line = ocf_atomic_addr2line(cache, addr); 70 | pos = ocf_atomic_addr2pos(cache, addr); 71 | 72 | if (!pos || addr < cache->device->metadata_offset) 73 | return 0; 74 | 75 | for (i = 0; i < pos; i++) { 76 | if (metadata_test_valid_one(cache, line, i)) 77 | return 0; 78 | } 79 | 80 | return i; 81 | } 82 | 83 | int ocf_metadata_check_invalid_after(ocf_cache_t cache, uint64_t addr, 84 | uint32_t bytes) 85 | { 86 | ocf_cache_line_t line; 87 | uint8_t pos; 88 | int i, count = 0; 89 | 90 | OCF_CHECK_NULL(cache); 91 | 92 | if (ocf_cache_is_standby(cache)) 93 | return -OCF_ERR_CACHE_STANDBY; 94 | 95 | line = ocf_atomic_addr2line(cache, addr + bytes); 96 | pos = ocf_atomic_addr2pos(cache, addr + bytes); 97 | 98 | if (!pos || addr < cache->device->metadata_offset) 99 | return 0; 100 | 101 | for (i = pos; i < ocf_line_sectors(cache); i++) { 102 | if (metadata_test_valid_one(cache, line, i)) 103 | return 0; 104 | 105 | count++; 106 | } 107 | 108 | return count; 109 | } 110 | -------------------------------------------------------------------------------- /tests/functional/tests/utils/random.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright(c) 2019-2023 Intel Corporation 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | # 5 | 6 | import random 7 | import string 8 | import enum 9 | from functools import reduce 10 | from ctypes import c_uint64, c_uint32, c_uint16, c_uint8, c_int, c_uint 11 | 12 | 13 | class Range: 14 | def __init__(self, min_val, max_val): 15 | self.min = min_val 16 | self.max = max_val 17 | 18 | def is_within(self, val): 19 | return val >= self.min and val <= self.max 20 | 21 | 22 | class DefaultRanges(Range, enum.Enum): 23 | UINT8 = 0, c_uint8(-1).value 24 | INT16 = int(-c_uint16(-1).value / 2) - 1, int(c_uint16(-1).value / 2) 25 | UINT16 = 0, c_uint16(-1).value 26 | UINT32 = 0, c_uint32(-1).value 27 | UINT64 = 0, c_uint64(-1).value 28 | INT = int(-c_uint(-1).value / 2) - 1, int(c_uint(-1).value / 2) 29 | 30 | 31 | class RandomGenerator: 32 | def __init__(self, base_range=DefaultRanges.INT, count=1000): 33 | with open("config/random.cfg") as f: 34 | self.random = random.Random(int(f.read())) 35 | self.exclude = [] 36 | self.range = base_range 37 | self.count = count 38 | self.n = 0 39 | 40 | def exclude_range(self, excl_range): 41 | self.exclude.append(excl_range) 42 | return self 43 | 44 | def __iter__(self): 45 | return self 46 | 47 | def __next__(self): 48 | if self.n >= self.count: 49 | raise StopIteration() 50 | self.n += 1 51 | while True: 52 | val = self.random.randint(self.range.min, self.range.max) 53 | if self.exclude: 54 | excl_map = map(lambda e: e.is_within(val), self.exclude) 55 | is_excluded = reduce(lambda a, b: a or b, excl_map) 56 | if is_excluded: 57 | continue 58 | return val 59 | 60 | 61 | class RandomStringGenerator: 62 | def __init__(self, len_range=Range(0, 20), count=700, extra_chars=[]): 63 | with open("config/random.cfg") as f: 64 | self.random = random.Random(int(f.read())) 65 | self.generator = self.__string_generator(len_range, extra_chars) 66 | self.count = count 67 | self.n = 0 68 | 69 | def __string_generator(self, len_range, extra_chars): 70 | while True: 71 | for t in [ 72 | string.digits, 73 | string.ascii_letters + string.digits, 74 | string.ascii_lowercase, 75 | string.ascii_uppercase, 76 | string.printable, 77 | string.punctuation, 78 | string.hexdigits, 79 | *extra_chars, 80 | ]: 81 | yield "".join( 82 | self.random.choice(t) 83 | for _ in range(self.random.randint(len_range.min, len_range.max)) 84 | ) 85 | 86 | def __iter__(self): 87 | return self 88 | 89 | def __next__(self): 90 | if self.n >= self.count: 91 | raise StopIteration() 92 | self.n += 1 93 | return next(self.generator) 94 | -------------------------------------------------------------------------------- /src/engine/engine_bf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(c) 2012-2022 Intel Corporation 3 | * Copyright(c) 2024-2025 Huawei Technologies 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include "ocf/ocf.h" 8 | #include "../ocf_cache_priv.h" 9 | #include "../ocf_ctx_priv.h" 10 | #include "engine_bf.h" 11 | #include "engine_inv.h" 12 | #include "engine_common.h" 13 | #include "engine_io.h" 14 | #include "cache_engine.h" 15 | #include "../ocf_request.h" 16 | #include "../concurrency/ocf_concurrency.h" 17 | #include "../utils/utils_io.h" 18 | 19 | #define OCF_ENGINE_DEBUG_IO_NAME "bf" 20 | #include "engine_debug.h" 21 | 22 | /* Decrements and checks if queue may be unblocked again */ 23 | static inline void backfill_queue_dec_unblock(struct ocf_cache *cache) 24 | { 25 | env_atomic_dec(&cache->pending_read_misses_list_count); 26 | 27 | if (!env_atomic_read(&cache->pending_read_misses_list_blocked)) 28 | return; 29 | 30 | if (env_atomic_read(&cache->pending_read_misses_list_count) 31 | < cache->backfill.queue_unblock_size) 32 | env_atomic_set(&cache->pending_read_misses_list_blocked, 0); 33 | } 34 | 35 | static inline void backfill_queue_inc_block(struct ocf_cache *cache) 36 | { 37 | if (env_atomic_inc_return(&cache->pending_read_misses_list_count) 38 | >= cache->backfill.max_queue_size) 39 | env_atomic_set(&cache->pending_read_misses_list_blocked, 1); 40 | } 41 | 42 | static int _ocf_backfill_update_metadata(struct ocf_request *req) 43 | { 44 | ocf_cache_t cache = req->cache; 45 | 46 | ocf_hb_req_prot_lock_wr(req); 47 | 48 | ocf_set_valid_map_info(req); 49 | 50 | ocf_hb_req_prot_unlock_wr(req); 51 | 52 | ocf_req_unlock(ocf_cache_line_concurrency(cache), req); 53 | 54 | ocf_req_put(req); 55 | 56 | return 0; 57 | } 58 | 59 | static void _ocf_backfill_complete(struct ocf_request *req, int error) 60 | { 61 | struct ocf_cache *cache = req->cache; 62 | 63 | if (error) { 64 | ocf_core_stats_cache_error_update(req->core, OCF_WRITE); 65 | inc_fallback_pt_error_counter(req->cache); 66 | } 67 | 68 | backfill_queue_dec_unblock(req->cache); 69 | 70 | /* We must free the pages we have allocated */ 71 | if (likely(req->data)) { 72 | ctx_data_secure_erase(cache->owner, req->data); 73 | ctx_data_munlock(cache->owner, req->data); 74 | ctx_data_free(cache->owner, req->data); 75 | req->data = NULL; 76 | } 77 | 78 | if (error) { 79 | ocf_engine_invalidate(req); 80 | } else { 81 | ocf_queue_push_req_cb(req, _ocf_backfill_update_metadata, 82 | OCF_QUEUE_ALLOW_SYNC | OCF_QUEUE_PRIO_HIGH); 83 | } 84 | } 85 | 86 | static int _ocf_backfill_do(struct ocf_request *req) 87 | { 88 | req->data = req->cp_data; 89 | if (unlikely(req->data == NULL)) { 90 | _ocf_backfill_complete(req, -OCF_ERR_NO_MEM); 91 | return 0; 92 | } 93 | 94 | ocf_engine_forward_cache_io_req(req, OCF_WRITE, _ocf_backfill_complete); 95 | 96 | return 0; 97 | } 98 | 99 | void ocf_engine_backfill(struct ocf_request *req) 100 | { 101 | backfill_queue_inc_block(req->cache); 102 | ocf_queue_push_req_cb(req, _ocf_backfill_do, 103 | OCF_QUEUE_ALLOW_SYNC | OCF_QUEUE_PRIO_HIGH); 104 | } 105 | --------------------------------------------------------------------------------