Patchwork [2/2] e1000: Fix DMA mapping error handling on RX

login
register
mail settings
Submitter Anton Blanchard
Date Jan. 21, 2010, 11:44 a.m.
Message ID <20100121114420.GA11892@kryten>
Download mbox | patch
Permalink /patch/43428/
State Awaiting Upstream
Delegated to: David Miller
Headers show

Comments

Anton Blanchard - Jan. 21, 2010, 11:44 a.m.
Check for error return from pci_map_single/pci_map_page and clean up.

With this and the previous patch the driver was able to handle a significant
percentage of errors (I set the fault injection rate to 10% and could still
download large files at a reasonable speed).

Signed-off-by: Anton Blanchard <anton@samba.org>
---

I wasn't able to stress the jumbo frame path, so that part could do with some
more eyes.

--
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
Jeff Kirsher - Jan. 23, 2010, 3:42 a.m.
On Thu, Jan 21, 2010 at 03:44, Anton Blanchard <anton@samba.org> wrote:
>
> Check for error return from pci_map_single/pci_map_page and clean up.
>
> With this and the previous patch the driver was able to handle a significant
> percentage of errors (I set the fault injection rate to 10% and could still
> download large files at a reasonable speed).
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
>
> I wasn't able to stress the jumbo frame path, so that part could do with some
> more eyes.
>
> Index: linux.trees.git/drivers/net/e1000/e1000_main.c
> ===================================================================
> --- linux.trees.git.orig/drivers/net/e1000/e1000_main.c 2010-01-21 11:13:10.000000000 +1100
> +++ linux.trees.git/drivers/net/e1000/e1000_main.c      2010-01-21 11:15:54.000000000 +1100
> @@ -4014,11 +4014,21 @@ check_page:
>                        }
>                }
>
> -               if (!buffer_info->dma)
> +               if (!buffer_info->dma) {
>                        buffer_info->dma = pci_map_page(pdev,
>                                                        buffer_info->page, 0,
>                                                        buffer_info->length,
>                                                        PCI_DMA_FROMDEVICE);
> +                       if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
> +                               put_page(buffer_info->page);
> +                               dev_kfree_skb(skb);
> +                               buffer_info->page = NULL;
> +                               buffer_info->skb = NULL;
> +                               buffer_info->dma = 0;
> +                               adapter->alloc_rx_buff_failed++;
> +                               break; /* while !buffer_info->skb */
> +                       }
> +               }
>
>                rx_desc = E1000_RX_DESC(*rx_ring, i);
>                rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
> @@ -4109,6 +4119,13 @@ map_skb:
>                                                  skb->data,
>                                                  buffer_info->length,
>                                                  PCI_DMA_FROMDEVICE);
> +               if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
> +                       dev_kfree_skb(skb);
> +                       buffer_info->skb = NULL;
> +                       buffer_info->dma = 0;
> +                       adapter->alloc_rx_buff_failed++;
> +                       break; /* while !buffer_info->skb */
> +               }
>
>                /*
>                 * XXX if it was allocated cleanly it will never map to a

I have added this patch to my queue of patches for review and testing.  Thanks.

Patch

Index: linux.trees.git/drivers/net/e1000/e1000_main.c
===================================================================
--- linux.trees.git.orig/drivers/net/e1000/e1000_main.c	2010-01-21 11:13:10.000000000 +1100
+++ linux.trees.git/drivers/net/e1000/e1000_main.c	2010-01-21 11:15:54.000000000 +1100
@@ -4014,11 +4014,21 @@  check_page:
 			}
 		}
 
-		if (!buffer_info->dma)
+		if (!buffer_info->dma) {
 			buffer_info->dma = pci_map_page(pdev,
 			                                buffer_info->page, 0,
 			                                buffer_info->length,
 			                                PCI_DMA_FROMDEVICE);
+			if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
+				put_page(buffer_info->page);
+				dev_kfree_skb(skb);
+				buffer_info->page = NULL;
+				buffer_info->skb = NULL;
+				buffer_info->dma = 0;
+				adapter->alloc_rx_buff_failed++;
+				break; /* while !buffer_info->skb */
+			}
+		}
 
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -4109,6 +4119,13 @@  map_skb:
 						  skb->data,
 						  buffer_info->length,
 						  PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
+			dev_kfree_skb(skb);
+			buffer_info->skb = NULL;
+			buffer_info->dma = 0;
+			adapter->alloc_rx_buff_failed++;
+			break; /* while !buffer_info->skb */
+		}
 
 		/*
 		 * XXX if it was allocated cleanly it will never map to a