Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1626059 > unrolled thread

[RFC 0/4] Replace mmap_sem by a range lock

Started byLaurent Dufour <ldufour@linux.vnet.ibm.com>
First post2017-04-19 14:20 +0200
Last post2017-04-24 17:50 +0200
Articles 7 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [RFC 0/4] Replace mmap_sem by a range lock Laurent Dufour <ldufour@linux.vnet.ibm.com> - 2017-04-19 14:20 +0200
    Re: [RFC 0/4] Replace mmap_sem by a range lock Matthew Wilcox <willy@infradead.org> - 2017-04-20 15:40 +0200
      Re: [RFC 0/4] Replace mmap_sem by a range lock Laurent Dufour <ldufour@linux.vnet.ibm.com> - 2017-04-20 16:40 +0200
    Re: [RFC 4/4] Change mmap_sem to range lock Peter Zijlstra <peterz@infradead.org> - 2017-04-20 16:40 +0200
      Re: [RFC 4/4] Change mmap_sem to range lock Laurent Dufour <ldufour@linux.vnet.ibm.com> - 2017-04-20 16:50 +0200
    Re: [RFC 4/4] Change mmap_sem to range lock Andi Kleen <andi@firstfloor.org> - 2017-04-21 01:40 +0200
      Re: [RFC 4/4] Change mmap_sem to range lock Laurent Dufour <ldufour@linux.vnet.ibm.com> - 2017-04-24 17:50 +0200

#1626059 — [RFC 0/4] Replace mmap_sem by a range lock

FromLaurent Dufour <ldufour@linux.vnet.ibm.com>
Date2017-04-19 14:20 +0200
Subject[RFC 0/4] Replace mmap_sem by a range lock
Message-ID<txWKu-3m5-15@gated-at.bofh.it>
Following the series pushed by Davidlohr Bueso based on the Jan Kara's
work [1] which introduces range locks, this series implements the
first step of the attempt to replace the mmap_sem by a range lock.

While this series simply replaces the mmap_sem by a full range lock,
the final goal is to introduce finer grain locking to allow better
multi-thread performance in regards to the process's memory layout
changes.

This series is currently supports x86 and PowerPc architectures only.
Some drivers are also impacted to allow build and basic test on few
platforms but a lot of additional works is required to complete the
job for all the supported architectures.

The goal of this series is to check that no major performance hit
happens for mono threaded process, as we could hope major improvements
in the multi-threaded case once the finer grain locking is
implemented.

I didn't do massive performance checking yet, but building a full
kernel on a 80 threaded Power node, doesn't show performance hits. The
build time is 11m56.701s on a vanilla kernel and 12m4.679s when range
lock is used.

The next steps will attempt to implement finer grain locking but
specific locking would certainly be required to protect mm data like
the VMA cache.

This series applies on top of 4.11-rc7.

The first patch introduce a new parameter to some memory service which
need to release the lock, since range lock require the range to
specify, caller has to know about it.

The second patch is removing some assert which were based on lock
service which are not provided by the range lock API. While some of
these checks will not be valid with range locks, some may be reviewed.

The third patch is replacing nest locking operation on mmap_sem to
simple locking operation has the nest lock check is not yet provided
by the range lock API.

The latest patch is doing the job of replacing the mmap_sem by a range
lock.

[1] "locking: Introduce range reader/writer lock"
http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1371431.html

