linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH] mm/hugetlb: Avoid soft lockup in set_max_huge_pages()
@ 2016-07-26 15:44 Jia He
  2016-07-26 15:58 ` Dave Hansen
  0 siblings, 1 reply; 5+ messages in thread
From: Jia He @ 2016-07-26 15:44 UTC (permalink / raw)
  To: linux-mm
  Cc: linux-kernel, Jia He, Andrew Morton, Naoya Horiguchi,
	Mike Kravetz, Kirill A. Shutemov, Michal Hocko, Dave Hansen,
	Paul Gortmaker

In large memory(32TB) powerpc servers, we watched several soft lockup under
stress tests.
The call trace are as follows:
1.
get_page_from_freelist+0x2d8/0xd50  
__alloc_pages_nodemask+0x180/0xc20  
alloc_fresh_huge_page+0xb0/0x190    
set_max_huge_pages+0x164/0x3b0      

2.
prep_new_huge_page+0x5c/0x100             
alloc_fresh_huge_page+0xc8/0x190          
set_max_huge_pages+0x164/0x3b0

This patch is to fix such soft lockup. I thouhgt it is safe to call 
cond_resched() because alloc_fresh_gigantic_page and alloc_fresh_huge_page 
are out of spin_lock/unlock section.

Signed-off-by: Jia He <hejianet@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>

---
 mm/hugetlb.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index addfe4ac..d51759d 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1146,6 +1146,10 @@ static int alloc_fresh_gigantic_page(struct hstate *h,
 
 	for_each_node_mask_to_alloc(h, nr_nodes, node, nodes_allowed) {
 		page = alloc_fresh_gigantic_page_node(h, node);
+
+		/* yield cpu */
+		cond_resched();
+
 		if (page)
 			return 1;
 	}
@@ -1381,6 +1385,10 @@ static int alloc_fresh_huge_page(struct hstate *h, nodemask_t *nodes_allowed)
 
 	for_each_node_mask_to_alloc(h, nr_nodes, node, nodes_allowed) {
 		page = alloc_fresh_huge_page_node(h, node);
+
+		/* yield cpu */
+		cond_resched();
+
 		if (page) {
 			ret = 1;
 			break;
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [RFC PATCH] mm/hugetlb: Avoid soft lockup in set_max_huge_pages()
  2016-07-26 15:44 [RFC PATCH] mm/hugetlb: Avoid soft lockup in set_max_huge_pages() Jia He
@ 2016-07-26 15:58 ` Dave Hansen
  2016-07-26 16:35   ` hejianet
  2016-07-27  1:39   ` hejianet
  0 siblings, 2 replies; 5+ messages in thread
From: Dave Hansen @ 2016-07-26 15:58 UTC (permalink / raw)
  To: Jia He, linux-mm
  Cc: linux-kernel, Andrew Morton, Naoya Horiguchi, Mike Kravetz,
	Kirill A. Shutemov, Michal Hocko, Paul Gortmaker

On 07/26/2016 08:44 AM, Jia He wrote:
> This patch is to fix such soft lockup. I thouhgt it is safe to call 
> cond_resched() because alloc_fresh_gigantic_page and alloc_fresh_huge_page 
> are out of spin_lock/unlock section.

Yikes.  So the call site for both the things you patch is this:

