Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1190060 > unrolled thread

Re: [RFC 1/4] mm, compaction: introduce kcompactd

Started byVlastimil Babka <vbabka@suse.cz>
First post2015-07-22 17:30 +0200
Last post2015-07-29 02:40 +0200
Articles 4 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [RFC 1/4] mm, compaction: introduce kcompactd Vlastimil Babka <vbabka@suse.cz> - 2015-07-22 17:30 +0200
    Re: [RFC 1/4] mm, compaction: introduce kcompactd David Rientjes <rientjes@google.com> - 2015-07-23 00:40 +0200
      Re: [RFC 1/4] mm, compaction: introduce kcompactd David Rientjes <rientjes@google.com> - 2015-07-23 23:30 +0200
        Re: [RFC 1/4] mm, compaction: introduce kcompactd David Rientjes <rientjes@google.com> - 2015-07-29 02:40 +0200

#1190060 — Re: [RFC 1/4] mm, compaction: introduce kcompactd

FromVlastimil Babka <vbabka@suse.cz>
Date2015-07-22 17:30 +0200
SubjectRe: [RFC 1/4] mm, compaction: introduce kcompactd
Message-ID<pP483-2op-33@gated-at.bofh.it>
On 07/22/2015 01:07 AM, David Rientjes wrote:
> On Tue, 21 Jul 2015, Vlastimil Babka wrote:
>
>>> Khugepaged benefits from the periodic memory compaction being done
>>> immediately before it attempts to compact memory, and that may be lost
>>> with a de-coupled approach like this.
>>
>
> Meant to say "before it attempts to allocate a hugepage", but it seems you
> understood that :)

Right :)

>> That could be helped with waking up khugepaged after kcompactd is successful
>> in making a hugepage available.
>
> I don't think the criteria for waking up khugepaged should become any more
> complex beyond its current state, which is impacted by two different
> tunables, and whether it actually has memory to scan.  During this
> additional wakeup, you'd also need to pass kcompactd's node and only do
> local khugepaged scanning since there's no guarantee khugepaged can
> allocate on all nodes when one kcompactd defragments memory.

Keeping track of the nodes where hugepage allocations are expected to 
succeed is already done in this series. "local khugepaged scanning" is 
unfortunately not possible in general, since the node that will be used 
for a given pmd is not known until half of pte's (or more) are scanned.

> I think
> coupling these two would be too complex and not worth it.

It wouldn't be that complex (see above), and go away if khugepaged 
scanning is converted to deferred task work. In that case it's also 
possible to assume that it's only worth touching memory local to the 
task, so if that node indicates no available hugepages, the scanning can 
be skipped.

>> Also in your rfc you propose the compaction
>> period to be 15 minutes, while khugepaged wakes up each 10 (or 30) seconds by
>> default for the scanning and collapsing, so only fraction of the work is
>> attempted right after the compaction anyway?
>>
>
> The rfc actually proposes the compaction period to be 0, meaning it's
> disabled, but suggests in the changelog that we have seen a reproducible
> benefit with the period of 15m.

Ah, right.

> I'm not concerned about scan_sleep_millisecs here, if khugepaged was able
> to successfully allocate in its last scan.  I'm only concerned with
> alloc_sleep_millisecs which defaults to 60000.  I think it would be
> unfortunate if kcompactd were to free a pageblock, and then khugepaged
> waits for 60s before allocating.

Don't forget that khugepaged has to find a suitable pmd first, which can 
take much longer than 60s. It might be rescanning address spaces that 
have no candidates, or processes that are sleeping and wouldn't benefit 
from THP. Another potential advantage for doing the scanning and 
collapses in task context...

>> Hm reports of even not-so-high-order allocation failures occur from time to
>> time. Some might be from atomic context, but some are because compaction just
>> can't help due to the unmovable fragmentation. That's mostly a guess, since
>> such detailed information isn't there, but I think Joonsoo did some
>> experiments that confirmed this.
>>
>
> If it's unmovable fragmentation, then any periodic synchronous memory
> compaction isn't going to help either.

It can help if it moves away movable pages out of unmovable pageblocks, 
so the following unmovable allocations can be served from those 
pageblocks and not fallback to pollute another movable pageblock. Even 
better if this is done (kcompactd woken up) in response to such 
fallback, where unmovable page falls to a partially filled movable 
pageblock. Stuffing also this into khugepaged would be really a stretch. 
Joonsoo proposed another daemon for that in
https://lkml.org/lkml/2015/4/27/94 but extending kcompactd would be a 
very natural way for this.

> The page allocator already does
> MIGRATE_SYNC_LIGHT compaction on its second pass and that will terminate
> when a high-order page is available.  If it is currently failing, then I
> don't see the benefit of synchronous memory compaction over all memory
> that would substantially help this case.

