Skip to content

Commit

Permalink
Merge branch 'nvmf-4.8-rc' of git://git.infradead.org/nvme-fabrics in…
Browse files Browse the repository at this point in the history
…to for-linus

Sagi writes:

Mostly stability fixes for nvmet, rdma:
- fix uninitialized rdma_cm private data from Roland.
- rdma device removal handling (host and target).
- fix controller disconnect during active mounts.
- fix namespaces lost after fabric reconnects.
- remove redundant calls to namespace removal (rdma, loop).
- actually send controller shutdown when disconnecting.
- reconnect fixes (ns rescan and aen requeue)
- nvmet controller serial number inconsistency fix.
  • Loading branch information
axboe committed Aug 8, 2016
2 parents 29b4817 + e326637 commit d3f422c
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 72 deletions.
83 changes: 45 additions & 38 deletions drivers/nvme/host/rdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,18 @@
* more details.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/jiffies.h>
#include <linux/atomic.h>
#include <linux/blk-mq.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/scatterlist.h>
#include <linux/nvme.h>
#include <linux/t10-pi.h>
#include <asm/unaligned.h>

#include <rdma/ib_verbs.h>
Expand Down Expand Up @@ -169,7 +166,6 @@ MODULE_PARM_DESC(register_always,
static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id,
struct rdma_cm_event *event);
static void nvme_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc);
static int __nvme_rdma_del_ctrl(struct nvme_rdma_ctrl *ctrl);

/* XXX: really should move to a generic header sooner or later.. */
static inline void put_unaligned_le24(u32 val, u8 *p)
Expand Down Expand Up @@ -687,11 +683,6 @@ static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl)
list_del(&ctrl->list);
mutex_unlock(&nvme_rdma_ctrl_mutex);

if (ctrl->ctrl.tagset) {
blk_cleanup_queue(ctrl->ctrl.connect_q);
blk_mq_free_tag_set(&ctrl->tag_set);
nvme_rdma_dev_put(ctrl->device);
}
kfree(ctrl->queues);
nvmf_free_options(nctrl->opts);
free_ctrl:
Expand Down Expand Up @@ -748,8 +739,11 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
WARN_ON_ONCE(!changed);

if (ctrl->queue_count > 1)
if (ctrl->queue_count > 1) {
nvme_start_queues(&ctrl->ctrl);
nvme_queue_scan(&ctrl->ctrl);
nvme_queue_async_events(&ctrl->ctrl);
}

dev_info(ctrl->ctrl.device, "Successfully reconnected\n");

Expand Down Expand Up @@ -1269,7 +1263,7 @@ static int nvme_rdma_route_resolved(struct nvme_rdma_queue *queue)
{
struct nvme_rdma_ctrl *ctrl = queue->ctrl;
struct rdma_conn_param param = { };
struct nvme_rdma_cm_req priv;
struct nvme_rdma_cm_req priv = { };
int ret;

param.qp_num = queue->qp->qp_num;
Expand Down Expand Up @@ -1318,37 +1312,39 @@ static int nvme_rdma_route_resolved(struct nvme_rdma_queue *queue)
* that caught the event. Since we hold the callout until the controller
* deletion is completed, we'll deadlock if the controller deletion will
* call rdma_destroy_id on this queue's cm_id. Thus, we claim ownership
* of destroying this queue before-hand, destroy the queue resources
* after the controller deletion completed with the exception of destroying
* the cm_id implicitely by returning a non-zero rc to the callout.
* of destroying this queue before-hand, destroy the queue resources,
* then queue the controller deletion which won't destroy this queue and
* we destroy the cm_id implicitely by returning a non-zero rc to the callout.
*/
static int nvme_rdma_device_unplug(struct nvme_rdma_queue *queue)
{
struct nvme_rdma_ctrl *ctrl = queue->ctrl;
int ret, ctrl_deleted = 0;
int ret;

/* First disable the queue so ctrl delete won't free it */
if (!test_and_clear_bit(NVME_RDMA_Q_CONNECTED, &queue->flags))
goto out;
/* Own the controller deletion */
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING))
return 0;

/* delete the controller */
ret = __nvme_rdma_del_ctrl(ctrl);
if (!ret) {
dev_warn(ctrl->ctrl.device,
"Got rdma device removal event, deleting ctrl\n");
flush_work(&ctrl->delete_work);
dev_warn(ctrl->ctrl.device,
"Got rdma device removal event, deleting ctrl\n");

/* Return non-zero so the cm_id will destroy implicitly */
ctrl_deleted = 1;
/* Get rid of reconnect work if its running */
cancel_delayed_work_sync(&ctrl->reconnect_work);

/* Disable the queue so ctrl delete won't free it */
if (test_and_clear_bit(NVME_RDMA_Q_CONNECTED, &queue->flags)) {
/* Free this queue ourselves */
rdma_disconnect(queue->cm_id);
ib_drain_qp(queue->qp);
nvme_rdma_stop_queue(queue);
nvme_rdma_destroy_queue_ib(queue);

/* Return non-zero so the cm_id will destroy implicitly */
ret = 1;
}

out:
return ctrl_deleted;
/* Queue controller deletion */
queue_work(nvme_rdma_wq, &ctrl->delete_work);
flush_work(&ctrl->delete_work);
return ret;
}

