Skip to content

Commit

Permalink
net/cpsw: don't continue if we miss to allocate rx skbs
Browse files Browse the repository at this point in the history
if during "ifconfig up" we run out of mem we continue regardless how
many skbs we got. In worst case we have zero RX skbs and can't ever
receive further packets since the RX skbs are never reallocated. If
cpdma_chan_submit() fails we even leak the skb.
This patch changes the behavior here:
If we fail to allocate an skb during bring up we don't continue and
report that error. Same goes for errors from cpdma_chan_submit().
While here I changed to __netdev_alloc_skb_ip_align() so GFP_KERNEL can
be used.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sebastian Siewior authored and David S. Miller committed Apr 25, 2013
1 parent 817f6d1 commit aacebbf
Showing 1 changed file with 22 additions and 13 deletions.
35 changes: 22 additions & 13 deletions drivers/net/ethernet/ti/cpsw.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,15 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
}
}

static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv)
{
if (!slave->phy)
return;
phy_stop(slave->phy);
phy_disconnect(slave->phy);
slave->phy = NULL;
}

static int cpsw_ndo_open(struct net_device *ndev)
{
struct cpsw_priv *priv = netdev_priv(ndev);
Expand Down Expand Up @@ -912,14 +921,16 @@ static int cpsw_ndo_open(struct net_device *ndev)
struct sk_buff *skb;

ret = -ENOMEM;
skb = netdev_alloc_skb_ip_align(priv->ndev,
priv->rx_packet_max);
skb = __netdev_alloc_skb_ip_align(priv->ndev,
priv->rx_packet_max, GFP_KERNEL);
if (!skb)
break;
goto err_cleanup;
ret = cpdma_chan_submit(priv->rxch, skb, skb->data,
skb_tailroom(skb), 0, GFP_KERNEL);
if (WARN_ON(ret < 0))
break;
if (ret < 0) {
kfree_skb(skb);
goto err_cleanup;
}
}
/* continue even if we didn't manage to submit all
* receive descs
Expand All @@ -944,15 +955,13 @@ static int cpsw_ndo_open(struct net_device *ndev)
if (priv->data.dual_emac)
priv->slaves[priv->emac_port].open_stat = true;
return 0;
}

static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv)
{
if (!slave->phy)
return;
phy_stop(slave->phy);
phy_disconnect(slave->phy);
slave->phy = NULL;
err_cleanup:
cpdma_ctlr_stop(priv->dma);
for_each_slave(priv, cpsw_slave_stop, priv);
pm_runtime_put_sync(&priv->pdev->dev);
netif_carrier_off(priv->ndev);
return ret;
}

static int cpsw_ndo_stop(struct net_device *ndev)
Expand Down

0 comments on commit aacebbf

Please sign in to comment.