Functional test for overflown pinned ioclass

Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
Michal Mielewczyk 2021-02-16 03:59:22 -05:00
parent 7f3f2ad115
commit 83f142c987

View File

@ -4,6 +4,7 @@
#
import logging
from math import ceil, isclose
from ctypes import c_int
import pytest
@ -12,7 +13,7 @@ from pyocf.types.cache import Cache, CacheMode
from pyocf.types.core import Core
from pyocf.types.data import Data
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.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
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(
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)