The sync compaction is no longer done for THP page faults, so if there's 
no other source of the sync compaction, system can fragment over time 
and then it might be too late when the need comes.

>> Also effects on the fragmentation are evaluated when making changes to
>> compaction, see e.g. http://marc.info/?l=linux-mm&m=143634369227134&w=2
>> In the past it has prevented changes that would improve latency of direct
>> compaction. They might be possible if there was a reliable source of more
>> thorough periodic compaction to counter the not-so-thorough direct compaction.
>>
>
> Hmm, I don't think we have to select one to the excusion of the other.  I
> don't think that because khugepaged may do periodic synchronous memory
> compaction (to eventually remove direct compaction entirely from the page
> fault path, since we have checks in the page allocator that specifically
> do that)

That would be nice for the THP page faults, yes. Or maybe just change 
the default for thp "defrag" tunable to "madvise".

> that we can't do background memory compaction elsewhere.  I think
> it would be trivial to schedule a workqueue in the page allocator when
> MIGRATE_ASYNC compaction fails for a high-order allocation on a node and
> to have that local compaction done in the background.

I think pushing compaction in a workqueue would meet a bigger resistance 
than new kthreads. It could be too heavyweight for this mechanism and 
what if there's suddenly lots of allocations in parallel failing and 
scheduling the work items? So if we do it elsewhere, I think it's best 
as kcompactd kthreads and then why would we do it also in khugepaged?

I guess a broader input than just us two would help :)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1190340

FromDavid Rientjes <rientjes@google.com>
Date2015-07-23 00:40 +0200
Message-ID<pPaQa-4FE-15@gated-at.bofh.it>
In reply to#1190060
On Wed, 22 Jul 2015, Vlastimil Babka wrote:

> > I don't think the criteria for waking up khugepaged should become any more
> > complex beyond its current state, which is impacted by two different
> > tunables, and whether it actually has memory to scan.  During this
> > additional wakeup, you'd also need to pass kcompactd's node and only do
> > local khugepaged scanning since there's no guarantee khugepaged can
> > allocate on all nodes when one kcompactd defragments memory.
> 
> Keeping track of the nodes where hugepage allocations are expected to succeed
> is already done in this series. "local khugepaged scanning" is unfortunately
> not possible in general, since the node that will be used for a given pmd is
> not known until half of pte's (or more) are scanned.
> 

When a khugepaged allocation fails for a node, it could easily kick off 
background compaction on that node and revisit the range later, very 
similar to how we can kick off background compaction in the page allocator 
when async or sync_light compaction fails.

The distinction I'm trying to draw is between "periodic" and "background" 
compaction.  I think there're usecases for both and we shouldn't be 
limiting ourselves to one or the other.

Periodic compaction would wakeup at a user-defined period and fully 
compact memory over all nodes, round-robin at each wakeup.  This keeps 
fragmentation low so that (ideally) background compaction or direct 
compaction wouldn't be needed.

Background compaction would be triggered from the page allocator when 
async or sync_light compaction fails, regardless of whether this was from 
khugepaged, page fault context, or any other high-order allocation.  This 
is an interesting discussion because I can think of lots of ways to be 
smart about it, but I haven't tried to implement it yet: heuristics that 
do ratelimiting, preemptive compaction based on fragmentation stats, etc.

My rfc implements periodic compaction in khugepaged simply because we find 
very large thp_fault_fallback numbers and these faults tend to come in 
bunches so that background compaction wouldn't really help the situation 
itself: it's simply not fast enough and we give up compaction at fault way 
too early for it have a chance of being successful.  I have a hard time 
finding other examples of that outside thp, especially at such large 
orders.  The number one culprit that I can think of would be slub and I 
haven't seen any complaints about high order_fallback stats.

The additional benefit of doing the periodic compaction in khugepaged is 
that we can do it before scanning, where alloc_sleep_millisecs is so high 
that kicking off background compaction on allocation failure wouldn't 
help.

Then, storing the nodes where khugepaged allocation has failed isn't 
needed: the allocation itself would trigger background compaction.

> > If it's unmovable fragmentation, then any periodic synchronous memory
> > compaction isn't going to help either.
> 
> It can help if it moves away movable pages out of unmovable pageblocks, so the
> following unmovable allocations can be served from those pageblocks and not
> fallback to pollute another movable pageblock. Even better if this is done
> (kcompactd woken up) in response to such fallback, where unmovable page falls
> to a partially filled movable pageblock. Stuffing also this into khugepaged
> would be really a stretch. Joonsoo proposed another daemon for that in
> https://lkml.org/lkml/2015/4/27/94 but extending kcompactd would be a very
> natural way for this.
> 

Sure, this is an example of why background compaction would be helpful and 
triggered by the page allocator when async or migrate_sync allocation 
fails.

> > Hmm, I don't think we have to select one to the excusion of the other.  I
> > don't think that because khugepaged may do periodic synchronous memory
> > compaction (to eventually remove direct compaction entirely from the page
> > fault path, since we have checks in the page allocator that specifically
> > do that)
> 
> That would be nice for the THP page faults, yes. Or maybe just change the
> default for thp "defrag" tunable to "madvise".
> 

Right, however I'm afraid that what we have done to compaction in the 
fault path for MIGRATE_ASYNC has been implicitly change that default in 
the code :)  I have examples where async compaction in the fault path 
scans three pageblocks and gives up because of the abort heuristics, 
that's not suggesting that we'll be very successful.  The hope is that we 
can change the default to "madvise" due to periodic and background 
compaction and then make the "always" case do some actual defrag :)

> I think pushing compaction in a workqueue would meet a bigger resistance than
> new kthreads. It could be too heavyweight for this mechanism and what if
> there's suddenly lots of allocations in parallel failing and scheduling the
> work items? So if we do it elsewhere, I think it's best as kcompactd kthreads
> and then why would we do it also in khugepaged?
> 

We'd need the aforementioned ratelimiting to ensure that background 
compaction is handled appropriately, absolutely.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1191323

FromDavid Rientjes <rientjes@google.com>
Date2015-07-23 23:30 +0200
Message-ID<pPwdY-21o-5@gated-at.bofh.it>
In reply to#1190340
On Thu, 23 Jul 2015, Vlastimil Babka wrote:

> > When a khugepaged allocation fails for a node, it could easily kick off 
> > background compaction on that node and revisit the range later, very 
> > similar to how we can kick off background compaction in the page allocator 
> > when async or sync_light compaction fails.
> 
> The revisiting sounds rather complicated. Page allocator doesn't have to do that.
> 

I'm referring to khugepaged having a hugepage allocation fail, the page 
allocator kicking off background compaction, and khugepaged rescanning the 
same memory for which the allocation failed later.

> > The distinction I'm trying to draw is between "periodic" and "background" 
> > compaction.  I think there're usecases for both and we shouldn't be 
> > limiting ourselves to one or the other.
> 
> OK, I understand you think we can have both, and the periodic one would be in
> khugepaged. My main concern is that if we do the periodic one in khugepaged,
> people might oppose adding yet another one as kcompactd. I hope we agree that
> khugepaged is not suitable for all the use cases of the background one.
> 

Yes, absolutely.  I agree that we need the ability to do background 
compaction without requiring CONFIG_TRANSPARENT_HUGEPAGE.

> My secondary concern/opinion is that I would hope that the background compaction
> would be good enough to remove the need for the periodic one. So I would try the
> background one first. But I understand the periodic one is simpler to implement.
> On the other hand, it's not as urgent if you can simulate it from userspace.
> With the 15min period you use, there's likely not much overhead saved when
> invoking it from within the kernel? Sure there wouldn't be the synchronization
> with khugepaged activity, but I still wonder if wiating for up to 1 minute
> before khugepaged wakes up can make much difference with the 15min period.
> Hm, your cron job could also perhaps adjust the khugepaged sleep tunable when
> compaction is done, which IIRC results in immediate wakeup.
> 

There are certainly ways to do this from userspace, but the premise is 
that this issue, specifically for users of thp, is significant for 
everyone ;)

The problem that I've encountered with a background-only approach is that 
it doesn't help when you exec a large process that wants to fault most of 
its text and thp immediately cannot be allocated.  This can be a result of 
never having done any compaction at all other than from the page 
allocator, which terminates when a page of the given order is available.  
So on a fragmented machine, all memory faulted is shown in 
thp_fault_fallback and we rely on khugepaged to (slowly) fix this problem 
up for us.  We have shown great improvement in cpu utilization by 
periodically compacting memory today.

Background compaction arguably wouldn't help that situation because it's 
not fast enough to compact memory simultaneous to the large number of page 
faults, and you can't wait for it to complete at exec().  The result is 
the same: large thp_fault_fallback.

So I can understand the need for both periodic and background compaction 
(and direct compaction for non-thp non-atomic high-order allocations 
today) and I'm perhaps not as convinced as you are that we can eventually 
do without periodic compaction.


It seems to me that the vast majority of this discussion has centered 
around the vehicle that performs the compaction.  We certainly require 
kcompactd for background compaction, and we both agree that we need that 
functionality.

