timer.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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/module.h>
  19. #include <linux/sunrpc/clnt.h>
  20. #define RPC_RTO_MAX (60*HZ)
  21. #define RPC_RTO_INIT (HZ/5)
  22. #define RPC_RTO_MIN (HZ/10)
  23. void
  24. rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo)
  25. {
  26. unsigned long init = 0;
  27. unsigned i;
  28. rt->timeo = timeo;
  29. if (timeo > RPC_RTO_INIT)
  30. init = (timeo - RPC_RTO_INIT) << 3;
  31. for (i = 0; i < 5; i++) {
  32. rt->srtt[i] = init;
  33. rt->sdrtt[i] = RPC_RTO_INIT;
  34. rt->ntimeouts[i] = 0;
  35. }
  36. }
  37. EXPORT_SYMBOL_GPL(rpc_init_rtt);
  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. EXPORT_SYMBOL_GPL(rpc_update_rtt);
  66. /*
  67. * Estimate rto for an nfs rpc sent via. an unreliable datagram.
  68. * Use the mean and mean deviation of rtt for the appropriate type of rpc
  69. * for the frequent rpcs and a default for the others.
  70. * The justification for doing "other" this way is that these rpcs
  71. * happen so infrequently that timer est. would probably be stale.
  72. * Also, since many of these rpcs are
  73. * non-idempotent, a conservative timeout is desired.
  74. * getattr, lookup,
  75. * read, write, commit - A+4D
  76. * other - timeo
  77. */
  78. unsigned long
  79. rpc_calc_rto(struct rpc_rtt *rt, unsigned timer)
  80. {
  81. unsigned long res;
  82. if (timer-- == 0)
  83. return rt->timeo;
  84. res = ((rt->srtt[timer] + 7) >> 3) + rt->sdrtt[timer];
  85. if (res > RPC_RTO_MAX)
  86. res = RPC_RTO_MAX;
  87. return res;
  88. }
  89. EXPORT_SYMBOL_GPL(rpc_calc_rto);