netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Chen Lin" <chen45464546@163.com>
To: "Alexander Duyck" <alexander.duyck@gmail.com>
Cc: "Maurizio Lombardi" <mlombard@redhat.com>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	linux-mm <linux-mm@kvack.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Netdev <netdev@vger.kernel.org>
Subject: Re:Re: Re: Re: [PATCH V3] mm: prevent page_frag_alloc() from corrupting the memory
Date: Thu, 21 Jul 2022 21:05:33 +0800 (CST)	[thread overview]
Message-ID: <351f0b3c.b021.18220dd0b35.Coremail.chen45464546@163.com> (raw)
In-Reply-To: <CAKgT0Ueq=9XGW4uySmDj1sa9MYosaF4S6Na_jcVyiofW_TqgwA@mail.gmail.com>


At 2022-07-20 22:54:18, "Alexander Duyck" <alexander.duyck@gmail.com> wrote:
>On Tue, Jul 19, 2022 at 3:27 PM Chen Lin <chen45464546@163.com> wrote:
>>
>> At 2022-07-18 23:33:42, "Alexander Duyck" <alexander.duyck@gmail.com> wrote:
>> >On Mon, Jul 18, 2022 at 8:25 AM Maurizio Lombardi <mlombard@redhat.com> wrote:
>> >>
>> >> po 18. 7. 2022 v 16:40 odesílatel Chen Lin <chen45464546@163.com> napsal:
>> >> >
>> >> > But the original intention of page frag interface is indeed to allocate memory
>> >> > less than one page. It's not a good idea to  complicate the definition of
>> >> > "page fragment".
>> >>
>> >> I see your point, I just don't think it makes much sense to break
>> >> drivers here and there
>> >> when a practically identical 2-lines patch can fix the memory corruption bug
>> >> without changing a single line of code in the drivers.
>> >>
>> >> By the way, I will wait for the maintainers to decide on the matter.
>> >>
>> >> Maurizio
>> >
>> >I'm good with this smaller approach. If it fails only under memory
>> >pressure I am good with that. The issue with the stricter checking is
>> >that it will add additional overhead that doesn't add much value to
>> >the code.
>> >
>> >Thanks,
>> >
>>
>> >- Alex
>>
>> One additional question:
>> I don't understand too much about  why point >A<  have more overhead than point >B<.
>> It all looks the same, except for jumping to the refill process, and the refill is a very long process.
>> Could you please give more explain?
>>
>>         if (unlikely(offset < 0)) {
>>                  -------------->A<------------
>
>In order to verify if the fragsz is larger than a page we would have
>to add a comparison between two values that aren't necessarily related
>to anything else in this block of code.
>
>Adding a comparison at this point should end up adding instructions
>along the lines of
>        cmp $0x1000,%[some register]
>        jg <return NULL block>
>
>These two lines would end up applying to everything that takes this
>path so every time we hit the end of a page we would encounter it, and
>in almost all cases it shouldn't apply so it is extra instructions. In
>addition they would be serialized with the earlier subtraction since
>we can't process it until after the first comparison which is actually
>using the flags to perform the check since it is checking if offset is
>signed.
>
>>                 page = virt_to_page(nc->va);
>>
>>                 if (!page_ref_sub_and_test(page, nc->pagecnt_bias))
>>                         goto refill;
>>
>>                 if (unlikely(nc->pfmemalloc)) {
>>                         free_the_page(page, compound_order(page));
>>                         goto refill;
>>                 }
>>
>> #if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE)
>>                 /* if size can vary use size else just use PAGE_SIZE */
>>                 size = nc->size;
>> #endif
>>                 /* OK, page count is 0, we can safely set it */
>>                 set_page_count(page, PAGE_FRAG_CACHE_MAX_SIZE + 1);
>>
>>                 /* reset page count bias and offset to start of new frag */
>>                 nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1;
>>                 offset = size - fragsz;
>>                  -------------->B<------------
>
>At this point we have already excluded the shared and pfmemalloc
>pages. Here we don't have to add a comparison. The comparison is
>already handled via the size - fragsz, we just need to make use of the
>flags following the operation by checking to see if offset is signed.
>
>So the added assembler would be something to the effect of:
>        js <return NULL block>
>
>In addition the assignment operations there should have no effect on
>the flags so the js can be added to the end of the block without
>having to do much in terms of forcing any reordering of the
>instructions.

Thank you for your detailed explanation, I get it.
I objdump the vmlinux on different modified versions and verified that 
the generated instructions are the same as what you said. 

Under the strict performance requirements, there seems no better way
than the patch Maurizio proposed.

  reply	other threads:[~2022-07-21 13:07 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-15 12:50 [PATCH V3] mm: prevent page_frag_alloc() from corrupting the memory Maurizio Lombardi
2022-07-18 13:14 ` Chen Lin
2022-07-18 13:50   ` [PATCH " Maurizio Lombardi
2022-07-18 14:40     ` Chen Lin
2022-07-18 15:25       ` Maurizio Lombardi
2022-07-18 15:33         ` Alexander Duyck
2022-07-19 22:27           ` Chen Lin
2022-07-20 14:54             ` Alexander Duyck
2022-07-21 13:05               ` Chen Lin [this message]
     [not found] ` <62aacb46.a9b1.182110646cf.Coremail.chen45464546@163.com>
2022-07-18 13:46   ` Maurizio Lombardi
2022-08-09  0:14 ` Andrew Morton
2022-08-09 11:45   ` Maurizio Lombardi
2022-08-09 14:33     ` Alexander Duyck

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=351f0b3c.b021.18220dd0b35.Coremail.chen45464546@163.com \
    --to=chen45464546@163.com \
    --cc=akpm@linux-foundation.org \
    --cc=alexander.duyck@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mlombard@redhat.com \
    --cc=netdev@vger.kernel.org \
    /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 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).