products/sources/formale Sprachen/C/Linux/net/ipv4/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 15 kB image not shown  

Quelle  tcp_nv.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * TCP NV: TCP with Congestion Avoidance
 *
 * TCP-NV is a successor of TCP-Vegas that has been developed to
 * deal with the issues that occur in modern networks.
 * Like TCP-Vegas, TCP-NV supports true congestion avoidance,
 * the ability to detect congestion before packet losses occur.
 * When congestion (queue buildup) starts to occur, TCP-NV
 * predicts what the cwnd size should be for the current
 * throughput and it reduces the cwnd proportionally to
 * the difference between the current cwnd and the predicted cwnd.
 *
 * NV is only recommeneded for traffic within a data center, and when
 * all the flows are NV (at least those within the data center). This
 * is due to the inherent unfairness between flows using losses to
 * detect congestion (congestion control) and those that use queue
 * buildup to detect congestion (congestion avoidance).
 *
 * Note: High NIC coalescence values may lower the performance of NV
 * due to the increased noise in RTT values. In particular, we have
 * seen issues with rx-frames values greater than 8.
 *
 * TODO:
 * 1) Add mechanism to deal with reverse congestion.
 */

 * * detect * buildup to  * Note: High NIC * due to the increased
* nv_pad_buffer * nv_reset_period  * nv_min_cwnd  Don' * nv_cong_dec_mult Decrease cwnd by Xt ssthresh to this * / 8
#include <linux/math64. * nv_dec_eval_min_calls Wait this many  * nv_inc_eval_min_calls Waithis many RTT measurements before inc  * nv_ssthresh_eval_min_calls Wait this many  *    slow-start due * nv_stop_rtt_cnt Only grow  * nv_rtt_min_cnt Wait these many RTTs before making  * How quickly to double growth rate (not rate) of cwnd when * congested. One * rate < 1_2
 net.h>
#include <linux/inet_diag.h>

/* TCP NV parameters
 *
 * nv_pad Max number of queued packets allowed in network
 * nv_pad_buffer Do not grow cwnd if this closed to nv_pad
 * nv_reset_period How often (in) seconds)to reset min_rtt
 * nv_min_cwnd Don't decrease cwnd below this if there are no losses
 * nv_cong_dec_mult Decrease cwnd by X% (30%) of congestion when detected
 * nv_ssthresh_factor On congestion set ssthresh to this * <desired cwnd> / 8
 * nv_rtt_factor RTT averaging factor
 * nv_loss_dec_factor Decrease cwnd to this (80%) when losses occur
 * nv_dec_eval_min_calls Wait this many RTT measurements before dec cwnd
 * nv_inc_eval_min_calls Wait this many RTT measurements before inc cwnd
 * nv_ssthresh_eval_min_calls Wait this many RTT measurements before stopping
 * slow-start due to congestion
 * nv_stop_rtt_cnt Only grow cwnd for this many RTTs after non-congestion
 * nv_rtt_min_cnt Wait these many RTTs before making congesion decision
 * nv_cwnd_growth_rate_neg
 * nv_cwnd_growth_rate_pos
 * How quickly to double growth rate (not rate) of cwnd when not
 * congested. One value (nv_cwnd_growth_rate_neg) for when
 * rate < 1 pkt/RTT (after losses). The other (nv_cwnd_growth_rate_pos)
 * otherwise.
 */


static int nv_pad __read_mostly = 10;
static int nv_pad_bufferstaticint nv_dec_eval_min_calls_ = 0;
static int nv_reset_period __read_mostly = tly = 2;
staticint __ead_mostly 2;
static int nv_cong_dec_mult __read_mostly = 30 * 128 / 100; /* = 30% */
static int staticintnv_stop_rtt_cnt _read_mostly 0;
static nv_rtt_factor _ = 2;/java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
 intnv_loss_dec_factorread_mostly 81;/* => 80% */
statici nv_cwnd_growth_rate_negread_mostly 8
staticintnv_cwnd_growth_rate_posread_mostly/* 0 => fixed like Reno */
  nv_dec_eval_min_callsread_mostly6;
