Print this page
re #13613 rb4516 Tunables needs volatile keyword


   4  * The contents of this file are subject to the terms of the
   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 /*
  23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.

  24  */
  25 
  26 #include <sys/types.h>
  27 #include <sys/strlog.h>
  28 #include <sys/policy.h>
  29 #include <sys/strsun.h>
  30 #include <sys/squeue_impl.h>
  31 #include <sys/squeue.h>

  32 
  33 #include <inet/common.h>
  34 #include <inet/ip.h>
  35 #include <inet/tcp.h>
  36 #include <inet/tcp_impl.h>
  37 
  38 /* Control whether TCP can enter defensive mode when under memory pressure. */
  39 static boolean_t tcp_do_reclaim = B_TRUE;
  40 
  41 /*
  42  * Routines related to the TCP_IOC_ABORT_CONN ioctl command.
  43  *
  44  * TCP_IOC_ABORT_CONN is a non-transparent ioctl command used for aborting
  45  * TCP connections. To invoke this ioctl, a tcp_ioc_abort_conn_t structure
  46  * (defined in tcp.h) needs to be filled in and passed into the kernel
  47  * via an I_STR ioctl command (see streamio(7I)). The tcp_ioc_abort_conn_t
  48  * structure contains the four-tuple of a TCP connection and a range of TCP
  49  * states (specified by ac_start and ac_end). The use of wildcard addresses
  50  * and ports is allowed. Connections with a matching four tuple and a state
  51  * within the specified range will be aborted. The valid states for the


 487         if (mp1 != NULL) {
 488                 freemsg(mp1);
 489                 mp->b_cont = NULL;
 490         }
 491 
 492         if (err != 0)
 493                 miocnak(q, mp, 0, err);
 494         else
 495                 miocack(q, mp, 0, 0);
 496 }
 497 
 498 /*
 499  * Timeout function to reset the TCP stack variable tcps_reclaim to false.
 500  */
 501 void
 502 tcp_reclaim_timer(void *arg)
 503 {
 504         tcp_stack_t *tcps = (tcp_stack_t *)arg;
 505         int64_t tot_conn = 0;
 506         int i;
 507         extern pgcnt_t lotsfree, needfree;
 508 
 509         for (i = 0; i < tcps->tcps_sc_cnt; i++)
 510                 tot_conn += tcps->tcps_sc[i]->tcp_sc_conn_cnt;
 511 
 512         /*
 513          * This happens only when a stack is going away.  tcps_reclaim_tid
 514          * should not be reset to 0 when returning in this case.
 515          */
 516         mutex_enter(&tcps->tcps_reclaim_lock);
 517         if (!tcps->tcps_reclaim) {
 518                 mutex_exit(&tcps->tcps_reclaim_lock);
 519                 return;
 520         }
 521 
 522         if ((freemem >= lotsfree + needfree) || tot_conn < maxusers) {
 523                 tcps->tcps_reclaim = B_FALSE;
 524                 tcps->tcps_reclaim_tid = 0;
 525         } else {
 526                 /* Stay in defensive mode and restart the timer */
 527                 tcps->tcps_reclaim_tid = timeout(tcp_reclaim_timer,


 529         }
 530         mutex_exit(&tcps->tcps_reclaim_lock);
 531 }
 532 
 533 /*
 534  * Kmem reclaim call back function.  When the system is under memory
 535  * pressure, we set the TCP stack variable tcps_reclaim to true.  This
 536  * variable is reset to false after tcps_reclaim_period msecs.  During this
 537  * period, TCP will be more aggressive in aborting connections not making
 538  * progress, meaning retransmitting for some time (tcp_early_abort seconds).
 539  * TCP will also not accept new connection request for those listeners whose
 540  * q or q0 is not empty.
 541  */
 542 /* ARGSUSED */
 543 void
 544 tcp_conn_reclaim(void *arg)
 545 {
 546         netstack_handle_t nh;
 547         netstack_t *ns;
 548         tcp_stack_t *tcps;
 549         extern pgcnt_t lotsfree, needfree;
 550 
 551         if (!tcp_do_reclaim)
 552                 return;
 553 
 554         /*
 555          * The reclaim function may be called even when the system is not
 556          * really under memory pressure.
 557          */
 558         if (freemem >= lotsfree + needfree)
 559                 return;
 560 
 561         netstack_next_init(&nh);
 562         while ((ns = netstack_next(&nh)) != NULL) {
 563                 int i;
 564                 int64_t tot_conn = 0;
 565 
 566                 /*
 567                  * During boot time, the first netstack_t is created and
 568                  * initialized before TCP has registered with the netstack
 569                  * framework.  If this reclaim function is called before TCP




   4  * The contents of this file are subject to the terms of the
   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 /*
  23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/strlog.h>
  29 #include <sys/policy.h>
  30 #include <sys/strsun.h>
  31 #include <sys/squeue_impl.h>
  32 #include <sys/squeue.h>
  33 #include <sys/vmsystm.h>
  34 
  35 #include <inet/common.h>
  36 #include <inet/ip.h>
  37 #include <inet/tcp.h>
  38 #include <inet/tcp_impl.h>
  39 
  40 /* Control whether TCP can enter defensive mode when under memory pressure. */
  41 static boolean_t tcp_do_reclaim = B_TRUE;
  42 
  43 /*
  44  * Routines related to the TCP_IOC_ABORT_CONN ioctl command.
  45  *
  46  * TCP_IOC_ABORT_CONN is a non-transparent ioctl command used for aborting
  47  * TCP connections. To invoke this ioctl, a tcp_ioc_abort_conn_t structure
  48  * (defined in tcp.h) needs to be filled in and passed into the kernel
  49  * via an I_STR ioctl command (see streamio(7I)). The tcp_ioc_abort_conn_t
  50  * structure contains the four-tuple of a TCP connection and a range of TCP
  51  * states (specified by ac_start and ac_end). The use of wildcard addresses
  52  * and ports is allowed. Connections with a matching four tuple and a state
  53  * within the specified range will be aborted. The valid states for the


 489         if (mp1 != NULL) {
 490                 freemsg(mp1);
 491                 mp->b_cont = NULL;
 492         }
 493 
 494         if (err != 0)
 495                 miocnak(q, mp, 0, err);
 496         else
 497                 miocack(q, mp, 0, 0);
 498 }
 499 
 500 /*
 501  * Timeout function to reset the TCP stack variable tcps_reclaim to false.
 502  */
 503 void
 504 tcp_reclaim_timer(void *arg)
 505 {
 506         tcp_stack_t *tcps = (tcp_stack_t *)arg;
 507         int64_t tot_conn = 0;
 508         int i;

 509 
 510         for (i = 0; i < tcps->tcps_sc_cnt; i++)
 511                 tot_conn += tcps->tcps_sc[i]->tcp_sc_conn_cnt;
 512 
 513         /*
 514          * This happens only when a stack is going away.  tcps_reclaim_tid
 515          * should not be reset to 0 when returning in this case.
 516          */
 517         mutex_enter(&tcps->tcps_reclaim_lock);
 518         if (!tcps->tcps_reclaim) {
 519                 mutex_exit(&tcps->tcps_reclaim_lock);
 520                 return;
 521         }
 522 
 523         if ((freemem >= lotsfree + needfree) || tot_conn < maxusers) {
 524                 tcps->tcps_reclaim = B_FALSE;
 525                 tcps->tcps_reclaim_tid = 0;
 526         } else {
 527                 /* Stay in defensive mode and restart the timer */
 528                 tcps->tcps_reclaim_tid = timeout(tcp_reclaim_timer,


 530         }
 531         mutex_exit(&tcps->tcps_reclaim_lock);
 532 }
 533 
 534 /*
 535  * Kmem reclaim call back function.  When the system is under memory
 536  * pressure, we set the TCP stack variable tcps_reclaim to true.  This
 537  * variable is reset to false after tcps_reclaim_period msecs.  During this
 538  * period, TCP will be more aggressive in aborting connections not making
 539  * progress, meaning retransmitting for some time (tcp_early_abort seconds).
 540  * TCP will also not accept new connection request for those listeners whose
 541  * q or q0 is not empty.
 542  */
 543 /* ARGSUSED */
 544 void
 545 tcp_conn_reclaim(void *arg)
 546 {
 547         netstack_handle_t nh;
 548         netstack_t *ns;
 549         tcp_stack_t *tcps;

 550 
 551         if (!tcp_do_reclaim)
 552                 return;
 553 
 554         /*
 555          * The reclaim function may be called even when the system is not
 556          * really under memory pressure.
 557          */
 558         if (freemem >= lotsfree + needfree)
 559                 return;
 560 
 561         netstack_next_init(&nh);
 562         while ((ns = netstack_next(&nh)) != NULL) {
 563                 int i;
 564                 int64_t tot_conn = 0;
 565 
 566                 /*
 567                  * During boot time, the first netstack_t is created and
 568                  * initialized before TCP has registered with the netstack
 569                  * framework.  If this reclaim function is called before TCP