* [PATCH 1/3] tracing, page-allocator: Add trace events for page allocation and page freeing
2009-07-28 22:23 [RFC PATCH 0/3] Add some trace events for the page allocator Mel Gorman
@ 2009-07-28 22:23 ` Mel Gorman
2009-07-28 22:23 ` [PATCH 2/3] tracing, mm: Add trace events for anti-fragmentation falling back to other migratetypes Mel Gorman
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Mel Gorman @ 2009-07-28 22:23 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, Peter Zijlstra, Mathieu Desnoyers
Cc: LKML, Mel Gorman
This patch adds trace events for the allocation and freeing of pages.
Using the events, it will be known what struct page and pfns are being
allocated and freed and what the call site was in many cases.
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
---
include/trace/events/kmem.h | 58 +++++++++++++++++++++++++++++++++++++++++++
mm/page_alloc.c | 3 ++
2 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 1493c54..ad07ffa 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -225,6 +225,64 @@ TRACE_EVENT(kmem_cache_free,
TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr)
);
+
+TRACE_EVENT(__free_pages,
+
+ TP_PROTO(unsigned long call_site, const void *page, unsigned int order),
+
+ TP_ARGS(call_site, page, order),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, call_site )
+ __field( const void *, page )
+ __field( unsigned int, order )
+ ),
+
+ TP_fast_assign(
+ __entry->call_site = call_site;
+ __entry->page = page;
+ __entry->order = order;
+ ),
+
+ TP_printk("call_site=%lx page=%p pfn=%lu order=%d",
+ __entry->call_site,
+ __entry->page,
+ page_to_pfn((struct page *)__entry->page),
+ __entry->order)
+);
+
+TRACE_EVENT(__alloc_pages_nodemask,
+
+ TP_PROTO(unsigned long call_site, const void *page, unsigned int order,
+ gfp_t gfp_flags, int migratetype),
+
+ TP_ARGS(call_site, page, order, gfp_flags, migratetype),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, call_site )
+ __field( const void *, page )
+ __field( unsigned int, order )
+ __field( gfp_t, gfp_flags )
+ __field( int, migratetype )
+ ),
+
+ TP_fast_assign(
+ __entry->call_site = call_site;
+ __entry->page = page;
+ __entry->order = order;
+ __entry->gfp_flags = gfp_flags;
+ __entry->migratetype = migratetype;
+ ),
+
+ TP_printk("call_site=%lx page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s",
+ __entry->call_site,
+ __entry->page,
+ page_to_pfn((struct page *)__entry->page),
+ __entry->order,
+ __entry->migratetype,
+ show_gfp_flags(__entry->gfp_flags))
+);
+
#endif /* _TRACE_KMEM_H */
/* This part must be outside protection */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index caa9268..5601dc6 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1894,6 +1894,8 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
zonelist, high_zoneidx, nodemask,
preferred_zone, migratetype);
+ trace___alloc_pages_nodemask(_RET_IP_, page, order, gfp_mask,
+ migratetype);
return page;
}
EXPORT_SYMBOL(__alloc_pages_nodemask);
@@ -1940,6 +1942,7 @@ void __pagevec_free(struct pagevec *pvec)
void __free_pages(struct page *page, unsigned int order)
{
+ trace___free_pages(_RET_IP_, page, order);
if (put_page_testzero(page)) {
if (order == 0)
free_hot_page(page);
--
1.6.3.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/3] tracing, mm: Add trace events for anti-fragmentation falling back to other migratetypes
2009-07-28 22:23 [RFC PATCH 0/3] Add some trace events for the page allocator Mel Gorman
2009-07-28 22:23 ` [PATCH 1/3] tracing, page-allocator: Add trace events for page allocation and page freeing Mel Gorman
@ 2009-07-28 22:23 ` Mel Gorman
2009-07-28 22:23 ` [PATCH 3/3] tracing, page-allocator: Add trace event for page traffic related to the buddy lists Mel Gorman
2009-07-28 22:48 ` [RFC PATCH 0/3] Add some trace events for the page allocator Frederic Weisbecker
3 siblings, 0 replies; 5+ messages in thread
From: Mel Gorman @ 2009-07-28 22:23 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, Peter Zijlstra, Mathieu Desnoyers
Cc: LKML, Mel Gorman
Fragmentation avoidance depends on being able to use free pages from
lists of the appropriate migrate type. In the event this is not
possible, __rmqueue_fallback() selects a different list and in some
circumstances change the migratetype of the pageblock. Simplistically,
the more times this event occurs, the more likely that fragmentation
will be a problem later for hugepage allocation at least but there are
other considerations such as the order of page being split to satisfy
the allocation.
This patch adds a trace event for __rmqueue_fallback() that reports what
page is being used for the fallback, the orders of relevant pages, the
desired migratetype and the migratetype of the lists being used, whether
the pageblock changed type and whether this event is important with
respect to fragmentation avoidance or not. This information can be used
to help analyse fragmentation avoidance and help decide whether
min_free_kbytes should be increased or not.
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
---
include/trace/events/kmem.h | 44 +++++++++++++++++++++++++++++++++++++++++++
mm/page_alloc.c | 6 +++++
2 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index ad07ffa..91a057c 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -283,6 +283,50 @@ TRACE_EVENT(__alloc_pages_nodemask,
show_gfp_flags(__entry->gfp_flags))
);
+TRACE_EVENT(__rmqueue_fallback,
+
+ TP_PROTO(const void *page,
+ int alloc_order, int fallback_order,
+ int alloc_migratetype, int fallback_migratetype,
+ int fragmenting, int change_ownership),
+
+ TP_ARGS(page,
+ alloc_order, fallback_order,
+ alloc_migratetype, fallback_migratetype,
+ fragmenting, change_ownership),
+
+ TP_STRUCT__entry(
+ __field( const void *, page )
+ __field( int, alloc_order )
+ __field( int, fallback_order )
+ __field( int, alloc_migratetype )
+ __field( int, fallback_migratetype )
+ __field( int, fragmenting )
+ __field( int, change_ownership )
+ ),
+
+ TP_fast_assign(
+ __entry->page = page;
+ __entry->alloc_order = alloc_order;
+ __entry->fallback_order = fallback_order;
+ __entry->alloc_migratetype = alloc_migratetype;
+ __entry->fallback_migratetype = fallback_migratetype;
+ __entry->fragmenting = fragmenting;
+ __entry->change_ownership = change_ownership;
+ ),
+
+ TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d",
+ __entry->page,
+ page_to_pfn((struct page *)__entry->page),
+ __entry->alloc_order,
+ __entry->fallback_order,
+ pageblock_order,
+ __entry->alloc_migratetype,
+ __entry->fallback_migratetype,
+ __entry->fragmenting,
+ __entry->change_ownership)
+);
+
#endif /* _TRACE_KMEM_H */
/* This part must be outside protection */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5601dc6..3fc9f09 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -839,6 +839,12 @@ __rmqueue_fallback(struct zone *zone, int order, int start_migratetype)
start_migratetype);
expand(zone, page, order, current_order, area, migratetype);
+
+ trace___rmqueue_fallback(page, order, current_order,
+ start_migratetype, migratetype,
+ current_order < pageblock_order,
+ migratetype == start_migratetype);
+
return page;
}
}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/3] tracing, page-allocator: Add trace event for page traffic related to the buddy lists
2009-07-28 22:23 [RFC PATCH 0/3] Add some trace events for the page allocator Mel Gorman
2009-07-28 22:23 ` [PATCH 1/3] tracing, page-allocator: Add trace events for page allocation and page freeing Mel Gorman
2009-07-28 22:23 ` [PATCH 2/3] tracing, mm: Add trace events for anti-fragmentation falling back to other migratetypes Mel Gorman
@ 2009-07-28 22:23 ` Mel Gorman
2009-07-28 22:48 ` [RFC PATCH 0/3] Add some trace events for the page allocator Frederic Weisbecker
3 siblings, 0 replies; 5+ messages in thread
From: Mel Gorman @ 2009-07-28 22:23 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, Peter Zijlstra, Mathieu Desnoyers
Cc: LKML, Mel Gorman
The page allocation trace event reports that a page was successfully allocated
but it does not specify where it came from. When analysing performance,
it can be important to distinguish between pages coming from the per-cpu
allocator and pages coming from the buddy lists as the latter requires the
zone lock to the taken and more data structures to be examined.
This patch adds a trace event for __rmqueue reporting when a page is being
allocated from the buddy lists. It distinguishes between being called
to refill the per-cpu lists or whether it is a high-order allocation.
Similarly, this patch adds an event to catch when the PCP lists are being
drained a little and pages are going back to the buddy lists. These two
events can be used as an indicator of how often the zone lock is being taken.
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
---
include/trace/events/kmem.h | 54 +++++++++++++++++++++++++++++++++++++++++++
mm/page_alloc.c | 2 +
2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 91a057c..fbc3779 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -283,6 +283,60 @@ TRACE_EVENT(__alloc_pages_nodemask,
show_gfp_flags(__entry->gfp_flags))
);
+TRACE_EVENT(__rmqueue,
+
+ TP_PROTO(const void *page, unsigned int order,
+ int migratetype, int percpu_refill),
+
+ TP_ARGS(page, order, migratetype, percpu_refill),
+
+ TP_STRUCT__entry(
+ __field( const void *, page )
+ __field( unsigned int, order )
+ __field( int, migratetype )
+ __field( int, percpu_refill )
+ ),
+
+ TP_fast_assign(
+ __entry->page = page;
+ __entry->order = order;
+ __entry->migratetype = migratetype;
+ __entry->percpu_refill = percpu_refill;
+ ),
+
+ TP_printk("page = %p pfn=%lu order=%u migratetype=%d percpu_refill=%d",
+ __entry->page,
+ page_to_pfn((struct page *)__entry->page),
+ __entry->order,
+ __entry->migratetype,
+ __entry->percpu_refill)
+);
+
+TRACE_EVENT(free_pages_bulk,
+
+ TP_PROTO(const void *page, int order, int migratetype),
+
+ TP_ARGS(page, order, migratetype),
+
+ TP_STRUCT__entry(
+ __field( const void *, page )
+ __field( int, order )
+ __field( int, migratetype )
+ ),
+
+ TP_fast_assign(
+ __entry->page = page;
+ __entry->order = order;
+ __entry->migratetype = migratetype;
+ ),
+
+ TP_printk("page=%p pfn=%lu order=%d migratetype=%d",
+ __entry->page,
+ page_to_pfn((struct page *)__entry->page),
+ __entry->order,
+ __entry->migratetype)
+);
+
TRACE_EVENT(__rmqueue_fallback,
TP_PROTO(const void *page,
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3fc9f09..f96bf2c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -535,6 +535,7 @@ static void free_pages_bulk(struct zone *zone, int count,
page = list_entry(list->prev, struct page, lru);
/* have to delete it as __free_one_page list manipulates */
list_del(&page->lru);
+ trace_free_pages_bulk(page, order, page_private(page));
__free_one_page(page, zone, order, page_private(page));
}
spin_unlock(&zone->lock);
@@ -878,6 +879,7 @@ retry_reserve:
}
}
+ trace___rmqueue(page, order, migratetype, order == 0);
return page;
}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [RFC PATCH 0/3] Add some trace events for the page allocator
2009-07-28 22:23 [RFC PATCH 0/3] Add some trace events for the page allocator Mel Gorman
` (2 preceding siblings ...)
2009-07-28 22:23 ` [PATCH 3/3] tracing, page-allocator: Add trace event for page traffic related to the buddy lists Mel Gorman
@ 2009-07-28 22:48 ` Frederic Weisbecker
3 siblings, 0 replies; 5+ messages in thread
From: Frederic Weisbecker @ 2009-07-28 22:48 UTC (permalink / raw)
To: Mel Gorman, Steven Rostedt, Li Zefan, Lai Jiangshan, Pekka Enberg,
Eduard - Gabriel Munteanu
Cc: Ingo Molnar, Thomas Gleixner, Peter Zijlstra, Mathieu Desnoyers,
LKML
On Tue, Jul 28, 2009 at 11:23:36PM +0100, Mel Gorman wrote:
> The following three patches add some trace events for the page allocator under
> the heading of kmem (should there be a pagealloc heading instead?). Testing
> under qemu seems to show up reasonable results but this is a prototype for
> comment that hasn't been very heavily tested. I was able to find at least
> one anomaly looking a the output in relation to anti-fragmentation which
> I'm still thinking about so minimally, it was useful for that but I've made
> an attempt to justify each of the events added.
>
> The patches are as follows
>
> Patch 1 adds events for plain old allocate and freeing of pages
> Patch 2 gives information useful for analysing fragmentation avoidance
> Patch 3 tracks pages going to and from the buddy lists as an indirect
> indication of zone lock hotness
>
> The first one could be used as an indicator as to whether the workload was
> heavily dependant on the page allocator or not. You can make a guess based
> on vmstat but you can't get a per-process breakdown. I did have trouble with
> the call-site portion of the allocation. Depending on the path, you might
> just get the address of __get_free_pages() instead of a useful callsite. I
> didn't see a nice way to always report a "useful" call_site.
>
> The second patch would mainly be useful for users of hugepages and
> particularly dynamic hugepage pool resizing as it could be used to tune
> min_free_kbytes to a level that fragmentation was rarely a problem. My
> main concern is that maybe I'm trying to jam too much into the TP_printk
> that could be extrapolated after the fact if you were familiar with the
> implementation. I couldn't determine if it was best to hold the hand of
> the administrator even if it cost more to figure it out.
>
> The last patch is trickier to draw conclusions from but high activity on
> those events could explain why there were a large number of cache misses
> on a page-allocator-intensive workload. The coalescing and splitting of
> buddies involves a lot of writing of page metadata and cache line bounces
> not to mention the acquisition of an interrupt-safe lock necessary to enter
> this path. One problem is that one function traced is likely to change its
> name in the future. When that happens, the trace event will be replaced
> with something similar, but not identical. I've been told this is probably
> ok but there has been whinging in the past about whether debugfs represents
> an ABI or not.
>
> This is the first time I've looked at adding trace events so apologies
> for any obvious mistakes made as I haven't been keeping a close eye on all
> the tracing discussions describing How Things Should Be Done. checkpatch
> throws major wobblies about this patchset, but it's consistent with the
> style of other events so I ignored it. The "To:" list is based taken from
> another tracepoint mail, if there is a specific list I should have used,
> feel free to slap with clue stick. All comments indicating whether this is
> generally useful and how it might be improved are welcome.
(Adding some other tracing + slab allocator/kmemtrace people in Cc)
^ permalink raw reply [flat|nested] 5+ messages in thread