Configure all io classes at once.

Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
Michal Mielewczyk
2019-01-09 04:57:23 -05:00
parent 5e97795630
commit 2dfd6248c9
14 changed files with 451 additions and 118 deletions

View File

@@ -14,6 +14,7 @@
#include "../engine/engine_common.h"
#include "../concurrency/ocf_cache_concurrency.h"
#include "cleaning_priv.h"
#include "../utils/utils_core.h"
#define OCF_ACP_DEBUG 0
@@ -184,10 +185,6 @@ static struct acp_chunk_info *_acp_get_chunk(struct ocf_cache *cache,
return &acp->chunk_info[core_line.core_id][chunk_id];
}
#define for_each_core(cache, iter) \
for (iter = 0; iter < OCF_CORE_MAX; iter++) \
if (cache->core_conf_meta[iter].added)
static void _acp_remove_cores(struct ocf_cache *cache)
{
int i;

View File

@@ -233,7 +233,7 @@ ocf_cache_mode_t ocf_get_effective_cache_mode(ocf_cache_t cache,
mode = ocf_cache_mode_pt;
if (mode == ocf_cache_mode_wb &&
env_atomic_read(&cache->dirty_rq_barrier))
env_atomic_read(&cache->flush_started))
mode = ocf_cache_mode_wt;
return mode;

View File

@@ -1856,7 +1856,7 @@ int ocf_mngt_cache_detach(ocf_cache_t cache)
return -EINVAL;
/* prevent dirty io */
env_atomic_inc(&cache->dirty_rq_barrier);
env_atomic_inc(&cache->flush_started);
result = ocf_mngt_cache_flush(cache, true);
if (result)
@@ -1867,7 +1867,7 @@ int ocf_mngt_cache_detach(ocf_cache_t cache)
env_waitqueue_wait(cache->pending_cache_wq,
!env_atomic_read(&cache->pending_cache_requests));
ENV_BUG_ON(env_atomic_dec_return(&cache->dirty_rq_barrier) < 0);
ENV_BUG_ON(env_atomic_dec_return(&cache->flush_started) < 0);
/* remove cacheline metadata and cleaning policy meta for all cores */
for (i = 0, j = 0; j < no && i < OCF_CORE_MAX; i++) {

View File

@@ -18,7 +18,7 @@ static inline void _ocf_mngt_begin_flush(struct ocf_cache *cache)
{
env_mutex_lock(&cache->flush_mutex);
env_atomic_inc(&cache->dirty_rq_barrier);
env_atomic_inc(&cache->flush_started);
env_waitqueue_wait(cache->pending_dirty_wq,
!env_atomic_read(&cache->pending_dirty_requests));
@@ -26,7 +26,7 @@ static inline void _ocf_mngt_begin_flush(struct ocf_cache *cache)
static inline void _ocf_mngt_end_flush(struct ocf_cache *cache)
{
ENV_BUG_ON(env_atomic_dec_return(&cache->dirty_rq_barrier) < 0);
ENV_BUG_ON(env_atomic_dec_return(&cache->flush_started) < 0);
env_mutex_unlock(&cache->flush_mutex);
}

View File

@@ -109,113 +109,118 @@ static int _ocf_mngt_io_class_configure(ocf_cache_t cache,
OCF_CHECK_NULL(cache->device);
OCF_METADATA_LOCK_WR();
dest_part = &cache->user_parts[part_id];
if (!ocf_part_is_added(dest_part)) {
ocf_cache_log(cache, log_info, "Setting IO class, id: %u, "
"name: '%s' [ ERROR ]\n", part_id, dest_part->config->name);
OCF_METADATA_UNLOCK_WR();
return -OCF_ERR_INVAL;
}
if (!name || !name[0])
return -OCF_ERR_IO_CLASS_NOT_EXIST;
if (part_id == PARTITION_DEFAULT) {
/* Special behavior for default partition */
if (!name[0]) {
/* Removing of default partition is not allowed */
ocf_cache_log(cache, log_info,
"Cannot remove unclassified IO class, "
"id: %u [ ERROR ]\n", part_id);
OCF_METADATA_UNLOCK_WR();
return 0;
}
/* Try set partition size */
if (_ocf_mngt_set_partition_size(cache, part_id, min, max)) {
ocf_cache_log(cache, log_info,
"Setting IO class size, id: %u, name: '%s' "
"[ ERROR ]\n", part_id, dest_part->config->name);
OCF_METADATA_UNLOCK_WR();
return -OCF_ERR_INVAL;
}
ocf_part_set_prio(cache, dest_part, prio);
ocf_part_sort(cache);
dest_part->config->cache_mode = cache_mode;
ocf_cache_log(cache, log_info,
"Updating Unclassified IO class, id: "
"%u [ OK ]\n", part_id);
OCF_METADATA_UNLOCK_WR();
return 0;
}
if (name[0]) {
/* Setting */
result = env_strncpy(dest_part->config->name, sizeof(dest_part->config->name), name,
sizeof(dest_part->config->name));
if (result) {
OCF_METADATA_UNLOCK_WR();
return result;
}
/* Setting */
result = env_strncpy(dest_part->config->name,
sizeof(dest_part->config->name), name,
sizeof(dest_part->config->name));
if (result)
return result;
/* Try set partition size */
if (_ocf_mngt_set_partition_size(cache, part_id, min, max)) {
ocf_cache_log(cache, log_info,
"Setting IO class size, id: %u, name: '%s' "
"[ ERROR ]\n", part_id, dest_part->config->name);
OCF_METADATA_UNLOCK_WR();
return -OCF_ERR_INVAL;
}
/* Try set partition size */
if (_ocf_mngt_set_partition_size(cache, part_id, min, max)) {
ocf_cache_log(cache, log_info,
"Setting IO class size, id: %u, name: '%s' "
"[ ERROR ]\n", part_id, dest_part->config->name);
return -OCF_ERR_INVAL;
}
if (ocf_part_is_valid(dest_part)) {
/* Updating existing */
ocf_cache_log(cache, log_info, "Updating existing IO "
"class, id: %u, name: '%s' [ OK ]\n",
part_id, dest_part->config->name);
if (ocf_part_is_valid(dest_part)) {
/* Updating existing */
ocf_cache_log(cache, log_info, "Updating existing IO "
"class, id: %u, name: '%s' [ OK ]\n",
part_id, dest_part->config->name);
} else {
/* Adding new */
ocf_part_set_valid(cache, part_id, true);
} else {
/* Adding new */
ocf_part_set_valid(cache, part_id, true);
ocf_cache_log(cache, log_info, "Adding new IO class, "
"id: %u, name: '%s' [ OK ]\n", part_id,
dest_part->config->name);
}
ocf_cache_log(cache, log_info, "Adding new IO class, "
"id: %u, name: '%s' [ OK ]\n", part_id,
dest_part->config->name);
}
ocf_part_set_prio(cache, dest_part, prio);
dest_part->config->cache_mode = cache_mode;
ocf_part_set_prio(cache, dest_part, prio);
dest_part->config->cache_mode = cache_mode;
return result;
}
static int _ocf_mngt_io_class_remove(ocf_cache_t cache,
const struct ocf_mngt_io_class_config *cfg)
{
struct ocf_user_part *dest_part;
ocf_part_id_t part_id = cfg->class_id;
int result;
dest_part = &cache->user_parts[part_id];
OCF_CHECK_NULL(cache->device);
if (part_id == PARTITION_DEFAULT) {
ocf_cache_log(cache, log_info,
"Cannot remove unclassified IO class, "
"id: %u [ ERROR ]\n", part_id);
return 0;
}
if (ocf_part_is_valid(dest_part)) {
result = 0;
ocf_part_set_valid(cache, part_id, false);
ocf_cache_log(cache, log_info,
"Removing IO class, id: %u [ %s ]\n",
part_id, result ? "ERROR" : "OK");
} else {
/* Clearing */
if (ocf_part_is_valid(dest_part)) {
/* Removing */
result = 0;
ocf_part_set_valid(cache, part_id, false);
ocf_cache_log(cache, log_info,
"Removing IO class, id: %u [ %s ]\n",
part_id, result ? "ERROR" : "OK");
} else {
/* Does not exist */
result = -OCF_ERR_IO_CLASS_NOT_EXIST;
}
/* Does not exist */
result = -OCF_ERR_IO_CLASS_NOT_EXIST;
}
ocf_part_sort(cache);
return result;
}
OCF_METADATA_UNLOCK_WR();
static int _ocf_mngt_io_class_edit(ocf_cache_t cache,
const struct ocf_mngt_io_class_config *cfg)
{
int result;
if (cfg->name) {
result = _ocf_mngt_io_class_configure(cache, cfg);
} else {
result = _ocf_mngt_io_class_remove(cache, cfg);
}
return result;
}
@@ -226,6 +231,10 @@ static int _ocf_mngt_io_class_validate_cfg(ocf_cache_t cache,
if (cfg->class_id >= OCF_IO_CLASS_MAX)
return -OCF_ERR_INVAL;
/* Name set to null means particular io_class should be removed */
if (!cfg->name)
return 0;
/* TODO(r.baldyga): ocf_cache_mode_max is allowed for compatibility
* with OCF 3.1 kernel adapter (upgrade in flight) and casadm.
* Forbid ocf_cache_mode_max after fixing these problems.
@@ -250,17 +259,60 @@ static int _ocf_mngt_io_class_validate_cfg(ocf_cache_t cache,
return 0;
}
int ocf_mngt_io_class_configure(ocf_cache_t cache,
const struct ocf_mngt_io_class_config *cfg)
int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache,
const struct ocf_mngt_io_classes_config *cfg)
{
struct ocf_user_part *old_config;
int result;
int i;
OCF_CHECK_NULL(cache);
OCF_CHECK_NULL(cfg);
result = _ocf_mngt_io_class_validate_cfg(cache, cfg);
if (result)
for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
result = _ocf_mngt_io_class_validate_cfg(cache, &cfg->config[i]);
if (result)
return result;
}
old_config = env_malloc(sizeof(cache->user_parts), ENV_MEM_NORMAL);
if (!old_config)
return -OCF_ERR_NO_MEM;
OCF_METADATA_LOCK_WR();
result = env_memcpy(old_config, sizeof(&cache->user_parts),
cache->user_parts, sizeof(&cache->user_parts));
if (result) {
env_free(old_config);
return result;
}
return _ocf_mngt_io_class_configure(cache, cfg);
for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
result = _ocf_mngt_io_class_edit(cache, &cfg->config[i]);
if (result && result != -OCF_ERR_IO_CLASS_NOT_EXIST) {
ocf_cache_log(cache, log_err,
"Failed to set new io class config\n");
goto err;
}
result = 0;
}
ocf_part_sort(cache);
if (ocf_metadata_flush_superblock(cache)) {
ocf_cache_log(cache, log_err, "Failed to store new io class config\n");
result = -OCF_ERR_WRITE_CACHE;
}
err:
if (result) {
ENV_BUG_ON(env_memcpy(cache->user_parts, sizeof(&cache->user_parts),
old_config, sizeof(&cache->user_parts)));
}
OCF_METADATA_UNLOCK_WR();
return result;
}

View File

@@ -195,8 +195,8 @@ struct ocf_cache {
env_atomic flush_in_progress;
/* Interpreted as a counter rather than a flag */
env_atomic dirty_rq_barrier;
/* Prevent dirty requests. May be incremented recursively */
env_atomic flush_started;
/* 1 if cache device attached, 0 otherwise */
env_atomic attached;

View File

@@ -653,14 +653,14 @@ static ctx_data_t *ocf_core_io_get_data(struct ocf_io *io)
return core_io->data;
}
const struct ocf_data_obj_properties ocf_core_data_obj_properties = {
const struct ocf_data_obj_properties ocf_core_data_obj_properties = {
.name = "OCF Core",
.io_priv_size = sizeof(struct ocf_core_io),
.dobj_priv_size = sizeof(struct ocf_core_dobj),
.caps = {
.caps = {
.atomic_writes = 0,
},
.ops = {
.ops = {
.submit_io = ocf_core_data_obj_submit_io,
.submit_flush = ocf_core_data_obj_submit_flush,
.submit_discard = ocf_core_data_obj_submit_discard,

View File

@@ -9,7 +9,7 @@
#include "engine/cache_engine.h"
#include "utils/utils_part.h"
int ocf_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
int ocf_cache_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
struct ocf_io_class_info *info)
{
ocf_part_id_t part_id = io_class;

View File

@@ -9,6 +9,7 @@
#include "engine/cache_engine.h"
#include "utils/utils_part.h"
#include "utils/utils_cache_line.h"
#include "utils/utils_core.h"
#ifdef OCF_DEBUG_STATS
static void ocf_stats_debug_init(struct ocf_counters_debug *stats)
@@ -160,39 +161,30 @@ static void copy_debug_stats(struct ocf_stats_core_debug *dest,
}
#endif
int ocf_io_class_get_stats(ocf_core_t core, uint32_t io_class,
int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id,
struct ocf_stats_io_class *stats)
{
ocf_part_id_t part_id = io_class;
ocf_cache_t cache;
uint32_t i;
uint32_t cache_occupancy_total = 0;
struct ocf_counters_part *part_stat;
ocf_core_id_t core_id;
ocf_cache_t cache;
OCF_CHECK_NULL(core);
OCF_CHECK_NULL(stats);
if (part_id < OCF_IO_CLASS_ID_MIN || part_id > OCF_IO_CLASS_ID_MAX)
return -OCF_ERR_INVAL;
core_id = ocf_core_get_id(core);
cache = ocf_core_get_cache(core);
if (!stats)
return -OCF_ERR_INVAL;
if (io_class >= OCF_IO_CLASS_MAX)
return -OCF_ERR_INVAL;
if (!ocf_part_is_valid(&cache->user_parts[part_id])) {
/* Partition does not exist */
if (!ocf_part_is_valid(&cache->user_parts[part_id]))
return -OCF_ERR_IO_CLASS_NOT_EXIST;
}
for (i = 0; i != OCF_CORE_MAX; ++i) {
if (!env_bit_test(i, cache->conf_meta->
valid_object_bitmap)) {
continue;
}
cache_occupancy_total += env_atomic_read(&cache->
core_runtime_meta[i].cached_clines);
for_each_core(cache, i) {
cache_occupancy_total += env_atomic_read(
&cache->core_runtime_meta[i].cached_clines);
}
part_stat = &core->counters->part_counters[part_id];

13
src/utils/utils_core.h Normal file
View File

@@ -0,0 +1,13 @@
/*
* Copyright(c) 2012-2018 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef __UTILS_CORE_H__
#define __UTILS_CORE_H__
#define for_each_core(cache, iter) \
for (iter = 0; iter < OCF_CORE_MAX; iter++) \
if (cache->core_conf_meta[iter].added)
#endif /* __UTILS_CORE_H__ */