diff mbox

RDMA/cxgb4: Fail RDMA initialization for unsupported cards.

Message ID 20110801215910.9774.75120.stgit@build.ogc.int (mailing list archive)
State New, archived
Headers show

Commit Message

Steve Wise Aug. 1, 2011, 9:59 p.m. UTC
The iw_cxgb4 module crashes at init time if the T4 card does not
support RDMA.  So clean up the init logic to correctly deal with
non-RDMA cards.

- If any RDMA resources are not available, then fail the initializtion
logging an info message.

- Clean up properly on initialization failures.

Signed-off-by: Steve Wise <swise@opengridcomputing.com>
---

 drivers/infiniband/hw/cxgb4/device.c |   41 +++++++++++++++++++++++++++-------
 1 files changed, 33 insertions(+), 8 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Steve Wise Aug. 22, 2011, 8:05 p.m. UTC | #1
Hey Roland,

Is this patch acceptable for heading upstream?

Thanks,

Steve.

On 08/01/2011 04:59 PM, Steve Wise wrote:
> The iw_cxgb4 module crashes at init time if the T4 card does not
> support RDMA.  So clean up the init logic to correctly deal with
> non-RDMA cards.
>
> - If any RDMA resources are not available, then fail the initializtion
> logging an info message.
>
> - Clean up properly on initialization failures.
>
> Signed-off-by: Steve Wise<swise@opengridcomputing.com>
> ---
>
>   drivers/infiniband/hw/cxgb4/device.c |   41 +++++++++++++++++++++++++++-------
>   1 files changed, 33 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
> index 40a13cc..6d0df6e 100644
> --- a/drivers/infiniband/hw/cxgb4/device.c
> +++ b/drivers/infiniband/hw/cxgb4/device.c
> @@ -376,10 +376,8 @@ struct uld_ctx {
>   	struct c4iw_dev *dev;
>   };
>
> -static void c4iw_remove(struct uld_ctx *ctx)
> +static void c4iw_dealloc(struct uld_ctx *ctx)
>   {
> -	PDBG("%s c4iw_dev %p\n", __func__,  ctx->dev);
> -	c4iw_unregister_device(ctx->dev);
>   	c4iw_rdev_close(&ctx->dev->rdev);
>   	idr_destroy(&ctx->dev->cqidr);
>   	idr_destroy(&ctx->dev->qpidr);
> @@ -389,11 +387,30 @@ static void c4iw_remove(struct uld_ctx *ctx)
>   	ctx->dev = NULL;
>   }
>
> +static void c4iw_remove(struct uld_ctx *ctx)
> +{
> +	PDBG("%s c4iw_dev %p\n", __func__,  ctx->dev);
> +	c4iw_unregister_device(ctx->dev);
> +	c4iw_dealloc(ctx);
> +}
> +
> +static int rdma_supported(const struct cxgb4_lld_info *infop)
> +{
> +	return infop->vr->stag.size>  0&&  infop->vr->pbl.size>  0&&
> +	       infop->vr->rq.size>  0&&  infop->vr->qp.size>  0&&
> +	       infop->vr->cq.size>  0&&  infop->vr->ocq.size>  0;
> +}
> +
>   static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
>   {
>   	struct c4iw_dev *devp;
>   	int ret;
>
> +	if (!rdma_supported(infop)) {
> +		printk(KERN_INFO MOD "%s: RDMA not supported on this device.\n",
> +		       pci_name(infop->pdev));
> +		return ERR_PTR(-ENOSYS);
> +	}
>   	devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp));
>   	if (!devp) {
>   		printk(KERN_ERR MOD "Cannot allocate ib device\n");
> @@ -414,7 +431,6 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
>
>   	ret = c4iw_rdev_open(&devp->rdev);
>   	if (ret) {
> -		mutex_unlock(&dev_mutex);
>   		printk(KERN_ERR MOD "Unable to open CXIO rdev err %d\n", ret);
>   		ib_dealloc_device(&devp->ibdev);
>   		return ERR_PTR(ret);
> @@ -519,15 +535,24 @@ static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state)
>   	case CXGB4_STATE_UP:
>   		printk(KERN_INFO MOD "%s: Up\n", pci_name(ctx->lldi.pdev));
>   		if (!ctx->dev) {
> -			int ret = 0;
> +			int ret;
>
>   			ctx->dev = c4iw_alloc(&ctx->lldi);
> -			if (!IS_ERR(ctx->dev))
> -				ret = c4iw_register_device(ctx->dev);
> -			if (IS_ERR(ctx->dev) || ret)
> +			if (IS_ERR(ctx->dev)) {
> +				printk(KERN_ERR MOD
> +				       "%s: initialization failed: %ld\n",
> +				       pci_name(ctx->lldi.pdev),
> +				       PTR_ERR(ctx->dev));
> +				ctx->dev = NULL;
> +				break;
> +			}
> +			ret = c4iw_register_device(ctx->dev);
> +			if (ret) {
>   				printk(KERN_ERR MOD
>   				       "%s: RDMA registration failed: %d\n",
>   				       pci_name(ctx->lldi.pdev), ret);
> +				c4iw_dealloc(ctx);
> +			}
>   		}
>   		break;
>   	case CXGB4_STATE_DOWN:
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 40a13cc..6d0df6e 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -376,10 +376,8 @@  struct uld_ctx {
 	struct c4iw_dev *dev;
 };
 
-static void c4iw_remove(struct uld_ctx *ctx)
+static void c4iw_dealloc(struct uld_ctx *ctx)
 {
-	PDBG("%s c4iw_dev %p\n", __func__,  ctx->dev);
-	c4iw_unregister_device(ctx->dev);
 	c4iw_rdev_close(&ctx->dev->rdev);
 	idr_destroy(&ctx->dev->cqidr);
 	idr_destroy(&ctx->dev->qpidr);
@@ -389,11 +387,30 @@  static void c4iw_remove(struct uld_ctx *ctx)
 	ctx->dev = NULL;
 }
 
+static void c4iw_remove(struct uld_ctx *ctx)
+{
+	PDBG("%s c4iw_dev %p\n", __func__,  ctx->dev);
+	c4iw_unregister_device(ctx->dev);
+	c4iw_dealloc(ctx);
+}
+
+static int rdma_supported(const struct cxgb4_lld_info *infop)
+{
+	return infop->vr->stag.size > 0 && infop->vr->pbl.size > 0 &&
+	       infop->vr->rq.size > 0 && infop->vr->qp.size > 0 &&
+	       infop->vr->cq.size > 0 && infop->vr->ocq.size > 0;
+}
+
 static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
 {
 	struct c4iw_dev *devp;
 	int ret;
 
+	if (!rdma_supported(infop)) {
+		printk(KERN_INFO MOD "%s: RDMA not supported on this device.\n",
+		       pci_name(infop->pdev));
+		return ERR_PTR(-ENOSYS);
+	}
 	devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp));
 	if (!devp) {
 		printk(KERN_ERR MOD "Cannot allocate ib device\n");
@@ -414,7 +431,6 @@  static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
 
 	ret = c4iw_rdev_open(&devp->rdev);
 	if (ret) {
-		mutex_unlock(&dev_mutex);
 		printk(KERN_ERR MOD "Unable to open CXIO rdev err %d\n", ret);
 		ib_dealloc_device(&devp->ibdev);
 		return ERR_PTR(ret);
@@ -519,15 +535,24 @@  static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state)
 	case CXGB4_STATE_UP:
 		printk(KERN_INFO MOD "%s: Up\n", pci_name(ctx->lldi.pdev));
 		if (!ctx->dev) {
-			int ret = 0;
+			int ret;
 
 			ctx->dev = c4iw_alloc(&ctx->lldi);
-			if (!IS_ERR(ctx->dev))
-				ret = c4iw_register_device(ctx->dev);
-			if (IS_ERR(ctx->dev) || ret)
+			if (IS_ERR(ctx->dev)) {
+				printk(KERN_ERR MOD
+				       "%s: initialization failed: %ld\n",
+				       pci_name(ctx->lldi.pdev),
+				       PTR_ERR(ctx->dev));
+				ctx->dev = NULL;
+				break;
+			}
+			ret = c4iw_register_device(ctx->dev);
+			if (ret) {
 				printk(KERN_ERR MOD
 				       "%s: RDMA registration failed: %d\n",
 				       pci_name(ctx->lldi.pdev), ret);
+				c4iw_dealloc(ctx);
+			}
 		}
 		break;
 	case CXGB4_STATE_DOWN: