0001
0002
0003
0004
0005
0006
0007 #ifndef DM_IO_TRACKER_H
0008 #define DM_IO_TRACKER_H
0009
0010 #include <linux/jiffies.h>
0011
0012 struct dm_io_tracker {
0013 spinlock_t lock;
0014
0015
0016
0017
0018 sector_t in_flight;
0019
0020
0021
0022
0023
0024 unsigned long idle_time;
0025 unsigned long last_update_time;
0026 };
0027
0028 static inline void dm_iot_init(struct dm_io_tracker *iot)
0029 {
0030 spin_lock_init(&iot->lock);
0031 iot->in_flight = 0ul;
0032 iot->idle_time = 0ul;
0033 iot->last_update_time = jiffies;
0034 }
0035
0036 static inline bool dm_iot_idle_for(struct dm_io_tracker *iot, unsigned long j)
0037 {
0038 bool r = false;
0039
0040 spin_lock_irq(&iot->lock);
0041 if (!iot->in_flight)
0042 r = time_after(jiffies, iot->idle_time + j);
0043 spin_unlock_irq(&iot->lock);
0044
0045 return r;
0046 }
0047
0048 static inline unsigned long dm_iot_idle_time(struct dm_io_tracker *iot)
0049 {
0050 unsigned long r = 0;
0051
0052 spin_lock_irq(&iot->lock);
0053 if (!iot->in_flight)
0054 r = jiffies - iot->idle_time;
0055 spin_unlock_irq(&iot->lock);
0056
0057 return r;
0058 }
0059
0060 static inline void dm_iot_io_begin(struct dm_io_tracker *iot, sector_t len)
0061 {
0062 spin_lock_irq(&iot->lock);
0063 iot->in_flight += len;
0064 spin_unlock_irq(&iot->lock);
0065 }
0066
0067 static inline void dm_iot_io_end(struct dm_io_tracker *iot, sector_t len)
0068 {
0069 unsigned long flags;
0070
0071 if (!len)
0072 return;
0073
0074 spin_lock_irqsave(&iot->lock, flags);
0075 iot->in_flight -= len;
0076 if (!iot->in_flight)
0077 iot->idle_time = jiffies;
0078 spin_unlock_irqrestore(&iot->lock, flags);
0079 }
0080
0081 #endif