Laurent Dufour (4):
  Add additional range parameter to GUP() and handle_page_fault()
  Deactivate mmap_sem assert
  Remove nest locking operation with mmap_sem
  Change mmap_sem to range lock

 arch/powerpc/kernel/vdso.c                         |  8 ++-
 arch/powerpc/kvm/book3s_64_mmu_hv.c                |  6 +-
 arch/powerpc/kvm/book3s_64_mmu_radix.c             |  6 +-
 arch/powerpc/kvm/book3s_64_vio.c                   |  6 +-
 arch/powerpc/kvm/book3s_hv.c                       |  8 ++-
 arch/powerpc/kvm/e500_mmu_host.c                   |  7 ++-
 arch/powerpc/mm/copro_fault.c                      |  8 ++-
 arch/powerpc/mm/fault.c                            | 12 ++--
 arch/powerpc/mm/mmu_context_iommu.c                |  6 +-
 arch/powerpc/mm/subpage-prot.c                     | 16 ++++--
 arch/powerpc/oprofile/cell/spu_task_sync.c         |  8 ++-
 arch/powerpc/platforms/cell/spufs/file.c           |  4 +-
 arch/x86/entry/vdso/vma.c                          | 14 +++--
 arch/x86/events/core.c                             |  1 -
 arch/x86/kernel/tboot.c                            |  2 +-
 arch/x86/kernel/vm86_32.c                          |  6 +-
 arch/x86/mm/fault.c                                | 39 +++++++------
 arch/x86/mm/mpx.c                                  | 20 ++++---
 drivers/android/binder.c                           |  8 ++-
 drivers/firmware/efi/arm-runtime.c                 |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c             |  9 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c            |  8 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c             |  8 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c            |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_events.c            |  6 +-
 drivers/gpu/drm/amd/amdkfd/kfd_process.c           |  6 +-
 drivers/gpu/drm/etnaviv/etnaviv_gem.c              |  9 ++-
 drivers/gpu/drm/i915/i915_gem.c                    |  6 +-
 drivers/gpu/drm/i915/i915_gem_userptr.c            | 14 +++--
 drivers/gpu/drm/radeon/radeon_cs.c                 |  9 ++-
 drivers/gpu/drm/radeon/radeon_gem.c                |  8 ++-
 drivers/gpu/drm/radeon/radeon_mn.c                 |  8 ++-
 drivers/gpu/drm/radeon/radeon_ttm.c                |  2 +-
 drivers/gpu/drm/ttm/ttm_bo_vm.c                    |  6 +-
 drivers/gpu/drm/via/via_dmablit.c                  |  6 +-
 drivers/infiniband/core/umem.c                     | 22 +++++---
 drivers/infiniband/core/umem_odp.c                 |  8 ++-
 drivers/infiniband/hw/hfi1/user_pages.c            | 18 ++++--
 drivers/infiniband/hw/mlx4/main.c                  |  6 +-
 drivers/infiniband/hw/mlx5/main.c                  |  6 +-
 drivers/infiniband/hw/mthca/mthca_memfree.c        |  3 +-
 drivers/infiniband/hw/qib/qib_user_pages.c         | 18 ++++--
 drivers/infiniband/hw/usnic/usnic_uiom.c           | 22 +++++---
 drivers/iommu/amd_iommu_v2.c                       |  8 ++-
 drivers/iommu/intel-svm.c                          |  8 ++-
 drivers/media/v4l2-core/videobuf-core.c            |  9 ++-
 drivers/media/v4l2-core/videobuf-dma-contig.c      |  6 +-
 drivers/media/v4l2-core/videobuf-dma-sg.c          |  8 ++-
 drivers/misc/cxl/fault.c                           |  6 +-
 drivers/misc/mic/scif/scif_rma.c                   | 19 ++++---
 drivers/oprofile/buffer_sync.c                     | 14 +++--
 drivers/staging/lustre/lustre/llite/llite_mmap.c   |  4 +-
 drivers/staging/lustre/lustre/llite/vvp_io.c       |  6 +-
 .../interface/vchiq_arm/vchiq_2835_arm.c           |  7 ++-
 .../vc04_services/interface/vchiq_arm/vchiq_arm.c  |  6 +-
 drivers/vfio/vfio_iommu_spapr_tce.c                | 13 +++--
 drivers/vfio/vfio_iommu_type1.c                    | 24 +++++---
 drivers/virt/fsl_hypervisor.c                      |  6 +-
 drivers/xen/gntdev.c                               |  6 +-
 drivers/xen/privcmd.c                              | 14 +++--
 fs/aio.c                                           |  7 ++-
 fs/coredump.c                                      |  6 +-
 fs/exec.c                                          | 26 ++++++---
 fs/proc/base.c                                     | 38 ++++++++-----
 fs/proc/internal.h                                 |  1 +
 fs/proc/task_mmu.c                                 | 30 ++++++----
 fs/proc/task_nommu.c                               | 27 +++++----
 fs/userfaultfd.c                                   | 33 +++++------
 include/linux/huge_mm.h                            |  2 -
 include/linux/hugetlb.h                            |  4 +-
 include/linux/mm.h                                 | 21 ++++---
 include/linux/mm_types.h                           |  3 +-
 include/linux/pagemap.h                            |  8 ++-
 include/linux/userfaultfd_k.h                      |  6 +-
 ipc/shm.c                                          | 13 +++--
 kernel/acct.c                                      |  6 +-
 kernel/events/core.c                               |  6 +-
 kernel/events/uprobes.c                            | 28 ++++++----
 kernel/exit.c                                      | 10 ++--
 kernel/fork.c                                      | 21 ++++---
 kernel/futex.c                                     |  8 ++-
 kernel/sched/fair.c                                |  7 ++-
 kernel/sys.c                                       | 31 ++++++++---
 kernel/trace/trace_output.c                        |  6 +-
 mm/filemap.c                                       |  9 +--
 mm/frame_vector.c                                  |  9 ++-
 mm/gup.c                                           | 65 ++++++++++++----------
 mm/hugetlb.c                                       |  3 +-
 mm/init-mm.c                                       |  2 +-
 mm/internal.h                                      |  3 +-
 mm/khugepaged.c                                    | 59 ++++++++++++--------
 mm/ksm.c                                           | 48 ++++++++++------
 mm/madvise.c                                       | 38 +++++++------
 mm/memcontrol.c                                    | 14 +++--
 mm/memory.c                                        | 43 +++++++-------
 mm/mempolicy.c                                     | 32 +++++++----
 mm/migrate.c                                       | 12 ++--
 mm/mincore.c                                       |  6 +-
 mm/mlock.c                                         | 25 ++++++---
 mm/mmap.c                                          | 51 +++++++++++------
 mm/mmu_notifier.c                                  |  6 +-
 mm/mprotect.c                                      | 21 ++++---
 mm/mremap.c                                        |  6 +-
 mm/msync.c                                         | 10 ++--
 mm/nommu.c                                         | 31 +++++++----
 mm/oom_kill.c                                      |  9 ++-
 mm/pagewalk.c                                      |  3 -
 mm/process_vm_access.c                             |  9 ++-
 mm/shmem.c                                         |  3 +-
 mm/swapfile.c                                      |  8 ++-
 mm/userfaultfd.c                                   | 25 +++++----
 mm/util.c                                          | 15 +++--
 security/tomoyo/domain.c                           |  2 +-
 virt/kvm/async_pf.c                                |  8 ++-
 virt/kvm/kvm_main.c                                | 31 +++++++----
 115 files changed, 960 insertions(+), 555 deletions(-)

