Commit b629be5c authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller

net: bcmgenet: check harder for out of memory conditions

There is a potential case where we might be failing to refill a
control block, leaving it with both a NULL skb pointer *and* a NULL
dma_unmap_addr.

The way we process incoming packets, by first calling
dma_unmap_single(), and then only checking for a potential NULL skb can
lead to situations where do pass a NULL dma_unmap_addr() to
dma_unmap_single(), resulting in an oops.

Fix this my moving the NULL skb check earlier, since no backing skb
also means no corresponding DMA mapping for this packet.
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fe24ba08
...@@ -1274,12 +1274,29 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, ...@@ -1274,12 +1274,29 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
while ((rxpktprocessed < rxpkttoprocess) && while ((rxpktprocessed < rxpkttoprocess) &&
(rxpktprocessed < budget)) { (rxpktprocessed < budget)) {
cb = &priv->rx_cbs[priv->rx_read_ptr];
skb = cb->skb;
rxpktprocessed++;
priv->rx_read_ptr++;
priv->rx_read_ptr &= (priv->num_rx_bds - 1);
/* We do not have a backing SKB, so we do not have a
* corresponding DMA mapping for this incoming packet since
* bcmgenet_rx_refill always either has both skb and mapping or
* none.
*/
if (unlikely(!skb)) {
dev->stats.rx_dropped++;
dev->stats.rx_errors++;
goto refill;
}
/* Unmap the packet contents such that we can use the /* Unmap the packet contents such that we can use the
* RSV from the 64 bytes descriptor when enabled and save * RSV from the 64 bytes descriptor when enabled and save
* a 32-bits register read * a 32-bits register read
*/ */
cb = &priv->rx_cbs[priv->rx_read_ptr];
skb = cb->skb;
dma_unmap_single(&dev->dev, dma_unmap_addr(cb, dma_addr), dma_unmap_single(&dev->dev, dma_unmap_addr(cb, dma_addr),
priv->rx_buf_len, DMA_FROM_DEVICE); priv->rx_buf_len, DMA_FROM_DEVICE);
...@@ -1307,18 +1324,6 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, ...@@ -1307,18 +1324,6 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
__func__, p_index, priv->rx_c_index, __func__, p_index, priv->rx_c_index,
priv->rx_read_ptr, dma_length_status); priv->rx_read_ptr, dma_length_status);
rxpktprocessed++;
priv->rx_read_ptr++;
priv->rx_read_ptr &= (priv->num_rx_bds - 1);
/* out of memory, just drop packets at the hardware level */
if (unlikely(!skb)) {
dev->stats.rx_dropped++;
dev->stats.rx_errors++;
goto refill;
}
if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) { if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
netif_err(priv, rx_status, dev, netif_err(priv, rx_status, dev,
"dropping fragmented packet!\n"); "dropping fragmented packet!\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment