Introduce ocf_cache_has_pending_cleaning() function
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
03c95d36f0
commit
5699422586
@ -174,6 +174,13 @@ void ocf_cache_wait_for_io_finish(ocf_cache_t cache);
|
|||||||
*/
|
*/
|
||||||
bool ocf_cache_has_pending_requests(ocf_cache_t cache);
|
bool ocf_cache_has_pending_requests(ocf_cache_t cache);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if cleaning triggered by eviction runs on the cache
|
||||||
|
*
|
||||||
|
* @param[in] cache Cache object
|
||||||
|
*/
|
||||||
|
bool ocf_cache_has_pending_cleaning(ocf_cache_t cache);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get cache mode of given cache object
|
* @brief Get cache mode of given cache object
|
||||||
*
|
*
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "../ocf_ctx_priv.h"
|
#include "../ocf_ctx_priv.h"
|
||||||
#include "../metadata/metadata.h"
|
#include "../metadata/metadata.h"
|
||||||
#include "../engine/cache_engine.h"
|
#include "../engine/cache_engine.h"
|
||||||
#include "../utils/utils_part.h"
|
|
||||||
#include "../utils/utils_req.h"
|
#include "../utils/utils_req.h"
|
||||||
#include "../utils/utils_device.h"
|
#include "../utils/utils_device.h"
|
||||||
#include "../eviction/ops.h"
|
#include "../eviction/ops.h"
|
||||||
@ -118,53 +117,6 @@ void cache_mng_core_remove_from_cache(struct ocf_cache *cache, int core_id)
|
|||||||
cache->conf_meta->core_count--;
|
cache->conf_meta->core_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wait for the end of asynchronous cleaning
|
|
||||||
*
|
|
||||||
* @param cache OCF cache instance
|
|
||||||
* @param timeout_ms Timeout for waiting in milliseconds
|
|
||||||
* @note When timeout is less than zero it means wait forever
|
|
||||||
*
|
|
||||||
* @retval 0 cleaning finished
|
|
||||||
* @retval non-zero timeout and cleaning still in progress
|
|
||||||
*/
|
|
||||||
static int _ocf_cleaning_wait_for_finish(struct ocf_cache *cache,
|
|
||||||
const int32_t timeout_ms)
|
|
||||||
{
|
|
||||||
struct ocf_user_part *curr_part;
|
|
||||||
ocf_part_id_t part_id;
|
|
||||||
bool cleaning_active = ocf_cache_is_device_attached(cache);
|
|
||||||
int64_t _timeout = timeout_ms;
|
|
||||||
|
|
||||||
while (cleaning_active) {
|
|
||||||
cleaning_active = false;
|
|
||||||
|
|
||||||
OCF_METADATA_LOCK_WR();
|
|
||||||
for_each_part(cache, curr_part, part_id) {
|
|
||||||
if (env_atomic_read(&cache->cleaning[part_id])) {
|
|
||||||
cleaning_active = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OCF_METADATA_UNLOCK_WR();
|
|
||||||
|
|
||||||
if (cleaning_active) {
|
|
||||||
env_msleep(20);
|
|
||||||
|
|
||||||
if (timeout_ms >= 0) {
|
|
||||||
_timeout -= 20;
|
|
||||||
if (_timeout <= 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (cleaning_active)
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ocf_mngt_cache_put(ocf_cache_t cache)
|
void ocf_mngt_cache_put(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
OCF_CHECK_NULL(cache);
|
OCF_CHECK_NULL(cache);
|
||||||
@ -275,15 +227,6 @@ static int _ocf_mngt_cache_lock(ocf_cache_t cache, int (*lock_fn)(env_rwsem *s),
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return, when asynchronous cleaning is finished */
|
|
||||||
if (_ocf_cleaning_wait_for_finish(cache, 60 * 1000)) {
|
|
||||||
/* Because of some reasons, asynchronous cleaning still active,
|
|
||||||
* cannot continue
|
|
||||||
*/
|
|
||||||
ret = -OCF_ERR_CACHE_IN_USE;
|
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
@ -321,15 +264,15 @@ int ocf_mngt_cache_read_trylock(ocf_cache_t cache)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if cache is either fully initialized or during recovery */
|
/* if cache is either fully initialized or during recovery */
|
||||||
static ocf_cache_t _ocf_mngt_cache_try_get(ocf_cache_t cache)
|
static bool _ocf_mngt_cache_try_get(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
if (!!cache->valid_ocf_cache_device_t) {
|
if (!!cache->valid_ocf_cache_device_t) {
|
||||||
/* Increase reference counter */
|
/* Increase reference counter */
|
||||||
env_atomic_inc(&cache->ref_count);
|
env_atomic_inc(&cache->ref_count);
|
||||||
return cache;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ocf_mngt_cache_get(ocf_cache_t cache)
|
int ocf_mngt_cache_get(ocf_cache_t cache)
|
||||||
@ -345,7 +288,7 @@ static int _ocf_mngt_cache_get_list_cpy(ocf_ctx_t ocf_ctx, ocf_cache_t **list,
|
|||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
uint32_t count = 0, i = 0;
|
uint32_t count = 0, i = 0;
|
||||||
struct ocf_cache *iter, *this;
|
ocf_cache_t iter;
|
||||||
|
|
||||||
*list = NULL;
|
*list = NULL;
|
||||||
*size = 0;
|
*size = 0;
|
||||||
@ -366,12 +309,9 @@ static int _ocf_mngt_cache_get_list_cpy(ocf_ctx_t ocf_ctx, ocf_cache_t **list,
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(iter, &ocf_ctx->caches, list) {
|
list_for_each_entry(iter, &ocf_ctx->caches, list) {
|
||||||
this = _ocf_mngt_cache_try_get(iter);
|
|
||||||
|
|
||||||
if (this) {
|
if (_ocf_mngt_cache_try_get(iter))
|
||||||
(*list)[i] = this;
|
(*list)[i++] = iter;
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i) {
|
if (i) {
|
||||||
|
@ -588,6 +588,26 @@ err_pipeline:
|
|||||||
cmpl(cache, NULL, priv, result);
|
cmpl(cache, NULL, priv, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Synchronously wait until cleaning triggered by eviction finishes.
|
||||||
|
* TODO: Replace it with asynchronous mechanism.
|
||||||
|
*/
|
||||||
|
static int _ocf_cleaning_wait_for_finish(ocf_cache_t cache, int32_t timeout_ms)
|
||||||
|
{
|
||||||
|
if (!ocf_cache_is_device_attached(cache))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (ocf_cache_has_pending_cleaning(cache)) {
|
||||||
|
env_msleep(20);
|
||||||
|
|
||||||
|
timeout_ms -= 20;
|
||||||
|
if (timeout_ms <= 0)
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct ocf_mngt_cache_remove_core_context {
|
struct ocf_mngt_cache_remove_core_context {
|
||||||
ocf_mngt_cache_remove_core_end_t cmpl;
|
ocf_mngt_cache_remove_core_end_t cmpl;
|
||||||
void *priv;
|
void *priv;
|
||||||
@ -650,6 +670,12 @@ void ocf_mngt_cache_remove_core(ocf_core_t core,
|
|||||||
cache = ocf_core_get_cache(core);
|
cache = ocf_core_get_cache(core);
|
||||||
core_id = ocf_core_get_id(core);
|
core_id = ocf_core_get_id(core);
|
||||||
|
|
||||||
|
/* TODO: Make this asynchronous */
|
||||||
|
if (_ocf_cleaning_wait_for_finish(cache, 60 * 1000)) {
|
||||||
|
cmpl(priv, -OCF_ERR_CACHE_IN_USE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
result = ocf_pipeline_create(&pipeline, cache,
|
result = ocf_pipeline_create(&pipeline, cache,
|
||||||
&ocf_mngt_cache_remove_core_pipeline_props);
|
&ocf_mngt_cache_remove_core_pipeline_props);
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -702,10 +728,21 @@ static int _ocf_mngt_cache_detach_core(ocf_core_t core)
|
|||||||
void ocf_mngt_cache_detach_core(ocf_core_t core,
|
void ocf_mngt_cache_detach_core(ocf_core_t core,
|
||||||
ocf_mngt_cache_detach_core_end_t cmpl, void *priv)
|
ocf_mngt_cache_detach_core_end_t cmpl, void *priv)
|
||||||
{
|
{
|
||||||
ocf_cache_t cache = ocf_core_get_cache(core);
|
ocf_cache_t cache;
|
||||||
const char *core_name = ocf_core_get_name(core);
|
const char *core_name;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
OCF_CHECK_NULL(core);
|
||||||
|
|
||||||
|
cache = ocf_core_get_cache(core);
|
||||||
|
core_name = ocf_core_get_name(core);
|
||||||
|
|
||||||
|
/* TODO: Make this asynchronous */
|
||||||
|
if (_ocf_cleaning_wait_for_finish(cache, 60 * 1000)) {
|
||||||
|
cmpl(priv, -OCF_ERR_CACHE_IN_USE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ocf_core_log(core, log_debug, "Detaching core\n");
|
ocf_core_log(core, log_debug, "Detaching core\n");
|
||||||
|
|
||||||
result = _ocf_mngt_cache_detach_core(core);
|
result = _ocf_mngt_cache_detach_core(core);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "engine/cache_engine.h"
|
#include "engine/cache_engine.h"
|
||||||
#include "utils/utils_cache_line.h"
|
#include "utils/utils_cache_line.h"
|
||||||
#include "utils/utils_req.h"
|
#include "utils/utils_req.h"
|
||||||
|
#include "utils/utils_part.h"
|
||||||
#include "ocf_priv.h"
|
#include "ocf_priv.h"
|
||||||
#include "ocf_cache_priv.h"
|
#include "ocf_cache_priv.h"
|
||||||
|
|
||||||
@ -68,12 +69,42 @@ void ocf_cache_wait_for_io_finish(ocf_cache_t cache)
|
|||||||
bool ocf_cache_has_pending_requests(ocf_cache_t cache)
|
bool ocf_cache_has_pending_requests(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
OCF_CHECK_NULL(cache);
|
OCF_CHECK_NULL(cache);
|
||||||
|
|
||||||
return ocf_req_get_allocated(cache) > 0;
|
return ocf_req_get_allocated(cache) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is temporary workaround allowing to check if cleaning triggered
|
||||||
|
* by eviction policy is running on the cache. This information is needed
|
||||||
|
* to remove core from cache properly.
|
||||||
|
*
|
||||||
|
* TODO: Replace this with asynchronous notification to which remove/detach
|
||||||
|
* core pipelines can subscribe.
|
||||||
|
*/
|
||||||
|
bool ocf_cache_has_pending_cleaning(ocf_cache_t cache)
|
||||||
|
{
|
||||||
|
struct ocf_user_part *curr_part;
|
||||||
|
ocf_part_id_t part_id;
|
||||||
|
bool cleaning_active = false;
|
||||||
|
|
||||||
|
OCF_CHECK_NULL(cache);
|
||||||
|
|
||||||
|
OCF_METADATA_LOCK_RD();
|
||||||
|
for_each_part(cache, curr_part, part_id) {
|
||||||
|
if (env_atomic_read(&cache->cleaning[part_id])) {
|
||||||
|
cleaning_active = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OCF_METADATA_UNLOCK_RD();
|
||||||
|
|
||||||
|
return cleaning_active;
|
||||||
|
}
|
||||||
|
|
||||||
ocf_cache_mode_t ocf_cache_get_mode(ocf_cache_t cache)
|
ocf_cache_mode_t ocf_cache_get_mode(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
OCF_CHECK_NULL(cache);
|
OCF_CHECK_NULL(cache);
|
||||||
|
|
||||||
return cache->conf_meta->cache_mode;
|
return cache->conf_meta->cache_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user