>         while (count > persistent_huge_pages(h)) {
...
>                 spin_unlock(&hugetlb_lock);
>                 if (hstate_is_gigantic(h))
>                         ret = alloc_fresh_gigantic_page(h, nodes_allowed);
>                 else
>                         ret = alloc_fresh_huge_page(h, nodes_allowed);
>                 spin_lock(&hugetlb_lock);

and you choose to patch both of the alloc_*() functions.  Why not just
fix it at the common call site?  Seems like that
spin_lock(&hugetlb_lock) could be a cond_resched_lock() which would fix
both cases.

Also, putting that cond_resched() inside the for_each_node*() loop is an
odd choice.  It seems to indicate that the loops can take a long time,
which really isn't the case.  The _loop_ isn't long, right?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC PATCH] mm/hugetlb: Avoid soft lockup in set_max_huge_pages()
  2016-07-26 15:58 ` Dave Hansen
@ 2016-07-26 16:35   ` hejianet
  2016-07-27  1:39   ` hejianet
  1 sibling, 0 replies; 5+ messages in thread
From: hejianet @ 2016-07-26 16:35 UTC (permalink / raw)
  To: Dave Hansen, linux-mm
  Cc: linux-kernel, Andrew Morton, Naoya Horiguchi, Mike Kravetz,
	Kirill A. Shutemov, Michal Hocko, Paul Gortmaker



On 7/26/16 11:58 PM, Dave Hansen wrote:
> On 07/26/2016 08:44 AM, Jia He wrote:
>> This patch is to fix such soft lockup. I thouhgt it is safe to call
>> cond_resched() because alloc_fresh_gigantic_page and alloc_fresh_huge_page
>> are out of spin_lock/unlock section.
> Yikes.  So the call site for both the things you patch is this:
>
>>          while (count > persistent_huge_pages(h)) {
> ...
>>                  spin_unlock(&hugetlb_lock);
>>                  if (hstate_is_gigantic(h))
>>                          ret = alloc_fresh_gigantic_page(h, nodes_allowed);
>>                  else
>>                          ret = alloc_fresh_huge_page(h, nodes_allowed);
>>                  spin_lock(&hugetlb_lock);
> and you choose to patch both of the alloc_*() functions.  Why not just
> fix it at the common call site?  Seems like that
> spin_lock(&hugetlb_lock) could be a cond_resched_lock() which would fix
> both cases.
>
> Also, putting that cond_resched() inside the for_each_node*() loop is an
> odd choice.  It seems to indicate that the loops can take a long time,
> which really isn't the case.  The _loop_ isn't long, right?
Yes,thanks for the suggestions
Will send out V2 later

B.R.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC PATCH] mm/hugetlb: Avoid soft lockup in set_max_huge_pages()
  2016-07-26 15:58 ` Dave Hansen
  2016-07-26 16:35   ` hejianet
@ 2016-07-27  1:39   ` hejianet
  2016-07-27 15:26     ` Dave Hansen
  1 sibling, 1 reply; 5+ messages in thread
From: hejianet @ 2016-07-27  1:39 UTC (permalink / raw)
  To: Dave Hansen, linux-mm
  Cc: linux-kernel, Andrew Morton, Naoya Horiguchi, Mike Kravetz,
	Kirill A. Shutemov, Michal Hocko, Paul Gortmaker

Hi Dave

On 7/26/16 11:58 PM, Dave Hansen wrote:
> On 07/26/2016 08:44 AM, Jia He wrote:
>> This patch is to fix such soft lockup. I thouhgt it is safe to call
>> cond_resched() because alloc_fresh_gigantic_page and alloc_fresh_huge_page
>> are out of spin_lock/unlock section.
> Yikes.  So the call site for both the things you patch is this:
>
>>          while (count > persistent_huge_pages(h)) {
> ...
>>                  spin_unlock(&hugetlb_lock);
>>                  if (hstate_is_gigantic(h))
>>                          ret = alloc_fresh_gigantic_page(h, nodes_allowed);
>>                  else
>>                          ret = alloc_fresh_huge_page(h, nodes_allowed);
>>                  spin_lock(&hugetlb_lock);
> and you choose to patch both of the alloc_*() functions.  Why not just
> fix it at the common call site?  Seems like that
> spin_lock(&hugetlb_lock) could be a cond_resched_lock() which would fix
> both cases.
I agree to move the cond_resched() to a common site in set_max_huge_pages().
But do you mean the spin_lock in this while loop can be replaced by
cond_resched_lock?
IIUC, cond_resched_lock = spin_unlock+cond_resched+spin_lock.
So could you please explain more details about it? Thanks.

B.R.
Justin
> Also, putting that cond_resched() inside the for_each_node*() loop is an
> odd choice.  It seems to indicate that the loops can take a long time,
> which really isn't the case.  The _loop_ isn't long, right?
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC PATCH] mm/hugetlb: Avoid soft lockup in set_max_huge_pages()
  2016-07-27  1:39   ` hejianet
@ 2016-07-27 15:26     ` Dave Hansen
  0 siblings, 0 replies; 5+ messages in thread
From: Dave Hansen @ 2016-07-27 15:26 UTC (permalink / raw)
  To: hejianet, linux-mm
  Cc: linux-kernel, Andrew Morton, Naoya Horiguchi, Mike Kravetz,
	Kirill A. Shutemov, Michal Hocko, Paul Gortmaker

On 07/26/2016 06:39 PM, hejianet wrote:
>>>
>> and you choose to patch both of the alloc_*() functions.  Why not just
>> fix it at the common call site?  Seems like that
>> spin_lock(&hugetlb_lock) could be a cond_resched_lock() which would fix
>> both cases.
> I agree to move the cond_resched() to a common site in 
> set_max_huge_pages(). But do you mean the spin_lock in this while
> loop can be replaced by cond_resched_lock? IIUC, cond_resched_lock =
> spin_unlock+cond_resched+spin_lock. So could you please explain more
> details about it? Thanks.

Ahh, good point.  A plain cond_resched() outside the lock is probably
sufficient here.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-07-27 15:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-26 15:44 [RFC PATCH] mm/hugetlb: Avoid soft lockup in set_max_huge_pages() Jia He
2016-07-26 15:58 ` Dave Hansen
2016-07-26 16:35   ` hejianet
2016-07-27  1:39   ` hejianet
2016-07-27 15:26     ` Dave Hansen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).