All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vitaly Kuznetsov <vkuznets@redhat.com>
To: David Hildenbrand <david@redhat.com>, devel@linuxdriverproject.org
Cc: Sasha Levin <sashal@kernel.org>,
	"K. Y. Srinivasan" <kys@microsoft.com>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	Stephen Hemminger <sthemmin@microsoft.com>,
	linux-kernel@vger.kernel.org, Dexuan Cui <decui@microsoft.com>
Subject: Re: [PATCH] hv_balloon: avoid touching uninitialized struct page during tail onlining
Date: Mon, 07 Jan 2019 14:44:30 +0100	[thread overview]
Message-ID: <87d0p837lt.fsf@vitty.brq.redhat.com> (raw)
In-Reply-To: <2ea7e975-6aae-de71-83e5-9302518802ef@redhat.com>

David Hildenbrand <david@redhat.com> writes:

> On 04.01.19 15:19, Vitaly Kuznetsov wrote:
>> Hyper-V memory hotplug protocol has 2M granularity and in Linux x86 we use
>> 128M. To deal with it we implement partial section onlining by registering
>> custom page onlining callback (hv_online_page()). Later, when more memory
>> arrives we try to online the 'tail' (see hv_bring_pgs_online()).
>> 
>> It was found that in some cases this 'tail' onlining causes issues:
>> 
>>  BUG: Bad page state in process kworker/0:2  pfn:109e3a
>>  page:ffffe08344278e80 count:0 mapcount:1 mapping:0000000000000000 index:0x0
>>  flags: 0xfffff80000000()
>>  raw: 000fffff80000000 dead000000000100 dead000000000200 0000000000000000
>>  raw: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>>  page dumped because: nonzero mapcount
>>  ...
>>  Workqueue: events hot_add_req [hv_balloon]
>>  Call Trace:
>>   dump_stack+0x5c/0x80
>>   bad_page.cold.112+0x7f/0xb2
>>   free_pcppages_bulk+0x4b8/0x690
>>   free_unref_page+0x54/0x70
>>   hv_page_online_one+0x5c/0x80 [hv_balloon]
>>   hot_add_req.cold.24+0x182/0x835 [hv_balloon]
>>   ...
>> 
>> Turns out that we now have deferred struct page initialization for memory
>> hotplug so e.g. memory_block_action() in drivers/base/memory.c does
>> pages_correctly_probed() check and in that check it avoids inspecting
>> struct pages and checks sections instead. But in Hyper-V balloon driver we
>> do PageReserved(pfn_to_page()) check and this is now wrong.
>> 
>> Switch to checking online_section_nr() instead.
>> 
>> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
>> ---
>>  drivers/hv/hv_balloon.c | 10 ++++++----
>>  1 file changed, 6 insertions(+), 4 deletions(-)
>> 
>> diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
>> index 5301fef16c31..7c6349a50ef1 100644
>> --- a/drivers/hv/hv_balloon.c
>> +++ b/drivers/hv/hv_balloon.c
>> @@ -888,12 +888,14 @@ static unsigned long handle_pg_range(unsigned long pg_start,
>>  			pfn_cnt -= pgs_ol;
>>  			/*
>>  			 * Check if the corresponding memory block is already
>> -			 * online by checking its last previously backed page.
>> -			 * In case it is we need to bring rest (which was not
>> -			 * backed previously) online too.
>> +			 * online. It is possible to observe struct pages still
>> +			 * being uninitialized here so check section instead.
>> +			 * In case the section is online we need to bring the
>> +			 * rest of pfns (which were not backed previously)
>> +			 * online too.
>>  			 */
>>  			if (start_pfn > has->start_pfn &&
>> -			    !PageReserved(pfn_to_page(start_pfn - 1)))
>> +			    online_section_nr(pfn_to_section_nr(start_pfn)))
>>  				hv_bring_pgs_online(has, start_pfn, pgs_ol);
>>  
>>  		}
>> 
>
> I wonder if you should use pfn_to_online_page() and check for PageOffline().
>
> (I guess online_section_nr() should also do the trick)

I'm worried a bit about racing with mm code here as we're not doing
mem_hotplug_begin()/done() so I'd slightly prefer keeping
online_section_nr() (pfn_to_online_page() also uses it but then it gets
to the particular struct page). Moreover, with pfn_to_online_page() we
will be looking at some other pfn - because the start_pfn is definitelly
offline (pre-patch we were looking at start_pfn-1). Just looking at the
whole section seems cleaner.

P.S. I still think about bringing mem_hotplug_begin()/done() to
hv_balloon but that's going to be a separate discussion, here I want to
have a small fix backportable to stable.

Thanks,

-- 
Vitaly

  reply	other threads:[~2019-01-07 13:44 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-04 14:19 [PATCH] hv_balloon: avoid touching uninitialized struct page during tail onlining Vitaly Kuznetsov
2019-01-07 10:21 ` David Hildenbrand
2019-01-07 13:44   ` Vitaly Kuznetsov [this message]
2019-01-07 17:56     ` Sasha Levin
2019-01-07 18:38       ` Vitaly Kuznetsov
2019-01-08  6:41         ` Greg KH
2019-01-08  9:47         ` Dan Carpenter
2019-01-08 14:34           ` Vitaly Kuznetsov
2019-01-08 21:23         ` Sasha Levin
2019-01-08  9:15     ` David Hildenbrand
2019-01-08  9:42       ` Vitaly Kuznetsov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87d0p837lt.fsf@vitty.brq.redhat.com \
    --to=vkuznets@redhat.com \
    --cc=david@redhat.com \
    --cc=decui@microsoft.com \
    --cc=devel@linuxdriverproject.org \
    --cc=haiyangz@microsoft.com \
    --cc=kys@microsoft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sashal@kernel.org \
    --cc=sthemmin@microsoft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.