dm-io-tracker.h 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. * Copyright (C) 2021 Red Hat, Inc. All rights reserved.
  3. *
  4. * This file is released under the GPL.
  5. */
  6. #ifndef DM_IO_TRACKER_H
  7. #define DM_IO_TRACKER_H
  8. #include <linux/jiffies.h>
  9. struct dm_io_tracker {
  10. spinlock_t lock;
  11. /*
  12. * Sectors of in-flight IO.
  13. */
  14. sector_t in_flight;
  15. /*
  16. * The time, in jiffies, when this device became idle
  17. * (if it is indeed idle).
  18. */
  19. unsigned long idle_time;
  20. unsigned long last_update_time;
  21. };
  22. static inline void dm_iot_init(struct dm_io_tracker *iot)
  23. {
  24. spin_lock_init(&iot->lock);
  25. iot->in_flight = 0ul;
  26. iot->idle_time = 0ul;
  27. iot->last_update_time = jiffies;
  28. }
  29. static inline bool dm_iot_idle_for(struct dm_io_tracker *iot, unsigned long j)
  30. {
  31. bool r = false;
  32. spin_lock_irq(&iot->lock);
  33. if (!iot->in_flight)
  34. r = time_after(jiffies, iot->idle_time + j);
  35. spin_unlock_irq(&iot->lock);
  36. return r;
  37. }
  38. static inline unsigned long dm_iot_idle_time(struct dm_io_tracker *iot)
  39. {
  40. unsigned long r = 0;
  41. spin_lock_irq(&iot->lock);
  42. if (!iot->in_flight)
  43. r = jiffies - iot->idle_time;
  44. spin_unlock_irq(&iot->lock);
  45. return r;
  46. }
  47. static inline void dm_iot_io_begin(struct dm_io_tracker *iot, sector_t len)
  48. {
  49. spin_lock_irq(&iot->lock);
  50. iot->in_flight += len;
  51. spin_unlock_irq(&iot->lock);
  52. }
  53. static inline void dm_iot_io_end(struct dm_io_tracker *iot, sector_t len)
  54. {
  55. unsigned long flags;
  56. if (!len)
  57. return;
  58. spin_lock_irqsave(&iot->lock, flags);
  59. iot->in_flight -= len;
  60. if (!iot->in_flight)
  61. iot->idle_time = jiffies;
  62. spin_unlock_irqrestore(&iot->lock, flags);
  63. }
  64. #endif