diff options
| author | Johannes Thumshirn <jthumshirn@suse.de> | 2018-06-01 03:11:20 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2018-06-08 14:51:10 -0400 |
| commit | 12a0b662210702c6b0ce9f66f0c177ff1dea99cb (patch) | |
| tree | 1ec47a51a7aa9cfdd5acc59f1970b2523fb76ae4 | |
| parent | f39ae4719b1c33d048aa4d3c284d82ecf252742b (diff) | |
nvme: don't hold nvmf_transports_rwsem for more than transport lookups
Only take nvmf_transports_rwsem when doing a lookup of registered
transports, so that a blocking ->create_ctrl doesn't prevent other
actions on /dev/nvme-fabrics.
Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
[hch: increased lock hold time a bit to be safe, added a comment
and updated the changelog]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
| -rw-r--r-- | drivers/nvme/host/fabrics.c | 3 | ||||
| -rw-r--r-- | drivers/nvme/host/fabrics.h | 3 |
2 files changed, 5 insertions, 1 deletions
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index 5f5f7067c41d..fa32c1216409 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c | |||
| @@ -952,6 +952,7 @@ nvmf_create_ctrl(struct device *dev, const char *buf, size_t count) | |||
| 952 | ret = -EBUSY; | 952 | ret = -EBUSY; |
| 953 | goto out_unlock; | 953 | goto out_unlock; |
| 954 | } | 954 | } |
| 955 | up_read(&nvmf_transports_rwsem); | ||
| 955 | 956 | ||
| 956 | ret = nvmf_check_required_opts(opts, ops->required_opts); | 957 | ret = nvmf_check_required_opts(opts, ops->required_opts); |
| 957 | if (ret) | 958 | if (ret) |
| @@ -968,11 +969,11 @@ nvmf_create_ctrl(struct device *dev, const char *buf, size_t count) | |||
| 968 | } | 969 | } |
| 969 | 970 | ||
| 970 | module_put(ops->module); | 971 | module_put(ops->module); |
| 971 | up_read(&nvmf_transports_rwsem); | ||
| 972 | return ctrl; | 972 | return ctrl; |
| 973 | 973 | ||
| 974 | out_module_put: | 974 | out_module_put: |
| 975 | module_put(ops->module); | 975 | module_put(ops->module); |
| 976 | goto out_free_opts; | ||
| 976 | out_unlock: | 977 | out_unlock: |
| 977 | up_read(&nvmf_transports_rwsem); | 978 | up_read(&nvmf_transports_rwsem); |
| 978 | out_free_opts: | 979 | out_free_opts: |
diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h index 0cf0460a5c92..7491a0bbf711 100644 --- a/drivers/nvme/host/fabrics.h +++ b/drivers/nvme/host/fabrics.h | |||
| @@ -124,6 +124,9 @@ struct nvmf_ctrl_options { | |||
| 124 | * 1. At minimum, 'required_opts' and 'allowed_opts' should | 124 | * 1. At minimum, 'required_opts' and 'allowed_opts' should |
| 125 | * be set to the same enum parsing options defined earlier. | 125 | * be set to the same enum parsing options defined earlier. |
| 126 | * 2. create_ctrl() must be defined (even if it does nothing) | 126 | * 2. create_ctrl() must be defined (even if it does nothing) |
| 127 | * 3. struct nvmf_transport_ops must be statically allocated in the | ||
| 128 | * modules .bss section so that a pure module_get on @module | ||
| 129 | * prevents the memory from beeing freed. | ||
| 127 | */ | 130 | */ |
| 128 | struct nvmf_transport_ops { | 131 | struct nvmf_transport_ops { |
| 129 | struct list_head entry; | 132 | struct list_head entry; |
