Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
timer.c
Go to the documentation of this file.
1 /*
2  * linux/net/sunrpc/timer.c
3  *
4  * Estimate RPC request round trip time.
5  *
6  * Based on packet round-trip and variance estimator algorithms described
7  * in appendix A of "Congestion Avoidance and Control" by Van Jacobson
8  * and Michael J. Karels (ACM Computer Communication Review; Proceedings
9  * of the Sigcomm '88 Symposium in Stanford, CA, August, 1988).
10  *
11  * This RTT estimator is used only for RPC over datagram protocols.
12  *
13  * Copyright (C) 2002 Trond Myklebust <[email protected]>
14  */
15 
16 #include <asm/param.h>
17 
18 #include <linux/types.h>
19 #include <linux/unistd.h>
20 #include <linux/module.h>
21 
22 #include <linux/sunrpc/clnt.h>
23 
24 #define RPC_RTO_MAX (60*HZ)
25 #define RPC_RTO_INIT (HZ/5)
26 #define RPC_RTO_MIN (HZ/10)
27 
34 void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo)
35 {
36  unsigned long init = 0;
37  unsigned int i;
38 
39  rt->timeo = timeo;
40 
41  if (timeo > RPC_RTO_INIT)
42  init = (timeo - RPC_RTO_INIT) << 3;
43  for (i = 0; i < 5; i++) {
44  rt->srtt[i] = init;
45  rt->sdrtt[i] = RPC_RTO_INIT;
46  rt->ntimeouts[i] = 0;
47  }
48 }
50 
60 void rpc_update_rtt(struct rpc_rtt *rt, unsigned int timer, long m)
61 {
62  long *srtt, *sdrtt;
63 
64  if (timer-- == 0)
65  return;
66 
67  /* jiffies wrapped; ignore this one */
68  if (m < 0)
69  return;
70 
71  if (m == 0)
72  m = 1L;
73 
74  srtt = (long *)&rt->srtt[timer];
75  m -= *srtt >> 3;
76  *srtt += m;
77 
78  if (m < 0)
79  m = -m;
80 
81  sdrtt = (long *)&rt->sdrtt[timer];
82  m -= *sdrtt >> 2;
83  *sdrtt += m;
84 
85  /* Set lower bound on the variance */
86  if (*sdrtt < RPC_RTO_MIN)
87  *sdrtt = RPC_RTO_MIN;
88 }
90 
109 unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned int timer)
110 {
111  unsigned long res;
112 
113  if (timer-- == 0)
114  return rt->timeo;
115 
116  res = ((rt->srtt[timer] + 7) >> 3) + rt->sdrtt[timer];
117  if (res > RPC_RTO_MAX)
118  res = RPC_RTO_MAX;
119 
120  return res;
121 }