5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/callb.h>
28 #include <sys/sdt.h>
29 #include <sys/strsubr.h>
30 #include <sys/strsun.h>
31 #include <sys/vlan.h>
32 #include <inet/ipsec_impl.h>
33 #include <inet/ip_impl.h>
34 #include <inet/sadb.h>
35 #include <inet/ipsecesp.h>
36 #include <inet/ipsecah.h>
37 #include <inet/ip6.h>
38
39 #include <sys/mac_impl.h>
40 #include <sys/mac_client_impl.h>
41 #include <sys/mac_client_priv.h>
42 #include <sys/mac_soft_ring.h>
43 #include <sys/mac_flow_impl.h>
44
45 static mac_tx_cookie_t mac_tx_single_ring_mode(mac_soft_ring_set_t *, mblk_t *,
46 uintptr_t, uint16_t, mblk_t **);
47 static mac_tx_cookie_t mac_tx_serializer_mode(mac_soft_ring_set_t *, mblk_t *,
48 uintptr_t, uint16_t, mblk_t **);
49 static mac_tx_cookie_t mac_tx_fanout_mode(mac_soft_ring_set_t *, mblk_t *,
50 uintptr_t, uint16_t, mblk_t **);
51 static mac_tx_cookie_t mac_tx_bw_mode(mac_soft_ring_set_t *, mblk_t *,
398 mutex_enter(&srs->srs_bw->mac_bw_lock);
399
400 #define MAC_SRS_BW_UNLOCK(srs) \
401 if (!(srs->srs_type & SRST_TX)) \
402 mutex_exit(&srs->srs_bw->mac_bw_lock);
403
404 #define MAC_TX_SRS_DROP_MESSAGE(srs, mp, cookie) { \
405 mac_pkt_drop(NULL, NULL, mp, B_FALSE); \
406 /* increment freed stats */ \
407 mac_srs->srs_tx.st_stat.mts_sdrops++; \
408 cookie = (mac_tx_cookie_t)srs; \
409 }
410
411 #define MAC_TX_SET_NO_ENQUEUE(srs, mp_chain, ret_mp, cookie) { \
412 mac_srs->srs_state |= SRS_TX_WAKEUP_CLIENT; \
413 cookie = (mac_tx_cookie_t)srs; \
414 *ret_mp = mp_chain; \
415 }
416
417 /*
418 * Drop the rx packet and advance to the next one in the chain.
419 */
420 static void
421 mac_rx_drop_pkt(mac_soft_ring_set_t *srs, mblk_t *mp)
422 {
423 mac_srs_rx_t *srs_rx = &srs->srs_rx;
424
425 ASSERT(mp->b_next == NULL);
426 mutex_enter(&srs->srs_lock);
427 MAC_UPDATE_SRS_COUNT_LOCKED(srs, 1);
428 MAC_UPDATE_SRS_SIZE_LOCKED(srs, msgdsize(mp));
429 mutex_exit(&srs->srs_lock);
430
431 srs_rx->sr_stat.mrs_sdrops++;
432 freemsg(mp);
433 }
434
435 /* DATAPATH RUNTIME ROUTINES */
436
437 /*
2402 * its associated soft rings exceeds the max allowed,
2403 * then drop the chain. If we are polling capable, this
2404 * shouldn't be happening.
2405 */
2406 if (!(mac_srs->srs_type & SRST_BW_CONTROL) &&
2407 (srs_rx->sr_poll_pkt_cnt > srs_rx->sr_hiwat)) {
2408 mac_bw = mac_srs->srs_bw;
2409 srs_rx->sr_stat.mrs_sdrops += count;
2410 mutex_enter(&mac_bw->mac_bw_lock);
2411 mac_bw->mac_bw_drop_bytes += sz;
2412 mutex_exit(&mac_bw->mac_bw_lock);
2413 freemsgchain(mp_chain);
2414 mutex_exit(&mac_srs->srs_lock);
2415 return;
2416 }
2417
2418 MAC_RX_SRS_ENQUEUE_CHAIN(mac_srs, mp_chain, tail, count, sz);
2419
2420 if (!(mac_srs->srs_state & SRS_PROC)) {
2421 /*
2422 * If we are coming via loopback or if we are not
2423 * optimizing for latency, we should signal the
2424 * worker thread.
2425 */
2426 if (loopback || !(mac_srs->srs_state & SRS_LATENCY_OPT)) {
2427 /*
2428 * For loopback, We need to let the worker take
2429 * over as we don't want to continue in the same
2430 * thread even if we can. This could lead to stack
2431 * overflows and may also end up using
2432 * resources (cpu) incorrectly.
2433 */
2434 cv_signal(&mac_srs->srs_async);
2435 } else {
2436 /*
2437 * Seems like no one is processing the SRS and
2438 * there is no backlog. We also inline process
2439 * our packet if its a single packet in non
2440 * latency optimized case (in latency optimized
2441 * case, we inline process chains of any size).
2442 */
2443 mac_srs->srs_drain_func(mac_srs, SRS_PROC_FAST);
2444 }
2445 }
2446 mutex_exit(&mac_srs->srs_lock);
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 /*
26 * Copyright 2011 Joyent, Inc. All rights reserved.
27 */
28
29 #include <sys/types.h>
30 #include <sys/callb.h>
31 #include <sys/sdt.h>
32 #include <sys/strsubr.h>
33 #include <sys/strsun.h>
34 #include <sys/vlan.h>
35 #include <sys/stack.h>
36 #include <sys/archsystm.h>
37 #include <inet/ipsec_impl.h>
38 #include <inet/ip_impl.h>
39 #include <inet/sadb.h>
40 #include <inet/ipsecesp.h>
41 #include <inet/ipsecah.h>
42 #include <inet/ip6.h>
43
44 #include <sys/mac_impl.h>
45 #include <sys/mac_client_impl.h>
46 #include <sys/mac_client_priv.h>
47 #include <sys/mac_soft_ring.h>
48 #include <sys/mac_flow_impl.h>
49
50 static mac_tx_cookie_t mac_tx_single_ring_mode(mac_soft_ring_set_t *, mblk_t *,
51 uintptr_t, uint16_t, mblk_t **);
52 static mac_tx_cookie_t mac_tx_serializer_mode(mac_soft_ring_set_t *, mblk_t *,
53 uintptr_t, uint16_t, mblk_t **);
54 static mac_tx_cookie_t mac_tx_fanout_mode(mac_soft_ring_set_t *, mblk_t *,
55 uintptr_t, uint16_t, mblk_t **);
56 static mac_tx_cookie_t mac_tx_bw_mode(mac_soft_ring_set_t *, mblk_t *,
403 mutex_enter(&srs->srs_bw->mac_bw_lock);
404
405 #define MAC_SRS_BW_UNLOCK(srs) \
406 if (!(srs->srs_type & SRST_TX)) \
407 mutex_exit(&srs->srs_bw->mac_bw_lock);
408
409 #define MAC_TX_SRS_DROP_MESSAGE(srs, mp, cookie) { \
410 mac_pkt_drop(NULL, NULL, mp, B_FALSE); \
411 /* increment freed stats */ \
412 mac_srs->srs_tx.st_stat.mts_sdrops++; \
413 cookie = (mac_tx_cookie_t)srs; \
414 }
415
416 #define MAC_TX_SET_NO_ENQUEUE(srs, mp_chain, ret_mp, cookie) { \
417 mac_srs->srs_state |= SRS_TX_WAKEUP_CLIENT; \
418 cookie = (mac_tx_cookie_t)srs; \
419 *ret_mp = mp_chain; \
420 }
421
422 /*
423 * MAC_RX_SRS_TOODEEP
424 *
425 * Macro called as part of receive-side processing to determine if handling
426 * can occur in situ (in the interrupt thread) or if it should be left to a
427 * worker thread. Note that the constant used to make this determination is
428 * not entirely made-up, and is a result of some emprical validation. That
429 * said, the constant is left as a static variable to allow it to be
430 * dynamically tuned in the field if and as needed.
431 */
432 static uintptr_t mac_rx_srs_stack_needed = 10240;
433 static uint_t mac_rx_srs_stack_toodeep;
434
435 #ifndef STACK_GROWTH_DOWN
436 #error Downward stack growth assumed.
437 #endif
438
439 #define MAC_RX_SRS_TOODEEP() (STACK_BIAS + (uintptr_t)getfp() - \
440 (uintptr_t)curthread->t_stkbase < mac_rx_srs_stack_needed && \
441 ++mac_rx_srs_stack_toodeep)
442
443
444 /*
445 * Drop the rx packet and advance to the next one in the chain.
446 */
447 static void
448 mac_rx_drop_pkt(mac_soft_ring_set_t *srs, mblk_t *mp)
449 {
450 mac_srs_rx_t *srs_rx = &srs->srs_rx;
451
452 ASSERT(mp->b_next == NULL);
453 mutex_enter(&srs->srs_lock);
454 MAC_UPDATE_SRS_COUNT_LOCKED(srs, 1);
455 MAC_UPDATE_SRS_SIZE_LOCKED(srs, msgdsize(mp));
456 mutex_exit(&srs->srs_lock);
457
458 srs_rx->sr_stat.mrs_sdrops++;
459 freemsg(mp);
460 }
461
462 /* DATAPATH RUNTIME ROUTINES */
463
464 /*
2429 * its associated soft rings exceeds the max allowed,
2430 * then drop the chain. If we are polling capable, this
2431 * shouldn't be happening.
2432 */
2433 if (!(mac_srs->srs_type & SRST_BW_CONTROL) &&
2434 (srs_rx->sr_poll_pkt_cnt > srs_rx->sr_hiwat)) {
2435 mac_bw = mac_srs->srs_bw;
2436 srs_rx->sr_stat.mrs_sdrops += count;
2437 mutex_enter(&mac_bw->mac_bw_lock);
2438 mac_bw->mac_bw_drop_bytes += sz;
2439 mutex_exit(&mac_bw->mac_bw_lock);
2440 freemsgchain(mp_chain);
2441 mutex_exit(&mac_srs->srs_lock);
2442 return;
2443 }
2444
2445 MAC_RX_SRS_ENQUEUE_CHAIN(mac_srs, mp_chain, tail, count, sz);
2446
2447 if (!(mac_srs->srs_state & SRS_PROC)) {
2448 /*
2449 * If we are coming via loopback, if we are not optimizing for
2450 * latency, or if our stack is running deep, we should signal
2451 * the worker thread.
2452 */
2453 if (loopback || !(mac_srs->srs_state & SRS_LATENCY_OPT) ||
2454 MAC_RX_SRS_TOODEEP()) {
2455 /*
2456 * For loopback, We need to let the worker take
2457 * over as we don't want to continue in the same
2458 * thread even if we can. This could lead to stack
2459 * overflows and may also end up using
2460 * resources (cpu) incorrectly.
2461 */
2462 cv_signal(&mac_srs->srs_async);
2463 } else {
2464 /*
2465 * Seems like no one is processing the SRS and
2466 * there is no backlog. We also inline process
2467 * our packet if its a single packet in non
2468 * latency optimized case (in latency optimized
2469 * case, we inline process chains of any size).
2470 */
2471 mac_srs->srs_drain_func(mac_srs, SRS_PROC_FAST);
2472 }
2473 }
2474 mutex_exit(&mac_srs->srs_lock);
|