Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c01c538 authored by Steve Wise's avatar Steve Wise Committed by Roland Dreier
Browse files

RDMA/cxgb4: Register RDMA provider based on LLD state_change events



The LLD now supports proper UP state change events, so move the RDMA
provider registration to UP path.

This fixes a crash when loading iw_cxgb4 _after_ the NFS/RDMA
transport is up and running.

Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent fd388ce6
Loading
Loading
Loading
Loading
+36 −10
Original line number Diff line number Diff line
@@ -306,6 +306,7 @@ static void c4iw_remove(struct c4iw_dev *dev)
	PDBG("%s c4iw_dev %p\n", __func__,  dev);
	cancel_delayed_work_sync(&dev->db_drop_task);
	list_del(&dev->entry);
	if (dev->registered)
		c4iw_unregister_device(dev);
	c4iw_rdev_close(&dev->rdev);
	idr_destroy(&dev->cqidr);
@@ -343,12 +344,6 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
	list_add_tail(&devp->entry, &dev_list);
	mutex_unlock(&dev_mutex);

	if (c4iw_register_device(devp)) {
		printk(KERN_ERR MOD "Unable to register device\n");
		mutex_lock(&dev_mutex);
		c4iw_remove(devp);
		mutex_unlock(&dev_mutex);
	}
	if (c4iw_debugfs_root) {
		devp->debugfs_root = debugfs_create_dir(
					pci_name(devp->rdev.lldi.pdev),
@@ -379,9 +374,6 @@ static void *c4iw_uld_add(const struct cxgb4_lld_info *infop)

	for (i = 0; i < dev->rdev.lldi.nrxq; i++)
		PDBG("rxqid[%u] %u\n", i, dev->rdev.lldi.rxq_ids[i]);

	printk(KERN_INFO MOD "Initialized device %s\n",
	       pci_name(dev->rdev.lldi.pdev));
out:
	return dev;
}
@@ -471,7 +463,41 @@ static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp,

static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state)
{
	struct c4iw_dev *dev = handle;

	PDBG("%s new_state %u\n", __func__, new_state);
	switch (new_state) {
	case CXGB4_STATE_UP:
		printk(KERN_INFO MOD "%s: Up\n", pci_name(dev->rdev.lldi.pdev));
		if (!dev->registered) {
			int ret;
			ret = c4iw_register_device(dev);
			if (ret)
				printk(KERN_ERR MOD
				       "%s: RDMA registration failed: %d\n",
				       pci_name(dev->rdev.lldi.pdev), ret);
		}
		break;
	case CXGB4_STATE_DOWN:
		printk(KERN_INFO MOD "%s: Down\n",
		       pci_name(dev->rdev.lldi.pdev));
		if (dev->registered)
			c4iw_unregister_device(dev);
		break;
	case CXGB4_STATE_START_RECOVERY:
		printk(KERN_INFO MOD "%s: Fatal Error\n",
		       pci_name(dev->rdev.lldi.pdev));
		if (dev->registered)
			c4iw_unregister_device(dev);
		break;
	case CXGB4_STATE_DETACH:
		printk(KERN_INFO MOD "%s: Detach\n",
		       pci_name(dev->rdev.lldi.pdev));
		mutex_lock(&dev_mutex);
		c4iw_remove(dev);
		mutex_unlock(&dev_mutex);
		break;
	}
	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@ struct c4iw_dev {
	struct list_head entry;
	struct delayed_work db_drop_task;
	struct dentry *debugfs_root;
	u8 registered;
};

static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
+2 −0
Original line number Diff line number Diff line
@@ -496,6 +496,7 @@ int c4iw_register_device(struct c4iw_dev *dev)
		if (ret)
			goto bail2;
	}
	dev->registered = 1;
	return 0;
bail2:
	ib_unregister_device(&dev->ibdev);
@@ -514,5 +515,6 @@ void c4iw_unregister_device(struct c4iw_dev *dev)
				   c4iw_class_attributes[i]);
	ib_unregister_device(&dev->ibdev);
	kfree(dev->ibdev.iwcm);
	dev->registered = 0;
	return;
}