dim.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
  2. /*
  3. * Copyright (c) 2019, Mellanox Technologies inc. All rights reserved.
  4. */
  5. #include <linux/dim.h>
  6. bool dim_on_top(struct dim *dim)
  7. {
  8. switch (dim->tune_state) {
  9. case DIM_PARKING_ON_TOP:
  10. case DIM_PARKING_TIRED:
  11. return true;
  12. case DIM_GOING_RIGHT:
  13. return (dim->steps_left > 1) && (dim->steps_right == 1);
  14. default: /* DIM_GOING_LEFT */
  15. return (dim->steps_right > 1) && (dim->steps_left == 1);
  16. }
  17. }
  18. EXPORT_SYMBOL(dim_on_top);
  19. void dim_turn(struct dim *dim)
  20. {
  21. switch (dim->tune_state) {
  22. case DIM_PARKING_ON_TOP:
  23. case DIM_PARKING_TIRED:
  24. break;
  25. case DIM_GOING_RIGHT:
  26. dim->tune_state = DIM_GOING_LEFT;
  27. dim->steps_left = 0;
  28. break;
  29. case DIM_GOING_LEFT:
  30. dim->tune_state = DIM_GOING_RIGHT;
  31. dim->steps_right = 0;
  32. break;
  33. }
  34. }
  35. EXPORT_SYMBOL(dim_turn);
  36. void dim_park_on_top(struct dim *dim)
  37. {
  38. dim->steps_right = 0;
  39. dim->steps_left = 0;
  40. dim->tired = 0;
  41. dim->tune_state = DIM_PARKING_ON_TOP;
  42. }
  43. EXPORT_SYMBOL(dim_park_on_top);
  44. void dim_park_tired(struct dim *dim)
  45. {
  46. dim->steps_right = 0;
  47. dim->steps_left = 0;
  48. dim->tune_state = DIM_PARKING_TIRED;
  49. }
  50. EXPORT_SYMBOL(dim_park_tired);
  51. bool dim_calc_stats(const struct dim_sample *start,
  52. const struct dim_sample *end,
  53. struct dim_stats *curr_stats)
  54. {
  55. /* u32 holds up to 71 minutes, should be enough */
  56. u32 delta_us = ktime_us_delta(end->time, start->time);
  57. u32 npkts = BIT_GAP(BITS_PER_TYPE(u32), end->pkt_ctr, start->pkt_ctr);
  58. u32 nbytes = BIT_GAP(BITS_PER_TYPE(u32), end->byte_ctr,
  59. start->byte_ctr);
  60. u32 ncomps = BIT_GAP(BITS_PER_TYPE(u32), end->comp_ctr,
  61. start->comp_ctr);
  62. if (!delta_us)
  63. return false;
  64. curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
  65. curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
  66. curr_stats->epms = DIV_ROUND_UP(DIM_NEVENTS * USEC_PER_MSEC,
  67. delta_us);
  68. curr_stats->cpms = DIV_ROUND_UP(ncomps * USEC_PER_MSEC, delta_us);
  69. if (curr_stats->epms != 0)
  70. curr_stats->cpe_ratio = DIV_ROUND_DOWN_ULL(
  71. curr_stats->cpms * 100, curr_stats->epms);
  72. else
  73. curr_stats->cpe_ratio = 0;
  74. return true;
  75. }
  76. EXPORT_SYMBOL(dim_calc_stats);
  77. MODULE_DESCRIPTION("Dynamic Interrupt Moderation (DIM) library");
  78. MODULE_LICENSE("Dual BSD/GPL");