diff mbox series

[linux-next] delayacct: track delays from memory compact

Message ID 1638542272-15187-1-git-send-email-wang.yong12@zte.com.cn (mailing list archive)
State New
Headers show
Series [linux-next] delayacct: track delays from memory compact | expand

Commit Message

yong w Dec. 3, 2021, 2:37 p.m. UTC
From: wangyong <wang.yong12@zte.com.cn>

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 memory compact.

To get the impact of tasks in direct memory compact, measure
the delay when allocating memory through memory compact.

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

Reported-by: Zeal Robot <zealci@zte.com.cn>
Signed-off-by: wangyong <wang.yong12@zte.com.cn>
Reviewed-by: Yang Yang <yang.yang29@zte.com.cn>
---
 include/linux/delayacct.h      | 29 +++++++++++++++++++++++++++++
 include/uapi/linux/taskstats.h |  6 +++++-
 kernel/delayacct.c             | 15 +++++++++++++++
 mm/page_alloc.c                |  3 +++
 tools/accounting/getdelays.c   |  8 +++++++-
 5 files changed, 59 insertions(+), 2 deletions(-)

Comments

Andrew Morton Dec. 3, 2021, 9:02 p.m. UTC | #1
On Fri,  3 Dec 2021 06:37:52 -0800 yongw.pur@gmail.com wrote:

> From: wangyong <wang.yong12@zte.com.cn>
> 
> 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 memory compact.
> 
> To get the impact of tasks in direct memory compact, measure
> the delay when allocating memory through memory compact.
> 
> ...
>
> --- a/include/linux/delayacct.h
> +++ b/include/linux/delayacct.h
> @@ -42,8 +42,13 @@ struct task_delay_info {
>  	u64 thrashing_start;
>  	u64 thrashing_delay;	/* wait for thrashing page */
>  
> +	u64 compact_start;
> +	u64 compact_delay;	/* wait for memory compact */
> +
> +	u64 freepages_start;

task_delay_info already has a freepages_start, so it fails to compile.

Did you send the correct version?
kernel test robot Dec. 4, 2021, 10:20 a.m. UTC | #2
Hi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on next-20211203]