-- 
2.7.4

[toc] | [next] | [standalone]


#1627458

FromMatthew Wilcox <willy@infradead.org>
Date2017-04-20 15:40 +0200
Message-ID<tykts-14Q-27@gated-at.bofh.it>
In reply to#1626059
On Wed, Apr 19, 2017 at 02:18:23PM +0200, Laurent Dufour wrote:
> Following the series pushed by Davidlohr Bueso based on the Jan Kara's
> work [1] which introduces range locks, this series implements the
> first step of the attempt to replace the mmap_sem by a range lock.

Have you previously documented attempts to replace the mmap_sem by an
existing lock type before introducing a new (and frankly weird) lock?
My initial question is "Why not use RCU for this?" -- the rxrpc code
uses an rbtree protected by RCU.

[toc] | [prev] | [next] | [standalone]


#1627542

FromLaurent Dufour <ldufour@linux.vnet.ibm.com>
Date2017-04-20 16:40 +0200
Message-ID<tylpw-1FW-17@gated-at.bofh.it>
In reply to#1627458
On 20/04/2017 15:33, Matthew Wilcox wrote:
> On Wed, Apr 19, 2017 at 02:18:23PM +0200, Laurent Dufour wrote:
>> Following the series pushed by Davidlohr Bueso based on the Jan Kara's
>> work [1] which introduces range locks, this series implements the
>> first step of the attempt to replace the mmap_sem by a range lock.
> 
> Have you previously documented attempts to replace the mmap_sem by an
> existing lock type before introducing a new (and frankly weird) lock?

No :/

> My initial question is "Why not use RCU for this?" -- the rxrpc code
> uses an rbtree protected by RCU.

I'm also working on forward-porting work done by Peter Zijlstra :

https://marc.info/?l=linux-mm&m=141384492326748

I'll send a series on top 4.10 soon.

[toc] | [prev] | [next] | [standalone]


#1627537 — Re: [RFC 4/4] Change mmap_sem to range lock

FromPeter Zijlstra <peterz@infradead.org>
Date2017-04-20 16:40 +0200
SubjectRe: [RFC 4/4] Change mmap_sem to range lock
Message-ID<tylpv-1FW-3@gated-at.bofh.it>
In reply to#1626059
On Thu, Apr 20, 2017 at 04:28:20PM +0200, Laurent Dufour wrote:
> [resent this patch which seems to have not reached the mailing lists]

Probably because its too big at ~180k ?

[toc] | [prev] | [next] | [standalone]


#1627555 — Re: [RFC 4/4] Change mmap_sem to range lock

FromLaurent Dufour <ldufour@linux.vnet.ibm.com>
Date2017-04-20 16:50 +0200
SubjectRe: [RFC 4/4] Change mmap_sem to range lock
Message-ID<tylzc-1JN-19@gated-at.bofh.it>
In reply to#1627537
On 20/04/2017 16:37, Peter Zijlstra wrote:
> On Thu, Apr 20, 2017 at 04:28:20PM +0200, Laurent Dufour wrote:
>> [resent this patch which seems to have not reached the mailing lists]
> 
> Probably because its too big at ~180k ?

Probably, but this time it has reached linux-mm ... at least.

[toc] | [prev] | [next] | [standalone]


#1627869 — Re: [RFC 4/4] Change mmap_sem to range lock

FromAndi Kleen <andi@firstfloor.org>
Date2017-04-21 01:40 +0200
SubjectRe: [RFC 4/4] Change mmap_sem to range lock
Message-ID<tytQ5-6Qy-1@gated-at.bofh.it>
In reply to#1626059
Laurent Dufour <ldufour@linux.vnet.ibm.com> writes:

> [resent this patch which seems to have not reached the mailing lists]
>
> Change the mmap_sem to a range lock to allow finer grain locking on
> the memory layout of a task.
>
> This patch rename mmap_sem into mmap_rw_tree to avoid confusion and
> replace any locking (read or write) by complete range locking.  So
> there is no functional change except in the way the underlying locking
> is achieved.
>
> Currently, this patch only supports x86 and PowerPc architectures,
> furthermore it should break the build of any others.

Thanks for working on this.

However as commented before I think the first step to make progress here
is a description of everything mmap_sem protects.

Surely the init full case could be done shorter with some wrapper
that combines the init_full and lock operation?

Then it would be likely a simple search'n'replace to move the
whole tree in one atomic step to the new wrappers.
Initially they could be just defined to use rwsems too to
not change anything at all.

It would be a good idea to merge such a patch as quickly
as possible beause it will be a nightmare to maintain
longer term.

Then you could add a config to use a range lock through
the wrappers.

Then after that you could add real ranges step by step,
after doing the proper analysis.

-Andi

[toc] | [prev] | [next] | [standalone]


#1629694 — Re: [RFC 4/4] Change mmap_sem to range lock

FromLaurent Dufour <ldufour@linux.vnet.ibm.com>
Date2017-04-24 17:50 +0200
SubjectRe: [RFC 4/4] Change mmap_sem to range lock
Message-ID<tzOpt-mK-37@gated-at.bofh.it>
In reply to#1627869
On 21/04/2017 01:36, Andi Kleen wrote:
> Laurent Dufour <ldufour@linux.vnet.ibm.com> writes:
> 
>> [resent this patch which seems to have not reached the mailing lists]
>>
>> Change the mmap_sem to a range lock to allow finer grain locking on
>> the memory layout of a task.
>>
>> This patch rename mmap_sem into mmap_rw_tree to avoid confusion and
>> replace any locking (read or write) by complete range locking.  So
>> there is no functional change except in the way the underlying locking
>> is achieved.
>>
>> Currently, this patch only supports x86 and PowerPc architectures,
>> furthermore it should break the build of any others.
> 
> Thanks for working on this.
> 
> However as commented before I think the first step to make progress here
> is a description of everything mmap_sem protects.

Hi Andy,

I looked for the write mmap_sem locking in x86 and ppc64 architectures,
here is what I found:

mmap_sem protects
 vdso mapping
 VMA layout changes
 VMA cache
 Page protection/layout
 Changes to mmu notifier chain
 mmap_sem is used to serialize khugepaged's access
 mmap_sem is used to serialize ksm's access
 protection keys (pkey_alloc()...)

Calls to
 get_unmap_area()
 do_mmap()
 do_mmap_pgoff()
 do_munmap()
 get_user_pages()
 put_page()
 set_page_dirty_lock()
 find_vma()
 find_vma_intersection()
 alloc_empty_pages()
 insert_vm_struct()
 get_mm_rss()
 uprobe_consumer->filter() (currently only uprobe_perf_filter())
 _install_special_mapping()
 pmdp_collapse_flush()
 do_swap_page()
 do_brk()
 __split_vma()
 mremap_to()
 vma_to_resize()
 vma_adjust()

MM fields
   pinned_vm
   stack_vm
   total_vm
   locked_vm
   start_stack
   start_code
   end_code
   start_data
   start_brk
   bd_addr
   mm_users
   core_state
   context.vdso_*
   def_flags
   mmu_notifier_mm

VMA fields
    vm_private_data
    vm_flags
    vm_page_prot
    vm_file
    vm_pgoff
    vm_policy


Userfaultfd has not been looked in details yet.
dup_mmap() locks the oldmm in write mode when copying it, is it necessary ?

> Surely the init full case could be done shorter with some wrapper
> that combines the init_full and lock operation?

Yes that doable, I wrote this like that, because the range should be
initialized based on the on going operation, so having an explicit init
operation is making this more explicit.

> Then it would be likely a simple search'n'replace to move the
> whole tree in one atomic step to the new wrappers.
> Initially they could be just defined to use rwsems too to
> not change anything at all.
> 
> It would be a good idea to merge such a patch as quickly
> as possible beause it will be a nightmare to maintain
> longer term.
> 
> Then you could add a config to use a range lock through
> the wrappers.

I agree, I should try a way to make that patch activated through a
CONFIG_value, but there is a the additional range value that make it
more complex to achieve. I'll try to figure out a way to do that.

> Then after that you could add real ranges step by step,
> after doing the proper analysis.

That's the biggest part of the job.
I'm also wondering if a dedicated lock/sem should be introduced to
protect the VMA cache and the VMA list, since the range itself will not
protect against change while walking the VMA list.

Please advise.

Cheers,
Laurent.

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web