Two issues I want to bring up:

 (1) do non-thp configs benefit from periodic compaction?

     In my experience, no, but perhaps there are other use cases where
     this has been a pain.  The primary candidates, in my opinion,
     would be the networking stack and slub.  Joonsoo reports having to
     workaround issues with high-order slub allocations being too
     expensive.  I'm not sure that would be better served by periodic
     compaction, but it seems like a candidate for background compaction.

     This is why my rfc tied periodic compaction to khugepaged, and we
     have strong evidence that this helps thp and cpu utilization.  For
     periodic compaction to be possible outside of thp, we'd need a use
     case for it.

 (2) does kcompactd have to be per-node?

     I don't see the immediate benefit since direct compaction can
     already scan remote memory and migrate it, khugepaged can do the
     same.  Is there evidence that suggests that a per-node kcompactd
     is significantly better than a single kthread?  I think others
     would be more receptive of a single kthread addition.

My theory is that periodic compaction is only significantly beneficial for 
thp per my rfc, and I think there's a significant advantage for khugepaged 
to be able to trigger this periodic compaction immediately before scanning 
and allocating to avoid waiting potentially for the lengthy 
alloc_sleep_millisecs.  I don't see a problem with defining the period 
with a khugepaged tunable for that reason.

For background compaction, which is more difficult, it would be simple to 
implement a kcompactd to perform the memory compaction and actually be 
triggered by khugepaged to do the compaction on its behalf and wait to 
scan and allocate until it' complete.  The vehicle will probably end up as 
kcompactd doing the actual compaction is both cases.

But until we have a background compaction implementation, it seems like 
there's no objection to doing and defining periodic compaction in 
khugepaged as the rfc proposes?  It seems like we can easily extend that 
in the future once background compaction is available.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1194746

FromDavid Rientjes <rientjes@google.com>
Date2015-07-29 02:40 +0200
Message-ID<pRnzA-qS-11@gated-at.bofh.it>
In reply to#1191323
On Fri, 24 Jul 2015, Vlastimil Babka wrote:

> > Two issues I want to bring up:
> > 
> >   (1) do non-thp configs benefit from periodic compaction?
> > 
> >       In my experience, no, but perhaps there are other use cases where
> >       this has been a pain.  The primary candidates, in my opinion,
> >       would be the networking stack and slub.  Joonsoo reports having to
> >       workaround issues with high-order slub allocations being too
> >       expensive.  I'm not sure that would be better served by periodic
> >       compaction, but it seems like a candidate for background compaction.
> 
> Yes hopefully a proactive background compaction would serve them enough.
> 
> >       This is why my rfc tied periodic compaction to khugepaged, and we
> >       have strong evidence that this helps thp and cpu utilization.  For
> >       periodic compaction to be possible outside of thp, we'd need a use
> >       case for it.
> > 
> >   (2) does kcompactd have to be per-node?
> > 
> >       I don't see the immediate benefit since direct compaction can
> >       already scan remote memory and migrate it, khugepaged can do the
> 
> It can work remotely, but it's slower.
> 
> >       same.  Is there evidence that suggests that a per-node kcompactd
> >       is significantly better than a single kthread?  I think others
> >       would be more receptive of a single kthread addition.
> 
> I think it's simpler design wrt waking up the kthread for the desired node,
> and self-tuning any sleeping depending on per-node pressure. It also matches
> the design of kswapd. And IMHO machines with many memory nodes should
> naturally have also many CPU's to cope with the threads, so it should all
> scale well.
> 

I see your "proactive background compaction" as my "periodic compaction" 
:)  And I agree with your comment that we should be careful about defining 
the API so it can be easily extended in the future.

I see the two mechanisms different enough that they need to be defined 
separately: periodic compaction that would be done at certain intervals 
regardless of fragmentation or allocation failures to keep fragmentation 
low, and background compaction that would be done when a zone reaches a 
certain fragmentation index for high orders, similar to extfrag_threshold, 
or an allocation failure.

Per-node kcompactd threads we agree would be optimal, so let's try to see 
if we can make that work.

What do you think about the following?

 - add vm.compact_period_secs to define the number of seconds between
   full compactions on each node.  This compaction would reset the
   pageblock skip heuristic and be synchronous.  It would default to 900
   based only on our evidence that 15m period compaction helps increase
   our cpu utilization for khugepaged; it is arbitrary and I'd happily
   change it if someone has a better suggestion.  Changing it to 0 would
   disable periodic compaction (we don't anticipate anybody will ever
   want kcompactd threads will take 100% of cpu on each node).  We can
   stagger this over all nodes to avoid all kcompactd threads working at
   the same time.

 - add vm.compact_background_extfrag_threshold to define the extfrag
   threshold when kcompactd should start doing sync_light migration
   in the background without resetting the pageblock skip heuristic.
   The threshold is defined at PAGE_ALLOC_COSTLY_ORDER and is halved
   for each order higher so that very high order allocations don't
   trigger it.  To reduce overhead, this can be checked only in the
   slowpath.

I'd also like to talk about compacting of mlocked memory and limit it to 
only periodic compaction so that we aren't constantly incurring minor 
faults when not expected.

How does this sound?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web