aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@dev.mellanox.co.il>2007-04-30 20:30:28 -0400
committerRoland Dreier <rolandd@cisco.com>2007-04-30 20:30:28 -0400
commit347fcfbed261fdd11f46fa03d524e1bddddab3a6 (patch)
tree370b7f5f3d0bdb8d344dadbffce4ec4eba0af4a7 /drivers/infiniband/ulp
parent6b66b2da1e821181a001c00b04a807724ad803cd (diff)
IPoIB/cm: Fix error handling in ipoib_cm_dev_open()
If skb allocation fails when we start the device, we call ipoib_cm_dev_stop() even though ipoib_cm_dev_open() did not run to completion, so we pass an invalid pointer to ib_destroy_cm_id and get an oops. Fix by clearing cm.id on error, and testing it in cm_dev_stop(). This fixes <https://bugs.openfabrics.org/show_bug.cgi?id=561> Signed-off-by: Michael S. Tsirkin <mst@dev.mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 0c4e59b906cd..76717410660e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -592,7 +592,9 @@ int ipoib_cm_dev_open(struct net_device *dev)
592 priv->cm.id = ib_create_cm_id(priv->ca, ipoib_cm_rx_handler, dev); 592 priv->cm.id = ib_create_cm_id(priv->ca, ipoib_cm_rx_handler, dev);
593 if (IS_ERR(priv->cm.id)) { 593 if (IS_ERR(priv->cm.id)) {
594 printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name); 594 printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
595 return IS_ERR(priv->cm.id); 595 ret = PTR_ERR(priv->cm.id);
596 priv->cm.id = NULL;
597 return ret;
596 } 598 }
597 599
598 ret = ib_cm_listen(priv->cm.id, cpu_to_be64(IPOIB_CM_IETF_ID | priv->qp->qp_num), 600 ret = ib_cm_listen(priv->cm.id, cpu_to_be64(IPOIB_CM_IETF_ID | priv->qp->qp_num),
@@ -601,6 +603,7 @@ int ipoib_cm_dev_open(struct net_device *dev)
601 printk(KERN_WARNING "%s: failed to listen on ID 0x%llx\n", priv->ca->name, 603 printk(KERN_WARNING "%s: failed to listen on ID 0x%llx\n", priv->ca->name,
602 IPOIB_CM_IETF_ID | priv->qp->qp_num); 604 IPOIB_CM_IETF_ID | priv->qp->qp_num);
603 ib_destroy_cm_id(priv->cm.id); 605 ib_destroy_cm_id(priv->cm.id);
606 priv->cm.id = NULL;
604 return ret; 607 return ret;
605 } 608 }
606 return 0; 609 return 0;
@@ -611,10 +614,11 @@ void ipoib_cm_dev_stop(struct net_device *dev)
611 struct ipoib_dev_priv *priv = netdev_priv(dev); 614 struct ipoib_dev_priv *priv = netdev_priv(dev);
612 struct ipoib_cm_rx *p; 615 struct ipoib_cm_rx *p;
613 616
614 if (!IPOIB_CM_SUPPORTED(dev->dev_addr)) 617 if (!IPOIB_CM_SUPPORTED(dev->dev_addr) || !priv->cm.id)
615 return; 618 return;
616 619
617 ib_destroy_cm_id(priv->cm.id); 620 ib_destroy_cm_id(priv->cm.id);
621 priv->cm.id = NULL;
618 spin_lock_irq(&priv->lock); 622 spin_lock_irq(&priv->lock);
619 while (!list_empty(&priv->cm.passive_ids)) { 623 while (!list_empty(&priv->cm.passive_ids)) {
620 p = list_entry(priv->cm.passive_ids.next, typeof(*p), list); 624 p = list_entry(priv->cm.passive_ids.next, typeof(*p), list);