Skip to content

Commit a3d5dc9

Browse files
yangyang20220519torvalds
authored andcommitted
delayacct: support swapin delay accounting for swapping without blkio
Currently delayacct accounts swapin delay only for swapping that cause blkio. If we use zram for swapping, tools/accounting/getdelays can't get any SWAP delay. It's useful to get zram swapin delay information, for example to adjust compress algorithm or /proc/sys/vm/swappiness. Reference to PSI, it accounts any kind of swapping by doing its work in swap_readpage(), no matter whether swapping causes blkio. Let delayacct do the similar work. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Yang Yang <[email protected]> Reported-by: Zeal Robot <[email protected]> Cc: Balbir Singh <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Johannes Weiner <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent e83a447 commit a3d5dc9

File tree

4 files changed

+43
-41
lines changed

4 files changed

+43
-41
lines changed

include/linux/delayacct.h

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@
99

1010
#include <uapi/linux/taskstats.h>
1111

12-
/*
13-
* Per-task flags relevant to delay accounting
14-
* maintained privately to avoid exhausting similar flags in sched.h:PF_*
15-
* Used to set current->delays->flags
16-
*/
17-
#define DELAYACCT_PF_SWAPIN 0x00000001 /* I am doing a swapin */
18-
#define DELAYACCT_PF_BLKIO 0x00000002 /* I am waiting on IO */
19-
2012
#ifdef CONFIG_TASK_DELAY_ACCT
2113
struct task_delay_info {
2214
raw_spinlock_t lock;
@@ -37,13 +29,13 @@ struct task_delay_info {
3729
* associated with the operation is added to XXX_delay.
3830
* XXX_delay contains the accumulated delay time in nanoseconds.
3931
*/
40-
u64 blkio_start; /* Shared by blkio, swapin */
32+
u64 blkio_start;
4133
u64 blkio_delay; /* wait for sync block io completion */
42-
u64 swapin_delay; /* wait for swapin block io completion */
34+
u64 swapin_start;
35+
u64 swapin_delay; /* wait for swapin */
4336
u32 blkio_count; /* total count of the number of sync block */
4437
/* io operations performed */
45-
u32 swapin_count; /* total count of the number of swapin block */
46-
/* io operations performed */
38+
u32 swapin_count; /* total count of swapin */
4739

4840
u64 freepages_start;
4941
u64 freepages_delay; /* wait for memory reclaim */
@@ -79,14 +71,8 @@ extern void __delayacct_freepages_start(void);
7971
extern void __delayacct_freepages_end(void);
8072
extern void __delayacct_thrashing_start(void);
8173
extern void __delayacct_thrashing_end(void);
82-
83-
static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
84-
{
85-
if (p->delays)
86-
return (p->delays->flags & DELAYACCT_PF_BLKIO);
87-
else
88-
return 0;
89-
}
74+
extern void __delayacct_swapin_start(void);
75+
extern void __delayacct_swapin_end(void);
9076

9177
static inline void delayacct_set_flag(struct task_struct *p, int flag)
9278
{
@@ -123,7 +109,6 @@ static inline void delayacct_blkio_start(void)
123109
if (!static_branch_unlikely(&delayacct_key))
124110
return;
125111

126-
delayacct_set_flag(current, DELAYACCT_PF_BLKIO);
127112
if (current->delays)
128113
__delayacct_blkio_start();
129114
}
@@ -135,7 +120,6 @@ static inline void delayacct_blkio_end(struct task_struct *p)
135120

136121
if (p->delays)
137122
__delayacct_blkio_end(p);
138-
delayacct_clear_flag(p, DELAYACCT_PF_BLKIO);
139123
}
140124

141125
static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
@@ -169,6 +153,18 @@ static inline void delayacct_thrashing_end(void)
169153
__delayacct_thrashing_end();
170154
}
171155

156+
static inline void delayacct_swapin_start(void)
157+
{
158+
if (current->delays)
159+
__delayacct_swapin_start();
160+
}
161+
162+
static inline void delayacct_swapin_end(void)
163+
{
164+
if (current->delays)
165+
__delayacct_swapin_end();
166+
}
167+
172168
#else
173169
static inline void delayacct_set_flag(struct task_struct *p, int flag)
174170
{}
@@ -199,6 +195,10 @@ static inline void delayacct_thrashing_start(void)
199195
{}
200196
static inline void delayacct_thrashing_end(void)
201197
{}
198+
static inline void delayacct_swapin_start(void)
199+
{}
200+
static inline void delayacct_swapin_end(void)
201+
{}
202202

203203
#endif /* CONFIG_TASK_DELAY_ACCT */
204204

kernel/delayacct.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,10 @@ void __delayacct_blkio_start(void)
100100
*/
101101
void __delayacct_blkio_end(struct task_struct *p)
102102
{
103-
struct task_delay_info *delays = p->delays;
104-
u64 *total;
105-
u32 *count;
106-
107-
if (p->delays->flags & DELAYACCT_PF_SWAPIN) {
108-
total = &delays->swapin_delay;
109-
count = &delays->swapin_count;
110-
} else {
111-
total = &delays->blkio_delay;
112-
count = &delays->blkio_count;
113-
}
114-
115-
delayacct_end(&delays->lock, &delays->blkio_start, total, count);
103+
delayacct_end(&p->delays->lock,
104+
&p->delays->blkio_start,
105+
&p->delays->blkio_delay,
106+
&p->delays->blkio_count);
116107
}
117108

118109
int delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
@@ -179,8 +170,7 @@ __u64 __delayacct_blkio_ticks(struct task_struct *tsk)
179170
unsigned long flags;
180171

181172
raw_spin_lock_irqsave(&tsk->delays->lock, flags);
182-
ret = nsec_to_clock_t(tsk->delays->blkio_delay +
183-
tsk->delays->swapin_delay);
173+
ret = nsec_to_clock_t(tsk->delays->blkio_delay);
184174
raw_spin_unlock_irqrestore(&tsk->delays->lock, flags);
185175
return ret;
186176
}
@@ -210,3 +200,16 @@ void __delayacct_thrashing_end(void)
210200
&current->delays->thrashing_delay,
211201
&current->delays->thrashing_count);
212202
}
203+
204+
void __delayacct_swapin_start(void)
205+
{
206+
current->delays->swapin_start = local_clock();
207+
}
208+
209+
void __delayacct_swapin_end(void)
210+
{
211+
delayacct_end(&current->delays->lock,
212+
&current->delays->swapin_start,
213+
&current->delays->swapin_delay,
214+
&current->delays->swapin_count);
215+
}

mm/memory.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3507,7 +3507,6 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
35073507
if (unlikely(!si))
35083508
goto out;
35093509

3510-
delayacct_set_flag(current, DELAYACCT_PF_SWAPIN);
35113510
page = lookup_swap_cache(entry, vma, vmf->address);
35123511
swapcache = page;
35133512

@@ -3555,7 +3554,6 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
35553554
vmf->address, &vmf->ptl);
35563555
if (likely(pte_same(*vmf->pte, vmf->orig_pte)))
35573556
ret = VM_FAULT_OOM;
3558-
delayacct_clear_flag(current, DELAYACCT_PF_SWAPIN);
35593557
goto unlock;
35603558
}
35613559

@@ -3569,13 +3567,11 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
35693567
* owner processes (which may be unknown at hwpoison time)
35703568
*/
35713569
ret = VM_FAULT_HWPOISON;
3572-
delayacct_clear_flag(current, DELAYACCT_PF_SWAPIN);
35733570
goto out_release;
35743571
}
35753572

35763573
locked = lock_page_or_retry(page, vma->vm_mm, vmf->flags);
35773574

3578-
delayacct_clear_flag(current, DELAYACCT_PF_SWAPIN);
35793575
if (!locked) {
35803576
ret |= VM_FAULT_RETRY;
35813577
goto out_release;

mm/page_io.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/psi.h>
2626
#include <linux/uio.h>
2727
#include <linux/sched/task.h>
28+
#include <linux/delayacct.h>
2829

2930
void end_swap_bio_write(struct bio *bio)
3031
{
@@ -370,6 +371,7 @@ int swap_readpage(struct page *page, bool synchronous)
370371
* significant part of overall IO time.
371372
*/
372373
psi_memstall_enter(&pflags);
374+
delayacct_swapin_start();
373375

374376
if (frontswap_load(page) == 0) {
375377
SetPageUptodate(page);
@@ -432,6 +434,7 @@ int swap_readpage(struct page *page, bool synchronous)
432434

433435
out:
434436
psi_memstall_leave(&pflags);
437+
delayacct_swapin_end();
435438
return ret;
436439
}
437440

0 commit comments

Comments
 (0)