All of lore.kernel.org
 help / color / mirror / Atom feed
From: Will Deacon <will@kernel.org>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Yang Shi <yang.shi@linux.alibaba.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Johannes Weiner <hannes@cmpxchg.org>,
	Hillf Danton <hdanton@sina.com>, Hugh Dickins <hughd@google.com>,
	Josef Bacik <josef@toxicpanda.com>,
	"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>,
	Linux-MM <linux-mm@kvack.org>,
	mm-commits@vger.kernel.org, Matthew Wilcox <willy@infradead.org>,
	xuyu@linux.alibaba.com
Subject: Re: [patch 01/15] mm/memory.c: avoid access flag update TLB flush for retried page fault
Date: Tue, 28 Jul 2020 11:21:23 +0100	[thread overview]
Message-ID: <20200728102122.GA21880@willie-the-truck> (raw)
In-Reply-To: <20200728093910.GB706@gaia>

On Tue, Jul 28, 2020 at 10:39:11AM +0100, Catalin Marinas wrote:
> On Tue, Jul 28, 2020 at 10:22:20AM +0100, Will Deacon wrote:
> > On Sat, Jul 25, 2020 at 04:58:43PM +0100, Catalin Marinas wrote:
> > > On Fri, Jul 24, 2020 at 06:29:43PM -0700, Linus Torvalds wrote:
> > > > For any architecture that guarantees that a page fault will always
> > > > flush the old TLB entry for this kind of situation, that
> > > > flush_tlb_fix_spurious_fault() thing can be a no-op.
> > > > 
> > > > So that's why on x86, we just do
> > > > 
> > > >   #define flush_tlb_fix_spurious_fault(vma, address) do { } while (0)
> > > > 
> > > > and have no issues.
> > > > 
> > > > Note that it does *not* need to do any cross-CPU flushing or anything
> > > > like that. So it's actually wrong (I think) to have that default
> > > > fallback for
> > > > 
> > > >    #define flush_tlb_fix_spurious_fault(vma, address)
> > > > flush_tlb_page(vma, address)
> > > > 
> > > > because flush_tlb_page() is the serious "do cross CPU etc".
> > > > 
> > > > Does the arm64 flush_tlb_page() perhaps do the whole expensive
> > > > cross-CPU thing rather than the much cheaper "just local invalidate"
> > > > version?
> > > 
> > > I think it makes sense to have a local-only
> > > flush_tlb_fix_spurious_fault(), but with ptep_set_access_flags() updated
> > > to still issue the full broadcast TLBI. In addition, I added a minor
> > > optimisation to avoid the TLB flush if the old pte was not accessible.
> > > In a read-access fault case (followed by mkyoung), the TLB wouldn't have
> > > cached a non-accessible pte (not sure it makes much difference to Yang's
> > > case). Anyway, from ARMv8.1 onwards, the hardware handles the access
> > > flag automatically.
> > > 
> > > I'm not sure the first dsb(nshst) below is of much use in this case. If
> > > we got a spurious fault, the write to the pte happened on a different
> > > CPU (IIUC, we shouldn't return to user with updated ptes without a TLB
> > > flush on the same CPU). Anyway, we can refine this if it solves Yang's
> > > performance regression.
> > > 
> > > -------------8<-----------------------
> > > diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
> > > index d493174415db..d1401cbad7d4 100644
> > > --- a/arch/arm64/include/asm/tlbflush.h
> > > +++ b/arch/arm64/include/asm/tlbflush.h
> > > @@ -268,6 +268,20 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
> > >  	dsb(ish);
> > >  }
> > >  
> > > +static inline void local_flush_tlb_page(struct vm_area_struct *vma,
> > > +					unsigned long uaddr)
> > > +{
> > > +	unsigned long addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm));
> > > +
> > > +	dsb(nshst);
> > > +	__tlbi(vale1, addr);
> > > +	__tlbi_user(vale1, addr);
> > > +	dsb(nsh);
> > > +}
> > > +
> > > +#define flush_tlb_fix_spurious_fault(vma, address) \
> > > +	local_flush_tlb_page(vma, address)
> > 
> > Why can't we just have flush_tlb_fix_spurious_fault() be a NOP on arm64?
> 
> Possibly, as long as any other optimisations only defer the TLB flushing
> for relatively short time (the fault is transient, it will get a
> broadcast TLBI eventually).

Define relatively short ;) There's always a window where these things can
happen, and we try to batch up TLB invalidation to avoid issuing tonnes
of messages, so it's a trade-off. The more important thing seems to be
that we don't have all those faulting CPUs repeating the TLB invalidation.

> Either way, it's worth benchmarking the above patch but with
> flush_tlb_fix_spurious_fault() a no-op (we still need flush_tlb_page()
> in ptep_set_access_flags()). Xu, Yang, could you please give it a try?

(agreed on the flush_tlb_page() in ptep_set_access_flags())

> > Given that the architecture prohibits the TLB from caching invalid entries,
> > then software access/dirty is fine without additional flushing.
> 
> The access fault is fine, the TLB has not cached the entry. For a dirty
> fault, however, the TLB could cache a read-only mapping, so it does need
> flushing.

Sorry, yes, you're right.

> Question is, do we make the pte dirty anywhere without a
> subsequent (broadcast) TLBI?

Given that we practically always use broadcast TLBI, then if we do this
it could cause the local CPU to get wedged as well. I think we can rely
on ptep_set_access_flags() to handle this for us.

> > The only
> > problematic case I can think of is on the invalid->valid (i.e. map) path,
> > where we elide the expensive DSB instruction because (a) most CPUs have a
> > walker that can snoop the store buffer and (b) even if they don't, the
> > store buffer tends to drain by the time we get back to userspace. Even
> > if that was a problem, flush_tlb_fix_spurious_fault() wouldn't be the
> > right hook, since the DSB must occur on the CPU that did the pte update.
> 
> I guess the best a CPU can do is attempt the page table walk again, in
> the hope that the write buffer on the other CPU eventually drains.

It _will_ drain on context-switch as we have a DSB in there, but in practice
it will happen way before that.

Will


  parent reply	other threads:[~2020-07-28 10:21 UTC|newest]

Thread overview: 141+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-24  4:14 incoming Andrew Morton
2020-07-24  4:15 ` [patch 01/15] mm/memory.c: avoid access flag update TLB flush for retried page fault Andrew Morton
2020-07-24  4:38   ` Yang Shi
2020-07-24  4:56     ` Andrew Morton
2020-07-24 19:27   ` Linus Torvalds
2020-07-24 20:22     ` Linus Torvalds
2020-07-25  0:36       ` Yang Shi
2020-07-25  1:29         ` Linus Torvalds
2020-07-25 15:58           ` Catalin Marinas
2020-07-28  9:22             ` Will Deacon
2020-07-28  9:39               ` Catalin Marinas
2020-07-28 10:07                 ` Yu Xu
2020-07-28 11:46                   ` Catalin Marinas
2020-07-28 10:21                 ` Will Deacon [this message]
2020-07-28 18:28                 ` Linus Torvalds
2020-07-27 17:52           ` Yang Shi
2020-07-27 18:04             ` Linus Torvalds
2020-07-27 18:42               ` Catalin Marinas
2020-07-27 20:56                 ` Linus Torvalds
2020-07-27 20:56                   ` Linus Torvalds
2020-07-27 22:34               ` Yang Shi
2020-07-27  7:31       ` Yu Xu
2020-07-27 11:05         ` Catalin Marinas
2020-07-27 17:01           ` Linus Torvalds
2020-07-28 11:19             ` Catalin Marinas
2020-07-27 17:12           ` Yu Xu
2020-07-27 18:04             ` Yang Shi
2020-07-27 18:37               ` Linus Torvalds
2020-07-27 18:37                 ` Linus Torvalds
2020-07-27 22:43                 ` Yang Shi
2020-07-28  0:38                   ` Linus Torvalds
2020-07-28  0:38                     ` Linus Torvalds
2020-07-28  0:13                 ` Yu Xu
2020-07-28 10:53                 ` Nicholas Piggin
2020-07-28 10:53                   ` Nicholas Piggin
2020-07-28 19:02                   ` Linus Torvalds
2020-07-28 19:02                     ` Linus Torvalds
2020-07-28 19:02                     ` Linus Torvalds
2020-07-28 22:53                     ` Nicholas Piggin
2020-07-28 22:53                       ` Nicholas Piggin
2020-07-29 13:58                       ` Michael Ellerman
2020-07-28  6:41             ` Yu Xu
2020-07-24  4:15 ` [patch 02/15] mm/mmap.c: close race between munmap() and expand_upwards()/downwards() Andrew Morton
2020-07-24  4:15 ` [patch 03/15] vfs/xattr: mm/shmem: kernfs: release simple xattr entry in a right way Andrew Morton
2020-07-24  4:15 ` [patch 04/15] mm: initialize return of vm_insert_pages Andrew Morton
2020-07-24  4:15 ` [patch 05/15] mm/memcontrol: fix OOPS inside mem_cgroup_get_nr_swap_pages() Andrew Morton
2020-07-24  4:15 ` [patch 06/15] mm/memcg: fix refcount error while moving and swapping Andrew Morton
2020-07-24 13:41   ` Alex Shi
2020-07-24  4:15 ` [patch 07/15] mm: memcg/slab: fix memory leak at non-root kmem_cache destroy Andrew Morton
2020-07-24  4:15 ` [patch 08/15] mm/hugetlb: avoid hardcoding while checking if cma is enabled Andrew Morton
2020-07-24  4:15 ` [patch 09/15] khugepaged: fix null-pointer dereference due to race Andrew Morton
2020-07-24  4:15 ` [patch 10/15] mailmap: add entry for Mike Rapoport Andrew Morton
2020-07-24  4:15 ` [patch 11/15] squashfs: fix length field overlap check in metadata reading Andrew Morton
2020-07-24  4:15 ` [patch 12/15] scripts/decode_stacktrace: strip basepath from all paths Andrew Morton
2020-07-24  4:15 ` [patch 13/15] io-mapping: indicate mapping failure Andrew Morton
2020-07-24  4:15 ` [patch 14/15] MAINTAINERS: add KCOV section Andrew Morton
2020-07-24  4:15 ` [patch 15/15] scripts/gdb: fix lx-symbols 'gdb.error' while loading modules Andrew Morton
2020-07-27 19:47 ` + mm-remove-unnecessary-wrapper-function-do_mmap_pgoff.patch added to -mm tree Andrew Morton
2020-07-27 19:56 ` + nilfs2-only-call-unlock_new_inode-if-i_new.patch " Andrew Morton
2020-07-27 19:57 ` + nilfs2-convert-__nilfs_msg-to-integrate-the-level-and-format.patch " Andrew Morton
2020-07-27 19:57 ` + nilfs2-use-a-more-common-logging-style.patch " Andrew Morton
2020-07-27 19:58 ` + checkpatch-add-test-for-repeated-words.patch " Andrew Morton
2020-07-27 20:05 ` + ocfs2-replace-http-links-with-https-ones.patch " Andrew Morton
2020-07-27 20:09 ` + ocfs2-fix-unbalanced-locking.patch " Andrew Morton
2020-07-27 20:10 ` + kernelh-remove-duplicate-include-of-asm-div64h.patch " Andrew Morton
2020-07-27 20:11 ` + tools-replace-http-links-with-https-ones.patch " Andrew Morton
2020-07-27 20:12 ` + lib-replace-http-links-with-https-ones.patch " Andrew Morton
2020-07-27 20:12 ` + include-replace-http-links-with-https-ones.patch " Andrew Morton
2020-07-27 20:34 ` + mm-make-mm-locked_vm-an-atomic64-counter.patch " Andrew Morton
2020-07-27 20:34 ` + mm-util-account_locked_vm-does-not-hold-mmap_lock.patch " Andrew Morton
2020-07-27 20:37 ` + cg_read_strcmp-fix-null-pointer-dereference.patch " Andrew Morton
2020-07-27 20:51 ` + mm-hugetlb-add-mempolicy-check-in-the-reservation-routine.patch " Andrew Morton
2020-07-27 20:52 ` [withdrawn] checkpatch-support-deprecated-terms-checking.patch removed from " Andrew Morton
2020-07-27 23:47 ` [obsolete] scripts-deprecated_terms-recommend-denylist-allowlist-instead-of-blacklist-whitelist.patch " Andrew Morton
2020-07-27 23:50 ` [obsolete] scripts-deprecated_terms-sync-with-inclusive-terms.patch " Andrew Morton
2020-07-28  0:18 ` [failures] mm-hugetlb-add-mempolicy-check-in-the-reservation-routine.patch " Andrew Morton
2020-07-28  1:19 ` mmotm 2020-07-27-18-18 uploaded Andrew Morton
2020-07-28  2:14   ` Stephen Rothwell
2020-07-28  3:22   ` mmotm 2020-07-27-18-18 uploaded (drivers/scsi/ufs/: SCSI_UFS_EXYNOS) Randy Dunlap
2020-07-28  8:23     ` Alim Akhtar
2020-07-28 12:33   ` mmotm 2020-07-27-18-18 uploaded (mm/page_alloc.c) Randy Dunlap
2020-07-28 21:55     ` Andrew Morton
2020-07-28 22:20       ` Stephen Rothwell
2020-07-28 22:31         ` Andrew Morton
2020-07-29 14:18           ` Michael S. Tsirkin
2020-07-29 14:38             ` David Hildenbrand
2020-07-29 16:14               ` David Hildenbrand
2020-07-29 17:29                 ` Randy Dunlap
2020-07-28 22:39       ` Randy Dunlap
2020-07-29  1:43         ` Nathan Chancellor
2020-07-29  1:44         ` Andrew Morton
2020-07-29  2:04           ` Randy Dunlap
2020-07-29 14:09           ` make oldconfig (Re: mmotm 2020-07-27-18-18 uploaded (mm/page_alloc.c)) Alexey Dobriyan
2020-07-28 20:53 ` + mm-mempolicy-fix-kerneldoc-of-numa_map_to_online_node.patch added to -mm tree Andrew Morton
2020-07-28 20:53 ` + mm-mmu_notifier-fix-and-extend-kerneldoc.patch " Andrew Morton
2020-07-28 20:54 ` + mm-swap-fix-kerneldoc-of-swap_vma_readahead.patch " Andrew Morton
2020-07-28 20:58 ` + mm-memcontrol-dont-count-limit-setting-reclaim-as-memory-pressure.patch " Andrew Morton
2020-07-28 21:01 ` + mm-memcontrol-restore-proper-dirty-throttling-when-memoryhigh-changes.patch " Andrew Morton
2020-07-28 22:06 ` + mm-compaction-correct-the-comments-of-compact_defer_shift.patch " Andrew Morton
2020-07-28 22:09 ` + selftests-add-mincore-tests.patch " Andrew Morton
2020-07-28 22:16 ` + proc-pid-smaps-consistent-whitespace-output-format.patch " Andrew Morton
2020-07-28 22:21 ` + xtensa-switch-to-generic-version-of-pte-allocation-fix.patch " Andrew Morton
2020-07-28 22:21 ` Andrew Morton
2020-07-29 21:49 ` + mm-slab-avoid-the-use-of-one-element-array-and-use-struct_size-helper.patch " Andrew Morton
2020-07-29 23:52 ` [obsolete] mm-slab-avoid-the-use-of-one-element-array-and-use-struct_size-helper.patch removed from " Andrew Morton
2020-07-31 19:24 ` + kasan-dont-tag-stacks-allocated-with-pagealloc.patch added to " Andrew Morton
2020-07-31 19:24 ` + kasan-arm64-dont-instrument-functions-that-enable-kasan.patch " Andrew Morton
2020-07-31 19:24 ` + kasan-allow-enabling-stack-tagging-for-tag-based-mode.patch " Andrew Morton
2020-07-31 19:24 ` + kasan-adjust-kasan_stack_oob-for-tag-based-mode.patch " Andrew Morton
2020-07-31 20:00 ` [obsolete] mmhwpoison-rework-soft-offline-for-in-use-pages-fix.patch removed from " Andrew Morton
2020-07-31 20:05 ` + mmhwpoison-cleanup-unused-pagehuge-check.patch added to " Andrew Morton
2020-07-31 20:05 ` + mm-hwpoison-remove-recalculating-hpage.patch " Andrew Morton
2020-07-31 20:05 ` + mmmadvise-call-soft_offline_page-without-mf_count_increased.patch " Andrew Morton
2020-07-31 20:05 ` + mmmadvise-refactor-madvise_inject_error.patch " Andrew Morton
2020-07-31 20:05 ` + mmhwpoison-inject-dont-pin-for-hwpoison_filter.patch " Andrew Morton
2020-07-31 20:05 ` + mmhwpoison-un-export-get_hwpoison_page-and-make-it-static.patch " Andrew Morton
2020-07-31 20:05 ` + mmhwpoison-kill-put_hwpoison_page.patch " Andrew Morton
2020-07-31 20:06 ` + mmhwpoison-remove-mf_count_increased.patch " Andrew Morton
2020-07-31 20:06 ` + mmhwpoison-remove-flag-argument-from-soft-offline-functions.patch " Andrew Morton
2020-07-31 20:06 ` + mmhwpoison-unify-thp-handling-for-hard-and-soft-offline.patch " Andrew Morton
2020-07-31 20:06 ` + mmhwpoison-rework-soft-offline-for-free-pages.patch " Andrew Morton
2020-07-31 20:06 ` + mmhwpoison-rework-soft-offline-for-in-use-pages.patch " Andrew Morton
2020-07-31 20:06 ` + mmhwpoison-refactor-soft_offline_huge_page-and-__soft_offline_page.patch " Andrew Morton
2020-07-31 20:06 ` + mmhwpoison-return-0-if-the-page-is-already-poisoned-in-soft-offline.patch " Andrew Morton
2020-07-31 20:06 ` + mmhwpoison-introduce-mf_msg_unsplit_thp.patch " Andrew Morton
2020-07-31 20:06 ` + mmhwpoison-double-check-page-count-in-__get_any_page.patch " Andrew Morton
2020-07-31 20:23 ` + mm-gup-restrict-cma-region-by-using-allocation-scope-api.patch " Andrew Morton
2020-07-31 20:23 ` + mm-hugetlb-make-hugetlb-migration-callback-cma-aware.patch " Andrew Morton
2020-07-31 20:23 ` + mm-gup-use-a-standard-migration-target-allocation-callback.patch " Andrew Morton
2020-07-31 20:25 ` + mm-migrate-make-a-standard-migration-target-allocation-function-fix.patch " Andrew Morton
2020-07-31 20:26 ` + mm-memcontrol-decouple-reference-counting-from-page-accounting-fix.patch " Andrew Morton
2020-07-31 20:32 ` + mm-dmapoolc-add-warn_on-in-dma_pool_destroy.patch " Andrew Morton
2020-07-31 20:49 ` + kstrto-correct-documentation-references-to-simple_strto.patch " Andrew Morton
2020-07-31 20:49 ` + kstrto-do-not-describe-simple_strto-as-obsolete-replaced.patch " Andrew Morton
2020-07-31 20:57 ` + mm-hugetlb-fix-calculation-of-adjust_range_if_pmd_sharing_possible.patch " Andrew Morton
2020-07-31 20:59 ` + poison-remove-obsolete-comment.patch " Andrew Morton
2020-07-31 21:02 ` + cma-dont-quit-at-first-error-when-activating-reserved-areas.patch " Andrew Morton
2020-07-31 21:10 ` [nacked] mm-dmapoolc-add-warn_on-in-dma_pool_destroy.patch removed from " Andrew Morton
2020-07-31 23:46 ` mmotm 2020-07-31-16-45 uploaded Andrew Morton
2020-08-01  5:24   ` mmotm 2020-07-31-16-45 uploaded (drivers/staging/vc04_services/) Randy Dunlap
2020-08-01  5:24     ` Randy Dunlap

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=20200728102122.GA21880@willie-the-truck \
    --to=will@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=catalin.marinas@arm.com \
    --cc=hannes@cmpxchg.org \
    --cc=hdanton@sina.com \
    --cc=hughd@google.com \
    --cc=josef@toxicpanda.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=linux-mm@kvack.org \
    --cc=mm-commits@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=willy@infradead.org \
    --cc=xuyu@linux.alibaba.com \
    --cc=yang.shi@linux.alibaba.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.