/*1* linux/net/sunrpc/timer.c2*3* Estimate RPC request round trip time.4*5* Based on packet round-trip and variance estimator algorithms described6* in appendix A of "Congestion Avoidance and Control" by Van Jacobson7* and Michael J. Karels (ACM Computer Communication Review; Proceedings8* of the Sigcomm '88 Symposium in Stanford, CA, August, 1988).9*10* This RTT estimator is used only for RPC over datagram protocols.11*12* Copyright (C) 2002 Trond Myklebust <[email protected]>13*/1415#include <asm/param.h>1617#include <linux/types.h>18#include <linux/unistd.h>19#include <linux/module.h>2021#include <linux/sunrpc/clnt.h>2223#define RPC_RTO_MAX (60*HZ)24#define RPC_RTO_INIT (HZ/5)25#define RPC_RTO_MIN (HZ/10)2627/**28* rpc_init_rtt - Initialize an RPC RTT estimator context29* @rt: context to initialize30* @timeo: initial timeout value, in jiffies31*32*/33void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo)34{35unsigned long init = 0;36unsigned i;3738rt->timeo = timeo;3940if (timeo > RPC_RTO_INIT)41init = (timeo - RPC_RTO_INIT) << 3;42for (i = 0; i < 5; i++) {43rt->srtt[i] = init;44rt->sdrtt[i] = RPC_RTO_INIT;45rt->ntimeouts[i] = 0;46}47}48EXPORT_SYMBOL_GPL(rpc_init_rtt);4950/**51* rpc_update_rtt - Update an RPC RTT estimator context52* @rt: context to update53* @timer: timer array index (request type)54* @m: recent actual RTT, in jiffies55*56* NB: When computing the smoothed RTT and standard deviation,57* be careful not to produce negative intermediate results.58*/59void rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m)60{61long *srtt, *sdrtt;6263if (timer-- == 0)64return;6566/* jiffies wrapped; ignore this one */67if (m < 0)68return;6970if (m == 0)71m = 1L;7273srtt = (long *)&rt->srtt[timer];74m -= *srtt >> 3;75*srtt += m;7677if (m < 0)78m = -m;7980sdrtt = (long *)&rt->sdrtt[timer];81m -= *sdrtt >> 2;82*sdrtt += m;8384/* Set lower bound on the variance */85if (*sdrtt < RPC_RTO_MIN)86*sdrtt = RPC_RTO_MIN;87}88EXPORT_SYMBOL_GPL(rpc_update_rtt);8990/**91* rpc_calc_rto - Provide an estimated timeout value92* @rt: context to use for calculation93* @timer: timer array index (request type)94*95* Estimate RTO for an NFS RPC sent via an unreliable datagram. Use96* the mean and mean deviation of RTT for the appropriate type of RPC97* for frequently issued RPCs, and a fixed default for the others.98*99* The justification for doing "other" this way is that these RPCs100* happen so infrequently that timer estimation would probably be101* stale. Also, since many of these RPCs are non-idempotent, a102* conservative timeout is desired.103*104* getattr, lookup,105* read, write, commit - A+4D106* other - timeo107*/108unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned timer)109{110unsigned long res;111112if (timer-- == 0)113return rt->timeo;114115res = ((rt->srtt[timer] + 7) >> 3) + rt->sdrtt[timer];116if (res > RPC_RTO_MAX)117res = RPC_RTO_MAX;118119return res;120}121EXPORT_SYMBOL_GPL(rpc_calc_rto);122123124