Skip to content

Commit 5bf1828

Browse files
wangyongtorvalds
authored andcommitted
delayacct: track delays from memory compact
Delay accounting does not track the delay of memory compact. When there is not enough free memory, tasks can spend a amount of their time waiting for compact. To get the impact of tasks in direct memory compact, measure the delay when allocating memory through memory compact. Also update tools/accounting/getdelays.c: / # ./getdelays_next -di -p 304 print delayacct stats ON printing IO accounting PID 304 CPU count real total virtual total delay total delay average 277 780000000 849039485 18877296 0.068ms IO count delay total delay average 0 0 0ms SWAP count delay total delay average 0 0 0ms RECLAIM count delay total delay average 5 11088812685 2217ms THRASHING count delay total delay average 0 0 0ms COMPACT count delay total delay average 3 72758 0ms watch: read=0, write=0, cancelled_write=0 Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: wangyong <[email protected]> Reviewed-by: Jiang Xuexin <[email protected]> Reviewed-by: Zhang Wenya <[email protected]> Reviewed-by: Yang Yang <[email protected]> Reviewed-by: Balbir Singh <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent ec710aa commit 5bf1828

File tree

5 files changed

+59
-2
lines changed

5 files changed

+59
-2
lines changed

include/linux/delayacct.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ struct task_delay_info {
4242
u64 thrashing_start;
4343
u64 thrashing_delay; /* wait for thrashing page */
4444

45+
u64 compact_start;
46+
u64 compact_delay; /* wait for memory compact */
47+
4548
u32 freepages_count; /* total count of memory reclaim */
4649
u32 thrashing_count; /* total count of thrash waits */
50+
u32 compact_count; /* total count of memory compact */
4751
};
4852
#endif
4953

@@ -72,6 +76,8 @@ extern void __delayacct_thrashing_start(void);
7276
extern void __delayacct_thrashing_end(void);
7377
extern void __delayacct_swapin_start(void);
7478
extern void __delayacct_swapin_end(void);
79+
extern void __delayacct_compact_start(void);
80+
extern void __delayacct_compact_end(void);
7581

7682
static inline void delayacct_tsk_init(struct task_struct *tsk)
7783
{
@@ -170,6 +176,24 @@ static inline void delayacct_swapin_end(void)
170176
__delayacct_swapin_end();
171177
}
172178

179+
static inline void delayacct_compact_start(void)
180+
{
181+
if (!static_branch_unlikely(&delayacct_key))
182+
return;
183+
184+
if (current->delays)
185+
__delayacct_compact_start();
186+
}
187+
188+
static inline void delayacct_compact_end(void)
189+
{
190+
if (!static_branch_unlikely(&delayacct_key))
191+
return;
192+
193+
if (current->delays)
194+
__delayacct_compact_end();
195+
}
196+
173197
#else
174198
static inline void delayacct_init(void)
175199
{}
@@ -200,6 +224,10 @@ static inline void delayacct_swapin_start(void)
200224
{}
201225
static inline void delayacct_swapin_end(void)
202226
{}
227+
static inline void delayacct_compact_start(void)
228+
{}
229+
static inline void delayacct_compact_end(void)
230+
{}
203231

204232
#endif /* CONFIG_TASK_DELAY_ACCT */
205233

include/uapi/linux/taskstats.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
*/
3535

3636

37-
#define TASKSTATS_VERSION 10
37+
#define TASKSTATS_VERSION 11
3838
#define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN
3939
* in linux/sched.h */
4040

@@ -172,6 +172,10 @@ struct taskstats {
172172

173173
/* v10: 64-bit btime to avoid overflow */
174174
__u64 ac_btime64; /* 64-bit begin time */
175+
176+
/* Delay waiting for memory compact */
177+
__u64 compact_count;
178+
__u64 compact_delay_total;
175179
};
176180

177181

kernel/delayacct.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,13 @@ int delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
155155
d->freepages_delay_total = (tmp < d->freepages_delay_total) ? 0 : tmp;
156156
tmp = d->thrashing_delay_total + tsk->delays->thrashing_delay;
157157
d->thrashing_delay_total = (tmp < d->thrashing_delay_total) ? 0 : tmp;
158+
tmp = d->compact_delay_total + tsk->delays->compact_delay;
159+
d->compact_delay_total = (tmp < d->compact_delay_total) ? 0 : tmp;
158160
d->blkio_count += tsk->delays->blkio_count;
159161
d->swapin_count += tsk->delays->swapin_count;
160162
d->freepages_count += tsk->delays->freepages_count;
161163
d->thrashing_count += tsk->delays->thrashing_count;
164+
d->compact_count += tsk->delays->compact_count;
162165
raw_spin_unlock_irqrestore(&tsk->delays->lock, flags);
163166

164167
return 0;
@@ -213,3 +216,16 @@ void __delayacct_swapin_end(void)
213216
&current->delays->swapin_delay,
214217
&current->delays->swapin_count);
215218
}
219+
220+
void __delayacct_compact_start(void)
221+
{
222+
current->delays->compact_start = local_clock();
223+
}
224+
225+
void __delayacct_compact_end(void)
226+
{
227+
delayacct_end(&current->delays->lock,
228+
&current->delays->compact_start,
229+
&current->delays->compact_delay,
230+
&current->delays->compact_count);
231+
}

mm/page_alloc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
#include <linux/padata.h>
7373
#include <linux/khugepaged.h>
7474
#include <linux/buffer_head.h>
75+
#include <linux/delayacct.h>
7576
#include <asm/sections.h>
7677
#include <asm/tlbflush.h>
7778
#include <asm/div64.h>
@@ -4348,13 +4349,15 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
43484349
return NULL;
43494350

43504351
psi_memstall_enter(&pflags);
4352+
delayacct_compact_start();
43514353
noreclaim_flag = memalloc_noreclaim_save();
43524354

43534355
*compact_result = try_to_compact_pages(gfp_mask, order, alloc_flags, ac,
43544356
prio, &page);
43554357

43564358
memalloc_noreclaim_restore(noreclaim_flag);
43574359
psi_memstall_leave(&pflags);
4360+
delayacct_compact_end();
43584361

43594362
if (*compact_result == COMPACT_SKIPPED)
43604363
return NULL;

tools/accounting/getdelays.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ static void print_delayacct(struct taskstats *t)
205205
"RECLAIM %12s%15s%15s\n"
206206
" %15llu%15llu%15llums\n"
207207
"THRASHING%12s%15s%15s\n"
208+
" %15llu%15llu%15llums\n"
209+
"COMPACT %12s%15s%15s\n"
208210
" %15llu%15llu%15llums\n",
209211
"count", "real total", "virtual total",
210212
"delay total", "delay average",
@@ -228,7 +230,11 @@ static void print_delayacct(struct taskstats *t)
228230
"count", "delay total", "delay average",
229231
(unsigned long long)t->thrashing_count,
230232
(unsigned long long)t->thrashing_delay_total,
231-
average_ms(t->thrashing_delay_total, t->thrashing_count));
233+
average_ms(t->thrashing_delay_total, t->thrashing_count),
234+
"count", "delay total", "delay average",
235+
(unsigned long long)t->compact_count,
236+
(unsigned long long)t->compact_delay_total,
237+
average_ms(t->compact_delay_total, t->compact_count));
232238
}
233239

234240
static void task_context_switch_counts(struct taskstats *t)

0 commit comments

Comments
 (0)