timer.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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 <trond.myklebust@fys.uio.no>
  14. */
  15. #include <asm/param.h>
  16. #include <linux/types.h>
  17. #include <linux/unistd.h>
  18. #include <linux/sunrpc/clnt.h>
  19. #include <linux/sunrpc/xprt.h>
  20. #include <linux/sunrpc/timer.h>
  21. #define RPC_RTO_MAX (60*HZ)
  22. #define RPC_RTO_INIT (HZ/5)
  23. #define RPC_RTO_MIN (HZ/10)
  24. void
  25. rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo)
  26. {
  27. unsigned long init = 0;
  28. unsigned i;
  29. rt->timeo = timeo;
  30. if (timeo > RPC_RTO_INIT)
  31. init = (timeo - RPC_RTO_INIT) << 3;
  32. for (i = 0; i < 5; i++) {
  33. rt->srtt[i] = init;
  34. rt->sdrtt[i] = RPC_RTO_INIT;
  35. rt->ntimeouts[i] = 0;
  36. }
  37. }
  38. /*
  39. * NB: When computing the smoothed RTT and standard deviation,
  40. * be careful not to produce negative intermediate results.
  41. */
  42. void
  43. rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m)
  44. {
  45. long *srtt, *sdrtt;
  46. if (timer-- == 0)
  47. return;
  48. /* jiffies wrapped; ignore this one */
  49. if (m < 0)
  50. return;
  51. if (m == 0)
  52. m = 1L;
  53. srtt = (long *)&rt->srtt[timer];
  54. m -= *srtt >> 3;
  55. *srtt += m;
  56. if (m < 0)
  57. m = -m;
  58. sdrtt = (long *)&rt->sdrtt[timer];
  59. m -= *sdrtt >> 2;
  60. *sdrtt += m;
  61. /* Set lower bound on the variance */
  62. if (*sdrtt < RPC_RTO_MIN)
  63. *sdrtt = RPC_RTO_MIN;
  64. }
  65. /*
  66. * Estimate rto for an nfs rpc sent via. an unreliable datagram.
  67. * Use the mean and mean deviation of rtt for the appropriate type of rpc
  68. * for the frequent rpcs and a default for the others.
  69. * The justification for doing "other" this way is that these rpcs
  70. * happen so infrequently that timer est. would probably be stale.
  71. * Also, since many of these rpcs are
  72. * non-idempotent, a conservative timeout is desired.
  73. * getattr, lookup,
  74. * read, write, commit - A+4D
  75. * other - timeo
  76. */
  77. unsigned long
  78. rpc_calc_rto(struct rpc_rtt *rt, unsigned timer)
  79. {
  80. unsigned long res;
  81. if (timer-- == 0)
  82. return rt->timeo;
  83. res = ((rt->srtt[timer] + 7) >> 3) + rt->sdrtt[timer];
  84. if (res > RPC_RTO_MAX)
  85. res = RPC_RTO_MAX;
  86. return res;
  87. }