Update management tests for WO (Write-only) cache mode

Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
Adam Rutkowski 2019-05-30 12:50:03 -04:00
parent 82e8c55f4a
commit a6312eb8aa
2 changed files with 26 additions and 16 deletions

View File

@ -74,8 +74,17 @@ class CacheMode(IntEnum):
WA = 2 WA = 2
PT = 3 PT = 3
WI = 4 WI = 4
WO = 5
DEFAULT = WT DEFAULT = WT
def lazy_write(self):
return self.value in [CacheMode.WB, CacheMode.WO]
def write_insert(self):
return self.value not in [CacheMode.PT, CacheMode.WA, CacheMode.WI]
def read_insert(self):
return self.value not in [CacheMode.PT, CacheMode.WO]
class EvictionPolicy(IntEnum): class EvictionPolicy(IntEnum):
LRU = 0 LRU = 0

View File

@ -180,7 +180,7 @@ def test_stop(pyocf_ctx, mode: CacheMode, cls: CacheLineSize, with_flush: bool):
run_io_and_cache_data_if_possible(core_exported, mode, cls) run_io_and_cache_data_if_possible(core_exported, mode, cls)
stats = cache.get_stats() stats = cache.get_stats()
assert int(stats["conf"]["dirty"]) == (1 if mode == CacheMode.WB else 0), "Dirty data before MD5" assert int(stats["conf"]["dirty"]) == (1 if mode.lazy_write() else 0), "Dirty data before MD5"
md5_exported_core = core_exported.exp_obj_md5() md5_exported_core = core_exported.exp_obj_md5()
@ -188,7 +188,7 @@ def test_stop(pyocf_ctx, mode: CacheMode, cls: CacheLineSize, with_flush: bool):
cache.flush() cache.flush()
cache.stop() cache.stop()
if mode == CacheMode.WB and not with_flush: if mode.lazy_write() and not with_flush:
pytest.xfail("MD5 sums equal without flush with dirty data") # TODO: remove after WB fixed pytest.xfail("MD5 sums equal without flush with dirty data") # TODO: remove after WB fixed
assert core_device.md5() != md5_exported_core, \ assert core_device.md5() != md5_exported_core, \
"MD5 check: core device vs exported object with dirty data" "MD5 check: core device vs exported object with dirty data"
@ -393,38 +393,39 @@ def io_from_exported_object(exported_obj: Core, buffer_size: int, offset: int):
def check_stats_read_empty(exported_obj: Core, mode: CacheMode, cls: CacheLineSize): def check_stats_read_empty(exported_obj: Core, mode: CacheMode, cls: CacheLineSize):
stats = exported_obj.cache.get_stats() stats = exported_obj.cache.get_stats()
assert stats["conf"]["cache_mode"] == mode, "Cache mode" assert stats["conf"]["cache_mode"] == mode, "Cache mode"
assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == (0 if mode == CacheMode.PT else 1), \ assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == (1 if mode.read_insert() else 0), \
"Writes to cache device" "Writes to cache device"
assert exported_obj.device.get_stats()[IoDir.READ] == 1, "Reads from core device" assert exported_obj.device.get_stats()[IoDir.READ] == 1, "Reads from core device"
assert stats["req"]["rd_full_misses"]["value"] == (0 if mode == CacheMode.PT else 1), \ assert stats["req"]["rd_full_misses"]["value"] == (0 if mode == CacheMode.PT else 1), \
"Read full misses" "Read full misses"
assert stats["usage"]["occupancy"]["value"] == \ assert stats["usage"]["occupancy"]["value"] == \
(0 if mode == CacheMode.PT else (cls / CacheLineSize.LINE_4KiB)), "Occupancy" ((cls / CacheLineSize.LINE_4KiB) if mode.read_insert() else 0), "Occupancy"
def check_stats_write_empty(exported_obj: Core, mode: CacheMode, cls: CacheLineSize): def check_stats_write_empty(exported_obj: Core, mode: CacheMode, cls: CacheLineSize):
stats = exported_obj.cache.get_stats() stats = exported_obj.cache.get_stats()
assert stats["conf"]["cache_mode"] == mode, "Cache mode" assert stats["conf"]["cache_mode"] == mode, "Cache mode"
# TODO(ajrutkow): why 1 for WT ??
assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \ assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \
(2 if mode == CacheMode.WB else (1 if mode == CacheMode.WT else 0)), \ (2 if mode.lazy_write() else (1 if mode == CacheMode.WT else 0)), \
"Writes to cache device" "Writes to cache device"
assert exported_obj.device.get_stats()[IoDir.WRITE] == (0 if mode == CacheMode.WB else 1), \ assert exported_obj.device.get_stats()[IoDir.WRITE] == (0 if mode.lazy_write() else 1), \
"Writes to core device" "Writes to core device"
assert stats["req"]["wr_full_misses"]["value"] == (1 if mode in {CacheMode.WT, CacheMode.WB} else 0), \ assert stats["req"]["wr_full_misses"]["value"] == (1 if mode.write_insert() else 0), \
"Write full misses" "Write full misses"
assert stats["usage"]["occupancy"]["value"] == \ assert stats["usage"]["occupancy"]["value"] == \
((cls / CacheLineSize.LINE_4KiB) if mode in {CacheMode.WB, CacheMode.WT} else 0), \ ((cls / CacheLineSize.LINE_4KiB) if mode.write_insert() else 0), \
"Occupancy" "Occupancy"
def check_stats_write_after_read(exported_obj: Core, mode: CacheMode, cls: CacheLineSize, read_from_empty=False): def check_stats_write_after_read(exported_obj: Core, mode: CacheMode, cls: CacheLineSize, read_from_empty=False):
stats = exported_obj.cache.get_stats() stats = exported_obj.cache.get_stats()
assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \ assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \
(0 if mode in {CacheMode.WI, CacheMode.PT} else (2 if read_from_empty and mode == CacheMode.WB else 1)), \ (0 if mode in {CacheMode.WI, CacheMode.PT} else (2 if read_from_empty and mode.lazy_write() else 1)), \
"Writes to cache device" "Writes to cache device"
assert exported_obj.device.get_stats()[IoDir.WRITE] == (0 if mode == CacheMode.WB else 1), \ assert exported_obj.device.get_stats()[IoDir.WRITE] == (0 if mode.lazy_write() else 1), \
"Writes to core device" "Writes to core device"
assert stats["req"]["wr_hits"]["value"] == (0 if mode in {CacheMode.WI, CacheMode.PT} else 1), \ assert stats["req"]["wr_hits"]["value"] == (1 if (mode.read_insert() and mode != CacheMode.WI) or (mode.write_insert() and not read_from_empty) else 0), \
"Write hits" "Write hits"
assert stats["usage"]["occupancy"]["value"] == \ assert stats["usage"]["occupancy"]["value"] == \
(0 if mode in {CacheMode.WI, CacheMode.PT} else (cls / CacheLineSize.LINE_4KiB)), \ (0 if mode in {CacheMode.WI, CacheMode.PT} else (cls / CacheLineSize.LINE_4KiB)), \
@ -434,26 +435,26 @@ def check_stats_write_after_read(exported_obj: Core, mode: CacheMode, cls: Cache
def check_stats_read_after_write(exported_obj, mode, cls, write_to_empty=False): def check_stats_read_after_write(exported_obj, mode, cls, write_to_empty=False):
stats = exported_obj.cache.get_stats() stats = exported_obj.cache.get_stats()
assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \ assert exported_obj.cache.device.get_stats()[IoDir.WRITE] == \
(2 if mode == CacheMode.WB else (0 if mode == CacheMode.PT else 1)), \ (2 if mode.lazy_write() else (0 if mode == CacheMode.PT else 1)), \
"Writes to cache device" "Writes to cache device"
assert exported_obj.cache.device.get_stats()[IoDir.READ] == \ assert exported_obj.cache.device.get_stats()[IoDir.READ] == \
(1 if mode in {CacheMode.WT, CacheMode.WB} or (mode == CacheMode.WA and not write_to_empty) else 0), \ (1 if mode in {CacheMode.WT, CacheMode.WB, CacheMode.WO} or (mode == CacheMode.WA and not write_to_empty) else 0), \
"Reads from cache device" "Reads from cache device"
assert exported_obj.device.get_stats()[IoDir.READ] == \ assert exported_obj.device.get_stats()[IoDir.READ] == \
(0 if mode in {CacheMode.WB, CacheMode.WT} or (mode == CacheMode.WA and not write_to_empty) else 1), \ (0 if mode in {CacheMode.WB, CacheMode.WO, CacheMode.WT} or (mode == CacheMode.WA and not write_to_empty) else 1), \
"Reads from core device" "Reads from core device"
assert stats["req"]["rd_full_misses"]["value"] == (1 if mode in {CacheMode.WA, CacheMode.WI} else 0) \ assert stats["req"]["rd_full_misses"]["value"] == (1 if mode in {CacheMode.WA, CacheMode.WI} else 0) \
+ (0 if write_to_empty or mode in {CacheMode.PT, CacheMode.WA} else 1), \ + (0 if write_to_empty or mode in {CacheMode.PT, CacheMode.WA} else 1), \
"Read full misses" "Read full misses"
assert stats["req"]["rd_hits"]["value"] == \ assert stats["req"]["rd_hits"]["value"] == \
(1 if mode in {CacheMode.WT, CacheMode.WB} or (mode == CacheMode.WA and not write_to_empty) else 0), \ (1 if mode in {CacheMode.WT, CacheMode.WB, CacheMode.WO} or (mode == CacheMode.WA and not write_to_empty) else 0), \
"Read hits" "Read hits"
assert stats["usage"]["occupancy"]["value"] == \ assert stats["usage"]["occupancy"]["value"] == \
(0 if mode == CacheMode.PT else (cls / CacheLineSize.LINE_4KiB)), "Occupancy" (0 if mode == CacheMode.PT else (cls / CacheLineSize.LINE_4KiB)), "Occupancy"
def check_md5_sums(exported_obj: Core, mode: CacheMode): def check_md5_sums(exported_obj: Core, mode: CacheMode):
if mode == CacheMode.WB: if mode.lazy_write():
assert exported_obj.device.md5() != exported_obj.exp_obj_md5(), \ assert exported_obj.device.md5() != exported_obj.exp_obj_md5(), \
"MD5 check: core device vs exported object without flush" "MD5 check: core device vs exported object without flush"
exported_obj.cache.flush() exported_obj.cache.flush()