aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVasu Dev <vasu.dev@intel.com>2011-05-11 01:41:46 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-06-21 04:22:44 -0400
commitdadbe85ac47f180fa1e3ef93b276ab7938b1a98b (patch)
treee2e6924ffa0c510e6ee246184593b82783c8c75a /drivers
parent9612de92e023bff0d1cd5725ee65293accc70c56 (diff)
ixgbe: setup per CPU PCI pool for FCoE DDP
Currently single PCI pool used across all CPUs and that doesn't scales up as number of CPU increases, so this patch adds per CPU PCI pool to setup udl and that aligns well from FCoE stack as that already has per CPU exch locking. Adds per CPU PCI alloc setup and free in ixgbe_fcoe_ddp_pools_alloc and ixgbe_fcoe_ddp_pools_free, use CPU specific pool during DDP setup. Re-arranged ixgbe_fcoe struct to have fewer holes along with adding pools ptr using pahole. Signed-off-by: Vasu Dev <vasu.dev@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c105
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.h13
2 files changed, 82 insertions, 36 deletions
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index 05920726e824..f5f39edb86ab 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -128,7 +128,11 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid)
128 if (ddp->sgl) 128 if (ddp->sgl)
129 pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc, 129 pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc,
130 DMA_FROM_DEVICE); 130 DMA_FROM_DEVICE);
131 pci_pool_free(fcoe->pool, ddp->udl, ddp->udp); 131 if (ddp->pool) {
132 pci_pool_free(ddp->pool, ddp->udl, ddp->udp);
133 ddp->pool = NULL;
134 }
135
132 ixgbe_fcoe_clear_ddp(ddp); 136 ixgbe_fcoe_clear_ddp(ddp);
133 137
134out_ddp_put: 138out_ddp_put:
@@ -163,6 +167,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
163 unsigned int thislen = 0; 167 unsigned int thislen = 0;
164 u32 fcbuff, fcdmarw, fcfltrw, fcrxctl; 168 u32 fcbuff, fcdmarw, fcfltrw, fcrxctl;
165 dma_addr_t addr = 0; 169 dma_addr_t addr = 0;
170 struct pci_pool *pool;
166 171
167 if (!netdev || !sgl) 172 if (!netdev || !sgl)
168 return 0; 173 return 0;
@@ -199,12 +204,14 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
199 return 0; 204 return 0;
200 } 205 }
201 206
202 /* alloc the udl from our ddp pool */ 207 /* alloc the udl from per cpu ddp pool */
203 ddp->udl = pci_pool_alloc(fcoe->pool, GFP_ATOMIC, &ddp->udp); 208 pool = *per_cpu_ptr(fcoe->pool, get_cpu());
209 ddp->udl = pci_pool_alloc(pool, GFP_ATOMIC, &ddp->udp);
204 if (!ddp->udl) { 210 if (!ddp->udl) {
205 e_err(drv, "failed allocated ddp context\n"); 211 e_err(drv, "failed allocated ddp context\n");
206 goto out_noddp_unmap; 212 goto out_noddp_unmap;
207 } 213 }
214 ddp->pool = pool;
208 ddp->sgl = sgl; 215 ddp->sgl = sgl;
209 ddp->sgc = sgc; 216 ddp->sgc = sgc;
210 217
@@ -268,6 +275,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
268 j++; 275 j++;
269 lastsize = 1; 276 lastsize = 1;
270 } 277 }
278 put_cpu();
271 279
272 fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); 280 fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
273 fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); 281 fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);
@@ -311,11 +319,12 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
311 return 1; 319 return 1;
312 320
313out_noddp_free: 321out_noddp_free:
314 pci_pool_free(fcoe->pool, ddp->udl, ddp->udp); 322 pci_pool_free(pool, ddp->udl, ddp->udp);
315 ixgbe_fcoe_clear_ddp(ddp); 323 ixgbe_fcoe_clear_ddp(ddp);
316 324
317out_noddp_unmap: 325out_noddp_unmap:
318 pci_unmap_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE); 326 pci_unmap_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE);
327 put_cpu();
319 return 0; 328 return 0;
320} 329}
321 330
@@ -585,6 +594,46 @@ int ixgbe_fso(struct ixgbe_adapter *adapter,
585 return skb_is_gso(skb); 594 return skb_is_gso(skb);
586} 595}
587 596
597static void ixgbe_fcoe_ddp_pools_free(struct ixgbe_fcoe *fcoe)
598{
599 unsigned int cpu;
600 struct pci_pool **pool;
601
602 for_each_possible_cpu(cpu) {
603 pool = per_cpu_ptr(fcoe->pool, cpu);
604 if (*pool)
605 pci_pool_destroy(*pool);
606 }
607 free_percpu(fcoe->pool);
608 fcoe->pool = NULL;
609}
610
611static void ixgbe_fcoe_ddp_pools_alloc(struct ixgbe_adapter *adapter)
612{
613 struct ixgbe_fcoe *fcoe = &adapter->fcoe;
614 unsigned int cpu;
615 struct pci_pool **pool;
616 char pool_name[32];
617
618 fcoe->pool = alloc_percpu(struct pci_pool *);
619 if (!fcoe->pool)
620 return;
621
622 /* allocate pci pool for each cpu */
623 for_each_possible_cpu(cpu) {
624 snprintf(pool_name, 32, "ixgbe_fcoe_ddp_%d", cpu);
625 pool = per_cpu_ptr(fcoe->pool, cpu);
626 *pool = pci_pool_create(pool_name,
627 adapter->pdev, IXGBE_FCPTR_MAX,
628 IXGBE_FCPTR_ALIGN, PAGE_SIZE);
629 if (!*pool) {
630 e_err(drv, "failed to alloc DDP pool on cpu:%d\n", cpu);
631 ixgbe_fcoe_ddp_pools_free(fcoe);
632 return;
633 }
634 }
635}
636
588/** 637/**
589 * ixgbe_configure_fcoe - configures registers for fcoe at start 638 * ixgbe_configure_fcoe - configures registers for fcoe at start
590 * @adapter: ptr to ixgbe adapter 639 * @adapter: ptr to ixgbe adapter
@@ -604,22 +653,20 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
604 u32 up2tc; 653 u32 up2tc;
605#endif 654#endif
606 655
607 /* create the pool for ddp if not created yet */
608 if (!fcoe->pool) { 656 if (!fcoe->pool) {
609 /* allocate ddp pool */
610 fcoe->pool = pci_pool_create("ixgbe_fcoe_ddp",
611 adapter->pdev, IXGBE_FCPTR_MAX,
612 IXGBE_FCPTR_ALIGN, PAGE_SIZE);
613 if (!fcoe->pool)
614 e_err(drv, "failed to allocated FCoE DDP pool\n");
615
616 spin_lock_init(&fcoe->lock); 657 spin_lock_init(&fcoe->lock);
617 658
659 ixgbe_fcoe_ddp_pools_alloc(adapter);
660 if (!fcoe->pool) {
661 e_err(drv, "failed to alloc percpu fcoe DDP pools\n");
662 return;
663 }
664
618 /* Extra buffer to be shared by all DDPs for HW work around */ 665 /* Extra buffer to be shared by all DDPs for HW work around */
619 fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC); 666 fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC);
620 if (fcoe->extra_ddp_buffer == NULL) { 667 if (fcoe->extra_ddp_buffer == NULL) {
621 e_err(drv, "failed to allocated extra DDP buffer\n"); 668 e_err(drv, "failed to allocated extra DDP buffer\n");
622 goto out_extra_ddp_buffer_alloc; 669 goto out_ddp_pools;
623 } 670 }
624 671
625 fcoe->extra_ddp_buffer_dma = 672 fcoe->extra_ddp_buffer_dma =
@@ -630,7 +677,7 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
630 if (dma_mapping_error(&adapter->pdev->dev, 677 if (dma_mapping_error(&adapter->pdev->dev,
631 fcoe->extra_ddp_buffer_dma)) { 678 fcoe->extra_ddp_buffer_dma)) {
632 e_err(drv, "failed to map extra DDP buffer\n"); 679 e_err(drv, "failed to map extra DDP buffer\n");
633 goto out_extra_ddp_buffer_dma; 680 goto out_extra_ddp_buffer;
634 } 681 }
635 } 682 }
636 683
@@ -684,11 +731,10 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
684 731
685 return; 732 return;
686 733
687out_extra_ddp_buffer_dma: 734out_extra_ddp_buffer:
688 kfree(fcoe->extra_ddp_buffer); 735 kfree(fcoe->extra_ddp_buffer);
689out_extra_ddp_buffer_alloc: 736out_ddp_pools:
690 pci_pool_destroy(fcoe->pool); 737 ixgbe_fcoe_ddp_pools_free(fcoe);
691 fcoe->pool = NULL;
692} 738}
693 739
694/** 740/**
@@ -704,18 +750,17 @@ void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter)
704 int i; 750 int i;
705 struct ixgbe_fcoe *fcoe = &adapter->fcoe; 751 struct ixgbe_fcoe *fcoe = &adapter->fcoe;
706 752
707 /* release ddp resource */ 753 if (!fcoe->pool)
708 if (fcoe->pool) { 754 return;
709 for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) 755
710 ixgbe_fcoe_ddp_put(adapter->netdev, i); 756 for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++)
711 dma_unmap_single(&adapter->pdev->dev, 757 ixgbe_fcoe_ddp_put(adapter->netdev, i);
712 fcoe->extra_ddp_buffer_dma, 758 dma_unmap_single(&adapter->pdev->dev,
713 IXGBE_FCBUFF_MIN, 759 fcoe->extra_ddp_buffer_dma,
714 DMA_FROM_DEVICE); 760 IXGBE_FCBUFF_MIN,
715 kfree(fcoe->extra_ddp_buffer); 761 DMA_FROM_DEVICE);
716 pci_pool_destroy(fcoe->pool); 762 kfree(fcoe->extra_ddp_buffer);
717 fcoe->pool = NULL; 763 ixgbe_fcoe_ddp_pools_free(fcoe);
718 }
719} 764}
720 765
721/** 766/**
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h
index 5a650a4ace66..d876e7ac2257 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.h
+++ b/drivers/net/ixgbe/ixgbe_fcoe.h
@@ -62,20 +62,21 @@ struct ixgbe_fcoe_ddp {
62 struct scatterlist *sgl; 62 struct scatterlist *sgl;
63 dma_addr_t udp; 63 dma_addr_t udp;
64 u64 *udl; 64 u64 *udl;
65 struct pci_pool *pool;
65}; 66};
66 67
67struct ixgbe_fcoe { 68struct ixgbe_fcoe {
68#ifdef CONFIG_IXGBE_DCB 69 struct pci_pool **pool;
69 u8 tc;
70 u8 up;
71#endif
72 unsigned long mode;
73 atomic_t refcnt; 70 atomic_t refcnt;
74 spinlock_t lock; 71 spinlock_t lock;
75 struct pci_pool *pool;
76 struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; 72 struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];
77 unsigned char *extra_ddp_buffer; 73 unsigned char *extra_ddp_buffer;
78 dma_addr_t extra_ddp_buffer_dma; 74 dma_addr_t extra_ddp_buffer_dma;
75 unsigned long mode;
76#ifdef CONFIG_IXGBE_DCB
77 u8 tc;
78 u8 up;
79#endif
79}; 80};
80 81
81#endif /* _IXGBE_FCOE_H */ 82#endif /* _IXGBE_FCOE_H */