IPoIB: Allocate priv->tx_ring with vmalloc()
Commit 7143740d
("IPoIB: Add send gather support") made struct
ipoib_tx_buf significantly larger, since the mapping member changed
from a single u64 to an array with MAX_SKB_FRAGS + 1 entries. This
means that allocating tx_rings with kzalloc() may fail because there
is not enough contiguous memory for the new, much bigger size. Fix
this regression by allocating the rings with vmalloc() instead.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
4200406b8f
commit
10313cbb92
|
@ -38,6 +38,7 @@
|
|||
#include <net/icmp.h>
|
||||
#include <linux/icmpv6.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "ipoib.h"
|
||||
|
||||
|
@ -1031,13 +1032,13 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
|
|||
struct ipoib_dev_priv *priv = netdev_priv(p->dev);
|
||||
int ret;
|
||||
|
||||
p->tx_ring = kzalloc(ipoib_sendq_size * sizeof *p->tx_ring,
|
||||
GFP_KERNEL);
|
||||
p->tx_ring = vmalloc(ipoib_sendq_size * sizeof *p->tx_ring);
|
||||
if (!p->tx_ring) {
|
||||
ipoib_warn(priv, "failed to allocate tx ring\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_tx;
|
||||
}
|
||||
memset(p->tx_ring, 0, ipoib_sendq_size * sizeof *p->tx_ring);
|
||||
|
||||
p->qp = ipoib_cm_create_tx_qp(p->dev, p);
|
||||
if (IS_ERR(p->qp)) {
|
||||
|
@ -1078,6 +1079,7 @@ err_id:
|
|||
ib_destroy_qp(p->qp);
|
||||
err_qp:
|
||||
p->qp = NULL;
|
||||
vfree(p->tx_ring);
|
||||
err_tx:
|
||||
return ret;
|
||||
}
|
||||
|
@ -1128,7 +1130,7 @@ timeout:
|
|||
if (p->qp)
|
||||
ib_destroy_qp(p->qp);
|
||||
|
||||
kfree(p->tx_ring);
|
||||
vfree(p->tx_ring);
|
||||
kfree(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <linux/if_arp.h> /* For ARPHRD_xxx */
|
||||
|
||||
|
@ -887,13 +888,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
|
|||
goto out;
|
||||
}
|
||||
|
||||
priv->tx_ring = kzalloc(ipoib_sendq_size * sizeof *priv->tx_ring,
|
||||
GFP_KERNEL);
|
||||
priv->tx_ring = vmalloc(ipoib_sendq_size * sizeof *priv->tx_ring);
|
||||
if (!priv->tx_ring) {
|
||||
printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n",
|
||||
ca->name, ipoib_sendq_size);
|
||||
goto out_rx_ring_cleanup;
|
||||
}
|
||||
memset(priv->tx_ring, 0, ipoib_sendq_size * sizeof *priv->tx_ring);
|
||||
|
||||
/* priv->tx_head, tx_tail & tx_outstanding are already 0 */
|
||||
|
||||
|
@ -903,7 +904,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
|
|||
return 0;
|
||||
|
||||
out_tx_ring_cleanup:
|
||||
kfree(priv->tx_ring);
|
||||
vfree(priv->tx_ring);
|
||||
|
||||
out_rx_ring_cleanup:
|
||||
kfree(priv->rx_ring);
|
||||
|
@ -928,7 +929,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
|
|||
ipoib_ib_dev_cleanup(dev);
|
||||
|
||||
kfree(priv->rx_ring);
|
||||
kfree(priv->tx_ring);
|
||||
vfree(priv->tx_ring);
|
||||
|
||||
priv->rx_ring = NULL;
|
||||
priv->tx_ring = NULL;
|
||||
|
|
Loading…
Reference in New Issue