Introduce asynchronous cache lock
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
@@ -186,24 +186,24 @@ class Cache:
|
||||
self.started = True
|
||||
|
||||
def change_cache_mode(self, cache_mode: CacheMode):
|
||||
self.get_and_write_lock()
|
||||
self.write_lock()
|
||||
status = self.owner.lib.ocf_mngt_cache_set_mode(
|
||||
self.cache_handle, cache_mode
|
||||
)
|
||||
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
|
||||
if status:
|
||||
raise OcfError("Error changing cache mode", status)
|
||||
|
||||
def set_cleaning_policy(self, cleaning_policy: CleaningPolicy):
|
||||
self.get_and_write_lock()
|
||||
self.write_lock()
|
||||
|
||||
status = self.owner.lib.ocf_mngt_cache_cleaning_set_policy(
|
||||
self.cache_handle, cleaning_policy
|
||||
)
|
||||
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
|
||||
if status:
|
||||
raise OcfError("Error changing cleaning policy", status)
|
||||
@@ -211,25 +211,25 @@ class Cache:
|
||||
def set_cleaning_policy_param(
|
||||
self, cleaning_policy: CleaningPolicy, param_id, param_value
|
||||
):
|
||||
self.get_and_write_lock()
|
||||
self.write_lock()
|
||||
|
||||
status = self.owner.lib.ocf_mngt_cache_cleaning_set_param(
|
||||
self.cache_handle, cleaning_policy, param_id, param_value
|
||||
)
|
||||
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
|
||||
if status:
|
||||
raise OcfError("Error setting cleaning policy param", status)
|
||||
|
||||
def set_seq_cut_off_policy(self, policy: SeqCutOffPolicy):
|
||||
self.get_and_write_lock()
|
||||
self.write_lock()
|
||||
|
||||
status = self.owner.lib.ocf_mngt_core_set_seq_cutoff_policy_all(
|
||||
self.cache_handle, policy
|
||||
)
|
||||
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
|
||||
if status:
|
||||
raise OcfError("Error setting cache seq cut off policy", status)
|
||||
@@ -261,7 +261,7 @@ class Cache:
|
||||
self, device, force=False, perform_test=False, cache_line_size=None
|
||||
):
|
||||
self.configure_device(device, force, perform_test, cache_line_size)
|
||||
self.get_and_write_lock()
|
||||
self.write_lock()
|
||||
|
||||
c = OcfCompletion(
|
||||
[("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]
|
||||
@@ -272,7 +272,7 @@ class Cache:
|
||||
)
|
||||
|
||||
c.wait()
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
|
||||
if c.results["error"]:
|
||||
raise OcfError("Attaching cache device failed", c.results["error"])
|
||||
@@ -316,26 +316,6 @@ class Cache:
|
||||
|
||||
return c
|
||||
|
||||
def _get_and_lock(self, read=True):
|
||||
self.get()
|
||||
|
||||
if read:
|
||||
status = self.owner.lib.ocf_mngt_cache_read_lock(self.cache_handle)
|
||||
else:
|
||||
status = self.owner.lib.ocf_mngt_cache_lock(self.cache_handle)
|
||||
|
||||
if status:
|
||||
self.put()
|
||||
raise OcfError("Couldn't lock cache instance", status)
|
||||
|
||||
def _put_and_unlock(self, read=True):
|
||||
if read:
|
||||
self.owner.lib.ocf_mngt_cache_read_unlock(self.cache_handle)
|
||||
else:
|
||||
self.owner.lib.ocf_mngt_cache_unlock(self.cache_handle)
|
||||
|
||||
self.put()
|
||||
|
||||
def put(self):
|
||||
self.owner.lib.ocf_mngt_cache_put(self.cache_handle)
|
||||
|
||||
@@ -344,20 +324,32 @@ class Cache:
|
||||
if status:
|
||||
raise OcfError("Couldn't get cache instance", status)
|
||||
|
||||
def get_and_read_lock(self):
|
||||
self._get_and_lock(True)
|
||||
def read_lock(self):
|
||||
c = OcfCompletion(
|
||||
[("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]
|
||||
)
|
||||
self.owner.lib.ocf_mngt_cache_read_lock(self.cache_handle, c, None)
|
||||
c.wait()
|
||||
if c.results["error"]:
|
||||
raise OcfError("Couldn't lock cache instance", c.results["error"])
|
||||
|
||||
def get_and_write_lock(self):
|
||||
self._get_and_lock(False)
|
||||
def write_lock(self):
|
||||
c = OcfCompletion(
|
||||
[("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]
|
||||
)
|
||||
self.owner.lib.ocf_mngt_cache_lock(self.cache_handle, c, None)
|
||||
c.wait()
|
||||
if c.results["error"]:
|
||||
raise OcfError("Couldn't lock cache instance", c.results["error"])
|
||||
|
||||
def put_and_read_unlock(self):
|
||||
self._put_and_unlock(True)
|
||||
def read_unlock(self):
|
||||
self.owner.lib.ocf_mngt_cache_read_unlock(self.cache_handle)
|
||||
|
||||
def put_and_write_unlock(self):
|
||||
self._put_and_unlock(False)
|
||||
def write_unlock(self):
|
||||
self.owner.lib.ocf_mngt_cache_unlock(self.cache_handle)
|
||||
|
||||
def add_core(self, core: Core):
|
||||
self.get_and_write_lock()
|
||||
self.write_lock()
|
||||
|
||||
c = OcfCompletion(
|
||||
[
|
||||
@@ -374,24 +366,24 @@ class Cache:
|
||||
|
||||
c.wait()
|
||||
if c.results["error"]:
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
raise OcfError("Failed adding core", c.results["error"])
|
||||
|
||||
core.cache = self
|
||||
core.handle = c.results["core"]
|
||||
self.cores.append(core)
|
||||
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
|
||||
def remove_core(self, core: Core):
|
||||
self.get_and_write_lock()
|
||||
self.write_lock()
|
||||
|
||||
c = OcfCompletion([("priv", c_void_p), ("error", c_int)])
|
||||
|
||||
self.owner.lib.ocf_mngt_cache_remove_core(core.handle, c, None)
|
||||
|
||||
c.wait()
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
|
||||
if c.results["error"]:
|
||||
raise OcfError("Failed removing core", c.results["error"])
|
||||
@@ -405,13 +397,13 @@ class Cache:
|
||||
block = BlocksStats()
|
||||
errors = ErrorsStats()
|
||||
|
||||
self.get_and_read_lock()
|
||||
self.read_lock()
|
||||
|
||||
status = self.owner.lib.ocf_cache_get_info(
|
||||
self.cache_handle, byref(cache_info)
|
||||
)
|
||||
if status:
|
||||
self.put_and_read_unlock()
|
||||
self.read_unlock()
|
||||
raise OcfError("Failed getting cache info", status)
|
||||
|
||||
status = self.owner.lib.ocf_stats_collect_cache(
|
||||
@@ -422,13 +414,13 @@ class Cache:
|
||||
byref(errors),
|
||||
)
|
||||
if status:
|
||||
self.put_and_read_unlock()
|
||||
self.read_unlock()
|
||||
raise OcfError("Failed getting stats", status)
|
||||
|
||||
line_size = CacheLineSize(cache_info.cache_line_size)
|
||||
cache_id = self.owner.lib.ocf_cache_get_id(self)
|
||||
|
||||
self.put_and_read_unlock()
|
||||
self.read_unlock()
|
||||
return {
|
||||
"conf": {
|
||||
"attached": cache_info.attached,
|
||||
@@ -494,7 +486,7 @@ class Cache:
|
||||
if not self.started:
|
||||
raise Exception("Already stopped!")
|
||||
|
||||
self.get_and_write_lock()
|
||||
self.write_lock()
|
||||
|
||||
c = OcfCompletion(
|
||||
[("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]
|
||||
@@ -504,40 +496,40 @@ class Cache:
|
||||
|
||||
c.wait()
|
||||
if c.results["error"]:
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
raise OcfError("Failed stopping cache", c.results["error"])
|
||||
|
||||
self.mngt_queue.put()
|
||||
del self.io_queues[:]
|
||||
self.started = False
|
||||
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
|
||||
self.owner.caches.remove(self)
|
||||
|
||||
def flush(self):
|
||||
self.get_and_write_lock()
|
||||
self.write_lock()
|
||||
|
||||
c = OcfCompletion(
|
||||
[("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]
|
||||
)
|
||||
self.owner.lib.ocf_mngt_cache_flush(self.cache_handle, c, None)
|
||||
c.wait()
|
||||
self.put_and_write_unlock()
|
||||
self.write_unlock()
|
||||
|
||||
if c.results["error"]:
|
||||
raise OcfError("Couldn't flush cache", c.results["error"])
|
||||
|
||||
|
||||
def get_name(self):
|
||||
self.get_and_read_lock()
|
||||
self.read_lock()
|
||||
|
||||
try:
|
||||
return str(self.owner.lib.ocf_cache_get_name(self), encoding="ascii")
|
||||
except:
|
||||
raise OcfError("Couldn't get cache name")
|
||||
finally:
|
||||
self.put_and_read_unlock()
|
||||
self.read_unlock()
|
||||
|
||||
|
||||
lib = OcfLib.getInstance()
|
||||
|
||||
@@ -112,22 +112,22 @@ class Core:
|
||||
blocks = BlocksStats()
|
||||
errors = ErrorsStats()
|
||||
|
||||
self.cache.get_and_read_lock()
|
||||
self.cache.read_lock()
|
||||
status = self.cache.owner.lib.ocf_stats_collect_core(
|
||||
self.handle, byref(usage), byref(req), byref(blocks), byref(errors)
|
||||
)
|
||||
if status:
|
||||
self.cache.put_and_read_unlock()
|
||||
self.cache.read_unlock()
|
||||
raise OcfError("Failed collecting core stats", status)
|
||||
|
||||
status = self.cache.owner.lib.ocf_core_get_stats(
|
||||
self.handle, byref(core_stats)
|
||||
)
|
||||
if status:
|
||||
self.cache.put_and_read_unlock()
|
||||
self.cache.read_unlock()
|
||||
raise OcfError("Failed getting core stats", status)
|
||||
|
||||
self.cache.put_and_read_unlock()
|
||||
self.cache.read_unlock()
|
||||
return {
|
||||
"size": Size(core_stats.core_size_bytes),
|
||||
"dirty_for": timedelta(seconds=core_stats.dirty_for),
|
||||
@@ -140,16 +140,16 @@ class Core:
|
||||
}
|
||||
|
||||
def set_seq_cut_off_policy(self, policy: SeqCutOffPolicy):
|
||||
self.cache.get_and_write_lock()
|
||||
self.cache.write_lock()
|
||||
|
||||
status = self.cache.owner.lib.ocf_mngt_core_set_seq_cutoff_policy(
|
||||
self.handle, policy
|
||||
)
|
||||
if status:
|
||||
self.cache.put_and_write_unlock()
|
||||
self.cache.write_unlock()
|
||||
raise OcfError("Error setting core seq cut off policy", status)
|
||||
|
||||
self.cache.put_and_write_unlock()
|
||||
self.cache.write_unlock()
|
||||
|
||||
def reset_stats(self):
|
||||
self.cache.owner.lib.ocf_core_stats_initialize(self.handle)
|
||||
|
||||
@@ -183,7 +183,7 @@ ocf_cache_t __wrap_ocf_cleaner_get_cache(ocf_cleaner_t c)
|
||||
return mock_ptr_type(struct ocf_cache*);
|
||||
}
|
||||
|
||||
bool __wrap_ocf_mngt_is_cache_locked(ocf_cache_t cache)
|
||||
bool __wrap_ocf_mngt_cache_is_locked(ocf_cache_t cache)
|
||||
{
|
||||
function_called();
|
||||
return mock();
|
||||
@@ -207,13 +207,13 @@ int __wrap_env_bit_test(int nr, const void *addr)
|
||||
return mock();
|
||||
}
|
||||
|
||||
int __wrap_env_rwsem_down_write_trylock(env_rwsem *s)
|
||||
int __wrap_ocf_mngt_cache_trylock(env_rwsem *s)
|
||||
{
|
||||
function_called();
|
||||
return mock();
|
||||
}
|
||||
|
||||
void __wrap_env_rwsem_up_write(env_rwsem *s)
|
||||
void __wrap_ocf_mngt_cache_unlock(env_rwsem *s)
|
||||
{
|
||||
function_called();
|
||||
}
|
||||
@@ -248,11 +248,11 @@ static void ocf_cleaner_run_test01(void **state)
|
||||
expect_function_call(__wrap_env_bit_test);
|
||||
will_return(__wrap_env_bit_test, 1);
|
||||
|
||||
expect_function_call(__wrap_ocf_mngt_is_cache_locked);
|
||||
will_return(__wrap_ocf_mngt_is_cache_locked, 0);
|
||||
expect_function_call(__wrap_ocf_mngt_cache_is_locked);
|
||||
will_return(__wrap_ocf_mngt_cache_is_locked, 0);
|
||||
|
||||
expect_function_call(__wrap_env_rwsem_down_write_trylock);
|
||||
will_return(__wrap_env_rwsem_down_write_trylock, 0);
|
||||
expect_function_call(__wrap_ocf_mngt_cache_trylock);
|
||||
will_return(__wrap_ocf_mngt_cache_trylock, 0);
|
||||
|
||||
expect_function_call(__wrap__ocf_cleaner_run_check_dirty_inactive);
|
||||
will_return(__wrap__ocf_cleaner_run_check_dirty_inactive, 0);
|
||||
|
||||
Reference in New Issue
Block a user