Skip to content

Commit 6da01e8

Browse files
Robert Baldygammichal10
authored andcommitted
Protect cache lock against locking during lock deinitialization
Signed-off-by: Robert Baldyga <robert.baldyga@huawei.com> Signed-off-by: Michal Mielewczyk <michal.mielewczyk@huawei.com>
1 parent caf6d46 commit 6da01e8

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

src/mngt/ocf_mngt_cache.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,14 +2317,14 @@ static void _ocf_mngt_cache_dealloc(void *priv)
23172317

23182318
static void ocf_mngt_cache_remove(ocf_ctx_t ctx, ocf_cache_t cache)
23192319
{
2320+
/* Deinitialize cache lock */
2321+
ocf_mngt_cache_lock_deinit(cache);
2322+
23202323
/* Mark device uninitialized */
23212324
env_refcnt_freeze(&cache->refcnt.cache);
23222325
env_refcnt_register_zero_cb(&cache->refcnt.cache,
23232326
_ocf_mngt_cache_dealloc, cache);
23242327

2325-
/* Deinitialize locks */
2326-
ocf_mngt_cache_lock_deinit(cache);
2327-
23282328
env_spinlock_destroy(&cache->io_queues_lock);
23292329

23302330
env_mutex_destroy(&cache->flush_mutex);

src/mngt/ocf_mngt_common.c

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,15 @@ static void _ocf_mngt_cache_lock(ocf_cache_t cache,
238238
if (ocf_mngt_cache_get(cache))
239239
OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_NOT_EXIST);
240240

241+
if (!env_refcnt_inc(&cache->refcnt.lock)) {
242+
ocf_mngt_cache_put(cache);
243+
OCF_CMPL_RET(cache, priv, -OCF_ERR_CACHE_NOT_EXIST);
244+
}
245+
241246
waiter = ocf_async_lock_new_waiter(&cache->lock,
242247
_ocf_mngt_cache_lock_complete);
243248
if (!waiter) {
249+
env_refcnt_dec(&cache->refcnt.lock);
244250
ocf_mngt_cache_put(cache);
245251
OCF_CMPL_RET(cache, priv, -OCF_ERR_NO_MEM);
246252
}
@@ -252,20 +258,26 @@ static void _ocf_mngt_cache_lock(ocf_cache_t cache,
252258
context->priv = priv;
253259

254260
lock_fn(waiter);
261+
env_refcnt_dec(&cache->refcnt.lock);
255262
}
256263

257264
static int _ocf_mngt_cache_trylock(ocf_cache_t cache,
258265
ocf_trylock_fn_t trylock_fn, ocf_unlock_fn_t unlock_fn)
259266
{
260-
int result;
267+
int result = 0;
261268

262269
if (ocf_mngt_cache_get(cache))
263270
return -OCF_ERR_CACHE_NOT_EXIST;
264271

272+
if (!env_refcnt_inc(&cache->refcnt.lock)) {
273+
ocf_mngt_cache_put(cache);
274+
return -OCF_ERR_CACHE_NOT_EXIST;
275+
}
276+
265277
result = trylock_fn(&cache->lock);
266278
if (result) {
267279
ocf_mngt_cache_put(cache);
268-
return result;
280+
goto out;
269281
}
270282

271283
if (env_bit_test(ocf_cache_state_stopping, &cache->cache_state)) {
@@ -274,6 +286,8 @@ static int _ocf_mngt_cache_trylock(ocf_cache_t cache,
274286
result = -OCF_ERR_CACHE_NOT_EXIST;
275287
}
276288

289+
out:
290+
env_refcnt_dec(&cache->refcnt.lock);
277291
return result;
278292
}
279293

@@ -286,13 +300,38 @@ static void _ocf_mngt_cache_unlock(ocf_cache_t cache,
286300

287301
int ocf_mngt_cache_lock_init(ocf_cache_t cache)
288302
{
289-
return ocf_async_lock_init(&cache->lock,
303+
int result;
304+
305+
result = env_refcnt_init(&cache->refcnt.lock, "lock", sizeof("lock"));
306+
if (result)
307+
return result;
308+
309+
result = ocf_async_lock_init(&cache->lock,
290310
sizeof(struct ocf_mngt_cache_lock_context));
311+
if (result)
312+
env_refcnt_deinit(&cache->refcnt.lock);
313+
314+
return result;
291315
}
292316

293-
void ocf_mngt_cache_lock_deinit(ocf_cache_t cache)
317+
static void _ocf_mngt_cache_lock_deinit(void *priv)
294318
{
319+
ocf_cache_t cache = priv;
320+
295321
ocf_async_lock_deinit(&cache->lock);
322+
env_refcnt_dec(&cache->refcnt.cache);
323+
env_refcnt_deinit(&cache->refcnt.lock);
324+
}
325+
326+
void ocf_mngt_cache_lock_deinit(ocf_cache_t cache)
327+
{
328+
bool cache_get;
329+
330+
cache_get = env_refcnt_inc(&cache->refcnt.cache);
331+
ENV_BUG_ON(!cache_get);
332+
env_refcnt_freeze(&cache->refcnt.lock);
333+
env_refcnt_register_zero_cb(&cache->refcnt.lock,
334+
_ocf_mngt_cache_lock_deinit, cache);
296335
}
297336

298337
void ocf_mngt_cache_lock(ocf_cache_t cache,

src/ocf_cache_priv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ struct ocf_cache {
8686
struct env_refcnt metadata;
8787
/* # of requests in d2c mode */
8888
struct env_refcnt d2c;
89+
/* # of unsettled cache lock operations (lock not acquired,
90+
* waiter not added yet) */
91+
struct env_refcnt lock;
8992
} refcnt;
9093

9194
struct {

0 commit comments

Comments
 (0)