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>

*** 18,27 **** --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2015 Joyent, Inc. */ /* * IEEE 802.3ad Link Aggregation -- Link Aggregation Groups. *
*** 570,579 **** --- 571,612 ---- return (0); } /* + * This is called in response to either our LACP state machine or a MAC + * notification that the link has gone down via aggr_send_port_disable(). At + * this point, we may need to update our default ring. To that end, we go + * through the set of ports (underlying datalinks in an aggregation) that are + * currently enabled to transmit data. If all our links have been disabled for + * transmit, then we don't do anything. + * + * Note, because we only have a single TX group, we don't have to worry about + * the rings moving between groups and the chance that mac will reassign it + * unless someone removes a port, at which point, we play it safe and call this + * again. + */ + void + aggr_grp_update_default(aggr_grp_t *grp) + { + aggr_port_t *port; + ASSERT(MAC_PERIM_HELD(grp->lg_mh)); + + rw_enter(&grp->lg_tx_lock, RW_WRITER); + + if (grp->lg_ntx_ports == 0) { + rw_exit(&grp->lg_tx_lock); + return; + } + + port = grp->lg_tx_ports[0]; + ASSERT(port->lp_tx_ring_cnt > 0); + mac_hwring_set_default(grp->lg_mh, port->lp_pseudo_tx_rings[0]); + rw_exit(&grp->lg_tx_lock); + } + + /* * Add a pseudo RX ring for the given HW ring handle. */ static int aggr_add_pseudo_rx_ring(aggr_port_t *port, aggr_pseudo_rx_group_t *rx_grp, mac_ring_handle_t hw_rh)
*** 815,824 **** --- 848,858 ---- if (hw_rh != NULL) { mac_hwring_setup(hw_rh, (mac_resource_handle_t)ring, mac_find_ring(tx_grp->atg_gh, i)); } } + return (err); } /* * Remove the pseudo TX ring of the given HW ring handle.
*** 917,926 **** --- 951,961 ---- port->lp_tx_grp_added = B_TRUE; port->lp_tx_notify_mh = mac_client_tx_notify(port->lp_mch, aggr_tx_ring_update, port); } mac_perim_exit(pmph); + aggr_grp_update_default(grp); return (err); } /* * This function is called by aggr to remove pseudo TX rings over the
*** 950,959 **** --- 985,995 ---- (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_cnt)); port->lp_tx_ring_cnt = 0; (void) mac_client_tx_notify(port->lp_mch, NULL, port->lp_tx_notify_mh); port->lp_tx_grp_added = B_FALSE; + aggr_grp_update_default(grp); done: mac_perim_exit(pmph); } static int