cacheline concurrency: move allocation outside critical section

Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
Adam Rutkowski 2019-10-18 18:33:32 -04:00
parent 07b1f0c064
commit 6423c48dfe

View File

@ -407,6 +407,14 @@ static inline bool __lock_cache_line_wr(struct ocf_cache_line_concurrency *c,
return true; 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); __lock_waiters_list(c, line, flags);
/* At the moment list is protected, double check if the cache line is /* At the moment list is protected, double check if the cache line is
@ -415,31 +423,26 @@ static inline bool __lock_cache_line_wr(struct ocf_cache_line_concurrency *c,
if (__try_lock_wr(c, line)) { if (__try_lock_wr(c, line)) {
/* Look get */ /* Look get */
locked = true; locked = true;
} else { } else if (cb) {
waiter = NULL; /* Setup waiters filed */
if (cb != NULL) { waiter->line = line;
/* Need to create waiters and add it into list */ waiter->ctx = ctx;
waiter = env_allocator_new(c->allocator); waiter->ctx_id = ctx_id;
} waiter->cb = cb;
if (waiter) { waiter->rw = OCF_WRITE;
/* Setup waiters filed */ INIT_LIST_HEAD(&waiter->item);
waiter->line = line;
waiter->ctx = ctx;
waiter->ctx_id = ctx_id;
waiter->cb = cb;
waiter->rw = OCF_WRITE;
INIT_LIST_HEAD(&waiter->item);
/* Add to waiters list */ /* Add to waiters list */
__add_waiter(c, line, waiter); __add_waiter(c, line, waiter);
waiting = true; waiting = true;
}
} }
__unlock_waiters_list(c, line, flags); __unlock_waiters_list(c, line, flags);
if (locked && cb) if (locked && cb)
_req_on_lock(ctx, cb, ctx_id, line, OCF_WRITE); _req_on_lock(ctx, cb, ctx_id, line, OCF_WRITE);
if (!waiting && waiter)
env_allocator_del(c->allocator, waiter);
return locked || waiting; return locked || waiting;
} }
@ -464,6 +467,9 @@ static inline bool __lock_cache_line_rd(struct ocf_cache_line_concurrency *c,
return true; return true;
} }
waiter = NULL;
repeat:
/* Lock waiters list */ /* Lock waiters list */
__lock_waiters_list(c, line, flags); __lock_waiters_list(c, line, flags);
@ -474,34 +480,42 @@ static inline bool __lock_cache_line_rd(struct ocf_cache_line_concurrency *c,
if (__try_lock_rd(c, line)) { if (__try_lock_rd(c, line)) {
/* Cache line locked */ /* Cache line locked */
locked = true; locked = true;
goto unlock;
} }
} }
if (!locked) { if (!cb)
waiter = NULL; goto unlock;
if (cb) {
/* Need to create waiters and add it into list */
waiter = env_allocator_new(c->allocator);
}
if (waiter) {
/* Setup waiters field */
waiter->line = line;
waiter->ctx = ctx;
waiter->ctx_id = ctx_id;
waiter->cb = cb;
waiter->rw = OCF_READ;
INIT_LIST_HEAD(&waiter->item);
/* Add to waiters list */ if (!waiter) {
__add_waiter(c, line, waiter); /* Need to create waiters and add it into list */
waiting = true; __unlock_waiters_list(c, line, flags);
} waiter = env_allocator_new(c->allocator);
if (!waiter)
goto end;
goto repeat;
} }
/* Setup waiters field */
waiter->line = line;
waiter->ctx = ctx;
waiter->ctx_id = ctx_id;
waiter->cb = cb;
waiter->rw = OCF_READ;
INIT_LIST_HEAD(&waiter->item);
/* Add to waiters list */
__add_waiter(c, line, waiter);
waiting = true;
unlock:
__unlock_waiters_list(c, line, flags); __unlock_waiters_list(c, line, flags);
end:
if (locked && cb) if (locked && cb)
_req_on_lock(ctx, cb, ctx_id, line, OCF_READ); _req_on_lock(ctx, cb, ctx_id, line, OCF_READ);
if (!waiting && waiter)
env_allocator_del(c->allocator, waiter);
return locked || waiting; return locked || waiting;
} }