aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Baron <jbaron@akamai.com>2016-09-22 17:12:25 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-26 09:43:06 -0400
commite8c6ae9fbf8ca70ef0c2de0d2f3995acb0dc8968 (patch)
treed1e1e5fbcee7979dc3dc58de4d41e732cd876c6d
parentb47c62c5de2bc43a26bcaca8d7a93bf9dee66ffe (diff)
bnx2x: allocate mac filtering 'mcast_list' in PAGE_SIZE increments
Currently, we can have high order page allocations that specify GFP_ATOMIC when configuring multicast MAC address filters. For example, we have seen order 2 page allocation failures with ~500 multicast addresses configured. Convert the allocation for 'mcast_list' to be done in PAGE_SIZE increments. Signed-off-by: Jason Baron <jbaron@akamai.com> Cc: Yuval Mintz <Yuval.Mintz@qlogic.com> Cc: Ariel Elior <Ariel.Elior@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c79
1 files changed, 51 insertions, 28 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index dab61a81a3ba..20fe6a8c35c1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12563,43 +12563,64 @@ static int bnx2x_close(struct net_device *dev)
12563 return 0; 12563 return 0;
12564} 12564}
12565 12565
12566static int bnx2x_init_mcast_macs_list(struct bnx2x *bp, 12566struct bnx2x_mcast_list_elem_group
12567 struct bnx2x_mcast_ramrod_params *p)
12568{ 12567{
12569 int mc_count = netdev_mc_count(bp->dev); 12568 struct list_head mcast_group_link;
12570 struct bnx2x_mcast_list_elem *mc_mac = 12569 struct bnx2x_mcast_list_elem mcast_elems[];
12571 kcalloc(mc_count, sizeof(*mc_mac), GFP_ATOMIC); 12570};
12572 struct netdev_hw_addr *ha;
12573 12571
12574 if (!mc_mac) { 12572#define MCAST_ELEMS_PER_PG \
12575 BNX2X_ERR("Failed to allocate mc MAC list\n"); 12573 ((PAGE_SIZE - sizeof(struct bnx2x_mcast_list_elem_group)) / \
12576 return -ENOMEM; 12574 sizeof(struct bnx2x_mcast_list_elem))
12575
12576static void bnx2x_free_mcast_macs_list(struct list_head *mcast_group_list)
12577{
12578 struct bnx2x_mcast_list_elem_group *current_mcast_group;
12579
12580 while (!list_empty(mcast_group_list)) {
12581 current_mcast_group = list_first_entry(mcast_group_list,
12582 struct bnx2x_mcast_list_elem_group,
12583 mcast_group_link);
12584 list_del(&current_mcast_group->mcast_group_link);
12585 free_page((unsigned long)current_mcast_group);
12577 } 12586 }
12587}
12578 12588
12579 INIT_LIST_HEAD(&p->mcast_list); 12589static int bnx2x_init_mcast_macs_list(struct bnx2x *bp,
12590 struct bnx2x_mcast_ramrod_params *p,
12591 struct list_head *mcast_group_list)
12592{
12593 struct bnx2x_mcast_list_elem *mc_mac;
12594 struct netdev_hw_addr *ha;
12595 struct bnx2x_mcast_list_elem_group *current_mcast_group = NULL;
12596 int mc_count = netdev_mc_count(bp->dev);
12597 int offset = 0;
12580 12598
12599 INIT_LIST_HEAD(&p->mcast_list);
12581 netdev_for_each_mc_addr(ha, bp->dev) { 12600 netdev_for_each_mc_addr(ha, bp->dev) {
12601 if (!offset) {
12602 current_mcast_group =
12603 (struct bnx2x_mcast_list_elem_group *)
12604 __get_free_page(GFP_ATOMIC);
12605 if (!current_mcast_group) {
12606 bnx2x_free_mcast_macs_list(mcast_group_list);
12607 BNX2X_ERR("Failed to allocate mc MAC list\n");
12608 return -ENOMEM;
12609 }
12610 list_add(&current_mcast_group->mcast_group_link,
12611 mcast_group_list);
12612 }
12613 mc_mac = &current_mcast_group->mcast_elems[offset];
12582 mc_mac->mac = bnx2x_mc_addr(ha); 12614 mc_mac->mac = bnx2x_mc_addr(ha);
12583 list_add_tail(&mc_mac->link, &p->mcast_list); 12615 list_add_tail(&mc_mac->link, &p->mcast_list);
12584 mc_mac++; 12616 offset++;
12617 if (offset == MCAST_ELEMS_PER_PG)
12618 offset = 0;
12585 } 12619 }
12586
12587 p->mcast_list_len = mc_count; 12620 p->mcast_list_len = mc_count;
12588
12589 return 0; 12621 return 0;
12590} 12622}
12591 12623
12592static void bnx2x_free_mcast_macs_list(
12593 struct bnx2x_mcast_ramrod_params *p)
12594{
12595 struct bnx2x_mcast_list_elem *mc_mac =
12596 list_first_entry(&p->mcast_list, struct bnx2x_mcast_list_elem,
12597 link);
12598
12599 WARN_ON(!mc_mac);
12600 kfree(mc_mac);
12601}
12602
12603/** 12624/**
12604 * bnx2x_set_uc_list - configure a new unicast MACs list. 12625 * bnx2x_set_uc_list - configure a new unicast MACs list.
12605 * 12626 *
@@ -12647,6 +12668,7 @@ static int bnx2x_set_uc_list(struct bnx2x *bp)
12647 12668
12648static int bnx2x_set_mc_list_e1x(struct bnx2x *bp) 12669static int bnx2x_set_mc_list_e1x(struct bnx2x *bp)
12649{ 12670{
12671 LIST_HEAD(mcast_group_list);
12650 struct net_device *dev = bp->dev; 12672 struct net_device *dev = bp->dev;
12651 struct bnx2x_mcast_ramrod_params rparam = {NULL}; 12673 struct bnx2x_mcast_ramrod_params rparam = {NULL};
12652 int rc = 0; 12674 int rc = 0;
@@ -12662,7 +12684,7 @@ static int bnx2x_set_mc_list_e1x(struct bnx2x *bp)
12662 12684
12663 /* then, configure a new MACs list */ 12685 /* then, configure a new MACs list */
12664 if (netdev_mc_count(dev)) { 12686 if (netdev_mc_count(dev)) {
12665 rc = bnx2x_init_mcast_macs_list(bp, &rparam); 12687 rc = bnx2x_init_mcast_macs_list(bp, &rparam, &mcast_group_list);
12666 if (rc) 12688 if (rc)
12667 return rc; 12689 return rc;
12668 12690
@@ -12673,7 +12695,7 @@ static int bnx2x_set_mc_list_e1x(struct bnx2x *bp)
12673 BNX2X_ERR("Failed to set a new multicast configuration: %d\n", 12695 BNX2X_ERR("Failed to set a new multicast configuration: %d\n",
12674 rc); 12696 rc);
12675 12697
12676 bnx2x_free_mcast_macs_list(&rparam); 12698 bnx2x_free_mcast_macs_list(&mcast_group_list);
12677 } 12699 }
12678 12700
12679 return rc; 12701 return rc;
@@ -12681,6 +12703,7 @@ static int bnx2x_set_mc_list_e1x(struct bnx2x *bp)
12681 12703
12682static int bnx2x_set_mc_list(struct bnx2x *bp) 12704static int bnx2x_set_mc_list(struct bnx2x *bp)
12683{ 12705{
12706 LIST_HEAD(mcast_group_list);
12684 struct bnx2x_mcast_ramrod_params rparam = {NULL}; 12707 struct bnx2x_mcast_ramrod_params rparam = {NULL};
12685 struct net_device *dev = bp->dev; 12708 struct net_device *dev = bp->dev;
12686 int rc = 0; 12709 int rc = 0;
@@ -12692,7 +12715,7 @@ static int bnx2x_set_mc_list(struct bnx2x *bp)
12692 rparam.mcast_obj = &bp->mcast_obj; 12715 rparam.mcast_obj = &bp->mcast_obj;
12693 12716
12694 if (netdev_mc_count(dev)) { 12717 if (netdev_mc_count(dev)) {
12695 rc = bnx2x_init_mcast_macs_list(bp, &rparam); 12718 rc = bnx2x_init_mcast_macs_list(bp, &rparam, &mcast_group_list);
12696 if (rc) 12719 if (rc)
12697 return rc; 12720 return rc;
12698 12721
@@ -12703,7 +12726,7 @@ static int bnx2x_set_mc_list(struct bnx2x *bp)
12703 BNX2X_ERR("Failed to set a new multicast configuration: %d\n", 12726 BNX2X_ERR("Failed to set a new multicast configuration: %d\n",
12704 rc); 12727 rc);
12705 12728
12706 bnx2x_free_mcast_macs_list(&rparam); 12729 bnx2x_free_mcast_macs_list(&mcast_group_list);
12707 } else { 12730 } else {
12708 /* If no mc addresses are required, flush the configuration */ 12731 /* If no mc addresses are required, flush the configuration */
12709 rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL); 12732 rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL);