linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: Bin Yang <bin.yang@intel.com>
Cc: mingo@kernel.org, hpa@zytor.com, x86@kernel.org,
	linux-kernel@vger.kernel.org, peterz@infradead.org,
	dave.hansen@intel.com, mark.gross@intel.com
Subject: Re: [PATCH v3 1/5] x86/mm: avoid redundant checking if pgprot has no change
Date: Mon, 3 Sep 2018 23:57:03 +0200 (CEST)	[thread overview]
Message-ID: <alpine.DEB.2.21.1809032127550.1462@nanos.tec.linutronix.de> (raw)
In-Reply-To: <1534814186-37067-2-git-send-email-bin.yang@intel.com>

On Tue, 21 Aug 2018, Bin Yang wrote:
> --- a/arch/x86/mm/pageattr.c
> +++ b/arch/x86/mm/pageattr.c
> @@ -629,6 +629,22 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
>  	new_prot = static_protections(req_prot, address, pfn);
>  
>  	/*
> +	 * The static_protections() is used to check specific protection flags
> +	 * for certain areas of memory. The old pgprot should be checked already
> +	 * when it was applied before. If it's not, then this is a bug in some
> +	 * other code and needs to be fixed there.
> +	 *
> +	 * If new pgprot is same as old pgprot, return directly without any
> +	 * additional checking. The following static_protections() checking is
> +	 * pointless if pgprot has no change. It can avoid the redundant
> +	 * checking and optimize the performance of large page split checking.
> +	 */
> +	if (pgprot_val(new_prot) == pgprot_val(old_prot)) {

This is actually broken.

Assume that for the start address:

       req_prot != old_prot
and
       new_prot != req_prot
and
       new_prot == old_prot
and
       numpages > number_of_static_protected_pages(address)

Then the new check will return with split = NO and the pages after the
static protected area won't be updated -> FAIL! IOW, you partially
reintroduce the bug which was fixed by adding this check loop.

So this is a new optimization check which needs to be:

	if (pgprot_val(req_prot) == pgprot_val(old_prot))

and that check wants to go above:

  	new_prot = static_protections(req_prot, address, pfn);

Both under the assumption that old_prot is correct already.

Now the question is whether this assumption can be made. The current code
does that already today in case of page splits because it copies the
existing pgprot of the large page unmodified over to the new split PTE
page. IOW, if the current mapping is incorrect it will stay that way if
it's not part of the actually modified range.

I'm a bit worried about not having such a check, but if we add that then
this should be done under a debug option for performance reasons.

The last patch which does the overlap check is equally broken:

+       /*
+        * Ensure that the requested pgprot does not violate static protection
+        * requirements.
+        */
+       new_prot = static_protections(req_prot, address,
+                                     numpages << PAGE_SHIFT, pfn);

It expands new_prot to the whole range even if the protections only
overlap. That should not happen in practice, but we have no checks for that
at all.

The whole thing needs way more thought in order not to (re)introduce subtle
and hard to debug bugs.

Thanks,

	tglx









  reply	other threads:[~2018-09-03 21:57 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-21  1:16 [PATCH v3 0/5] x86/mm: fix cpu stuck issue in __change_page_attr_set_clr Bin Yang
2018-08-21  1:16 ` [PATCH v3 1/5] x86/mm: avoid redundant checking if pgprot has no change Bin Yang
2018-09-03 21:57   ` Thomas Gleixner [this message]
2018-09-04  7:01     ` Yang, Bin
2018-09-04  7:49       ` Thomas Gleixner
2018-09-04  9:12         ` Yang, Bin
2018-09-04  9:22           ` Yang, Bin
2018-08-21  1:16 ` [PATCH v3 2/5] x86/mm: avoid static_protection() checking if not whole large page attr change Bin Yang
2018-08-21  1:16 ` [PATCH v3 3/5] x86/mm: add help function to check specific protection flags in range Bin Yang
2018-09-03 22:10   ` Thomas Gleixner
2018-09-04  6:22     ` Yang, Bin
2018-08-21  1:16 ` [PATCH v3 4/5] x86/mm: optimize static_protection() by using overlap() Bin Yang
2018-09-04 12:22   ` Thomas Gleixner
2018-09-07  1:14     ` Yang, Bin
2018-09-07  7:49       ` Thomas Gleixner
2018-09-07  8:04         ` Yang, Bin
2018-09-07  8:21           ` Thomas Gleixner
2018-09-07  8:26             ` Yang, Bin
2018-08-21  1:16 ` [PATCH v3 5/5] x86/mm: add WARN_ON_ONCE() for wrong large page mapping Bin Yang
2018-09-03 22:27   ` Thomas Gleixner
2018-09-04  6:32     ` Yang, Bin
2018-09-04  7:41       ` Thomas Gleixner
2018-09-04 16:52         ` Thomas Gleixner
2018-09-07  2:12           ` Yang, Bin

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=alpine.DEB.2.21.1809032127550.1462@nanos.tec.linutronix.de \
    --to=tglx@linutronix.de \
    --cc=bin.yang@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.gross@intel.com \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=x86@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).