From 365f4f0d199317bef0b01eeef89dac7927de13cb Mon Sep 17 00:00:00 2001 From: Kozlowski Mateusz Date: Tue, 23 Mar 2021 09:50:34 +0100 Subject: [PATCH] Use read/write locks in queue sequential cutoffs If user thread is preempted during tree/list update and another IO is issued on the same CPU, the structure will be in undefined state. This may result in hung tasks, if the tree stops being a tree and a loop exists - tree search functions won't be able to end properly; or panics if a NULL value appears suddenly in the preempted thread, after a null-check was already done. Signed-off-by: Kozlowski Mateusz --- src/ocf_seq_cutoff.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ocf_seq_cutoff.c b/src/ocf_seq_cutoff.c index d7bd8fd..36c3a74 100644 --- a/src/ocf_seq_cutoff.c +++ b/src/ocf_seq_cutoff.c @@ -204,9 +204,11 @@ bool ocf_core_seq_cutoff_check(ocf_core_t core, struct ocf_request *req) return false; } + env_rwlock_read_lock(&req->io_queue->seq_cutoff->lock); result = ocf_core_seq_cutoff_base_check(req->io_queue->seq_cutoff, req->byte_position, req->byte_length, req->rw, threshold, &queue_stream); + env_rwlock_read_unlock(&req->io_queue->seq_cutoff->lock); if (queue_stream) return result; @@ -319,8 +321,10 @@ void ocf_core_seq_cutoff_update(ocf_core_t core, struct ocf_request *req) return; } + env_rwlock_write_lock(&req->io_queue->seq_cutoff->lock); stream = ocf_core_seq_cutoff_base_update(req->io_queue->seq_cutoff, req->byte_position, req->byte_length, req->rw, true); + env_rwlock_write_unlock(&req->io_queue->seq_cutoff->lock); if (stream->bytes >= threshold) promote = true; @@ -330,8 +334,10 @@ void ocf_core_seq_cutoff_update(ocf_core_t core, struct ocf_request *req) if (promote) { env_rwlock_write_lock(&core->seq_cutoff->lock); + env_rwlock_write_lock(&req->io_queue->seq_cutoff->lock); ocf_core_seq_cutoff_base_promote(core->seq_cutoff, req->io_queue->seq_cutoff, stream); + env_rwlock_write_unlock(&req->io_queue->seq_cutoff->lock); env_rwlock_write_unlock(&core->seq_cutoff->lock); } }