Hello.
This patch set fixes DMA API usage issues in gianfar ethernet driver
reported by the kernel w/ DMA API debug enabled.
There were even reports that the kernel sometimes oopsed in the past
because of kernel paging request handling failures, though it was likely
observed on some ancient versions. And while I personally doesn't have
any strong evidence of this, there's no reason to let these possible
failures live any longer.
Arseny Solokha (2):
gianfar: handle map error in gfar_new_rxbdp()
gianfar: handle map error in gfar_start_xmit()
drivers/net/ethernet/freescale/gianfar.c | 49 ++++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 8 deletions(-)
--
Regards,
Arseny Solokha.
@@ -2805,6 +2816,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)while(!((bdp->status&RXBD_EMPTY)||(--rx_work_limit<0))){structsk_buff*newskb;+intrxbdpret;rmb();
@@ -2854,7 +2866,15 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)rx_queue->rx_skbuff[rx_queue->skb_currx]=newskb;/* Setup the new bdp */-gfar_new_rxbdp(rx_queue,bdp,newskb);+rxbdpret=gfar_new_rxbdp(rx_queue,bdp,newskb);+if(unlikely(rxbdpret)){+/* We drop the frame if we failed to map a new DMA+*buffer+*/+count_errors(bdp->status,dev);+dev_kfree_skb(newskb);+continue;+}/* Update to the next pointer */bdp=next_bd(bdp,base,rx_queue->rx_ring_size);
@@ -2296,6 +2296,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)0,frag_len,DMA_TO_DEVICE);+if(unlikely(dma_mapping_error(priv->dev,bufaddr))){+/* As DMA mapping failed, pretend the TX path+*isbusytoretrylater+*/+returnNETDEV_TX_BUSY;+}/* set the TxBD length and buffer pointer */txbdp->bufPtr=bufaddr;
@@ -2345,8 +2351,15 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)fcb->ptp=1;}-txbdp_start->bufPtr=dma_map_single(priv->dev,skb->data,-skb_headlen(skb),DMA_TO_DEVICE);+bufaddr=dma_map_single(priv->dev,skb->data,skb_headlen(skb),+DMA_TO_DEVICE);+if(unlikely(dma_mapping_error(priv->dev,bufaddr))){+/* As DMA mapping failed, pretend the TX path is busy to retry+*later+*/+returnNETDEV_TX_BUSY;+}+txbdp_start->bufPtr=bufaddr;/* If time stamping is requested one additional TxBD must be set up. The*firstTxBDpointstotheFCBandmusthaveadatalengthof
@@ -2296,6 +2296,12 @@ static int gfar_start_xmit(struct sk_buff *skb,
struct net_device *dev)
0,
frag_len,
DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(priv->dev, bufaddr))) {
+ /* As DMA mapping failed, pretend the TX path
+ * is busy to retry later
+ */
+ return NETDEV_TX_BUSY;
+ }
/* set the TxBD length and buffer pointer */
txbdp->bufPtr = bufaddr;
@@ -2345,8 +2351,15 @@ static int gfar_start_xmit(struct sk_buff *skb,
struct net_device *dev)
fcb->ptp = 1;
}
- txbdp_start->bufPtr = dma_map_single(priv->dev, skb->data,
- skb_headlen(skb), DMA_TO_DEVICE);
+ bufaddr = dma_map_single(priv->dev, skb->data, skb_headlen(skb),
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(priv->dev, bufaddr))) {
+ /* As DMA mapping failed, pretend the TX path is busy to retry
+ * later
+ */
+ return NETDEV_TX_BUSY;
+ }
+ txbdp_start->bufPtr = bufaddr;
/* If time stamping is requested one additional TxBD must be set up. The
* first TxBD points to the FCB and must have a data length of
--
You have to return TX_BUSY in the case of the full hw queue.
Have you tested your changes with fault injection?
2.2.0
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello.
This patch set fixes DMA API usage issues in gianfar ethernet driver
reported by the kernel w/ DMA API debug enabled.
There were even reports that the kernel sometimes oopsed in the past
because of kernel paging request handling failures, though it was likely
observed on some ancient versions. And while I personally doesn't have
any strong evidence of this, there's no reason to let these possible
failures live any longer.
Arseny Solokha (2):
gianfar: handle map error in gfar_new_rxbdp()
gianfar: handle map error in gfar_start_xmit()
drivers/net/ethernet/freescale/gianfar.c | 49 ++++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 8 deletions(-)
Thanks but please note that Kevin Hao already provided a fix for this issue:
http://permalink.gmane.org/gmane.linux.network/336274
His patch was only deferred for testing (and bandwidth) reasons.
I will try to resend his patch to the netdev list today if possible,
I apologize for the delay.
Also note that there are some issues with your patches.
As said before, I will resubmit Kevin Hao's patch.
Thanks,
Claudiu
@@ -2296,6 +2296,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)0,frag_len,DMA_TO_DEVICE);+if(unlikely(dma_mapping_error(priv->dev,bufaddr))){+/* As DMA mapping failed, pretend the TX path+*isbusytoretrylater+*/+returnNETDEV_TX_BUSY;
This is not right.
Proper bailout code missing: un-mapping of skb fragments and
de-allocation of resources.
This is not a TX_BUSY error condition, it's a system failure.
(will resubmit this one:
http://permalink.gmane.org/gmane.linux.network/336274)
quoted hunk
+ }
/* set the TxBD length and buffer pointer */
txbdp->bufPtr = bufaddr;
@@ -2345,8 +2351,15 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) fcb->ptp = 1; }- txbdp_start->bufPtr = dma_map_single(priv->dev, skb->data,- skb_headlen(skb), DMA_TO_DEVICE);+ bufaddr = dma_map_single(priv->dev, skb->data, skb_headlen(skb),+ DMA_TO_DEVICE);+ if (unlikely(dma_mapping_error(priv->dev, bufaddr))) {+ /* As DMA mapping failed, pretend the TX path is busy to retry+ * later+ */+ return NETDEV_TX_BUSY;
same here
+ }
+ txbdp_start->bufPtr = bufaddr;
/* If time stamping is requested one additional TxBD must be set up. The
* first TxBD points to the FCB and must have a data length of
From: Kevin Hao <redacted>
We need to use dma_mapping_error() to check the dma address returned
by dma_map_single/page(). Otherwise we would get warning like this:
WARNING: at lib/dma-debug.c:1140
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.18.0-rc2-next-20141029 #196
task: c0834300 ti: effe6000 task.ti: c0874000
NIP: c02b2c98 LR: c02b2c98 CTR: c030abc4
REGS: effe7d70 TRAP: 0700 Not tainted (3.18.0-rc2-next-20141029)
MSR: 00021000 <CE,ME> CR: 22044022 XER: 20000000
GPR00: c02b2c98 effe7e20 c0834300 00000098 00021000 00000000 c030b898 00000003
GPR08: 00000001 00000000 00000001 749eec9d 22044022 1001abe0 00000020 ef278678
GPR16: ef278670 ef278668 ef278660 070a8040 c087f99c c08cdc60 00029000 c0840d44
GPR24: c08be6e8 c0840000 effe7e78 ef041340 00000600 ef114e10 00000000 c08be6e0
NIP [c02b2c98] check_unmap+0x51c/0x9e4
LR [c02b2c98] check_unmap+0x51c/0x9e4
Call Trace:
[effe7e20] [c02b2c98] check_unmap+0x51c/0x9e4 (unreliable)
[effe7e70] [c02b31d8] debug_dma_unmap_page+0x78/0x8c
[effe7ed0] [c03d1640] gfar_clean_rx_ring+0x208/0x488
[effe7f40] [c03d1a9c] gfar_poll_rx_sq+0x3c/0xa8
[effe7f60] [c04f8714] net_rx_action+0xc0/0x178
[effe7f90] [c00435a0] __do_softirq+0x100/0x1fc
[effe7fe0] [c0043958] irq_exit+0xa4/0xc8
[effe7ff0] [c000d14c] call_do_irq+0x24/0x3c
[c0875e90] [c00048a0] do_IRQ+0x8c/0xf8
[c0875eb0] [c000ed10] ret_from_except+0x0/0x18
For TX, we need to unmap the pages which has already been mapped and
free the skb before return. For RX, just let the rxbdp as unempty.
We can retry to initialize it to empty in next round.
Signed-off-by: Kevin Hao <redacted>
Signed-off-by: Claudiu Manoil <redacted>
---
drivers/net/ethernet/freescale/gianfar.c | 58 ++++++++++++++++++++++++++------
1 file changed, 47 insertions(+), 11 deletions(-)
@@ -2290,6 +2294,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)0,frag_len,DMA_TO_DEVICE);+if(unlikely(dma_mapping_error(priv->dev,bufaddr)))+gotodma_map_err;/* set the TxBD length and buffer pointer */txbdp->bufPtr=bufaddr;
@@ -2339,8 +2345,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)fcb->ptp=1;}-txbdp_start->bufPtr=dma_map_single(priv->dev,skb->data,-skb_headlen(skb),DMA_TO_DEVICE);+bufaddr=dma_map_single(priv->dev,skb->data,skb_headlen(skb),+DMA_TO_DEVICE);+if(unlikely(dma_mapping_error(priv->dev,bufaddr)))+gotodma_map_err;++txbdp_start->bufPtr=bufaddr;/* If time stamping is requested one additional TxBD must be set up. The*firstTxBDpointstotheFCBandmusthaveadatalengthof
@@ -2406,6 +2416,25 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)spin_unlock_irqrestore(&tx_queue->txlock,flags);returnNETDEV_TX_OK;++dma_map_err:+txbdp=next_txbd(txbdp_start,base,tx_queue->tx_ring_size);+if(do_tstamp)+txbdp=next_txbd(txbdp,base,tx_queue->tx_ring_size);+for(i=0;i<nr_frags;i++){+lstatus=txbdp->lstatus;+if(!(lstatus&BD_LFLAG(TXBD_READY)))+break;++txbdp->lstatus=lstatus&~BD_LFLAG(TXBD_READY);+bufaddr=txbdp->bufPtr;+dma_unmap_page(priv->dev,bufaddr,txbdp->length,+DMA_TO_DEVICE);+txbdp=next_txbd(txbdp,base,tx_queue->tx_ring_size);+}+gfar_wmb();+dev_kfree_skb_any(skb);+returnNETDEV_TX_OK;}/* Stops the kernel queue, and halts the controller */
@@ -2851,10 +2884,13 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)}-rx_queue->rx_skbuff[rx_queue->skb_currx]=newskb;-/* Setup the new bdp */-gfar_new_rxbdp(rx_queue,bdp,newskb);+if(unlikely(gfar_new_rxbdp(rx_queue,bdp,newskb))){+dev_kfree_skb_any(newskb);+newskb=NULL;+}++rx_queue->rx_skbuff[rx_queue->skb_currx]=newskb;/* Update to the next pointer */bdp=next_bd(bdp,base,rx_queue->rx_ring_size);
@@ -2854,7 +2866,15 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) rx_queue->rx_skbuff[rx_queue->skb_currx] = newskb; /* Setup the new bdp */- gfar_new_rxbdp(rx_queue, bdp, newskb);+ rxbdpret = gfar_new_rxbdp(rx_queue, bdp, newskb);+ if (unlikely(rxbdpret)) {+ /* We drop the frame if we failed to map a new DMA+ * buffer+ */+ count_errors(bdp->status, dev);+ dev_kfree_skb(newskb);+ continue;+ } /* Update to the next pointer */ bdp = next_bd(bdp, base, rx_queue->rx_ring_size);
You need to add much more sophisticated handling of this error.
Otherwise the chip will just stop when it gets to the first
descriptor for which a DMA mapping failed in this way.
What you need to do is allocate and attempt to map the new SKB
_first_, and only if that succeeds will you pass the original
SKB up into the networking stack.
If the DMA mapping fails, you leave the OLD skb in the RX ring
and advance the ring pointer, as if the received packet never
happened. You are essentially dropping it.
@@ -2296,6 +2296,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) 0, frag_len, DMA_TO_DEVICE);+ if (unlikely(dma_mapping_error(priv->dev, bufaddr))) {+ /* As DMA mapping failed, pretend the TX path+ * is busy to retry later+ */+ return NETDEV_TX_BUSY;+ }
You are not "busy", you are dropping the packet due to insufficient system
resources.
Therefore the appropriate thing to do is to free the SKB, increment
the drop statistical counter, and return NETDEV_TX_OK.
@@ -2296,6 +2296,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) 0, frag_len, DMA_TO_DEVICE);+ if (unlikely(dma_mapping_error(priv->dev, bufaddr))) {+ /* As DMA mapping failed, pretend the TX path+ * is busy to retry later+ */+ return NETDEV_TX_BUSY;+ }
You are not "busy", you are dropping the packet due to insufficient system
resources.
Therefore the appropriate thing to do is to free the SKB, increment
the drop statistical counter, and return NETDEV_TX_OK.
Plausibly the error action could depend on the number of messages
in the transmit ring.
If the ring is empty you definitely want to drop the packet.
If mapping a ring full of packets takes more dma map space than
the system has available you may want to be "busy" - otherwise you
get systemic packet loss when transmitting large burst of data.
This could be a problem if all the available dma mapping resources
have been allocated to receive buffers.
Do any common systems actually have limited dma space (apart from
limited bounce buffers)?
If people are only testing on systems with unlimited dma space (eg x86)
then these paths will never be exercised unless an artificial limit
is applied.
David
From: Kevin Hao <redacted>
We need to use dma_mapping_error() to check the dma address returned
by dma_map_single/page(). Otherwise we would get warning like this:
...
For TX, we need to unmap the pages which has already been mapped and
free the skb before return. For RX, just let the rxbdp as unempty.
We can retry to initialize it to empty in next round.
Signed-off-by: Kevin Hao <redacted>
Signed-off-by: Claudiu Manoil <redacted>
The RX behavior needs to be adjusted.
You should never leave holes in the RX ring, ever.
Instead, try allocating the new RX skb first, and only if
you are successful should you pass up the original SKB. If
it fails, then reuse the original SKB in the RX ring.
From: Kevin Hao <redacted>
We need to use dma_mapping_error() to check the dma address returned
by dma_map_single/page(). Otherwise we would get warning like this:
...
quoted
For TX, we need to unmap the pages which has already been mapped and
free the skb before return. For RX, just let the rxbdp as unempty.
We can retry to initialize it to empty in next round.
Signed-off-by: Kevin Hao <redacted>
Signed-off-by: Claudiu Manoil <redacted>
The RX behavior needs to be adjusted.
You should never leave holes in the RX ring, ever.
Instead, try allocating the new RX skb first, and only if
you are successful should you pass up the original SKB. If
it fails, then reuse the original SKB in the RX ring.
From: Kevin Hao <hidden> Date: 2014-12-11 06:10:01
We need to use dma_mapping_error() to check the dma address returned
by dma_map_single/page(). Otherwise we would get warning like this:
WARNING: at lib/dma-debug.c:1140
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.18.0-rc2-next-20141029 #196
task: c0834300 ti: effe6000 task.ti: c0874000
NIP: c02b2c98 LR: c02b2c98 CTR: c030abc4
REGS: effe7d70 TRAP: 0700 Not tainted (3.18.0-rc2-next-20141029)
MSR: 00021000 <CE,ME> CR: 22044022 XER: 20000000
GPR00: c02b2c98 effe7e20 c0834300 00000098 00021000 00000000 c030b898 00000003
GPR08: 00000001 00000000 00000001 749eec9d 22044022 1001abe0 00000020 ef278678
GPR16: ef278670 ef278668 ef278660 070a8040 c087f99c c08cdc60 00029000 c0840d44
GPR24: c08be6e8 c0840000 effe7e78 ef041340 00000600 ef114e10 00000000 c08be6e0
NIP [c02b2c98] check_unmap+0x51c/0x9e4
LR [c02b2c98] check_unmap+0x51c/0x9e4
Call Trace:
[effe7e20] [c02b2c98] check_unmap+0x51c/0x9e4 (unreliable)
[effe7e70] [c02b31d8] debug_dma_unmap_page+0x78/0x8c
[effe7ed0] [c03d1640] gfar_clean_rx_ring+0x208/0x488
[effe7f40] [c03d1a9c] gfar_poll_rx_sq+0x3c/0xa8
[effe7f60] [c04f8714] net_rx_action+0xc0/0x178
[effe7f90] [c00435a0] __do_softirq+0x100/0x1fc
[effe7fe0] [c0043958] irq_exit+0xa4/0xc8
[effe7ff0] [c000d14c] call_do_irq+0x24/0x3c
[c0875e90] [c00048a0] do_IRQ+0x8c/0xf8
[c0875eb0] [c000ed10] ret_from_except+0x0/0x18
For TX, we need to unmap the pages which has already been mapped and
free the skb before return.
For RX, move the dma mapping and error check to gfar_new_skb(). We
would reuse the original skb in the rx ring when either allocating
skb failure or dma mapping error.
Signed-off-by: Kevin Hao <redacted>
Signed-off-by: Claudiu Manoil <redacted>
---
v2: Just update the RX path to reuse the original skb when dma mapping error
occurs as suggested by David.
drivers/net/ethernet/freescale/gianfar.c | 84 +++++++++++++++++++++-----------
1 file changed, 56 insertions(+), 28 deletions(-)
@@ -2290,6 +2287,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)0,frag_len,DMA_TO_DEVICE);+if(unlikely(dma_mapping_error(priv->dev,bufaddr)))+gotodma_map_err;/* set the TxBD length and buffer pointer */txbdp->bufPtr=bufaddr;
@@ -2339,8 +2338,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)fcb->ptp=1;}-txbdp_start->bufPtr=dma_map_single(priv->dev,skb->data,-skb_headlen(skb),DMA_TO_DEVICE);+bufaddr=dma_map_single(priv->dev,skb->data,skb_headlen(skb),+DMA_TO_DEVICE);+if(unlikely(dma_mapping_error(priv->dev,bufaddr)))+gotodma_map_err;++txbdp_start->bufPtr=bufaddr;/* If time stamping is requested one additional TxBD must be set up. The*firstTxBDpointstotheFCBandmusthaveadatalengthof
@@ -2406,6 +2409,25 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)spin_unlock_irqrestore(&tx_queue->txlock,flags);returnNETDEV_TX_OK;++dma_map_err:+txbdp=next_txbd(txbdp_start,base,tx_queue->tx_ring_size);+if(do_tstamp)+txbdp=next_txbd(txbdp,base,tx_queue->tx_ring_size);+for(i=0;i<nr_frags;i++){+lstatus=txbdp->lstatus;+if(!(lstatus&BD_LFLAG(TXBD_READY)))+break;++txbdp->lstatus=lstatus&~BD_LFLAG(TXBD_READY);+bufaddr=txbdp->bufPtr;+dma_unmap_page(priv->dev,bufaddr,txbdp->length,+DMA_TO_DEVICE);+txbdp=next_txbd(txbdp,base,tx_queue->tx_ring_size);+}+gfar_wmb();+dev_kfree_skb_any(skb);+returnNETDEV_TX_OK;}/* Stops the kernel queue, and halts the controller */
@@ -2805,11 +2831,12 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)while(!((bdp->status&RXBD_EMPTY)||(--rx_work_limit<0))){structsk_buff*newskb;+dma_addr_tbufaddr;rmb();/* Add another skb for the future */-newskb=gfar_new_skb(dev);+newskb=gfar_new_skb(dev,&bufaddr);skb=rx_queue->rx_skbuff[rx_queue->skb_currx];
@@ -2825,9 +2852,10 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)bdp->status&RXBD_ERR)){count_errors(bdp->status,dev);-if(unlikely(!newskb))+if(unlikely(!newskb)){newskb=skb;-elseif(skb)+bufaddr=bdp->bufPtr;+}elseif(skb)dev_kfree_skb(skb);}else{/* Increment the number of packets */
@@ -2854,7 +2882,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)rx_queue->rx_skbuff[rx_queue->skb_currx]=newskb;/* Setup the new bdp */-gfar_new_rxbdp(rx_queue,bdp,newskb);+gfar_init_rxbdp(rx_queue,bdp,bufaddr);/* Update to the next pointer */bdp=next_bd(bdp,base,rx_queue->rx_ring_size);
We need to use dma_mapping_error() to check the dma address returned
by dma_map_single/page(). Otherwise we would get warning like this:
WARNING: at lib/dma-debug.c:1140
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.18.0-rc2-next-20141029 #196
task: c0834300 ti: effe6000 task.ti: c0874000
NIP: c02b2c98 LR: c02b2c98 CTR: c030abc4
REGS: effe7d70 TRAP: 0700 Not tainted (3.18.0-rc2-next-20141029)
MSR: 00021000 <CE,ME> CR: 22044022 XER: 20000000
GPR00: c02b2c98 effe7e20 c0834300 00000098 00021000 00000000 c030b898 00000003
GPR08: 00000001 00000000 00000001 749eec9d 22044022 1001abe0 00000020 ef278678
GPR16: ef278670 ef278668 ef278660 070a8040 c087f99c c08cdc60 00029000 c0840d44
GPR24: c08be6e8 c0840000 effe7e78 ef041340 00000600 ef114e10 00000000 c08be6e0
NIP [c02b2c98] check_unmap+0x51c/0x9e4
LR [c02b2c98] check_unmap+0x51c/0x9e4
Call Trace:
[effe7e20] [c02b2c98] check_unmap+0x51c/0x9e4 (unreliable)
[effe7e70] [c02b31d8] debug_dma_unmap_page+0x78/0x8c
[effe7ed0] [c03d1640] gfar_clean_rx_ring+0x208/0x488
[effe7f40] [c03d1a9c] gfar_poll_rx_sq+0x3c/0xa8
[effe7f60] [c04f8714] net_rx_action+0xc0/0x178
[effe7f90] [c00435a0] __do_softirq+0x100/0x1fc
[effe7fe0] [c0043958] irq_exit+0xa4/0xc8
[effe7ff0] [c000d14c] call_do_irq+0x24/0x3c
[c0875e90] [c00048a0] do_IRQ+0x8c/0xf8
[c0875eb0] [c000ed10] ret_from_except+0x0/0x18
For TX, we need to unmap the pages which has already been mapped and
free the skb before return.
For RX, move the dma mapping and error check to gfar_new_skb(). We
would reuse the original skb in the rx ring when either allocating
skb failure or dma mapping error.
Signed-off-by: Kevin Hao <redacted>
---
v2: Just update the RX path to reuse the original skb when dma mapping error
occurs as suggested by David.
Very nice refactoring of gfar_new_skb(), removing gfar_new_rxbdp() in
the process. (Did not have the time to test it yet.)
Thanks.
Reviewed-by: Claudiu Manoil <redacted>
From: David Miller <davem@davemloft.net> Date: 2014-12-11 19:27:54
From: Kevin Hao <redacted>
Date: Thu, 11 Dec 2014 14:08:41 +0800
We need to use dma_mapping_error() to check the dma address returned
by dma_map_single/page(). Otherwise we would get warning like this:
...
For TX, we need to unmap the pages which has already been mapped and
free the skb before return.
For RX, move the dma mapping and error check to gfar_new_skb(). We
would reuse the original skb in the rx ring when either allocating
skb failure or dma mapping error.
Signed-off-by: Kevin Hao <redacted>
Signed-off-by: Claudiu Manoil <redacted>
---
v2: Just update the RX path to reuse the original skb when dma mapping error
occurs as suggested by David.