Merge pull request #461 from mmichal10/evict-pinned
Evict pinned overflown ioclass
This commit is contained in:
commit
91cbeed611
@ -62,7 +62,7 @@ static inline uint32_t ocf_evict_part_do(ocf_cache_t cache,
|
|||||||
|
|
||||||
static inline uint32_t ocf_evict_partitions(ocf_cache_t cache,
|
static inline uint32_t ocf_evict_partitions(ocf_cache_t cache,
|
||||||
ocf_queue_t io_queue, uint32_t evict_cline_no,
|
ocf_queue_t io_queue, uint32_t evict_cline_no,
|
||||||
bool overflown_only, uint32_t max_priority)
|
bool overflown_only, int16_t max_priority)
|
||||||
{
|
{
|
||||||
uint32_t to_evict = 0, evicted = 0;
|
uint32_t to_evict = 0, evicted = 0;
|
||||||
struct ocf_user_part *part;
|
struct ocf_user_part *part;
|
||||||
@ -84,8 +84,9 @@ static inline uint32_t ocf_evict_partitions(ocf_cache_t cache,
|
|||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!part->config->flags.eviction) {
|
if (!overflown_only && !part->config->flags.eviction) {
|
||||||
/* no more partitions available for viction
|
/* If partition is overflown it should be evcited
|
||||||
|
* even if its pinned
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -132,8 +133,9 @@ static inline uint32_t ocf_evict_do(ocf_cache_t cache,
|
|||||||
* priority in this case, as overflown partitions should
|
* priority in this case, as overflown partitions should
|
||||||
* free its cachelines regardless of destination partition
|
* free its cachelines regardless of destination partition
|
||||||
* priority. */
|
* priority. */
|
||||||
|
|
||||||
evicted = ocf_evict_partitions(cache, io_queue, evict_cline_no,
|
evicted = ocf_evict_partitions(cache, io_queue, evict_cline_no,
|
||||||
true, OCF_IO_CLASS_PRIO_HIGHEST);
|
true, OCF_IO_CLASS_PRIO_PINNED);
|
||||||
if (evicted >= evict_cline_no)
|
if (evicted >= evict_cline_no)
|
||||||
return evicted;
|
return evicted;
|
||||||
/* Not enough cachelines in overflown partitions. Go through
|
/* Not enough cachelines in overflown partitions. Go through
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from math import ceil, isclose
|
||||||
from ctypes import c_int
|
from ctypes import c_int
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -12,7 +13,7 @@ from pyocf.types.cache import Cache, CacheMode
|
|||||||
from pyocf.types.core import Core
|
from pyocf.types.core import Core
|
||||||
from pyocf.types.data import Data
|
from pyocf.types.data import Data
|
||||||
from pyocf.types.io import IoDir
|
from pyocf.types.io import IoDir
|
||||||
from pyocf.types.shared import OcfCompletion, CacheLineSize, SeqCutOffPolicy
|
from pyocf.types.shared import OcfCompletion, CacheLineSize, SeqCutOffPolicy, CacheLines
|
||||||
from pyocf.types.volume import Volume
|
from pyocf.types.volume import Volume
|
||||||
from pyocf.utils import Size
|
from pyocf.utils import Size
|
||||||
|
|
||||||
@ -74,10 +75,89 @@ def test_write_size_greater_than_cache(pyocf_ctx, mode: CacheMode, cls: CacheLin
|
|||||||
io_size_bigger_than_cache.blocks_4k
|
io_size_bigger_than_cache.blocks_4k
|
||||||
|
|
||||||
|
|
||||||
def send_io(exported_obj: Core, data: Data, addr: int = 0):
|
@pytest.mark.parametrize("cls", CacheLineSize)
|
||||||
|
def test_evict_overflown_pinned(pyocf_ctx, cls: CacheLineSize):
|
||||||
|
""" Verify if overflown pinned ioclass is evicted """
|
||||||
|
cache_device = Volume(Size.from_MiB(35))
|
||||||
|
core_device = Volume(Size.from_MiB(100))
|
||||||
|
cache = Cache.start_on_device(
|
||||||
|
cache_device, cache_mode=CacheMode.WT, cache_line_size=cls
|
||||||
|
)
|
||||||
|
core = Core.using_device(core_device)
|
||||||
|
cache.add_core(core)
|
||||||
|
|
||||||
|
test_ioclass_id = 1
|
||||||
|
pinned_ioclass_id = 2
|
||||||
|
pinned_ioclass_max_occupancy = 10
|
||||||
|
|
||||||
|
cache.configure_partition(
|
||||||
|
part_id=test_ioclass_id,
|
||||||
|
name="default_ioclass",
|
||||||
|
min_size=0,
|
||||||
|
max_size=100,
|
||||||
|
priority=1,
|
||||||
|
)
|
||||||
|
cache.configure_partition(
|
||||||
|
part_id=pinned_ioclass_id,
|
||||||
|
name="pinned_ioclass",
|
||||||
|
min_size=0,
|
||||||
|
max_size=pinned_ioclass_max_occupancy,
|
||||||
|
priority=-1,
|
||||||
|
)
|
||||||
|
|
||||||
|
cache.set_seq_cut_off_policy(SeqCutOffPolicy.NEVER)
|
||||||
|
|
||||||
|
cache_size = cache.get_stats()["conf"]["size"]
|
||||||
|
|
||||||
|
data = Data(4096)
|
||||||
|
|
||||||
|
# Populate cache with data
|
||||||
|
for i in range(cache_size.blocks_4k):
|
||||||
|
send_io(core, data, i * 4096, test_ioclass_id)
|
||||||
|
|
||||||
|
part_current_size = CacheLines(
|
||||||
|
cache.get_partition_info(part_id=test_ioclass_id)["_curr_size"], cls
|
||||||
|
)
|
||||||
|
assert isclose(
|
||||||
|
part_current_size.blocks_4k, cache_size.blocks_4k, abs_tol=Size(cls).blocks_4k
|
||||||
|
), "Failed to populate the default partition"
|
||||||
|
|
||||||
|
# Repart - force overflow of second partition occupancy limit
|
||||||
|
pinned_double_size = ceil(
|
||||||
|
(cache_size.blocks_4k * pinned_ioclass_max_occupancy * 2) / 100
|
||||||
|
)
|
||||||
|
for i in range(pinned_double_size):
|
||||||
|
send_io(core, data, i * 4096, pinned_ioclass_id)
|
||||||
|
|
||||||
|
part_current_size = CacheLines(
|
||||||
|
cache.get_partition_info(part_id=pinned_ioclass_id)["_curr_size"], cls
|
||||||
|
)
|
||||||
|
assert isclose(
|
||||||
|
part_current_size.blocks_4k, pinned_double_size, abs_tol=Size(cls).blocks_4k
|
||||||
|
), "Occupancy of pinned ioclass doesn't match expected value"
|
||||||
|
|
||||||
|
# Trigger IO to the default ioclass - force eviction from overlown ioclass
|
||||||
|
for i in range(cache_size.blocks_4k):
|
||||||
|
send_io(core, data, (cache_size.blocks_4k + i) * 4096, test_ioclass_id)
|
||||||
|
|
||||||
|
part_current_size = CacheLines(
|
||||||
|
cache.get_partition_info(part_id=pinned_ioclass_id)["_curr_size"], cls
|
||||||
|
)
|
||||||
|
assert isclose(
|
||||||
|
part_current_size.blocks_4k,
|
||||||
|
ceil(cache_size.blocks_4k * 0.1),
|
||||||
|
abs_tol=Size(cls).blocks_4k,
|
||||||
|
), "Overflown part has not been evicted"
|
||||||
|
|
||||||
|
|
||||||
|
def send_io(exported_obj: Core, data: Data, addr: int = 0, target_ioclass: int = 0):
|
||||||
io = exported_obj.new_io(
|
io = exported_obj.new_io(
|
||||||
exported_obj.cache.get_default_queue(),
|
exported_obj.cache.get_default_queue(),
|
||||||
addr, data.size, IoDir.WRITE, 0, 0
|
addr,
|
||||||
|
data.size,
|
||||||
|
IoDir.WRITE,
|
||||||
|
target_ioclass,
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
|
|
||||||
io.set_data(data)
|
io.set_data(data)
|
||||||
|
Loading…
Reference in New Issue
Block a user