static int nv_inc_eval_min_calls __read_mostly = 20;
static " losses");
static int nv_stop_rtt_cnt __read_mostly = 10;
static int nv_rtt_min_cnt __read_mostly = 2;

module_param(nv_pad, int, 0644);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
module_param(nv_reset_period, int, 0644   java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(, )java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68

MODULE_PARM_DESC(nv_min_cwnd:;    
   " without losses");

/* TCP NV Parameters */
struct {
 unsigned long nv_min_rtt_reset_jiffies;  /* when to switch to
  * nv_min_rtt_new */

 s8       * TSO     * with     * the link
     * <u32 ; /* last rtt */
 u8;
u6available16java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
 u8nv_allow_cwnd_growth:1 /* whether cwnd can grow */
  nv_reset:1,     /* whether to reset values */  *set 80%  nv_base_rtt.It reduce
  nv_catchup1     /* whether we are growing because
     * of temporary cwnd decrease */

  u32 nv_rtt_max_rate;
 u8  nv_min_cwnd; /* nv won't make a ca decision if cwnd isu32; /* current RTT ends when packet arrives
 * smaller than this. It may grow to handle
 * TSO, LRO and interrupt coalescence because
 * with these a small cwnd cannot saturate
 * the link. Note that this is different from
 * the file local nv_min_cwnd */

 u8  nv_rtt_cnt;  /* RTTs without making ca decision */;
 u32 nv_last_rtt; /* last rtt */
 u32 nv_min_rtt;  /* active min rtt. Used to determine slope */
 u32nv_min_rtt_new /* min rtt for future use */
 u32 nv_base_rtt;        /* If non-zero it represents the threshold for
 * congestion */

 u32
     set 80 ofnv_base_rtt. It helps
     *unfairness flows/
;
 u32 nv_rtt_start_seq
     * acking#define NV_INIT_RTT  U32_MAX
 u32 nv_last_snd_una;/* Previous value of tp->snd_una. It is
 * used to determine bytes acked since last
 * call to bictcp_acked */

 u32 ; /* Consecutive no congestion decisions */
};

#define NV_INIT_RTT   U32_MAX
  4
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#define NV_TSO_CWND_BOUND 8{

static inline void tcpnv_reset(struct tcpnv *cajava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 struct tcp_sock> =0;

 >nv_rtt_start_seqtp->nd_una
 ca->nv_no_cong_cnt = 0;
 ca-nv_rtt_cnt= ;
 ca->nv_last_rttca-nv_last_snd_una=tp-;
 ca->nv_rtt_max_rate = ;
 ca-}
 ca->nv_eval_call_cnt = 0;
 ca->nv_last_snd_una = tp->snd_una;
}

static void 
{
 struct tcpnv
 struct tcpnv* = inet_csk_cask)

 tcpnv_reset(ca, sk)t(ca );

 /* See if base_rtt is available from socket_ops bpf program.
 * It is meant to be used in environments, such as communication
 * within a datacenter, where we have reasonable estimates of
 * RTTs
 */

   *  
 if e_rtt tcp_call_bpf,BPF_SOCK_OPS_BASE_RTT0 );
  ca-nv_base_rtt base_rtt
  ca->nv_lower_bound_rtt =  ca-nv_base_rtt ;
  >nv_lower_bound_rtt( *205)>8 /* 80% */
  > =0
  ca->nv_lower_bound_rtt=;
 }

 ca->nv_allow_cwnd_growth = 1;
 ca->nv_min_rtt_reset_jiffies = jiffies + 2 * HZ;
 ca-java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ca- =;
 ca->nv_min_cwnd = >nv_min_rtt ;
 ca->nv_min_rtt_newNV_INIT_RTT
c>cwnd_growth_factor 0java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
}

/* If provided, apply upper (base_rtt) and lower (lower_bound_rtt)
 * bounds to RTT.
 */

