Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Vasu Dev and committed by
Jeff Kirsher
dadbe85a 9612de92

+83 -37
+75 -30
drivers/net/ixgbe/ixgbe_fcoe.c
··· 128 128 if (ddp->sgl) 129 129 pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc, 130 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 136 ixgbe_fcoe_clear_ddp(ddp); 133 137 134 138 out_ddp_put: ··· 167 163 unsigned int thislen = 0; 168 164 u32 fcbuff, fcdmarw, fcfltrw, fcrxctl; 169 165 dma_addr_t addr = 0; 166 + struct pci_pool *pool; 170 167 171 168 if (!netdev || !sgl) 172 169 return 0; ··· 204 199 return 0; 205 200 } 206 201 207 - /* alloc the udl from our ddp pool */ 208 - ddp->udl = pci_pool_alloc(fcoe->pool, GFP_ATOMIC, &ddp->udp); 202 + /* alloc the udl from per cpu ddp pool */ 203 + pool = *per_cpu_ptr(fcoe->pool, get_cpu()); 204 + ddp->udl = pci_pool_alloc(pool, GFP_ATOMIC, &ddp->udp); 209 205 if (!ddp->udl) { 210 206 e_err(drv, "failed allocated ddp context\n"); 211 207 goto out_noddp_unmap; 212 208 } 209 + ddp->pool = pool; 213 210 ddp->sgl = sgl; 214 211 ddp->sgc = sgc; 215 212 ··· 275 268 j++; 276 269 lastsize = 1; 277 270 } 271 + put_cpu(); 278 272 279 273 fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); 280 274 fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); ··· 319 311 return 1; 320 312 321 313 out_noddp_free: 322 - pci_pool_free(fcoe->pool, ddp->udl, ddp->udp); 314 + pci_pool_free(pool, ddp->udl, ddp->udp); 323 315 ixgbe_fcoe_clear_ddp(ddp); 324 316 325 317 out_noddp_unmap: 326 318 pci_unmap_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE); 319 + put_cpu(); 327 320 return 0; 328 321 } 329 322 ··· 594 585 return skb_is_gso(skb); 595 586 } 596 587 588 + static void ixgbe_fcoe_ddp_pools_free(struct ixgbe_fcoe *fcoe) 589 + { 590 + unsigned int cpu; 591 + struct pci_pool **pool; 592 + 593 + for_each_possible_cpu(cpu) { 594 + pool = per_cpu_ptr(fcoe->pool, cpu); 595 + if (*pool) 596 + pci_pool_destroy(*pool); 597 + } 598 + free_percpu(fcoe->pool); 599 + fcoe->pool = NULL; 600 + } 601 + 602 + static void ixgbe_fcoe_ddp_pools_alloc(struct ixgbe_adapter *adapter) 603 + { 604 + struct ixgbe_fcoe *fcoe = &adapter->fcoe; 605 + unsigned int cpu; 606 + struct pci_pool **pool; 607 + char pool_name[32]; 608 + 609 + fcoe->pool = alloc_percpu(struct pci_pool *); 610 + if (!fcoe->pool) 611 + return; 612 + 613 + /* allocate pci pool for each cpu */ 614 + for_each_possible_cpu(cpu) { 615 + snprintf(pool_name, 32, "ixgbe_fcoe_ddp_%d", cpu); 616 + pool = per_cpu_ptr(fcoe->pool, cpu); 617 + *pool = pci_pool_create(pool_name, 618 + adapter->pdev, IXGBE_FCPTR_MAX, 619 + IXGBE_FCPTR_ALIGN, PAGE_SIZE); 620 + if (!*pool) { 621 + e_err(drv, "failed to alloc DDP pool on cpu:%d\n", cpu); 622 + ixgbe_fcoe_ddp_pools_free(fcoe); 623 + return; 624 + } 625 + } 626 + } 627 + 597 628 /** 598 629 * ixgbe_configure_fcoe - configures registers for fcoe at start 599 630 * @adapter: ptr to ixgbe adapter ··· 653 604 u32 up2tc; 654 605 #endif 655 606 656 - /* create the pool for ddp if not created yet */ 657 607 if (!fcoe->pool) { 658 - /* allocate ddp pool */ 659 - fcoe->pool = pci_pool_create("ixgbe_fcoe_ddp", 660 - adapter->pdev, IXGBE_FCPTR_MAX, 661 - IXGBE_FCPTR_ALIGN, PAGE_SIZE); 662 - if (!fcoe->pool) 663 - e_err(drv, "failed to allocated FCoE DDP pool\n"); 664 - 665 608 spin_lock_init(&fcoe->lock); 609 + 610 + ixgbe_fcoe_ddp_pools_alloc(adapter); 611 + if (!fcoe->pool) { 612 + e_err(drv, "failed to alloc percpu fcoe DDP pools\n"); 613 + return; 614 + } 666 615 667 616 /* Extra buffer to be shared by all DDPs for HW work around */ 668 617 fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC); 669 618 if (fcoe->extra_ddp_buffer == NULL) { 670 619 e_err(drv, "failed to allocated extra DDP buffer\n"); 671 - goto out_extra_ddp_buffer_alloc; 620 + goto out_ddp_pools; 672 621 } 673 622 674 623 fcoe->extra_ddp_buffer_dma = ··· 677 630 if (dma_mapping_error(&adapter->pdev->dev, 678 631 fcoe->extra_ddp_buffer_dma)) { 679 632 e_err(drv, "failed to map extra DDP buffer\n"); 680 - goto out_extra_ddp_buffer_dma; 633 + goto out_extra_ddp_buffer; 681 634 } 682 635 } 683 636 ··· 731 684 732 685 return; 733 686 734 - out_extra_ddp_buffer_dma: 687 + out_extra_ddp_buffer: 735 688 kfree(fcoe->extra_ddp_buffer); 736 - out_extra_ddp_buffer_alloc: 737 - pci_pool_destroy(fcoe->pool); 738 - fcoe->pool = NULL; 689 + out_ddp_pools: 690 + ixgbe_fcoe_ddp_pools_free(fcoe); 739 691 } 740 692 741 693 /** ··· 750 704 int i; 751 705 struct ixgbe_fcoe *fcoe = &adapter->fcoe; 752 706 753 - /* release ddp resource */ 754 - if (fcoe->pool) { 755 - for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) 756 - ixgbe_fcoe_ddp_put(adapter->netdev, i); 757 - dma_unmap_single(&adapter->pdev->dev, 758 - fcoe->extra_ddp_buffer_dma, 759 - IXGBE_FCBUFF_MIN, 760 - DMA_FROM_DEVICE); 761 - kfree(fcoe->extra_ddp_buffer); 762 - pci_pool_destroy(fcoe->pool); 763 - fcoe->pool = NULL; 764 - } 707 + if (!fcoe->pool) 708 + return; 709 + 710 + for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) 711 + ixgbe_fcoe_ddp_put(adapter->netdev, i); 712 + dma_unmap_single(&adapter->pdev->dev, 713 + fcoe->extra_ddp_buffer_dma, 714 + IXGBE_FCBUFF_MIN, 715 + DMA_FROM_DEVICE); 716 + kfree(fcoe->extra_ddp_buffer); 717 + ixgbe_fcoe_ddp_pools_free(fcoe); 765 718 } 766 719 767 720 /**
+8 -7
drivers/net/ixgbe/ixgbe_fcoe.h
··· 62 62 struct scatterlist *sgl; 63 63 dma_addr_t udp; 64 64 u64 *udl; 65 + struct pci_pool *pool; 65 66 }; 66 67 67 68 struct ixgbe_fcoe { 69 + struct pci_pool **pool; 70 + atomic_t refcnt; 71 + spinlock_t lock; 72 + struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; 73 + unsigned char *extra_ddp_buffer; 74 + dma_addr_t extra_ddp_buffer_dma; 75 + unsigned long mode; 68 76 #ifdef CONFIG_IXGBE_DCB 69 77 u8 tc; 70 78 u8 up; 71 79 #endif 72 - unsigned long mode; 73 - atomic_t refcnt; 74 - spinlock_t lock; 75 - struct pci_pool *pool; 76 - struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; 77 - unsigned char *extra_ddp_buffer; 78 - dma_addr_t extra_ddp_buffer_dma; 79 80 }; 80 81 81 82 #endif /* _IXGBE_FCOE_H */