Print this page
1925 stack overflow from mac code


   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);