Print this page
11493 aggr needs support for multiple pseudo rx groups
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/mac/mac_datapath_setup.c
          +++ new/usr/src/uts/common/io/mac/mac_datapath_setup.c
↓ open down ↓ 1967 lines elided ↑ open up ↑
1968 1968                   * This is the case when there is no fanout which is
1969 1969                   * true for subflows.
1970 1970                   */
1971 1971                  mac_rx_srs->srs_type |= SRST_NO_SOFT_RINGS;
1972 1972          }
1973 1973          mac_srs_update_fanout_list(mac_rx_srs);
1974 1974          mac_srs_client_poll_enable(mcip, mac_rx_srs);
1975 1975  }
1976 1976  
1977 1977  /*
1978      - * mac_fanout_setup:
1979      - *
1980 1978   * Calls mac_srs_fanout_init() or modify() depending upon whether
1981 1979   * the SRS is getting initialized or re-initialized.
1982 1980   */
1983 1981  void
1984 1982  mac_fanout_setup(mac_client_impl_t *mcip, flow_entry_t *flent,
1985 1983      mac_resource_props_t *mrp, mac_direct_rx_t rx_func, void *x_arg1,
1986 1984      mac_resource_handle_t x_arg2, cpupart_t *cpupart)
1987 1985  {
1988 1986          mac_soft_ring_set_t *mac_rx_srs, *mac_tx_srs;
1989 1987          int i, rx_srs_cnt;
1990 1988  
1991 1989          ASSERT(MAC_PERIM_HELD((mac_handle_t)mcip->mci_mip));
     1990 +
1992 1991          /*
1993      -         * This is an aggregation port. Fanout will be setup
1994      -         * over the aggregation itself.
     1992 +         * Aggr ports do not have SRSes. This function should never be
     1993 +         * called on an aggr port.
1995 1994           */
1996      -        if (mcip->mci_state_flags & MCIS_EXCLUSIVE)
1997      -                return;
1998      -
     1995 +        ASSERT3U((mcip->mci_state_flags & MCIS_IS_AGGR_PORT), ==, 0);
1999 1996          mac_rx_srs = flent->fe_rx_srs[0];
     1997 +
2000 1998          /*
2001 1999           * Set up the fanout on the tx side only once, with the
2002 2000           * first rx SRS. The CPU binding, fanout, and bandwidth
2003 2001           * criteria are common to both RX and TX, so
2004 2002           * initializing them along side avoids redundant code.
2005 2003           */
2006 2004          mac_tx_srs = flent->fe_tx_srs;
2007 2005          rx_srs_cnt = flent->fe_rx_srs_cnt;
2008 2006  
2009 2007          /* No fanout for subflows */
↓ open down ↓ 35 lines elided ↑ open up ↑
2045 2043                          break;
2046 2044                  default:
2047 2045                          VERIFY(mac_rx_srs->srs_fanout_state <=
2048 2046                              SRS_FANOUT_REINIT);
2049 2047                          break;
2050 2048                  }
2051 2049          }
2052 2050  }
2053 2051  
2054 2052  /*
2055      - * mac_srs_create:
2056      - *
2057 2053   * Create a mac_soft_ring_set_t (SRS). If soft_ring_fanout_type is
2058 2054   * SRST_TX, an SRS for Tx side is created. Otherwise an SRS for Rx side
2059 2055   * processing is created.
2060 2056   *
2061 2057   * Details on Rx SRS:
2062 2058   * Create a SRS and also add the necessary soft rings for TCP and
2063 2059   * non-TCP based on fanout type and count specified.
2064 2060   *
2065 2061   * mac_soft_ring_fanout, mac_srs_fanout_modify (?),
2066 2062   * mac_soft_ring_stop_workers, mac_soft_ring_set_destroy, etc need
↓ open down ↓ 281 lines elided ↑ open up ↑
2348 2344      uint32_t link_type)
2349 2345  {
2350 2346          cpupart_t               *cpupart;
2351 2347          mac_resource_props_t    *mrp = MCIP_RESOURCE_PROPS(mcip);
2352 2348          mac_resource_props_t    *emrp = MCIP_EFFECTIVE_PROPS(mcip);
2353 2349          boolean_t               use_default = B_FALSE;
2354 2350  
2355 2351          mac_rx_srs_group_setup(mcip, flent, link_type);
2356 2352          mac_tx_srs_group_setup(mcip, flent, link_type);
2357 2353  
     2354 +        /* Aggr ports don't have SRSes; thus there is no soft ring fanout. */
     2355 +        if ((mcip->mci_state_flags & MCIS_IS_AGGR_PORT) != 0)
     2356 +                return;
     2357 +