url:    https://github.com/0day-ci/linux/commits/yongw-pur-gmail-com/delayacct-track-delays-from-memory-compact/20211203-224016
base:    7afeac307a9561e3a93682c1e7eb22f918aa1187
config: x86_64-randconfig-a011-20211203 (https://download.01.org/0day-ci/archive/20211204/202112041804.vsvLifnA-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 5f1d1854eb1450d352663ee732235893c5782237)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/ccd829e34aa6aefecf6428975fa82384c6139fd1
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review yongw-pur-gmail-com/delayacct-track-delays-from-memory-compact/20211203-224016
        git checkout ccd829e34aa6aefecf6428975fa82384c6139fd1
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from init/main.c:58:
>> include/linux/delayacct.h:48:6: error: duplicate member 'freepages_start'
           u64 freepages_start;
               ^
   include/linux/delayacct.h:39:6: note: previous declaration is here
           u64 freepages_start;
               ^
   init/main.c:783:20: warning: no previous prototype for function 'mem_encrypt_init' [-Wmissing-prototypes]
   void __init __weak mem_encrypt_init(void) { }
                      ^
   init/main.c:783:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void __init __weak mem_encrypt_init(void) { }
   ^
   static 
   1 warning and 1 error generated.
--
   In file included from kernel/delayacct.c:14:
>> include/linux/delayacct.h:48:6: error: duplicate member 'freepages_start'
           u64 freepages_start;
               ^
   include/linux/delayacct.h:39:6: note: previous declaration is here
           u64 freepages_start;
               ^
   1 error generated.
--
   In file included from mm/page_alloc.c:77:
>> include/linux/delayacct.h:48:6: error: duplicate member 'freepages_start'
           u64 freepages_start;
               ^
   include/linux/delayacct.h:39:6: note: previous declaration is here
           u64 freepages_start;
               ^
   mm/page_alloc.c:3820:15: warning: no previous prototype for function 'should_fail_alloc_page' [-Wmissing-prototypes]
   noinline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
                 ^
   mm/page_alloc.c:3820:10: note: declare 'static' if the function is not intended to be used outside of this translation unit
   noinline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
            ^
            static 
   1 warning and 1 error generated.
--
   In file included from kernel/sched/core.c:13:
   In file included from kernel/sched/sched.h:47:
>> include/linux/delayacct.h:48:6: error: duplicate member 'freepages_start'
           u64 freepages_start;
               ^
   include/linux/delayacct.h:39:6: note: previous declaration is here
           u64 freepages_start;
               ^
   kernel/sched/core.c:3450:6: warning: no previous prototype for function 'sched_set_stop_task' [-Wmissing-prototypes]
   void sched_set_stop_task(int cpu, struct task_struct *stop)
        ^
   kernel/sched/core.c:3450:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void sched_set_stop_task(int cpu, struct task_struct *stop)
   ^
   static 
   1 warning and 1 error generated.
--
   In file included from kernel/sched/fair.c:23:
   In file included from kernel/sched/sched.h:47:
>> include/linux/delayacct.h:48:6: error: duplicate member 'freepages_start'
           u64 freepages_start;
               ^
   include/linux/delayacct.h:39:6: note: previous declaration is here
           u64 freepages_start;
               ^
   kernel/sched/fair.c:11094:6: warning: no previous prototype for function 'task_vruntime_update' [-Wmissing-prototypes]
   void task_vruntime_update(struct rq *rq, struct task_struct *p, bool in_fi)
        ^
   kernel/sched/fair.c:11094:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void task_vruntime_update(struct rq *rq, struct task_struct *p, bool in_fi)
   ^
   static 
   1 warning and 1 error generated.
--
   In file included from kernel/sched/rt.c:6:
   In file included from kernel/sched/sched.h:47:
>> include/linux/delayacct.h:48:6: error: duplicate member 'freepages_start'
           u64 freepages_start;
               ^
   include/linux/delayacct.h:39:6: note: previous declaration is here
           u64 freepages_start;
               ^
   kernel/sched/rt.c:675:6: warning: no previous prototype for function 'sched_rt_bandwidth_account' [-Wmissing-prototypes]
   bool sched_rt_bandwidth_account(struct rt_rq *rt_rq)
        ^
   kernel/sched/rt.c:675:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   bool sched_rt_bandwidth_account(struct rt_rq *rt_rq)
   ^
   static 
   1 warning and 1 error generated.


vim +/freepages_start +48 include/linux/delayacct.h

    11	
    12	#ifdef CONFIG_TASK_DELAY_ACCT
    13	struct task_delay_info {
    14		raw_spinlock_t	lock;
    15	
    16		/* For each stat XXX, add following, aligned appropriately
    17		 *
    18		 * struct timespec XXX_start, XXX_end;
    19		 * u64 XXX_delay;
    20		 * u32 XXX_count;
    21		 *
    22		 * Atomicity of updates to XXX_delay, XXX_count protected by
    23		 * single lock above (split into XXX_lock if contention is an issue).
    24		 */
    25	
    26		/*
    27		 * XXX_count is incremented on every XXX operation, the delay
    28		 * associated with the operation is added to XXX_delay.
    29		 * XXX_delay contains the accumulated delay time in nanoseconds.
    30		 */
    31		u64 blkio_start;
    32		u64 blkio_delay;	/* wait for sync block io completion */
    33		u64 swapin_start;
    34		u64 swapin_delay;	/* wait for swapin */
    35		u32 blkio_count;	/* total count of the number of sync block */
    36					/* io operations performed */
    37		u32 swapin_count;	/* total count of swapin */
    38	
    39		u64 freepages_start;
    40		u64 freepages_delay;	/* wait for memory reclaim */
    41	
    42		u64 thrashing_start;
    43		u64 thrashing_delay;	/* wait for thrashing page */
    44	
    45		u64 compact_start;
    46		u64 compact_delay;	/* wait for memory compact */
    47	
  > 48		u64 freepages_start;
    49		u32 freepages_count;	/* total count of memory reclaim */
    50		u32 thrashing_count;	/* total count of thrash waits */
    51		u32 compact_count;	/* total count of memory compact */
    52	};
    53	#endif
    54	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
yong w Dec. 4, 2021, 11:23 a.m. UTC | #3
Sorry, the patch has something wrong.
I'll resend the patch later.

Thanks!

Andrew Morton <akpm@linux-foundation.org> 于2021年12月4日周六 05:02写道:
>
> On Fri,  3 Dec 2021 06:37:52 -0800 yongw.pur@gmail.com wrote:
>
> > From: wangyong <wang.yong12@zte.com.cn>
> >
> > 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 memory compact.
> >
> > To get the impact of tasks in direct memory compact, measure
> > the delay when allocating memory through memory compact.
> >
> > ...
> >
> > --- a/include/linux/delayacct.h
> > +++ b/include/linux/delayacct.h
> > @@ -42,8 +42,13 @@ struct task_delay_info {
> >       u64 thrashing_start;
> >       u64 thrashing_delay;    /* wait for thrashing page */
> >
> > +     u64 compact_start;
> > +     u64 compact_delay;      /* wait for memory compact */
> > +
> > +     u64 freepages_start;
>
> task_delay_info already has a freepages_start, so it fails to compile.
>
> Did you send the correct version?
>
diff mbox series

Patch

diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h
index 435c365..547cba9 100644
--- a/include/linux/delayacct.h
+++ b/include/linux/delayacct.h
@@ -42,8 +42,13 @@  struct task_delay_info {
 	u64 thrashing_start;
 	u64 thrashing_delay;	/* wait for thrashing page */
 
+	u64 compact_start;
+	u64 compact_delay;	/* wait for memory compact */
+
+	u64 freepages_start;
 	u32 freepages_count;	/* total count of memory reclaim */
 	u32 thrashing_count;	/* total count of thrash waits */
+	u32 compact_count;	/* total count of memory compact */
 };
 #endif
 
@@ -72,6 +77,8 @@  extern void __delayacct_thrashing_start(void);
 extern void __delayacct_thrashing_end(void);
 extern void __delayacct_swapin_start(void);
 extern void __delayacct_swapin_end(void);
+extern void __delayacct_compact_start(void);
+extern void __delayacct_compact_end(void);
 
 static inline void delayacct_tsk_init(struct task_struct *tsk)
 {
@@ -170,6 +177,24 @@  static inline void delayacct_swapin_end(void)
 		__delayacct_swapin_end();
 }
 
+static inline void delayacct_compact_start(void)
+{
+	if (!static_branch_unlikely(&delayacct_key))
+		return;
+
+	if (current->delays)
+		__delayacct_compact_start();
+}
+
+static inline void delayacct_compact_end(void)
+{
+	if (!static_branch_unlikely(&delayacct_key))
+		return;
+
+	if (current->delays)
+		__delayacct_compact_end();
+}
+
 #else
 static inline void delayacct_init(void)
 {}
@@ -200,6 +225,10 @@  static inline void delayacct_swapin_start(void)
 {}
 static inline void delayacct_swapin_end(void)
 {}
+static inline void delayacct_compact_start(void)
+{}
+static inline void delayacct_compact_end(void)
+{}
 
 #endif /* CONFIG_TASK_DELAY_ACCT */
 
diff --git a/include/uapi/linux/taskstats.h b/include/uapi/linux/taskstats.h
index ccbd087..12327d3 100644
--- a/include/uapi/linux/taskstats.h
+++ b/include/uapi/linux/taskstats.h
@@ -34,7 +34,7 @@ 
  */
 
 
-#define TASKSTATS_VERSION	10
+#define TASKSTATS_VERSION	11
 #define TS_COMM_LEN		32	/* should be >= TASK_COMM_LEN
 					 * in linux/sched.h */
 
@@ -172,6 +172,10 @@  struct taskstats {
 
 	/* v10: 64-bit btime to avoid overflow */
 	__u64	ac_btime64;		/* 64-bit begin time */
+
+	/* Delay waiting for memory compact */
+	__u64	compact_count;
+	__u64	compact_delay_total;
 };
 
 
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
index 11f3cd8..c5e8cea 100644
--- a/kernel/delayacct.c
+++ b/kernel/delayacct.c
@@ -155,10 +155,13 @@  int delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
 	d->freepages_delay_total = (tmp < d->freepages_delay_total) ? 0 : tmp;
 	tmp = d->thrashing_delay_total + tsk->delays->thrashing_delay;
 	d->thrashing_delay_total = (tmp < d->thrashing_delay_total) ? 0 : tmp;
+	tmp = d->compact_delay_total + tsk->delays->compact_delay;
+	d->compact_delay_total = (tmp < d->compact_delay_total) ? 0 : tmp;
 	d->blkio_count += tsk->delays->blkio_count;
 	d->swapin_count += tsk->delays->swapin_count;
 	d->freepages_count += tsk->delays->freepages_count;
 	d->thrashing_count += tsk->delays->thrashing_count;
+	d->compact_count += tsk->delays->compact_count;
 	raw_spin_unlock_irqrestore(&tsk->delays->lock, flags);
 
 	return 0;
@@ -214,3 +217,15 @@  void __delayacct_swapin_end(void)
 		      &current->delays->swapin_count);
 }
 
