/* * Copyright(c) 2012-2018 Intel Corporation * SPDX-License-Identifier: BSD-3-Clause-Clear */ #ifndef UTILS_CLEANER_H_ #define UTILS_CLEANER_H_ #include "../ocf_request.h" /** * @brief Getter for next cache line to be cleaned * * @param cache[in] Cache instance * @param getter_context[in] Context for cleaner caller * @param item[in] Current iteration item when collection cache lines * @param line[out] line to be cleaned * @retval 0 When caller return zero it means take this cache line to clean * @retval Non-zero Means skip this cache line and do not clean it */ typedef int (*ocf_cleaner_get_item)(struct ocf_cache *cache, void *getter_context, uint32_t item, ocf_cache_line_t *line); /** * @brief Cleaning attributes for clean request */ struct ocf_cleaner_attribs { uint8_t cache_line_lock : 1; /*!< Clean under cache line lock */ uint8_t do_sort : 1; /*!< Sort cache lines which will be cleaned */ uint32_t count; /*!< max number of cache lines to be cleaned */ void *cmpl_context; /*!< Completion context of cleaning requester */ void (*cmpl_fn)(void *priv, int error); /*!< Completion function of requester */ ocf_cleaner_get_item getter; /*!< Getter for collecting cache lines which will be cleaned */ void *getter_context; /*!< Context for getting cache lines */ uint32_t getter_item; /*!< Additional variable that can be used by cleaner caller * to iterate over items */ ocf_queue_t io_queue; }; /** * @brief Flush table entry structure */ struct flush_data { uint64_t core_line; uint32_t cache_line; ocf_core_id_t core_id; }; typedef void (*ocf_flush_containter_coplete_t)(void *ctx); /** * @brief Flush table container */ struct flush_container { ocf_core_id_t core_id; struct flush_data *flush_data; uint32_t count; uint32_t iter; struct ocf_cleaner_attribs attribs; ocf_cache_t cache; struct ocf_request *req; uint64_t flush_portion; uint64_t ticks1; uint64_t ticks2; ocf_flush_containter_coplete_t end; struct ocf_mngt_cache_flush_context *context; }; typedef void (*ocf_cleaner_refcnt_zero_cb_t)(void *priv); /** * @brief Context for ocf_cleaner_refcnt_register_zero_cb */ struct ocf_cleaner_wait_context { env_atomic waiting; ocf_cleaner_refcnt_zero_cb_t cb; void *priv; }; /** * @brief Run cleaning procedure * * @param cache - Cache instance * @param attribs - Cleaning attributes */ void ocf_cleaner_fire(struct ocf_cache *cache, const struct ocf_cleaner_attribs *attribs); /** * @brief Perform cleaning procedure for specified flush data. Only dirty * cache lines will be cleaned. * * @param cache - Cache instance * @param flush - flush data to be cleaned * @param count - Count of cache lines to be cleaned * @param attribs - Cleaning attributes * @return - Cleaning result. 0 - no errors, non zero errors occurred */ int ocf_cleaner_do_flush_data_async(struct ocf_cache *cache, struct flush_data *flush, uint32_t count, struct ocf_cleaner_attribs *attribs); /** * @brief Sort flush data by core sector * * @param tbl Flush data to sort * @param num Number of entries in tbl */ void ocf_cleaner_sort_sectors(struct flush_data *tbl, uint32_t num); /** * @brief Sort flush data in all flush containters * * @param tbl Flush containers to sort * @param num Number of entries in fctbl */ void ocf_cleaner_sort_flush_containers(struct flush_container *fctbl, uint32_t num); /** * @brief Disable incrementing of cleaner reference counters * * @param cache - Cache instance */ void ocf_cleaner_refcnt_freeze(ocf_cache_t cache); /** * @brief Enable incrementing of cleaner reference counters * * @param cache - Cache instance */ void ocf_cleaner_refcnt_unfreeze(ocf_cache_t cache); /** * @brief Register callback for cleaner reference counters dropping to 0 * * @param cache - Cache instance * @param ctx - Routine private context, allocated by caller to avoid ENOMEM * @param cb - Caller callback * @param priv - Caller callback private data */ void ocf_cleaner_refcnt_register_zero_cb(ocf_cache_t cache, struct ocf_cleaner_wait_context *ctx, ocf_cleaner_refcnt_zero_cb_t cb, void *priv); #endif /* UTILS_CLEANER_H_ */