timer.c 2.3 KB

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