Print this page
6274 MAC tries to use aggr rings from downed links
Reviewed by: Bryan Cantrill <bryan@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Approved by: Richard Lowe <richlowe@richlowe.net>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/aggr/aggr_grp.c
          +++ new/usr/src/uts/common/io/aggr/aggr_grp.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2015 Joyent, Inc.
  23   24   */
  24   25  
  25   26  /*
  26   27   * IEEE 802.3ad Link Aggregation -- Link Aggregation Groups.
  27   28   *
  28   29   * An instance of the structure aggr_grp_t is allocated for each
  29   30   * link aggregation group. When created, aggr_grp_t objects are
  30   31   * entered into the aggr_grp_hash hash table maintained by the modhash
  31   32   * module. The hash key is the linkid associated with the link
  32   33   * aggregation group.
↓ open down ↓ 532 lines elided ↑ open up ↑
 565  566          aggr_lacp_init_port(port);
 566  567          mac_perim_exit(mph);
 567  568  
 568  569          if (pp != NULL)
 569  570                  *pp = port;
 570  571  
 571  572          return (0);
 572  573  }
 573  574  
 574  575  /*
      576 + * This is called in response to either our LACP state machine or a MAC
      577 + * notification that the link has gone down via aggr_send_port_disable(). At
      578 + * this point, we may need to update our default ring. To that end, we go
      579 + * through the set of ports (underlying datalinks in an aggregation) that are
      580 + * currently enabled to transmit data. If all our links have been disabled for
      581 + * transmit, then we don't do anything.
      582 + *
      583 + * Note, because we only have a single TX group, we don't have to worry about
      584 + * the rings moving between groups and the chance that mac will reassign it
      585 + * unless someone removes a port, at which point, we play it safe and call this
      586 + * again.
      587 + */
      588 +void
      589 +aggr_grp_update_default(aggr_grp_t *grp)
      590 +{
      591 +        aggr_port_t *port;
      592 +        ASSERT(MAC_PERIM_HELD(grp->lg_mh));
      593 +
      594 +        rw_enter(&grp->lg_tx_lock, RW_WRITER);
      595 +
      596 +        if (grp->lg_ntx_ports == 0) {
      597 +                rw_exit(&grp->lg_tx_lock);
      598 +                return;
      599 +        }
      600 +
      601 +        port = grp->lg_tx_ports[0];
      602 +        ASSERT(port->lp_tx_ring_cnt > 0);
      603 +        mac_hwring_set_default(grp->lg_mh, port->lp_pseudo_tx_rings[0]);
      604 +        rw_exit(&grp->lg_tx_lock);
      605 +}
      606 +
      607 +/*
 575  608   * Add a pseudo RX ring for the given HW ring handle.
 576  609   */
 577  610  static int
 578  611  aggr_add_pseudo_rx_ring(aggr_port_t *port,
 579  612      aggr_pseudo_rx_group_t *rx_grp, mac_ring_handle_t hw_rh)
 580  613  {
 581  614          aggr_pseudo_rx_ring_t   *ring;
 582  615          int                     err;
 583  616          int                     j;
 584  617  
↓ open down ↓ 225 lines elided ↑ open up ↑
 810  843                  ring->atr_hw_rh = NULL;
 811  844                  ring->atr_port = NULL;
 812  845                  tx_grp->atg_ring_cnt--;
 813  846          } else {
 814  847                  *pseudo_rh = mac_find_ring(tx_grp->atg_gh, i);
 815  848                  if (hw_rh != NULL) {
 816  849                          mac_hwring_setup(hw_rh, (mac_resource_handle_t)ring,
 817  850                              mac_find_ring(tx_grp->atg_gh, i));
 818  851                  }
 819  852          }
      853 +
 820  854          return (err);
 821  855  }
 822  856  
 823  857  /*
 824  858   * Remove the pseudo TX ring of the given HW ring handle.
 825  859   */
 826  860  static void
 827  861  aggr_rem_pseudo_tx_ring(aggr_pseudo_tx_group_t *tx_grp,
 828  862      mac_ring_handle_t pseudo_hw_rh)
 829  863  {
↓ open down ↓ 82 lines elided ↑ open up ↑
 912  946                      (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_cnt));
 913  947                  kmem_free(port->lp_pseudo_tx_rings,
 914  948                      (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_cnt));
 915  949                  port->lp_tx_ring_cnt = 0;
 916  950          } else {
 917  951                  port->lp_tx_grp_added = B_TRUE;
 918  952                  port->lp_tx_notify_mh = mac_client_tx_notify(port->lp_mch,
 919  953                      aggr_tx_ring_update, port);
 920  954          }
 921  955          mac_perim_exit(pmph);
      956 +        aggr_grp_update_default(grp);
 922  957          return (err);
 923  958  }
 924  959  
 925  960  /*
 926  961   * This function is called by aggr to remove pseudo TX rings over the
 927  962   * HW rings of the underlying port.
 928  963   */
 929  964  static void
 930  965  aggr_rem_pseudo_tx_group(aggr_port_t *port, aggr_pseudo_tx_group_t *tx_grp)
 931  966  {
↓ open down ↓ 13 lines elided ↑ open up ↑
 945  980                  aggr_rem_pseudo_tx_ring(tx_grp, port->lp_pseudo_tx_rings[i]);
 946  981  
 947  982          kmem_free(port->lp_tx_rings,
 948  983              (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_cnt));
 949  984          kmem_free(port->lp_pseudo_tx_rings,
 950  985              (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_cnt));
 951  986  
 952  987          port->lp_tx_ring_cnt = 0;
 953  988          (void) mac_client_tx_notify(port->lp_mch, NULL, port->lp_tx_notify_mh);
 954  989          port->lp_tx_grp_added = B_FALSE;
      990 +        aggr_grp_update_default(grp);
 955  991  done:
 956  992          mac_perim_exit(pmph);
 957  993  }
 958  994  
 959  995  static int
 960  996  aggr_pseudo_disable_intr(mac_intr_handle_t ih)
 961  997  {
 962  998          aggr_pseudo_rx_ring_t *rr_ring = (aggr_pseudo_rx_ring_t *)ih;
 963  999          return (mac_hwring_disable_intr(rr_ring->arr_hw_rh));
 964 1000  }
↓ open down ↓ 2025 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX