diff mbox series

mm/page_owner: Record timestamp and pid

Message ID 20201112184106.733-1-georgi.djakov@linaro.org (mailing list archive)
State New, archived
Headers show
Series mm/page_owner: Record timestamp and pid | expand

Commit Message

Georgi Djakov Nov. 12, 2020, 6:41 p.m. UTC
From: Liam Mark <lmark@codeaurora.org>

Collect the time for each allocation recorded in page owner so that
allocation "surges" can be measured.

Record the pid for each allocation recorded in page owner so that
the source of allocation "surges" can be better identified.

Signed-off-by: Liam Mark <lmark@codeaurora.org>
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---
 mm/page_owner.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Andrew Morton Nov. 12, 2020, 7:14 p.m. UTC | #1
On Thu, 12 Nov 2020 20:41:06 +0200 Georgi Djakov <georgi.djakov@linaro.org> wrote:

> From: Liam Mark <lmark@codeaurora.org>
> 
> Collect the time for each allocation recorded in page owner so that
> allocation "surges" can be measured.
> 
> Record the pid for each allocation recorded in page owner so that
> the source of allocation "surges" can be better identified.

Please provide a description of why this is considered useful.  What
has it been used for, what problems has it been used to solve?

Are there userspace tools which aid in the processing of this new
information?

Can/should Documentation/vm/page_owner.rst be updated?

> --- a/mm/page_owner.c
> +++ b/mm/page_owner.c
> @@ -10,6 +10,7 @@
>  #include <linux/migrate.h>
>  #include <linux/stackdepot.h>
>  #include <linux/seq_file.h>
> +#include <linux/sched/clock.h>
>  
>  #include "internal.h"
>  
> @@ -25,6 +26,8 @@ struct page_owner {
>  	gfp_t gfp_mask;
>  	depot_stack_handle_t handle;
>  	depot_stack_handle_t free_handle;
> +	u64 ts_nsec;
> +	int pid;

pid_t would be nicer?
Georgi Djakov Nov. 13, 2020, 8:40 p.m. UTC | #2
On 11/12/20 21:14, Andrew Morton wrote:
> On Thu, 12 Nov 2020 20:41:06 +0200 Georgi Djakov <georgi.djakov@linaro.org> wrote:
> 
>> From: Liam Mark <lmark@codeaurora.org>
>>
>> Collect the time for each allocation recorded in page owner so that
>> allocation "surges" can be measured.
>>
>> Record the pid for each allocation recorded in page owner so that
>> the source of allocation "surges" can be better identified.
> 
> Please provide a description of why this is considered useful.  What
> has it been used for, what problems has it been used to solve?

Thanks for the quick feedback. I'll add more details in the commit message
when i post v2 next week.

> 
> Are there userspace tools which aid in the processing of this new
> information?

I'm not aware of any.

> 
> Can/should Documentation/vm/page_owner.rst be updated?

Yeah, probably i should update at least the size of the objects.

>> --- a/mm/page_owner.c
>> +++ b/mm/page_owner.c
>> @@ -10,6 +10,7 @@
>>  #include <linux/migrate.h>
>>  #include <linux/stackdepot.h>
>>  #include <linux/seq_file.h>
>> +#include <linux/sched/clock.h>
>>  
>>  #include "internal.h"
>>  
>> @@ -25,6 +26,8 @@ struct page_owner {
>>  	gfp_t gfp_mask;
>>  	depot_stack_handle_t handle;
>>  	depot_stack_handle_t free_handle;
>> +	u64 ts_nsec;
>> +	int pid;
> 
> pid_t would be nicer?

Yes, indeed! Thank you!

BR,
Georgi
Vlastimil Babka Nov. 27, 2020, 5:52 p.m. UTC | #3
On 11/12/20 8:14 PM, Andrew Morton wrote:
> On Thu, 12 Nov 2020 20:41:06 +0200 Georgi Djakov <georgi.djakov@linaro.org> wrote:
> 
>> From: Liam Mark <lmark@codeaurora.org>
>> 
>> Collect the time for each allocation recorded in page owner so that
>> allocation "surges" can be measured.
>> 
>> Record the pid for each allocation recorded in page owner so that
>> the source of allocation "surges" can be better identified.
> 
> Please provide a description of why this is considered useful.  What
> has it been used for, what problems has it been used to solve?

Worth noting that on x86_64 it doubles the size of struct page_owner
from 16 bytes to 32, so it better be justified:

struct page_owner {
         short unsigned int         order;                /*     0     2 */
         short int                  last_migrate_reason;  /*     2     2 */
         gfp_t                      gfp_mask;             /*     4     4 */
         depot_stack_handle_t       handle;               /*     8     4 */
         depot_stack_handle_t       free_handle;          /*    12     4 */
         u64                        ts_nsec;              /*    16     8 */
         int                        pid;                  /*    24     4 */

         /* size: 32, cachelines: 1, members: 7 */
         /* padding: 4 */
         /* last cacheline: 32 bytes */
};


> Are there userspace tools which aid in the processing of this new
> information?
> 
> Can/should Documentation/vm/page_owner.rst be updated?
> 
>> --- a/mm/page_owner.c
>> +++ b/mm/page_owner.c
>> @@ -10,6 +10,7 @@
>>  #include <linux/migrate.h>
>>  #include <linux/stackdepot.h>
>>  #include <linux/seq_file.h>
>> +#include <linux/sched/clock.h>
>>  
>>  #include "internal.h"
>>  
>> @@ -25,6 +26,8 @@ struct page_owner {
>>  	gfp_t gfp_mask;
>>  	depot_stack_handle_t handle;
>>  	depot_stack_handle_t free_handle;
>> +	u64 ts_nsec;
>> +	int pid;
> 
> pid_t would be nicer?
> 
> 
>
Georgi Djakov Nov. 27, 2020, 6:57 p.m. UTC | #4
Hi Vlastimil,

Thanks for the comment!

On 11/27/20 19:52, Vlastimil Babka wrote:
> On 11/12/20 8:14 PM, Andrew Morton wrote:
>> On Thu, 12 Nov 2020 20:41:06 +0200 Georgi Djakov <georgi.djakov@linaro.org> 
>> wrote:
>>
>>> From: Liam Mark <lmark@codeaurora.org>
>>>
>>> Collect the time for each allocation recorded in page owner so that
>>> allocation "surges" can be measured.
>>>
>>> Record the pid for each allocation recorded in page owner so that
>>> the source of allocation "surges" can be better identified.
>>
>> Please provide a description of why this is considered useful.  What
>> has it been used for, what problems has it been used to solve?
> 
> Worth noting that on x86_64 it doubles the size of struct page_owner
> from 16 bytes to 32, so it better be justified:

Well, that's true. But for debug options there is almost always some penalty.
The timestamp and pid information is very useful for me (and others, i believe)
when doing memory analysis. On a crash for example, we can get this information
from kdump (or RAM-dump) and look into it to catch memory allocation problems
more easily.

If you find the above argument not strong enough, how about a separate config 
option for this? Maybe something like CONFIG_PAGE_OWNER_EXTENDED, which could
be enabled in addition to CONFIG_PAGE_OWNER?

Thanks,
Georgi

> 
> struct page_owner {
>          short unsigned int         order;                /*     0     2 */
>          short int                  last_migrate_reason;  /*     2     2 */
>          gfp_t                      gfp_mask;             /*     4     4 */
>          depot_stack_handle_t       handle;               /*     8     4 */
>          depot_stack_handle_t       free_handle;          /*    12     4 */
>          u64                        ts_nsec;              /*    16     8 */
>          int                        pid;                  /*    24     4 */
> 
>          /* size: 32, cachelines: 1, members: 7 */
>          /* padding: 4 */
>          /* last cacheline: 32 bytes */
> };
>
Vlastimil Babka Nov. 27, 2020, 7:06 p.m. UTC | #5
On 11/27/20 7:57 PM, Georgi Djakov wrote:
> Hi Vlastimil,
> 
> Thanks for the comment!
> 
> On 11/27/20 19:52, Vlastimil Babka wrote:
>> On 11/12/20 8:14 PM, Andrew Morton wrote:
>>> On Thu, 12 Nov 2020 20:41:06 +0200 Georgi Djakov <georgi.djakov@linaro.org> 
>>> wrote:
>>>
>>>> From: Liam Mark <lmark@codeaurora.org>
>>>>
>>>> Collect the time for each allocation recorded in page owner so that
>>>> allocation "surges" can be measured.
>>>>
>>>> Record the pid for each allocation recorded in page owner so that
>>>> the source of allocation "surges" can be better identified.
>>>
>>> Please provide a description of why this is considered useful.  What
>>> has it been used for, what problems has it been used to solve?
>> 
>> Worth noting that on x86_64 it doubles the size of struct page_owner
>> from 16 bytes to 32, so it better be justified:
> 
> Well, that's true. But for debug options there is almost always some penalty.
> The timestamp and pid information is very useful for me (and others, i believe)
> when doing memory analysis. On a crash for example, we can get this information
> from kdump (or RAM-dump) and look into it to catch memory allocation problems
> more easily.

Right. Btw, you should add printing the info to __dump_page_owner().

> If you find the above argument not strong enough, how about a separate config
> option for this? Maybe something like CONFIG_PAGE_OWNER_EXTENDED, which could
> be enabled in addition to CONFIG_PAGE_OWNER?

It might be strong enough if it's mentioned in changelog, and also what exactly 
the space tradeoff is :)

You can also mention that SLUB object tracking has also pid+timestamp.

> Thanks,
> Georgi
> 
>> 
>> struct page_owner {
>>          short unsigned int         order;                /*     0     2 */
>>          short int                  last_migrate_reason;  /*     2     2 */
>>          gfp_t                      gfp_mask;             /*     4     4 */
>>          depot_stack_handle_t       handle;               /*     8     4 */
>>          depot_stack_handle_t       free_handle;          /*    12     4 */
>>          u64                        ts_nsec;              /*    16     8 */
>>          int                        pid;                  /*    24     4 */
>> 
>>          /* size: 32, cachelines: 1, members: 7 */
>>          /* padding: 4 */
>>          /* last cacheline: 32 bytes */
>> };
>> 
>
Souptick Joarder Nov. 27, 2020, 7:23 p.m. UTC | #6
On Sat, Nov 28, 2020 at 12:36 AM Vlastimil Babka <vbabka@suse.cz> wrote:
>
> On 11/27/20 7:57 PM, Georgi Djakov wrote:
> > Hi Vlastimil,
> >
> > Thanks for the comment!
> >
> > On 11/27/20 19:52, Vlastimil Babka wrote:
> >> On 11/12/20 8:14 PM, Andrew Morton wrote:
> >>> On Thu, 12 Nov 2020 20:41:06 +0200 Georgi Djakov <georgi.djakov@linaro.org>
> >>> wrote:
> >>>
> >>>> From: Liam Mark <lmark@codeaurora.org>
> >>>>
> >>>> Collect the time for each allocation recorded in page owner so that
> >>>> allocation "surges" can be measured.
> >>>>
> >>>> Record the pid for each allocation recorded in page owner so that
> >>>> the source of allocation "surges" can be better identified.
> >>>
> >>> Please provide a description of why this is considered useful.  What
> >>> has it been used for, what problems has it been used to solve?
> >>
> >> Worth noting that on x86_64 it doubles the size of struct page_owner
> >> from 16 bytes to 32, so it better be justified:
> >
> > Well, that's true. But for debug options there is almost always some penalty.
> > The timestamp and pid information is very useful for me (and others, i believe)
> > when doing memory analysis. On a crash for example, we can get this information
> > from kdump (or RAM-dump) and look into it to catch memory allocation problems
> > more easily.
>
> Right. Btw, you should add printing the info to __dump_page_owner().
>
> > If you find the above argument not strong enough, how about a separate config
> > option for this? Maybe something like CONFIG_PAGE_OWNER_EXTENDED, which could
> > be enabled in addition to CONFIG_PAGE_OWNER?
>
> It might be strong enough if it's mentioned in changelog, and also what exactly
> the space tradeoff is :)

Just a thought ... putting it inside CONFIG_PAGE_OWNER_DEBUG might be
better if it is used
purely for debugging purposes.

>
> You can also mention that SLUB object tracking has also pid+timestamp.
>
> > Thanks,
> > Georgi
> >
> >>
> >> struct page_owner {
> >>          short unsigned int         order;                /*     0     2 */
> >>          short int                  last_migrate_reason;  /*     2     2 */
> >>          gfp_t                      gfp_mask;             /*     4     4 */
> >>          depot_stack_handle_t       handle;               /*     8     4 */
> >>          depot_stack_handle_t       free_handle;          /*    12     4 */
> >>          u64                        ts_nsec;              /*    16     8 */
> >>          int                        pid;                  /*    24     4 */
> >>
> >>          /* size: 32, cachelines: 1, members: 7 */
> >>          /* padding: 4 */
> >>          /* last cacheline: 32 bytes */
> >> };
> >>
> >
>
>
Vlastimil Babka Nov. 30, 2020, 12:04 p.m. UTC | #7
On 11/27/20 8:23 PM, Souptick Joarder wrote:
> On Sat, Nov 28, 2020 at 12:36 AM Vlastimil Babka <vbabka@suse.cz> wrote:
>>
>> On 11/27/20 7:57 PM, Georgi Djakov wrote:
>> > Hi Vlastimil,
>> >
>> > Thanks for the comment!
>> >
>> > On 11/27/20 19:52, Vlastimil Babka wrote:
>> >> On 11/12/20 8:14 PM, Andrew Morton wrote:
>> >>> On Thu, 12 Nov 2020 20:41:06 +0200 Georgi Djakov <georgi.djakov@linaro.org>
>> >>> wrote:
>> >>>
>> >>>> From: Liam Mark <lmark@codeaurora.org>
>> >>>>
>> >>>> Collect the time for each allocation recorded in page owner so that
>> >>>> allocation "surges" can be measured.
>> >>>>
>> >>>> Record the pid for each allocation recorded in page owner so that
>> >>>> the source of allocation "surges" can be better identified.
>> >>>
>> >>> Please provide a description of why this is considered useful.  What
>> >>> has it been used for, what problems has it been used to solve?
>> >>
>> >> Worth noting that on x86_64 it doubles the size of struct page_owner
>> >> from 16 bytes to 32, so it better be justified:
>> >
>> > Well, that's true. But for debug options there is almost always some penalty.
>> > The timestamp and pid information is very useful for me (and others, i believe)
>> > when doing memory analysis. On a crash for example, we can get this information
>> > from kdump (or RAM-dump) and look into it to catch memory allocation problems
>> > more easily.
>>
>> Right. Btw, you should add printing the info to __dump_page_owner().
>>
>> > If you find the above argument not strong enough, how about a separate config
>> > option for this? Maybe something like CONFIG_PAGE_OWNER_EXTENDED, which could
>> > be enabled in addition to CONFIG_PAGE_OWNER?
>>
>> It might be strong enough if it's mentioned in changelog, and also what exactly
>> the space tradeoff is :)
> 
> Just a thought ... putting it inside CONFIG_PAGE_OWNER_DEBUG might be
> better if it is used
> purely for debugging purposes.

I don't think we need to introduce new config just yet, until someone makes the 
case for it. Even then, it could be instead doable as an extension to 
"page_owner=on" boot option.
I mean let's add those fields, but improve the changelog.

>>
>> You can also mention that SLUB object tracking has also pid+timestamp.
>>
>> > Thanks,
>> > Georgi
>> >
>> >>
>> >> struct page_owner {
>> >>          short unsigned int         order;                /*     0     2 */
>> >>          short int                  last_migrate_reason;  /*     2     2 */
>> >>          gfp_t                      gfp_mask;             /*     4     4 */
>> >>          depot_stack_handle_t       handle;               /*     8     4 */
>> >>          depot_stack_handle_t       free_handle;          /*    12     4 */
>> >>          u64                        ts_nsec;              /*    16     8 */
>> >>          int                        pid;                  /*    24     4 */
>> >>
>> >>          /* size: 32, cachelines: 1, members: 7 */
>> >>          /* padding: 4 */
>> >>          /* last cacheline: 32 bytes */
>> >> };
>> >>
>> >
>>
>>
>
diff mbox series

Patch

diff --git a/mm/page_owner.c b/mm/page_owner.c
index b735a8eafcdb..e6dc52db5ba5 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -10,6 +10,7 @@ 
 #include <linux/migrate.h>
 #include <linux/stackdepot.h>
 #include <linux/seq_file.h>
+#include <linux/sched/clock.h>
 
 #include "internal.h"
 
@@ -25,6 +26,8 @@  struct page_owner {
 	gfp_t gfp_mask;
 	depot_stack_handle_t handle;
 	depot_stack_handle_t free_handle;
+	u64 ts_nsec;
+	int pid;
 };
 
 static bool page_owner_enabled = false;
@@ -172,6 +175,8 @@  static inline void __set_page_owner_handle(struct page *page,
 		page_owner->order = order;
 		page_owner->gfp_mask = gfp_mask;
 		page_owner->last_migrate_reason = -1;
+		page_owner->pid = current->pid;
+		page_owner->ts_nsec = local_clock();
 		__set_bit(PAGE_EXT_OWNER, &page_ext->flags);
 		__set_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags);
 
@@ -236,6 +241,8 @@  void __copy_page_owner(struct page *oldpage, struct page *newpage)
 	new_page_owner->last_migrate_reason =
 		old_page_owner->last_migrate_reason;
 	new_page_owner->handle = old_page_owner->handle;
+	new_page_owner->pid = old_page_owner->pid;
+	new_page_owner->ts_nsec = old_page_owner->ts_nsec;
 
 	/*
 	 * We don't clear the bit on the oldpage as it's going to be freed
@@ -349,9 +356,10 @@  print_page_owner(char __user *buf, size_t count, unsigned long pfn,
 		return -ENOMEM;
 
 	ret = snprintf(kbuf, count,
-			"Page allocated via order %u, mask %#x(%pGg)\n",
+			"Page allocated via order %u, mask %#x(%pGg), pid %d, ts %llu ns\n",
 			page_owner->order, page_owner->gfp_mask,
-			&page_owner->gfp_mask);
+			&page_owner->gfp_mask, page_owner->pid,
+			page_owner->ts_nsec);
 
 	if (ret >= count)
 		goto err;