2358 2358          pool_lock();
2359 2359          cpupart = mac_pset_find(mrp, &use_default);
2360 2360          mac_fanout_setup(mcip, flent, MCIP_RESOURCE_PROPS(mcip),
2361 2361              mac_rx_deliver, mcip, NULL, cpupart);
2362 2362          mac_set_pool_effective(use_default, cpupart, mrp, emrp);
2363 2363          pool_unlock();
2364 2364  }
2365 2365  
2366 2366  /*
2367 2367   * Set up the Rx SRSes. If there is no group associated with the
↓ open down ↓ 6 lines elided ↑ open up ↑
2374 2374  mac_rx_srs_group_setup(mac_client_impl_t *mcip, flow_entry_t *flent,
2375 2375      uint32_t link_type)
2376 2376  {
2377 2377          mac_impl_t              *mip = mcip->mci_mip;
2378 2378          mac_soft_ring_set_t     *mac_srs;
2379 2379          mac_ring_t              *ring;
2380 2380          uint32_t                fanout_type;
2381 2381          mac_group_t             *rx_group = flent->fe_rx_ring_group;
2382 2382          boolean_t               no_unicast;
2383 2383  
     2384 +        /*
     2385 +         * If this is an an aggr port, then don't setup Rx SRS and Rx
     2386 +         * soft rings as they won't be used. However, we still need to
     2387 +         * start the rings to receive data on them.
     2388 +         */
     2389 +        if (mcip->mci_state_flags & MCIS_IS_AGGR_PORT) {
     2390 +                if (rx_group == NULL)
     2391 +                        return;
     2392 +
     2393 +                for (ring = rx_group->mrg_rings; ring != NULL;
     2394 +                    ring = ring->mr_next) {
     2395 +                        if (ring->mr_state != MR_INUSE)
     2396 +                                (void) mac_start_ring(ring);
     2397 +                }
     2398 +
     2399 +                return;
     2400 +        }
     2401 +
     2402 +        /*
     2403 +         * Aggr ports should never have SRSes.
     2404 +         */
     2405 +        ASSERT3U((mcip->mci_state_flags & MCIS_IS_AGGR_PORT), ==, 0);
     2406 +
2384 2407          fanout_type = mac_find_fanout(flent, link_type);
2385 2408          no_unicast = (mcip->mci_state_flags & MCIS_NO_UNICAST_ADDR) != 0;
2386 2409  
2387 2410          /* Create the SRS for SW classification if none exists */
2388 2411          if (flent->fe_rx_srs[0] == NULL) {
2389 2412                  ASSERT(flent->fe_rx_srs_cnt == 0);
2390 2413                  mac_srs = mac_srs_create(mcip, flent, fanout_type | link_type,
2391 2414                      mac_rx_deliver, mcip, NULL, NULL);
2392 2415                  mutex_enter(&flent->fe_lock);
2393 2416                  flent->fe_cb_fn = (flow_fn_t)mac_srs->srs_rx.sr_lower_proc;
↓ open down ↓ 68 lines elided ↑ open up ↑
2462 2485          }
2463 2486  }
2464 2487  
2465 2488  /*
2466 2489   * Set up the TX SRS.
2467 2490   */
2468 2491  void
2469 2492  mac_tx_srs_group_setup(mac_client_impl_t *mcip, flow_entry_t *flent,
2470 2493      uint32_t link_type)
2471 2494  {
2472      -        int                     cnt;
2473      -        int                     ringcnt;
2474      -        mac_ring_t              *ring;
2475      -        mac_group_t             *grp;
2476      -
2477 2495          /*
2478      -         * If we are opened exclusively (like aggr does for aggr_ports),
2479      -         * don't set up Tx SRS and Tx soft rings as they won't be used.
2480      -         * The same thing has to be done for Rx side also. See bug:
2481      -         * 6880080
     2496 +         * If this is an exclusive client (e.g. an aggr port), then
     2497 +         * don't setup Tx SRS and Tx soft rings as they won't be used.
     2498 +         * However, we still need to start the rings to send data
     2499 +         * across them.
2482 2500           */
2483 2501          if (mcip->mci_state_flags & MCIS_EXCLUSIVE) {
2484      -                /*
2485      -                 * If we have rings, start them here.
2486      -                 */
2487      -                if (flent->fe_tx_ring_group == NULL)
2488      -                        return;
     2502 +                mac_ring_t              *ring;
     2503 +                mac_group_t             *grp;
     2504 +
2489 2505                  grp = (mac_group_t *)flent->fe_tx_ring_group;
2490      -                ringcnt = grp->mrg_cur_count;
2491      -                ring = grp->mrg_rings;
2492      -                for (cnt = 0; cnt < ringcnt; cnt++) {
2493      -                        if (ring->mr_state != MR_INUSE) {
     2506 +
     2507 +                if (grp == NULL)
     2508 +                        return;
     2509 +
     2510 +                for (ring = grp->mrg_rings; ring != NULL;
     2511 +                    ring = ring->mr_next) {
     2512 +                        if (ring->mr_state != MR_INUSE)
2494 2513                                  (void) mac_start_ring(ring);
2495      -                        }
2496      -                        ring = ring->mr_next;
2497 2514                  }
     2515 +
2498 2516                  return;
2499 2517          }
     2518 +
     2519 +        /*
     2520 +         * Aggr ports should never have SRSes.
     2521 +         */
     2522 +        ASSERT3U((mcip->mci_state_flags & MCIS_IS_AGGR_PORT), ==, 0);
     2523 +
2500 2524          if (flent->fe_tx_srs == NULL) {
2501 2525                  (void) mac_srs_create(mcip, flent, SRST_TX | link_type,
2502 2526                      NULL, mcip, NULL, NULL);
2503 2527          }
     2528 +
2504 2529          mac_tx_srs_setup(mcip, flent);
2505 2530  }
2506 2531  
2507 2532  /*
2508 2533   * Teardown all the Rx SRSes. Unless hwonly is set, then only teardown
2509 2534   * the Rx HW SRSes and leave the SW SRS alone. The hwonly flag is set
2510 2535   * when we wish to move a MAC client from one group to another. In
2511 2536   * that case, we need to release the current HW SRSes but keep the SW
2512 2537   * SRS for continued traffic classifiction.
2513 2538   */
↓ open down ↓ 647 lines elided ↑ open up ↑
3161 3186                                      mip->mi_name, err);
3162 3187                          }
3163 3188  
3164 3189                          mcip->mci_unicast = NULL;
3165 3190                  }
3166 3191  
3167 3192                  /* Stop the packets coming from the S/W classifier */
3168 3193                  mac_flow_remove(mip->mi_flow_tab, flent, B_FALSE);
3169 3194                  mac_flow_wait(flent, FLOW_DRIVER_UPCALL);
3170 3195  
3171      -                /* Now quiesce and destroy all SRS and soft rings */
     3196 +                /* Quiesce and destroy all the SRSes. */
3172 3197                  mac_rx_srs_group_teardown(flent, B_FALSE);
3173 3198                  mac_tx_srs_group_teardown(mcip, flent, SRST_LINK);
3174 3199  
3175      -                ASSERT((mcip->mci_flent == flent) &&
3176      -                    (flent->fe_next == NULL));
     3200 +                ASSERT3P(mcip->mci_flent, ==, flent);
     3201 +                ASSERT3P(flent->fe_next, ==, NULL);