+void __delayacct_compact_start(void)
+{
+	current->delays->compact_start = local_clock();
+}
+
+void __delayacct_compact_end(void)
+{
+	delayacct_end(&current->delays->lock,
+		      &current->delays->compact_start,
+		      &current->delays->compact_delay,
+		      &current->delays->compact_count);
+}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index edfd6c8..6430226 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -74,6 +74,7 @@ 
 #include <linux/padata.h>
 #include <linux/khugepaged.h>
 #include <linux/buffer_head.h>
+#include <linux/delayacct.h>
 #include <asm/sections.h>
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -4363,6 +4364,7 @@  __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
 		return NULL;
 
 	psi_memstall_enter(&pflags);
+	delayacct_compact_start();
 	noreclaim_flag = memalloc_noreclaim_save();
 
 	*compact_result = try_to_compact_pages(gfp_mask, order, alloc_flags, ac,
@@ -4370,6 +4372,7 @@  __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
 
 	memalloc_noreclaim_restore(noreclaim_flag);
 	psi_memstall_leave(&pflags);
+	delayacct_compact_end();
 
 	if (*compact_result == COMPACT_SKIPPED)
 		return NULL;
diff --git a/tools/accounting/getdelays.c b/tools/accounting/getdelays.c
index 5ef1c15..11e8673 100644
--- a/tools/accounting/getdelays.c
+++ b/tools/accounting/getdelays.c
@@ -205,6 +205,8 @@  static void print_delayacct(struct taskstats *t)
 	       "RECLAIM  %12s%15s%15s\n"
 	       "      %15llu%15llu%15llums\n"
 	       "THRASHING%12s%15s%15s\n"
+	       "      %15llu%15llu%15llums\n"
+	       "COMPACT  %12s%15s%15s\n"
 	       "      %15llu%15llu%15llums\n",
 	       "count", "real total", "virtual total",
 	       "delay total", "delay average",
@@ -228,7 +230,11 @@  static void print_delayacct(struct taskstats *t)
 	       "count", "delay total", "delay average",
 	       (unsigned long long)t->thrashing_count,
 	       (unsigned long long)t->thrashing_delay_total,
-	       average_ms(t->thrashing_delay_total, t->thrashing_count));
+	       average_ms(t->thrashing_delay_total, t->thrashing_count),
+	       "count", "delay total", "delay average",
+	       (unsigned long long)t->compact_count,
+	       (unsigned long long)t->compact_delay_total,
+	       average_ms(t->compact_delay_total, t->compact_count));
 }
 
 static void task_context_switch_counts(struct taskstats *t)