cacheline concurrency: move allocation outside critical section
@@ -407,6 +407,14 @@ static inline bool __lock_cache_line_wr(struct ocf_cache_line_concurrency *c,
return true;
}
+ waiter = NULL;
+ if (cb) {
+ /* Need to create waiter */
+ waiter = env_allocator_new(c->allocator);
+ if (!waiter)
+ return false;
+ }
+
__lock_waiters_list(c, line, flags);
/* At the moment list is protected, double check if the cache line is
@@ -415,13 +423,7 @@ static inline bool __lock_cache_line_wr(struct ocf_cache_line_concurrency *c,
if (__try_lock_wr(c, line)) {
/* Look get */
locked = true;
- } else {
- waiter = NULL;
- if (cb != NULL) {
- /* Need to create waiters and add it into list */
- waiter = env_allocator_new(c->allocator);
- }
- if (waiter) {
+ } else if (cb) {
/* Setup waiters filed */
waiter->line = line;
waiter->ctx = ctx;
@@ -434,12 +436,13 @@ static inline bool __lock_cache_line_wr(struct ocf_cache_line_concurrency *c,
__add_waiter(c, line, waiter);
waiting = true;
}
- }
__unlock_waiters_list(c, line, flags);
if (locked && cb)
_req_on_lock(ctx, cb, ctx_id, line, OCF_WRITE);
+ if (!waiting && waiter)
+ env_allocator_del(c->allocator, waiter);
return locked || waiting;
}
@@ -464,6 +467,9 @@ static inline bool __lock_cache_line_rd(struct ocf_cache_line_concurrency *c,
return true;
}
+ waiter = NULL;
+
+repeat:
/* Lock waiters list */
__lock_waiters_list(c, line, flags);
@@ -474,16 +480,22 @@ static inline bool __lock_cache_line_rd(struct ocf_cache_line_concurrency *c,
if (__try_lock_rd(c, line)) {
/* Cache line locked */
locked = true;
+ goto unlock;
}
}
- if (!locked) {
- waiter = NULL;
- if (cb) {
+ if (!cb)
+ goto unlock;
+
+ if (!waiter) {
/* Need to create waiters and add it into list */
+ __unlock_waiters_list(c, line, flags);
waiter = env_allocator_new(c->allocator);
+ if (!waiter)
+ goto end;
+ goto repeat;
}
- if (waiter) {
+
/* Setup waiters field */
waiter->line = line;
waiter->ctx = ctx;
@@ -495,13 +507,15 @@ static inline bool __lock_cache_line_rd(struct ocf_cache_line_concurrency *c,
/* Add to waiters list */
__add_waiter(c, line, waiter);
waiting = true;
- }
- }
+unlock:
__unlock_waiters_list(c, line, flags);
+end:
if (locked && cb)
_req_on_lock(ctx, cb, ctx_id, line, OCF_READ);
+ if (!waiting && waiter)
+ env_allocator_del(c->allocator, waiter);
return locked || waiting;
}