3177 3202  
3178 3203                  /*
3179 3204                   * Release our hold on the group as well. We need
3180 3205                   * to check if the shared group has only one client
3181 3206                   * left who can use it exclusively. Also, if we
3182 3207                   * were the last client, release the group.
3183 3208                   */
3184 3209                  default_group = MAC_DEFAULT_RX_GROUP(mip);
3185 3210                  if (group != NULL) {
3186 3211                          mac_group_remove_client(group, mcip);
↓ open down ↓ 828 lines elided ↑ open up ↑
4015 4040                  rx_srs = flent->fe_rx_srs[0];
4016 4041                  srs_cpu = &rx_srs->srs_cpu;
4017 4042                  if (soft_ring_count != srs_cpu->mc_rx_fanout_cnt) {
4018 4043                          mac_fanout_setup(mcip, flent, mcip_mrp,
4019 4044                              mac_rx_deliver, mcip, NULL, cpupart);
4020 4045                  }
4021 4046          }
4022 4047  }
4023 4048  
4024 4049  /*
4025      - * Walk through the list of mac clients for the MAC.
4026      - * For each active mac client, recompute the number of soft rings
     4050 + * Walk through the list of MAC clients for the MAC.
     4051 + * For each active MAC client, recompute the number of soft rings
4027 4052   * associated with every client, only if current speed is different
4028 4053   * from the speed that was previously used for soft ring computation.
4029 4054   * If the cable is disconnected whlie the NIC is started, we would get
4030 4055   * notification with speed set to 0. We do not recompute in that case.
4031 4056   */
4032 4057  void
4033 4058  mac_fanout_recompute(mac_impl_t *mip)
4034 4059  {
4035 4060          mac_client_impl_t       *mcip;
4036 4061          cpupart_t               *cpupart;
↓ open down ↓ 2 lines elided ↑ open up ↑
4039 4064  
4040 4065          i_mac_perim_enter(mip);
4041 4066          if ((mip->mi_state_flags & MIS_IS_VNIC) != 0 ||
4042 4067              mip->mi_linkstate != LINK_STATE_UP) {
4043 4068                  i_mac_perim_exit(mip);
4044 4069                  return;
4045 4070          }
4046 4071  
4047 4072          for (mcip = mip->mi_clients_list; mcip != NULL;
4048 4073              mcip = mcip->mci_client_next) {
     4074 +                /* Aggr port clients don't have SRSes. */
     4075 +                if ((mcip->mci_state_flags & MCIS_IS_AGGR_PORT) != 0)
     4076 +                        continue;
     4077 +
4049 4078                  if ((mcip->mci_state_flags & MCIS_SHARE_BOUND) != 0 ||
4050 4079                      !MCIP_DATAPATH_SETUP(mcip))
4051 4080                          continue;
4052 4081                  mrp = MCIP_RESOURCE_PROPS(mcip);
4053 4082                  emrp = MCIP_EFFECTIVE_PROPS(mcip);
4054 4083                  use_default = B_FALSE;
4055 4084                  pool_lock();
4056 4085                  cpupart = mac_pset_find(mrp, &use_default);
4057 4086                  mac_fanout_recompute_client(mcip, cpupart);
4058 4087                  mac_set_pool_effective(use_default, cpupart, mrp, emrp);
4059 4088                  pool_unlock();
4060 4089          }
     4090 +
4061 4091          i_mac_perim_exit(mip);
4062 4092  }
4063 4093  
4064 4094  /*
4065 4095   * Given a MAC, change the polling state for all its MAC clients.  'enable' is
4066 4096   * B_TRUE to enable polling or B_FALSE to disable.  Polling is enabled by
4067 4097   * default.
4068 4098   */
4069 4099  void
4070 4100  mac_poll_state_change(mac_handle_t mh, boolean_t enable)
↓ open down ↓ 14 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX