aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRoger Oksanen <roger.oksanen@cs.helsinki.fi>2009-11-29 20:17:29 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-29 20:17:29 -0500
commit98468efddb101f8a29af974101c17ba513b07be1 (patch)
treee4d66cca447ab2065224a6afb66edbf78b079d48 /drivers
parent5fdd4baef6195a1f2960e901c8877e2105f832ca (diff)
e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failure
pci_alloc_consistent uses GFP_ATOMIC allocation that may fail on some systems with limited memory (Bug #14265). pci_pool_alloc allows waiting with GFP_KERNEL. Tested-by: Karol Lewandowski <karol.k.lewandowski@gmail.com> Signed-off-by: Roger Oksanen <roger.oksanen@cs.helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/e100.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 3c29a20b751e..d269a68ce354 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -157,6 +157,7 @@
157#include <linux/init.h> 157#include <linux/init.h>
158#include <linux/pci.h> 158#include <linux/pci.h>
159#include <linux/dma-mapping.h> 159#include <linux/dma-mapping.h>
160#include <linux/dmapool.h>
160#include <linux/netdevice.h> 161#include <linux/netdevice.h>
161#include <linux/etherdevice.h> 162#include <linux/etherdevice.h>
162#include <linux/mii.h> 163#include <linux/mii.h>
@@ -602,6 +603,7 @@ struct nic {
602 struct mem *mem; 603 struct mem *mem;
603 dma_addr_t dma_addr; 604 dma_addr_t dma_addr;
604 605
606 struct pci_pool *cbs_pool;
605 dma_addr_t cbs_dma_addr; 607 dma_addr_t cbs_dma_addr;
606 u8 adaptive_ifs; 608 u8 adaptive_ifs;
607 u8 tx_threshold; 609 u8 tx_threshold;
@@ -1793,9 +1795,7 @@ static void e100_clean_cbs(struct nic *nic)
1793 nic->cb_to_clean = nic->cb_to_clean->next; 1795 nic->cb_to_clean = nic->cb_to_clean->next;
1794 nic->cbs_avail++; 1796 nic->cbs_avail++;
1795 } 1797 }
1796 pci_free_consistent(nic->pdev, 1798 pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr);
1797 sizeof(struct cb) * nic->params.cbs.count,
1798 nic->cbs, nic->cbs_dma_addr);
1799 nic->cbs = NULL; 1799 nic->cbs = NULL;
1800 nic->cbs_avail = 0; 1800 nic->cbs_avail = 0;
1801 } 1801 }
@@ -1813,8 +1813,8 @@ static int e100_alloc_cbs(struct nic *nic)
1813 nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; 1813 nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;
1814 nic->cbs_avail = 0; 1814 nic->cbs_avail = 0;
1815 1815
1816 nic->cbs = pci_alloc_consistent(nic->pdev, 1816 nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL,
1817 sizeof(struct cb) * count, &nic->cbs_dma_addr); 1817 &nic->cbs_dma_addr);
1818 if (!nic->cbs) 1818 if (!nic->cbs)
1819 return -ENOMEM; 1819 return -ENOMEM;
1820 1820
@@ -2841,7 +2841,11 @@ static int __devinit e100_probe(struct pci_dev *pdev,
2841 DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); 2841 DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
2842 goto err_out_free; 2842 goto err_out_free;
2843 } 2843 }
2844 2844 nic->cbs_pool = pci_pool_create(netdev->name,
2845 nic->pdev,
2846 nic->params.cbs.count * sizeof(struct cb),
2847 sizeof(u32),
2848 0);
2845 DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", 2849 DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
2846 (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), 2850 (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0),
2847 pdev->irq, netdev->dev_addr); 2851 pdev->irq, netdev->dev_addr);
@@ -2871,6 +2875,7 @@ static void __devexit e100_remove(struct pci_dev *pdev)
2871 unregister_netdev(netdev); 2875 unregister_netdev(netdev);
2872 e100_free(nic); 2876 e100_free(nic);
2873 pci_iounmap(pdev, nic->csr); 2877 pci_iounmap(pdev, nic->csr);
2878 pci_pool_destroy(nic->cbs_pool);
2874 free_netdev(netdev); 2879 free_netdev(netdev);
2875 pci_release_regions(pdev); 2880 pci_release_regions(pdev);
2876 pci_disable_device(pdev); 2881 pci_disable_device(pdev);