Skip to content

Commit 10ab564

Browse files
htejunIngo Molnar
authored andcommitted
sched/core: Separate out io_schedule_prepare() and io_schedule_finish()
Now that IO schedule accounting is done inside __schedule(), io_schedule() can be split into three steps - prep, schedule, and finish - where the schedule part doesn't need any special annotation. This allows marking a sleep as iowait by simply wrapping an existing blocking function with io_schedule_prepare() and io_schedule_finish(). Because task_struct->in_iowait is single bit, the caller of io_schedule_prepare() needs to record and the pass its state to io_schedule_finish() to be safe regarding nesting. While this isn't the prettiest, these functions are mostly gonna be used by core functions and we don't want to use more space for ->in_iowait. While at it, as it's simple to do now, reimplement io_schedule() without unnecessarily going through io_schedule_timeout(). Signed-off-by: Tejun Heo <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Mike Galbraith <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent e33a9bb commit 10ab564

File tree

2 files changed

+31
-10
lines changed

2 files changed

+31
-10
lines changed

include/linux/sched.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -461,12 +461,10 @@ extern signed long schedule_timeout_idle(signed long timeout);
461461
asmlinkage void schedule(void);
462462
extern void schedule_preempt_disabled(void);
463463

464+
extern int __must_check io_schedule_prepare(void);
465+
extern void io_schedule_finish(int token);
464466
extern long io_schedule_timeout(long timeout);
465-
466-
static inline void io_schedule(void)
467-
{
468-
io_schedule_timeout(MAX_SCHEDULE_TIMEOUT);
469-
}
467+
extern void io_schedule(void);
470468

471469
void __noreturn do_task_dead(void);
472470

kernel/sched/core.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5128,25 +5128,48 @@ int __sched yield_to(struct task_struct *p, bool preempt)
51285128
}
51295129
EXPORT_SYMBOL_GPL(yield_to);
51305130

5131+
int io_schedule_prepare(void)
5132+
{
5133+
int old_iowait = current->in_iowait;
5134+
5135+
current->in_iowait = 1;
5136+
blk_schedule_flush_plug(current);
5137+
5138+
return old_iowait;
5139+
}
5140+
5141+
void io_schedule_finish(int token)
5142+
{
5143+
current->in_iowait = token;
5144+
}
5145+
51315146
/*
51325147
* This task is about to go to sleep on IO. Increment rq->nr_iowait so
51335148
* that process accounting knows that this is a task in IO wait state.
51345149
*/
51355150
long __sched io_schedule_timeout(long timeout)
51365151
{
5137-
int old_iowait = current->in_iowait;
5152+
int token;
51385153
long ret;
51395154

5140-
current->in_iowait = 1;
5141-
blk_schedule_flush_plug(current);
5142-
5155+
token = io_schedule_prepare();
51435156
ret = schedule_timeout(timeout);
5144-
current->in_iowait = old_iowait;
5157+
io_schedule_finish(token);
51455158

51465159
return ret;
51475160
}
51485161
EXPORT_SYMBOL(io_schedule_timeout);
51495162

5163+
void io_schedule(void)
5164+
{
5165+
int token;
5166+
5167+
token = io_schedule_prepare();
5168+
schedule();
5169+
io_schedule_finish(token);
5170+
}
5171+
EXPORT_SYMBOL(io_schedule);
5172+
51505173
/**
51515174
* sys_sched_get_priority_max - return maximum RT priority.
51525175
* @policy: scheduling class.

0 commit comments

Comments
 (0)