aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonas Jensen <jonas.jensen@gmail.com>2014-08-25 10:22:40 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-25 20:25:39 -0400
commit2b7890e757bc42f963c835521c2657bd16d7b7d6 (patch)
tree329a381b4a657a7964f5b58b0d909ad50537c304
parent777fbc31447f111a1492c90fae2bc616f836d407 (diff)
net: moxa: continue loop on skb allocation failure
If netdev_alloc_skb_ip_align() fails, subsequent code will try to dereference an invalid pointer. Continue to next descriptor on error. While we're at it, 1. eliminate the chance of an endless loop, replace the main loop with while(rx < budget) 2. use napi_complete() and remove the explicit napi_gro_flush() Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/moxa/moxart_ether.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 983d01949795..2f12c88c66ab 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -206,7 +206,7 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
206 int rx_head = priv->rx_head; 206 int rx_head = priv->rx_head;
207 int rx = 0; 207 int rx = 0;
208 208
209 while (1) { 209 while (rx < budget) {
210 desc = priv->rx_desc_base + (RX_REG_DESC_SIZE * rx_head); 210 desc = priv->rx_desc_base + (RX_REG_DESC_SIZE * rx_head);
211 desc0 = readl(desc + RX_REG_OFFSET_DESC0); 211 desc0 = readl(desc + RX_REG_OFFSET_DESC0);
212 212
@@ -218,7 +218,7 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
218 net_dbg_ratelimited("packet error\n"); 218 net_dbg_ratelimited("packet error\n");
219 priv->stats.rx_dropped++; 219 priv->stats.rx_dropped++;
220 priv->stats.rx_errors++; 220 priv->stats.rx_errors++;
221 continue; 221 goto rx_next;
222 } 222 }
223 223
224 len = desc0 & RX_DESC0_FRAME_LEN_MASK; 224 len = desc0 & RX_DESC0_FRAME_LEN_MASK;
@@ -235,6 +235,7 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
235 net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n"); 235 net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
236 priv->stats.rx_dropped++; 236 priv->stats.rx_dropped++;
237 priv->stats.rx_errors++; 237 priv->stats.rx_errors++;
238 goto rx_next;
238 } 239 }
239 240
240 memcpy(skb->data, priv->rx_buf[rx_head], len); 241 memcpy(skb->data, priv->rx_buf[rx_head], len);
@@ -249,18 +250,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
249 if (desc0 & RX_DESC0_MULTICAST) 250 if (desc0 & RX_DESC0_MULTICAST)
250 priv->stats.multicast++; 251 priv->stats.multicast++;
251 252
253rx_next:
252 writel(RX_DESC0_DMA_OWN, desc + RX_REG_OFFSET_DESC0); 254 writel(RX_DESC0_DMA_OWN, desc + RX_REG_OFFSET_DESC0);
253 255
254 rx_head = RX_NEXT(rx_head); 256 rx_head = RX_NEXT(rx_head);
255 priv->rx_head = rx_head; 257 priv->rx_head = rx_head;
256
257 if (rx >= budget)
258 break;
259 } 258 }
260 259
261 if (rx < budget) { 260 if (rx < budget) {
262 napi_gro_flush(napi, false); 261 napi_complete(napi);
263 __napi_complete(napi);
264 } 262 }
265 263
266 priv->reg_imr |= RPKT_FINISH_M; 264 priv->reg_imr |= RPKT_FINISH_M;