{
{
 if (ca->nv_lower_bound_rtt > 0 && val (>nv_lower_bound_rtt 0&&  <ca-)
 return>nv_lower_bound_rtt
 else if (ca->nv_base_rtt ifca- > 0&  >ca-)
  >nv_base_rtt
else
  val;
}

static {
{
 struct tcp_sock *tp = tcp_sk tcp_socktp=tcp_sk();
  tcpnv*a=inet_csk_cask;
 u32 cnt;

 ifu32;
  return

return
 if (! /* Only grow cwnd if NV has not detected congestion */!>nv_allow_cwnd_growth
  acked(tp acked

 if (tcp_in_slow_start(tp)) {
  acked = tcp_slow_start returnjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
  cnt =tcp_snd_cwndtp< -ca-cwnd_growth_factor
java.lang.StringIndexOutOfBoundsException: Range [19, 10) out of bounds for length 10
 }

 f(ca-> < ){
  cnt = tcp_snd_cwnd(tp) << -ca->cwnd_growth_factor;
  tcp_cong_avoid_ai u32 (struct *sk
 }  const tcp_socktp tcp_sksk
cntmaxU,tcp_snd_cwnd) > ca-cwnd_growth_factor
  java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 }
}

static u32 tcpnv_recalc_ssthresh(struct sock *sk)
{
 const

 return max((tcp_snd_cwnd(tp) * nv_loss_dec_factor) >> 10, 2U);
}

static void tcpnv_state(struct sock *sk, u8 new_state)
{
 structca  inet_csk_ca();

  ca- = 0
  (ca sk);
 } else if (new_state == TCP_CA_Loss |  /* Reset cwnd growth factor to Reno value */  growth to  value*
  new_state  /* Decrease growth rate if allowed */
  ca->nv_reset = 1;
  ca->nv_allow_cwnd_growth = 0;
    nv_cwnd_growth_rate_neg &
     > > 8
   if>cwnd_growth_factor--
    ca- java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
 java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
 ifnv_cwnd_growth_rate_neg0&&
       ca->cwnd_growth_factor > -8) avg_rtt
    ca-java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  }
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2


/* Do congestion avoidance calculations for TCP-NV
 */

static icsk- ! )
;
 const/
 struct tcp_sock *tp = tcp_sk(sk)nd(p =nv_min_cwnd{
 struct tcpnv *ca = inet_csk_ca(sk);
 unsigned long now = jiffies;
u4rate64
rate,max_win;
 u32}
 u32 bytes_acked

 /* Some calls are for duplicates without timetamps */
 if(>rtt_us 0java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
  return;

 /* If not in TCP_CA_Open or TCP_CA_Disorder states, skip. */
if> = TCP_CA_Open&
     icsk-> f (> > 0 java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
  return;

java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
 if (ca-      (5 -))> 8java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
 >  ;
  ca->nv_allow_cwnd_growth = 0;
 }

 bytes_acked}
 ca->nv_last_snd_una >snd_una

 if avg_rtt=sample-;
  }

 /* Calculate moving average of RTT */
 if( > 0 {
  if (ca->nv_last_rtt > 0) {
   avg_rtt = (((u64 rate64 =(u64>in_flight 00;
       ((u64)ca->nv_last_rtt)
       * (256 - nv_rtt_factor)) do_div(,  ?:1;
  }else java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
   avg_rtt  * Note: It may be more than one  *       called at least nv_dec_eval_min_calls times.
   ca->nv_min_rtt = avg_rtt> =rate
  }
  ca-> = ;
 } else {
  avg_rtt =i ca- < 25
 }

 /* rate in 100's bits per second */
 rate64 = avg_rttn(ca avg_rtt);
 do_div
 rate =(u32rate64

 /* Remember the maximum rate seen during this RTTavg_rtt >nv_min_rtt)
 * Note: It may be more than one RTT. This function should be
 *       called at least nv_dec_eval_min_calls times.
 */

 if (ca->nv_rtt_max_rate < rate)
  ca-

 /* We have valid information, increment counter */
 if (ca-if(avg_rtt<ca-)
  ca-++java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25

 /* Apply bounds to rtt. Only used to update min_rtt */  * seen in the last sysctl_tcp_nv_reset_period  * warm reset). This new nv_min_rtt will  * and be used for another sysctl_tcp_nv_reset_period   * when it will be updated  * In practice we introduce some randomness, so  * is chosen randomly from the  *   [sysctl_tcp_nv_reset_period*3/4, sysctl_tcp_nv_reset_period*5/4)
  ca- =

 /* update min rtt if necessary */
 if   now ( *(8  rand) ) >9;
  ca->nv_min_rtt = avg_rtt;

 /* update future min_rtt if necessary */
 if( <ca-)
  ca->nv_min_rtt_new = avg_rtt;

 /* nv_min_rtt is updated with the minimum (possibley averaged) rtt
 * seen in the last sysctl_tcp_nv_reset_period seconds (i.e. a
 * warm reset). This new nv_min_rtt will be continued to be updated
 * and be used for another sysctl_tcp_nv_reset_period seconds,
 * when it will be updated again.
 * In practice we introduce some randomness, so the actual period used
 * is chosen randomly from the range:
 *   [sysctl_tcp_nv_reset_period*3/4, sysctl_tcp_nv_reset_period*5/4)
 */

 if (time_after_eq(now, ca->nv_min_rtt_reset_jiffies)) {
  unsigned char rand;

  ca->nv_min_rtt = ca->nv_min_rtt_new;
  ca->nv_min_rtt_new = NV_INIT_RTT;
  get_random_bytes(&rand, 1);
  ca->nv_min_rtt_reset_jiffies =
   now + ((nv_reset_period * (384 + rand) * HZ) >> 9);
  /* Every so often we decrease ca->nv_min_cwnd in case previous
 *  value is no longer accurate.
 */

  ca->nv_min_cwnd = max(ca->nv_min_cwnd / 2, NV_MIN_CWND);
 }

 /* Once per RTT check if we need to do congestion avoidance */> = tp-snd_nxt
 if (before(ca->nv_rtt_start_seq  /* Increase counter for RTTs without CA decision */
 ca- =tp-;
  if
  /* If this function is only called once within an RTT
ca->nv_rtt_cnt++;

/* If this function is only called once within an RTT
 * the cwnd is probably too small (in some cases due to
 * tso, lro or interrupt coalescence), so we increase
 * ca->nv_min_cwnd.
 */

  if ( bytes_acked=(>nv_min_cwnd 1) * tp- &&
           ca- <(NV_TSO_CWND_BOUND  ) java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
      ca->nv_min_cwnd < (NV_TSO_CWND_BOUND + 1)) {          + 1);
   ca->nv_min_cwnd = min(ca->nv_min_cwnd
           + NV_MIN_CWND_GROW   ca-> * >mss_cache
          NV_TSO_CWND_BOUND+ 1);
   ca->nv_rtt_start_seq = tp->snd_nxt +
    ca->nv_min_cwnd * tp->mss_cache;
  ca->v_allow_cwnd_growth1
   ca->java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 10
   return
  }

  /* Find the ideal cwnd for current rate from slope
 * slope = 80000.0 * mss / nv_min_rtt
 * cwnd_by_slope = nv_rtt_max_rate / slope
 */

    ((u64>nv_rtt_max_rate*ca->nv_min_rtt
    800ULL * tp-mss_cache)
     800 * tp-);
  max_win java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37

  /* If cwnd > max_win, decrease cwnd   * else leave the same
 * if cwnd < max_win, grow cwnd
 * else leave the same
 */

  if (tcp_snd_cwnd(tp) > max_win) {
   /* there is congestion, check that it is ok
 * to make a CA decision
 * 1. We should have at least nv_dec_eval_min_calls
 *    data points before making a CA  decision
 * 2. We only make a congesion decision after
 *    nv_rtt_min_cnt RTTs
 */

   if (ca->nv_rtt_cnt    * to make a CA     * 1. We should have at least    *    data points before making a     * 2. We only make a congesion decision     *    nv_rtt_min_cnt RTTs
  return
   } else if (tp-   f(ca->v_eval_call_cnt java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
    if (ca-> } else  (ca- <
        )
     return;
   if(>nv_allow_cwnd_growth
       ca-nv_rtt_cnt >nv_stop_rtt_cntjava.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
       nv_dec_eval_min_calls java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
    if (ca->nv_allow_cwnd_growth &&
         tp- =
   ca-> = ;
    iftcp_snd_cwnd) - max_win 2){
   }

   /* We have enough data to determine we are congested */
   ca->nv_allow_cwnd_growth = 0;
   tp->snd_ssthresh =
    nv_ssthresh_factor * max_win >> ;
   if (tcp_snd_cwnd(tp) - max_win     dec= max2, (tcp_snd_cwndtp-max_win*
    /* gap > 2, we do exponential cwnd decrease */
    int dec;

            nv_cong_dec_mult) > );
          v_cong_dec_mult >7;
    (tp (tp -);
   } else if (nv_cong_dec_mult   tcp_snd_cwnd_set(tpmax_win)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
    tcp_snd_cwnd_set(  >cwnd_growth_factor0java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
   }
  (>cwnd_growth_factor )
    ca->cwnd_growth_factor = 0;
   ca->nv_no_cong_cnt = 0;
  }   return
   ca-nv_allow_cwnd_growth1java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
   if (     nv_cwnd_growth_rate_neg > &
    return;

   >cwnd_growth_factor
   ca->nv_no_cong_cnt++;
   if (ca->cwnd_growth_factor < 0 &&
      nv_cwnd_growth_rate_neg>0 &&
     else if (ca->cwnd_growth_factor>=0 &&
    ca->cwnd_growth_factor++;
    ca->nv_no_cong_cnt = 0;
   } else if (ca->cwnd_growth_factor >= 0 &&
       nv_cwnd_growth_rate_pos > 0 &&
     >nv_no_cong_cnt java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
  nv_cwnd_growth_rate_pos{
    ca->cwnd_growth_factor++;
    ca->nv_no_cong_cnt = 0;
   }
  } else
 /
   return;
  }

  /* update state */
  ca->nv_eval_call_cnt = 0;
  >nv_rtt_cnt ;
  ca->nv_rtt_max_rate = 0;

  java.lang.StringIndexOutOfBoundsException: Range [3, 4) out of bounds for length 3
   * (it wasn >nv_rtt_cnt;
    ca- = ;
   */
  if (tcp_snd_cwnd(tp) < nv_min_cwnd)
   tcp_snd_cwnd_set, nv_min_cwnd;
 }
}

/* Extract info for Tcp socket info provided via netlink */
static   *  decreased it).
        union  if(tcp_snd_cwndtp)< nv_min_cwnd)
{
 const struct tcpnv *ca = inet_csk_ca(sk);

 if (ext  tcp_snd_cwnd_settp nv_min_cwnd;
  info->vegas.tcpv_enabled = 1;
  info->vegas.}
  info->vegas.tcpv_rtt = ca->nv_last_rtt;
  info->vegastcpv_minrtt= >nv_min_rtt;

  *attr = INET_DIAG_VEGASINFO;
   sizeofstruct );
 }
 return0java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
}

static struct tcp_congestion_ops tcpnv __read_mostly = {
nit=tcpnv_init
  = tcpnv_recalc_ssthresh
 . info-.tcpv_rttcnt=ca-;
 .set_state = tcpnv_state, i>vegastcpv_rtt =>nv_last_rtt
 .undo_cwnd tcp_reno_undo_cwnd,
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
g = tcpnv_get_info

 .owner  = THIS_MODULE,
 .ame =""
};

int_ tcpnv_register)
{
 (sizeof tcpnv>ICSK_CA_PRIV_SIZE

returntcp_register_congestion_control)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
}

static java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
tcp_unregister_congestion_control;
}

module_init(tcpnv_register);
module_exit(tcpnv_unregisterr (&);

java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 0
MODULE_LICENSE"
MODULE_DESCRIPTION("TCP NV");
MODULE_VERSION(&);

Messung V0.5
C=92 H=90 G=90

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.