static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id,
Expand Down Expand Up @@ -1648,7 +1644,7 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl)
nvme_rdma_free_io_queues(ctrl);
}

if (ctrl->ctrl.state == NVME_CTRL_LIVE)
if (test_bit(NVME_RDMA_Q_CONNECTED, &ctrl->queues[0].flags))
nvme_shutdown_ctrl(&ctrl->ctrl);

blk_mq_stop_hw_queues(ctrl->ctrl.admin_q);
Expand All @@ -1657,15 +1653,27 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl)
nvme_rdma_destroy_admin_queue(ctrl);
}

static void __nvme_rdma_remove_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown)
{
nvme_uninit_ctrl(&ctrl->ctrl);
if (shutdown)
nvme_rdma_shutdown_ctrl(ctrl);

if (ctrl->ctrl.tagset) {
blk_cleanup_queue(ctrl->ctrl.connect_q);
blk_mq_free_tag_set(&ctrl->tag_set);
nvme_rdma_dev_put(ctrl->device);
}

nvme_put_ctrl(&ctrl->ctrl);
}

static void nvme_rdma_del_ctrl_work(struct work_struct *work)
{
struct nvme_rdma_ctrl *ctrl = container_of(work,
struct nvme_rdma_ctrl, delete_work);

nvme_remove_namespaces(&ctrl->ctrl);
nvme_rdma_shutdown_ctrl(ctrl);
nvme_uninit_ctrl(&ctrl->ctrl);
nvme_put_ctrl(&ctrl->ctrl);
__nvme_rdma_remove_ctrl(ctrl, true);
}

static int __nvme_rdma_del_ctrl(struct nvme_rdma_ctrl *ctrl)
Expand Down Expand Up @@ -1698,9 +1706,7 @@ static void nvme_rdma_remove_ctrl_work(struct work_struct *work)
struct nvme_rdma_ctrl *ctrl = container_of(work,
struct nvme_rdma_ctrl, delete_work);

nvme_remove_namespaces(&ctrl->ctrl);
nvme_uninit_ctrl(&ctrl->ctrl);
nvme_put_ctrl(&ctrl->ctrl);
__nvme_rdma_remove_ctrl(ctrl, false);
}

static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
Expand Down Expand Up @@ -1739,6 +1745,7 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
if (ctrl->queue_count > 1) {
nvme_start_queues(&ctrl->ctrl);
nvme_queue_scan(&ctrl->ctrl);
nvme_queue_async_events(&ctrl->ctrl);
}

return;
Expand Down
6 changes: 1 addition & 5 deletions drivers/nvme/target/admin-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/random.h>
#include <generated/utsrelease.h>
#include "nvmet.h"

Expand Down Expand Up @@ -83,7 +82,6 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
{
struct nvmet_ctrl *ctrl = req->sq->ctrl;
struct nvme_id_ctrl *id;
u64 serial;
u16 status = 0;

id = kzalloc(sizeof(*id), GFP_KERNEL);
Expand All @@ -96,10 +94,8 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
id->vid = 0;
id->ssvid = 0;

/* generate a random serial number as our controllers are ephemeral: */
get_random_bytes(&serial, sizeof(serial));
memset(id->sn, ' ', sizeof(id->sn));
snprintf(id->sn, sizeof(id->sn), "%llx", serial);
snprintf(id->sn, sizeof(id->sn), "%llx", ctrl->serial);

memset(id->mn, ' ', sizeof(id->mn));
strncpy((char *)id->mn, "Linux", sizeof(id->mn));
Expand Down
4 changes: 4 additions & 0 deletions drivers/nvme/target/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/random.h>
#include "nvmet.h"

static struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX];
Expand Down Expand Up @@ -728,6 +729,9 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE);
memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE);

/* generate a random serial number as our controllers are ephemeral: */
get_random_bytes(&ctrl->serial, sizeof(ctrl->serial));

kref_init(&ctrl->ref);
ctrl->subsys = subsys;

Expand Down
4 changes: 1 addition & 3 deletions drivers/nvme/target/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,8 @@ static void nvme_loop_del_ctrl_work(struct work_struct *work)
struct nvme_loop_ctrl *ctrl = container_of(work,
struct nvme_loop_ctrl, delete_work);

nvme_remove_namespaces(&ctrl->ctrl);
nvme_loop_shutdown_ctrl(ctrl);
nvme_uninit_ctrl(&ctrl->ctrl);
nvme_loop_shutdown_ctrl(ctrl);
nvme_put_ctrl(&ctrl->ctrl);
}

Expand Down Expand Up @@ -501,7 +500,6 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work)
nvme_loop_destroy_admin_queue(ctrl);
out_disable:
dev_warn(ctrl->ctrl.device, "Removing after reset failure\n");
nvme_remove_namespaces(&ctrl->ctrl);
nvme_uninit_ctrl(&ctrl->ctrl);
nvme_put_ctrl(&ctrl->ctrl);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/nvme/target/nvmet.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ struct nvmet_ctrl {

struct mutex lock;
u64 cap;
u64 serial;
u32 cc;
u32 csts;

Expand Down
Loading

0 comments on commit d3f422c

Please sign in to comment.