All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Daney <ddaney@caviumnetworks.com>
To: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>, <linux-mips@linux-mips.org>,
	Lars Persson <lars.persson@axis.com>,
	"stable # v4 . 1+" <stable@vger.kernel.org>,
	"Steven J. Hill" <Steven.Hill@imgtec.com>,
	David Daney <david.daney@cavium.com>,
	Huacai Chen <chenhc@lemote.com>,
	Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>,
	<linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Jerome Marchand <jmarchan@redhat.com>,
	"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Subject: Re: [PATCH 4/4] MIPS: Sync icache & dcache in set_pte_at
Date: Fri, 4 Mar 2016 09:43:54 -0800	[thread overview]
Message-ID: <56D9C95A.5020106@caviumnetworks.com> (raw)
In-Reply-To: <20160301171940.GA26791@NP-P-BURTON>

On 03/01/2016 09:19 AM, Paul Burton wrote:
> On Tue, Mar 01, 2016 at 09:13:23AM -0800, David Daney wrote:
>> On 02/29/2016 06:37 PM, Paul Burton wrote:
>> [...]
>>> @@ -234,6 +237,22 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
>>>   }
>>>   #endif
>>>
>>> +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
>>> +			      pte_t *ptep, pte_t pteval)
>>> +{
>>> +	extern void __update_cache(unsigned long address, pte_t pte);
>>> +
>>> +	if (!pte_present(pteval))
>>> +		goto cache_sync_done;
>>> +
>>> +	if (pte_present(*ptep) && (pte_pfn(*ptep) == pte_pfn(pteval)))
>>> +		goto cache_sync_done;
>>> +
>>> +	__update_cache(addr, pteval);
>>> +cache_sync_done:
>>> +	set_pte(ptep, pteval);
>>> +}
>>> +
>>
>> This seems crazy.
>
> Perhaps, but also correct...
>
>> I don't think any other architecture does this type of work in set_pte_at().
>
> Yes they do. As mentioned in the commit message see arm, ia64 or powerpc
> for architectures that all do the same sort of thing in set_pte_at.
>
>> Can you look into finding a better way?
>
> Not that I can see.
>
>> What if you ...
>>
>>
>>>   /*
>>>    * (pmds are folded into puds so this doesn't get actually called,
>>>    * but the define is needed for a generic inline function.)
>>> @@ -430,15 +449,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
>>>
>>>   extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
>>>   	pte_t pte);
>>> -extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
>>> -	pte_t pte);
>>>
>>>   static inline void update_mmu_cache(struct vm_area_struct *vma,
>>>   	unsigned long address, pte_t *ptep)
>>>   {
>>>   	pte_t pte = *ptep;
>>>   	__update_tlb(vma, address, pte);
>>> -	__update_cache(vma, address, pte);
>>
>> ... Reversed the order of these two operations?
>
> It would make no difference. The window for the race exists between
> flush_dcache_page & set_pte_at. update_mmu_cache isn't called until
> later than set_pte_at, so cannot possibly avoid the race. The commit
> message walks through where the race exists - I don't think you've read
> it.


I think the code that calls set_pte_at() should be fixed.

If cache maintenance is needed before modifying the page tables, that is 
explicitly done in the calling code.

In migrate.c (remove_migration_pte, similar in do_swap_page) we have:
    .
    .
    .
	flush_dcache_page(new);
	set_pte_at(mm, addr, ptep, pte);
    .
    .
    .

Similar in huge_memory.c (unfreeze_page_vma, freeze_page_vma, etc.)

The point being, the callers have the knowledge about what is changing 
and should make sure they do the right thing to keep the caches 
consistent.  The job of set_pte_at() is to manipulate the page tables, 
nothing else.

WARNING: multiple messages have this Message-ID (diff)
From: David Daney <ddaney@caviumnetworks.com>
To: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>,
	linux-mips@linux-mips.org, Lars Persson <lars.persson@axis.com>,
	"stable # v4 . 1+" <stable@vger.kernel.org>,
	"Steven J. Hill" <Steven.Hill@imgtec.com>,
	David Daney <david.daney@cavium.com>,
	Huacai Chen <chenhc@lemote.com>,
	"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>,
	linux-kernel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Jerome Marchand <jmarchan@redhat.com>,
	"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Subject: Re: [PATCH 4/4] MIPS: Sync icache & dcache in set_pte_at
Date: Fri, 4 Mar 2016 09:43:54 -0800	[thread overview]
Message-ID: <56D9C95A.5020106@caviumnetworks.com> (raw)
Message-ID: <20160304174354.-Hdgm0_N162uv5X-X0-oeubcq7TqjV8zdcmYCODU1tQ@z> (raw)
In-Reply-To: <20160301171940.GA26791@NP-P-BURTON>

On 03/01/2016 09:19 AM, Paul Burton wrote:
> On Tue, Mar 01, 2016 at 09:13:23AM -0800, David Daney wrote:
>> On 02/29/2016 06:37 PM, Paul Burton wrote:
>> [...]
>>> @@ -234,6 +237,22 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
>>>   }
>>>   #endif
>>>
>>> +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
>>> +			      pte_t *ptep, pte_t pteval)
>>> +{
>>> +	extern void __update_cache(unsigned long address, pte_t pte);
>>> +
>>> +	if (!pte_present(pteval))
>>> +		goto cache_sync_done;
>>> +
>>> +	if (pte_present(*ptep) && (pte_pfn(*ptep) == pte_pfn(pteval)))
>>> +		goto cache_sync_done;
>>> +
>>> +	__update_cache(addr, pteval);
>>> +cache_sync_done:
>>> +	set_pte(ptep, pteval);
>>> +}
>>> +
>>
>> This seems crazy.
>
> Perhaps, but also correct...
>
>> I don't think any other architecture does this type of work in set_pte_at().
>
> Yes they do. As mentioned in the commit message see arm, ia64 or powerpc
> for architectures that all do the same sort of thing in set_pte_at.
>
>> Can you look into finding a better way?
>
> Not that I can see.
>
>> What if you ...
>>
>>
>>>   /*
>>>    * (pmds are folded into puds so this doesn't get actually called,
>>>    * but the define is needed for a generic inline function.)
>>> @@ -430,15 +449,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
>>>
>>>   extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
>>>   	pte_t pte);
>>> -extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
>>> -	pte_t pte);
>>>
>>>   static inline void update_mmu_cache(struct vm_area_struct *vma,
>>>   	unsigned long address, pte_t *ptep)
>>>   {
>>>   	pte_t pte = *ptep;
>>>   	__update_tlb(vma, address, pte);
>>> -	__update_cache(vma, address, pte);
>>
>> ... Reversed the order of these two operations?
>
> It would make no difference. The window for the race exists between
> flush_dcache_page & set_pte_at. update_mmu_cache isn't called until
> later than set_pte_at, so cannot possibly avoid the race. The commit
> message walks through where the race exists - I don't think you've read
> it.


I think the code that calls set_pte_at() should be fixed.

If cache maintenance is needed before modifying the page tables, that is 
explicitly done in the calling code.

In migrate.c (remove_migration_pte, similar in do_swap_page) we have:
    .
    .
    .
	flush_dcache_page(new);
	set_pte_at(mm, addr, ptep, pte);
    .
    .
    .

Similar in huge_memory.c (unfreeze_page_vma, freeze_page_vma, etc.)

The point being, the callers have the knowledge about what is changing 
and should make sure they do the right thing to keep the caches 
consistent.  The job of set_pte_at() is to manipulate the page tables, 
nothing else.

  parent reply	other threads:[~2016-03-04 17:44 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-01  2:37 [PATCH 0/4] MIPS cache & highmem fixes Paul Burton
2016-03-01  2:37 ` Paul Burton
2016-03-01  2:37 ` [PATCH 1/4] MIPS: Flush dcache for flush_kernel_dcache_page Paul Burton
2016-03-01  2:37   ` Paul Burton
2016-03-04 15:09   ` Lars Persson
2016-03-29  8:29     ` Ralf Baechle
2016-03-01  2:37 ` [PATCH 2/4] MIPS: Flush highmem pages in __flush_dcache_page Paul Burton
2016-03-01  2:37   ` Paul Burton
2016-03-29  8:35   ` Ralf Baechle
2016-03-29  8:55     ` Paul Burton
2016-03-29  8:55       ` Paul Burton
2016-03-01  2:37 ` [PATCH 3/4] MIPS: Handle highmem pages in __update_cache Paul Burton
2016-03-01  2:37   ` Paul Burton
2016-03-29  8:39   ` Ralf Baechle
2016-03-01  2:37 ` [PATCH 4/4] MIPS: Sync icache & dcache in set_pte_at Paul Burton
2016-03-01  2:37   ` Paul Burton
2016-03-01  9:44   ` Lars Persson
2016-03-01  9:44     ` Lars Persson
2016-03-01 17:13   ` David Daney
2016-03-01 17:13     ` David Daney
2016-03-01 17:19     ` Paul Burton
2016-03-01 17:19       ` Paul Burton
2016-03-02 14:12       ` Ralf Baechle
2016-03-02 14:24         ` Paul Burton
2016-03-02 14:24           ` Paul Burton
2016-03-04 17:43       ` David Daney [this message]
2016-03-04 17:43         ` David Daney
2016-03-04 17:47         ` Paul Burton
2016-03-04 17:47           ` Paul Burton
2016-03-03  3:03   ` [4/4] " Leonid Yegoshin
2016-03-03  3:03     ` Leonid Yegoshin
2016-03-04 10:37     ` Paul Burton
2016-03-04 10:37       ` Paul Burton
2016-03-04 15:20       ` Lars Persson
2016-03-04 21:01       ` Leonid Yegoshin
2016-03-04 21:01         ` Leonid Yegoshin
2016-03-04 21:21         ` Leonid Yegoshin
2016-03-04 21:21           ` Leonid Yegoshin
2016-03-05  1:06         ` Leonid Yegoshin
2016-03-05  1:06           ` Leonid Yegoshin
2016-03-04 19:02   ` [PATCH 4/4] " Lars Persson
2016-03-05  0:21     ` Paul Burton
2016-03-05  0:27       ` Paul Burton
2016-03-02 11:39 ` [PATCH 0/4] MIPS cache & highmem fixes Harvey Hunt
2016-03-02 11:39   ` Harvey Hunt

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=56D9C95A.5020106@caviumnetworks.com \
    --to=ddaney@caviumnetworks.com \
    --cc=Steven.Hill@imgtec.com \
    --cc=akpm@linux-foundation.org \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=chenhc@lemote.com \
    --cc=david.daney@cavium.com \
    --cc=jmarchan@redhat.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=lars.persson@axis.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=paul.burton@imgtec.com \
    --cc=ralf@linux-mips.org \
    --cc=stable@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 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.