Skip to content

Commit

Permalink
[PATCH] per-task-delay-accounting: sync block I/O and swapin delay co…
Browse files Browse the repository at this point in the history
…llection

Unlike earlier iterations of the delay accounting patches, now delays are only
collected for the actual I/O waits rather than try and cover the delays seen
in I/O submission paths.

Account separately for block I/O delays incurred as a result of swapin page
faults whose frequency can be affected by the task/process' rss limit.  Hence
swapin delays can act as feedback for rss limit changes independent of I/O
priority changes.

Signed-off-by: Shailabh Nagar <[email protected]>
Signed-off-by: Balbir Singh <[email protected]>
Cc: Jes Sorensen <[email protected]>
Cc: Peter Chubb <[email protected]>
Cc: Erich Focht <[email protected]>
Cc: Levent Serinol <[email protected]>
Cc: Jay Lan <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Shailabh Nagar authored and Linus Torvalds committed Jul 15, 2006
1 parent ca74e92 commit 0ff9224
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 0 deletions.
25 changes: 25 additions & 0 deletions include/linux/delayacct.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,22 @@

#include <linux/sched.h>

/*
* Per-task flags relevant to delay accounting
* maintained privately to avoid exhausting similar flags in sched.h:PF_*
* Used to set current->delays->flags
*/
#define DELAYACCT_PF_SWAPIN 0x00000001 /* I am doing a swapin */

#ifdef CONFIG_TASK_DELAY_ACCT

extern int delayacct_on; /* Delay accounting turned on/off */
extern kmem_cache_t *delayacct_cache;
extern void delayacct_init(void);
extern void __delayacct_tsk_init(struct task_struct *);
extern void __delayacct_tsk_exit(struct task_struct *);
extern void __delayacct_blkio_start(void);
extern void __delayacct_blkio_end(void);

static inline void delayacct_set_flag(int flag)
{
Expand Down Expand Up @@ -53,6 +62,18 @@ static inline void delayacct_tsk_exit(struct task_struct *tsk)
__delayacct_tsk_exit(tsk);
}

static inline void delayacct_blkio_start(void)
{
if (current->delays)
__delayacct_blkio_start();
}

static inline void delayacct_blkio_end(void)
{
if (current->delays)
__delayacct_blkio_end();
}

#else
static inline void delayacct_set_flag(int flag)
{}
Expand All @@ -64,6 +85,10 @@ static inline void delayacct_tsk_init(struct task_struct *tsk)
{}
static inline void delayacct_tsk_exit(struct task_struct *tsk)
{}
static inline void delayacct_blkio_start(void)
{}
static inline void delayacct_blkio_end(void)
{}
#endif /* CONFIG_TASK_DELAY_ACCT */

#endif
13 changes: 13 additions & 0 deletions include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,19 @@ struct task_delay_info {
* Atomicity of updates to XXX_delay, XXX_count protected by
* single lock above (split into XXX_lock if contention is an issue).
*/

/*
* XXX_count is incremented on every XXX operation, the delay
* associated with the operation is added to XXX_delay.
* XXX_delay contains the accumulated delay time in nanoseconds.
*/
struct timespec blkio_start, blkio_end; /* Shared by blkio, swapin */
u64 blkio_delay; /* wait for sync block io completion */
u64 swapin_delay; /* wait for swapin block io completion */
u32 blkio_count; /* total count of the number of sync block */
/* io operations performed */
u32 swapin_count; /* total count of the number of swapin block */
/* io operations performed */
};
#endif

Expand Down
19 changes: 19 additions & 0 deletions kernel/delayacct.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,22 @@ static void delayacct_end(struct timespec *start, struct timespec *end,
spin_unlock(&current->delays->lock);
}

void __delayacct_blkio_start(void)
{
delayacct_start(&current->delays->blkio_start);
}

void __delayacct_blkio_end(void)
{
if (current->delays->flags & DELAYACCT_PF_SWAPIN)
/* Swapin block I/O */
delayacct_end(&current->delays->blkio_start,
&current->delays->blkio_end,
&current->delays->swapin_delay,
&current->delays->swapin_count);
else /* Other block I/O */
delayacct_end(&current->delays->blkio_start,
&current->delays->blkio_end,
&current->delays->blkio_delay,
&current->delays->blkio_count);
}
5 changes: 5 additions & 0 deletions kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include <linux/times.h>
#include <linux/acct.h>
#include <linux/kprobes.h>
#include <linux/delayacct.h>
#include <asm/tlb.h>

#include <asm/unistd.h>
Expand Down Expand Up @@ -4534,9 +4535,11 @@ void __sched io_schedule(void)
{
struct rq *rq = &__raw_get_cpu_var(runqueues);

delayacct_blkio_start();
atomic_inc(&rq->nr_iowait);
schedule();
atomic_dec(&rq->nr_iowait);
delayacct_blkio_end();
}
EXPORT_SYMBOL(io_schedule);

Expand All @@ -4545,9 +4548,11 @@ long __sched io_schedule_timeout(long timeout)
struct rq *rq = &__raw_get_cpu_var(runqueues);
long ret;

delayacct_blkio_start();
atomic_inc(&rq->nr_iowait);
ret = schedule_timeout(timeout);
atomic_dec(&rq->nr_iowait);
delayacct_blkio_end();
return ret;
}

Expand Down
4 changes: 4 additions & 0 deletions mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include <linux/pagemap.h>
#include <linux/rmap.h>
#include <linux/module.h>
#include <linux/delayacct.h>
#include <linux/init.h>

#include <asm/pgalloc.h>
Expand Down Expand Up @@ -1934,6 +1935,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
migration_entry_wait(mm, pmd, address);
goto out;
}
delayacct_set_flag(DELAYACCT_PF_SWAPIN);
page = lookup_swap_cache(entry);
if (!page) {
swapin_readahead(entry, address, vma);
Expand All @@ -1946,6 +1948,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
if (likely(pte_same(*page_table, orig_pte)))
ret = VM_FAULT_OOM;
delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
goto unlock;
}

Expand All @@ -1955,6 +1958,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
grab_swap_token();
}

delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
mark_page_accessed(page);
lock_page(page);

Expand Down

0 comments on commit 0ff9224

Please sign in to comment.