Before commit: e33a9bba85a8 ("sched/core: move IO scheduling accounting from io_schedule_timeout() into scheduler") delayacct_blkio_end() was called after context-switching into the task which completed I/O. This resulted in double counting: the task would account a delay both waiting for I/O and for time spent in the runqueue. With e33a9bba85a8, delayacct_blkio_end() is called by try_to_wake_up(). In ttwu, we have not yet context-switched. This is more correct, in that the delay accounting ends when the I/O is complete. But delayacct_blkio_end() relies on 'get_current()', and we have not yet context-switched into the task whose I/O completed. This results in the wrong task having its delay accounting statistics updated. Instead of doing that, pass the task_struct being woken to delayacct_blkio_end(), so that it can update the statistics of the correct task.
Showing the changes to include/linux (1 of 3 files). Show all
Unified · Split
| @@ -71,7 +71,7 @@ extern void delayacct_init(void); · 70 unmodified lines | ||
| 71 | 71 | extern void __delayacct_tsk_init(struct task_struct *); |
| 72 | 72 | extern void __delayacct_tsk_exit(struct task_struct *); |
| 73 | 73 | extern void __delayacct_blkio_start(void); |
| 74 | −extern void __delayacct_blkio_end(void); | |
| 74 | +extern void __delayacct_blkio_end(struct task_struct *); | |
| 75 | 75 | extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *); |
| 76 | 76 | extern __u64 __delayacct_blkio_ticks(struct task_struct *); |
| 77 | 77 | extern void __delayacct_freepages_start(void); |
| @@ -122,10 +122,10 @@ static inline void delayacct_blkio_start(void) · 44 unmodified lines | ||
| 122 | 122 | __delayacct_blkio_start(); |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | −static inline void delayacct_blkio_end(void) | |
| 125 | +static inline void delayacct_blkio_end(struct task_struct *p) | |
| 126 | 126 | { |
| 127 | 127 | if (current->delays) |
| 128 | − __delayacct_blkio_end(); | |
| 128 | + __delayacct_blkio_end(p); | |
| 129 | 129 | delayacct_clear_flag(DELAYACCT_PF_BLKIO); |
| 130 | 130 | } |
| 131 | 131 | |
| @@ -169,7 +169,7 @@ static inline void delayacct_tsk_free(struct task_struct *tsk) · 37 unmodified lines | ||
| 169 | 169 | {} |
| 170 | 170 | static inline void delayacct_blkio_start(void) |
| 171 | 171 | {} |
| 172 | −static inline void delayacct_blkio_end(void) | |
| 172 | +static inline void delayacct_blkio_end(struct task_struct *p) | |
| 173 | 173 | {} |
| 174 | 174 | static inline int delayacct_add_tsk(struct taskstats *d, |
| 175 | 175 | struct task_struct *tsk) |