aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Wise <swise@opengridcomputing.com>2016-09-02 12:01:54 -0400
committerSagi Grimberg <sagi@grimberg.me>2016-09-12 15:29:41 -0400
commite87a911fed07e368c6f97e75152e6297a7dfba48 (patch)
tree993be810cc0bd7019f3e1c5faf2d2a02b33202a4
parente89ca58f9c901c8c4cfb09f96d879b186bb01492 (diff)
nvme-rdma: use ib_client API to detect device removal
Change nvme-rdma to use the IB Client API to detect device removal. This has the wonderful benefit of being able to blow away all the ib/rdma_cm resources for the device being removed. No craziness about not destroying the cm_id handling the event. No deadlocks due to broken iw_cm/rdma_cm/iwarp dependencies. And no need to have a bound cm_id around during controller recovery/reconnect to catch device removal events. We don't use the device_add aspect of the ib_client service since we only want to create resources for an IB device if we have a target utilizing that device. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
-rw-r--r--drivers/nvme/host/rdma.c108
1 files changed, 40 insertions, 68 deletions
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index eeb08b658640..d6bdf55a969e 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -1320,64 +1320,6 @@ out_destroy_queue_ib:
1320 return ret; 1320 return ret;
1321} 1321}
1322 1322
1323/**
1324 * nvme_rdma_device_unplug() - Handle RDMA device unplug
1325 * @queue: Queue that owns the cm_id that caught the event
1326 *
1327 * DEVICE_REMOVAL event notifies us that the RDMA device is about
1328 * to unplug so we should take care of destroying our RDMA resources.
1329 * This event will be generated for each allocated cm_id.
1330 *
1331 * In our case, the RDMA resources are managed per controller and not
1332 * only per queue. So the way we handle this is we trigger an implicit
1333 * controller deletion upon the first DEVICE_REMOVAL event we see, and
1334 * hold the event inflight until the controller deletion is completed.
1335 *
1336 * One exception that we need to handle is the destruction of the cm_id
1337 * that caught the event. Since we hold the callout until the controller
1338 * deletion is completed, we'll deadlock if the controller deletion will
1339 * call rdma_destroy_id on this queue's cm_id. Thus, we claim ownership
1340 * of destroying this queue before-hand, destroy the queue resources,
1341 * then queue the controller deletion which won't destroy this queue and
1342 * we destroy the cm_id implicitely by returning a non-zero rc to the callout.
1343 */
1344static int nvme_rdma_device_unplug(struct nvme_rdma_queue *queue)
1345{
1346 struct nvme_rdma_ctrl *ctrl = queue->ctrl;
1347 int ret = 0;
1348
1349 /* Own the controller deletion */
1350 if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING))
1351 return 0;
1352
1353 dev_warn(ctrl->ctrl.device,
1354 "Got rdma device removal event, deleting ctrl\n");
1355
1356 /* Get rid of reconnect work if its running */
1357 cancel_delayed_work_sync(&ctrl->reconnect_work);
1358
1359 /* Disable the queue so ctrl delete won't free it */
1360 if (!test_and_set_bit(NVME_RDMA_Q_DELETING, &queue->flags)) {
1361 /* Free this queue ourselves */
1362 nvme_rdma_stop_queue(queue);
1363 nvme_rdma_destroy_queue_ib(queue);
1364
1365 /* Return non-zero so the cm_id will destroy implicitly */
1366 ret = 1;
1367 }
1368
1369 /*
1370 * Queue controller deletion. Keep a reference until all
1371 * work is flushed since delete_work will free the ctrl mem
1372 */
1373 kref_get(&ctrl->ctrl.kref);
1374 queue_work(nvme_rdma_wq, &ctrl->delete_work);
1375 flush_work(&ctrl->delete_work);
1376 nvme_put_ctrl(&ctrl->ctrl);
1377
1378 return ret;
1379}
1380
1381static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id, 1323static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id,
1382 struct rdma_cm_event *ev) 1324 struct rdma_cm_event *ev)
1383{ 1325{
@@ -1419,8 +1361,8 @@ static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id,
1419 nvme_rdma_error_recovery(queue->ctrl); 1361 nvme_rdma_error_recovery(queue->ctrl);
1420 break; 1362 break;
1421 case RDMA_CM_EVENT_DEVICE_REMOVAL: 1363 case RDMA_CM_EVENT_DEVICE_REMOVAL:
1422 /* return 1 means impliciy CM ID destroy */ 1364 /* device removal is handled via the ib_client API */
1423 return nvme_rdma_device_unplug(queue); 1365 break;
1424 default: 1366 default:
1425 dev_err(queue->ctrl->ctrl.device, 1367 dev_err(queue->ctrl->ctrl.device,
1426 "Unexpected RDMA CM event (%d)\n", ev->event); 1368 "Unexpected RDMA CM event (%d)\n", ev->event);
@@ -2030,27 +1972,57 @@ static struct nvmf_transport_ops nvme_rdma_transport = {
2030 .create_ctrl = nvme_rdma_create_ctrl, 1972 .create_ctrl = nvme_rdma_create_ctrl,
2031}; 1973};
2032 1974
1975static void nvme_rdma_add_one(struct ib_device *ib_device)
1976{
1977}
1978
1979static void nvme_rdma_remove_one(struct ib_device *ib_device, void *client_data)
1980{
1981 struct nvme_rdma_ctrl *ctrl;
1982
1983 /* Delete all controllers using this device */
1984 mutex_lock(&nvme_rdma_ctrl_mutex);
1985 list_for_each_entry(ctrl, &nvme_rdma_ctrl_list, list) {
1986 if (ctrl->device->dev != ib_device)
1987 continue;
1988 dev_info(ctrl->ctrl.device,
1989 "Removing ctrl: NQN \"%s\", addr %pISp\n",
1990 ctrl->ctrl.opts->subsysnqn, &ctrl->addr);
1991 __nvme_rdma_del_ctrl(ctrl);
1992 }
1993 mutex_unlock(&nvme_rdma_ctrl_mutex);
1994
1995 flush_workqueue(nvme_rdma_wq);
1996}
1997
1998static struct ib_client nvme_rdma_ib_client = {
1999 .name = "nvme_rdma",
2000 .add = nvme_rdma_add_one,
2001 .remove = nvme_rdma_remove_one
2002};
2003
2033static int __init nvme_rdma_init_module(void) 2004static int __init nvme_rdma_init_module(void)
2034{ 2005{
2006 int ret;
2007
2035 nvme_rdma_wq = create_workqueue("nvme_rdma_wq"); 2008 nvme_rdma_wq = create_workqueue("nvme_rdma_wq");
2036 if (!nvme_rdma_wq) 2009 if (!nvme_rdma_wq)
2037 return -ENOMEM; 2010 return -ENOMEM;
2038 2011
2012 ret = ib_register_client(&nvme_rdma_ib_client);
2013 if (ret) {
2014 destroy_workqueue(nvme_rdma_wq);
2015 return ret;
2016 }
2017
2039 nvmf_register_transport(&nvme_rdma_transport); 2018 nvmf_register_transport(&nvme_rdma_transport);
2040 return 0; 2019 return 0;
2041} 2020}
2042 2021
2043static void __exit nvme_rdma_cleanup_module(void) 2022static void __exit nvme_rdma_cleanup_module(void)
2044{ 2023{
2045 struct nvme_rdma_ctrl *ctrl;
2046
2047 nvmf_unregister_transport(&nvme_rdma_transport); 2024 nvmf_unregister_transport(&nvme_rdma_transport);
2048 2025 ib_unregister_client(&nvme_rdma_ib_client);
2049 mutex_lock(&nvme_rdma_ctrl_mutex);
2050 list_for_each_entry(ctrl, &nvme_rdma_ctrl_list, list)
2051 __nvme_rdma_del_ctrl(ctrl);
2052 mutex_unlock(&nvme_rdma_ctrl_mutex);
2053
2054 destroy_workqueue(nvme_rdma_wq); 2026 destroy_workqueue(nvme_rdma_wq);
2055} 2027}
2056 2028