Commit 5cd90785 authored by Matias Bjørling's avatar Matias Bjørling Committed by Jens Axboe

lightnvm: remove nested lock conflict with mm

If a media manager tries to initialize it targets upon media manager
initialization, the media manager will need to know which target types
are available in LightNVM. The lists of which managers and target types
are available shares the same lock.

Therefore, on initialization, the nvm_lock is taken by LightNVM core,
which later leads to a deadlock when target types are enumerated by the
media manager.

Add an exclusive lock for target types to resolve this conflict.
Signed-off-by: default avatarMatias Bjørling <m@bjorling.me>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent b76eb20b
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/sched/sysctl.h> #include <linux/sched/sysctl.h>
static LIST_HEAD(nvm_tgt_types); static LIST_HEAD(nvm_tgt_types);
static DECLARE_RWSEM(nvm_tgtt_lock);
static LIST_HEAD(nvm_mgrs); static LIST_HEAD(nvm_mgrs);
static LIST_HEAD(nvm_devices); static LIST_HEAD(nvm_devices);
static DECLARE_RWSEM(nvm_lock); static DECLARE_RWSEM(nvm_lock);
...@@ -37,7 +38,7 @@ struct nvm_tgt_type *nvm_find_target_type(const char *name, int lock) ...@@ -37,7 +38,7 @@ struct nvm_tgt_type *nvm_find_target_type(const char *name, int lock)
struct nvm_tgt_type *tmp, *tt = NULL; struct nvm_tgt_type *tmp, *tt = NULL;
if (lock) if (lock)
down_write(&nvm_lock); down_write(&nvm_tgtt_lock);
list_for_each_entry(tmp, &nvm_tgt_types, list) list_for_each_entry(tmp, &nvm_tgt_types, list)
if (!strcmp(name, tmp->name)) { if (!strcmp(name, tmp->name)) {
...@@ -46,7 +47,7 @@ struct nvm_tgt_type *nvm_find_target_type(const char *name, int lock) ...@@ -46,7 +47,7 @@ struct nvm_tgt_type *nvm_find_target_type(const char *name, int lock)
} }
if (lock) if (lock)
up_write(&nvm_lock); up_write(&nvm_tgtt_lock);
return tt; return tt;
} }
EXPORT_SYMBOL(nvm_find_target_type); EXPORT_SYMBOL(nvm_find_target_type);
...@@ -55,12 +56,12 @@ int nvm_register_tgt_type(struct nvm_tgt_type *tt) ...@@ -55,12 +56,12 @@ int nvm_register_tgt_type(struct nvm_tgt_type *tt)
{ {
int ret = 0; int ret = 0;
down_write(&nvm_lock); down_write(&nvm_tgtt_lock);
if (nvm_find_target_type(tt->name, 0)) if (nvm_find_target_type(tt->name, 0))
ret = -EEXIST; ret = -EEXIST;
else else
list_add(&tt->list, &nvm_tgt_types); list_add(&tt->list, &nvm_tgt_types);
up_write(&nvm_lock); up_write(&nvm_tgtt_lock);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment