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>
This commit is contained in:
Родитель
6b66b2da1e
Коммит
347fcfbed2
|
@ -592,7 +592,9 @@ int ipoib_cm_dev_open(struct net_device *dev)
|
||||||
priv->cm.id = ib_create_cm_id(priv->ca, ipoib_cm_rx_handler, dev);
|
priv->cm.id = ib_create_cm_id(priv->ca, ipoib_cm_rx_handler, dev);
|
||||||
if (IS_ERR(priv->cm.id)) {
|
if (IS_ERR(priv->cm.id)) {
|
||||||
printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
|
printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
|
||||||
return IS_ERR(priv->cm.id);
|
ret = PTR_ERR(priv->cm.id);
|
||||||
|
priv->cm.id = NULL;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ib_cm_listen(priv->cm.id, cpu_to_be64(IPOIB_CM_IETF_ID | priv->qp->qp_num),
|
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)
|
||||||
printk(KERN_WARNING "%s: failed to listen on ID 0x%llx\n", priv->ca->name,
|
printk(KERN_WARNING "%s: failed to listen on ID 0x%llx\n", priv->ca->name,
|
||||||
IPOIB_CM_IETF_ID | priv->qp->qp_num);
|
IPOIB_CM_IETF_ID | priv->qp->qp_num);
|
||||||
ib_destroy_cm_id(priv->cm.id);
|
ib_destroy_cm_id(priv->cm.id);
|
||||||
|
priv->cm.id = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -611,10 +614,11 @@ void ipoib_cm_dev_stop(struct net_device *dev)
|
||||||
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
||||||
struct ipoib_cm_rx *p;
|
struct ipoib_cm_rx *p;
|
||||||
|
|
||||||
if (!IPOIB_CM_SUPPORTED(dev->dev_addr))
|
if (!IPOIB_CM_SUPPORTED(dev->dev_addr) || !priv->cm.id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ib_destroy_cm_id(priv->cm.id);
|
ib_destroy_cm_id(priv->cm.id);
|
||||||
|
priv->cm.id = NULL;
|
||||||
spin_lock_irq(&priv->lock);
|
spin_lock_irq(&priv->lock);
|
||||||
while (!list_empty(&priv->cm.passive_ids)) {
|
while (!list_empty(&priv->cm.passive_ids)) {
|
||||||
p = list_entry(priv->cm.passive_ids.next, typeof(*p), list);
|
p = list_entry(priv->cm.passive_ids.next, typeof(*p), list);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче