![]() |
|
|||
0001 // SPDX-License-Identifier: GPL-2.0-only 0002 /* 0003 * linux/net/sunrpc/timer.c 0004 * 0005 * Estimate RPC request round trip time. 0006 * 0007 * Based on packet round-trip and variance estimator algorithms described 0008 * in appendix A of "Congestion Avoidance and Control" by Van Jacobson 0009 * and Michael J. Karels (ACM Computer Communication Review; Proceedings 0010 * of the Sigcomm '88 Symposium in Stanford, CA, August, 1988). 0011 * 0012 * This RTT estimator is used only for RPC over datagram protocols. 0013 * 0014 * Copyright (C) 2002 Trond Myklebust <trond.myklebust@fys.uio.no> 0015 */ 0016 0017 #include <asm/param.h> 0018 0019 #include <linux/types.h> 0020 #include <linux/unistd.h> 0021 #include <linux/module.h> 0022 0023 #include <linux/sunrpc/clnt.h> 0024 0025 #define RPC_RTO_MAX (60*HZ) 0026 #define RPC_RTO_INIT (HZ/5) 0027 #define RPC_RTO_MIN (HZ/10) 0028 0029 /** 0030 * rpc_init_rtt - Initialize an RPC RTT estimator context 0031 * @rt: context to initialize 0032 * @timeo: initial timeout value, in jiffies 0033 * 0034 */ 0035 void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo) 0036 { 0037 unsigned long init = 0; 0038 unsigned int i; 0039 0040 rt->timeo = timeo; 0041 0042 if (timeo > RPC_RTO_INIT) 0043 init = (timeo - RPC_RTO_INIT) << 3; 0044 for (i = 0; i < 5; i++) { 0045 rt->srtt[i] = init; 0046 rt->sdrtt[i] = RPC_RTO_INIT; 0047 rt->ntimeouts[i] = 0; 0048 } 0049 } 0050 EXPORT_SYMBOL_GPL(rpc_init_rtt); 0051 0052 /** 0053 * rpc_update_rtt - Update an RPC RTT estimator context 0054 * @rt: context to update 0055 * @timer: timer array index (request type) 0056 * @m: recent actual RTT, in jiffies 0057 * 0058 * NB: When computing the smoothed RTT and standard deviation, 0059 * be careful not to produce negative intermediate results. 0060 */ 0061 void rpc_update_rtt(struct rpc_rtt *rt, unsigned int timer, long m) 0062 { 0063 long *srtt, *sdrtt; 0064 0065 if (timer-- == 0) 0066 return; 0067 0068 /* jiffies wrapped; ignore this one */ 0069 if (m < 0) 0070 return; 0071 0072 if (m == 0) 0073 m = 1L; 0074 0075 srtt = (long *)&rt->srtt[timer]; 0076 m -= *srtt >> 3; 0077 *srtt += m; 0078 0079 if (m < 0) 0080 m = -m; 0081 0082 sdrtt = (long *)&rt->sdrtt[timer]; 0083 m -= *sdrtt >> 2; 0084 *sdrtt += m; 0085 0086 /* Set lower bound on the variance */ 0087 if (*sdrtt < RPC_RTO_MIN) 0088 *sdrtt = RPC_RTO_MIN; 0089 } 0090 EXPORT_SYMBOL_GPL(rpc_update_rtt); 0091 0092 /** 0093 * rpc_calc_rto - Provide an estimated timeout value 0094 * @rt: context to use for calculation 0095 * @timer: timer array index (request type) 0096 * 0097 * Estimate RTO for an NFS RPC sent via an unreliable datagram. Use 0098 * the mean and mean deviation of RTT for the appropriate type of RPC 0099 * for frequently issued RPCs, and a fixed default for the others. 0100 * 0101 * The justification for doing "other" this way is that these RPCs 0102 * happen so infrequently that timer estimation would probably be 0103 * stale. Also, since many of these RPCs are non-idempotent, a 0104 * conservative timeout is desired. 0105 * 0106 * getattr, lookup, 0107 * read, write, commit - A+4D 0108 * other - timeo 0109 */ 0110 unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned int timer) 0111 { 0112 unsigned long res; 0113 0114 if (timer-- == 0) 0115 return rt->timeo; 0116 0117 res = ((rt->srtt[timer] + 7) >> 3) + rt->sdrtt[timer]; 0118 if (res > RPC_RTO_MAX) 0119 res = RPC_RTO_MAX; 0120 0121 return res; 0122 } 0123 EXPORT_SYMBOL_GPL(rpc_calc_rto);
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |