diff --git a/inc/ocf_queue.h b/inc/ocf_queue.h index 7002ce5c..2a59103d 100644 --- a/inc/ocf_queue.h +++ b/inc/ocf_queue.h @@ -72,6 +72,28 @@ int ocf_queue_create(ocf_cache_t cache, ocf_queue_t *queue, int ocf_queue_create_mngt(ocf_cache_t cache, ocf_queue_t *queue, const struct ocf_queue_ops *ops); +/** + * @brief Queue visitor function + * @param[in] queue Queue handle + * @param[in] ctx Visitor function context + * + * @return Zero on success, otherwise error code + */ +typedef int (*ocf_cache_queue_visitor_t)(ocf_queue_t queue, void *ctx); + +/** + * @brief Call @visitor for every IO queue + * + * @param[in] cache Cache instance + * @param[in] visitor Function to be called on every queue. + * The visitor function is called in atomic context + * @param[in] ctx Context to be passes to @visitor + * + * @return Zero on success, otherwise error code + */ +int ocf_queue_visit(ocf_cache_t cache, ocf_cache_queue_visitor_t visitor, + void *ctx); + /** * @brief Increase reference counter in queue * diff --git a/src/ocf_queue.c b/src/ocf_queue.c index 6615ad9d..cb985aaa 100644 --- a/src/ocf_queue.c +++ b/src/ocf_queue.c @@ -78,6 +78,26 @@ int ocf_queue_create(ocf_cache_t cache, ocf_queue_t *queue, return 0; } +int ocf_queue_visit(ocf_cache_t cache, ocf_cache_queue_visitor_t visitor, + void *ctx) +{ + ocf_queue_t queue; + int result = 0; + unsigned long flags = 0; + + env_spinlock_lock_irqsave(&cache->io_queues_lock, flags); + + list_for_each_entry(queue, &cache->io_queues, list) { + result = visitor(queue, ctx); + if (result) + break; + } + + env_spinlock_unlock_irqrestore(&cache->io_queues_lock, flags); + + return result; +} + int ocf_queue_create_mngt(ocf_cache_t cache, ocf_queue_t *queue, const struct ocf_queue_ops *ops) {