mm.git review status for linus..mm-stable

Everything:
 
 Total patches:       213
 Fixes: tags:         69
 cc:stable patches:   43
 Reviews/patch:       2.04
 Reviewed rate:       86%
 
 Excluding DAMON:
 
 Total patches:       192
 Fixes: tags:         63
 cc:stable patches:   39
 Reviews/patch:       2.18
 Reviewed rate:       89%
 
 Excluding DAMON and selftests:
 
 Total patches:       182
 Fixes: tags:         57
 cc:stable patches:   39
 Reviews/patch:       2.23
 Reviewed rate:       89%
 
 Summary of series in this merge:
 
 - "mm: make VMA flag semantics explicit, eliminate VM_SPECIAL"
   (Lorenzo Stoakes (ARM)):
 
   Replace VM_SPECIAL with helpers describing mapping ownership and
   behavior.  Enforce the mmap flag rules and convert affected drivers,
   removing ambiguous tests shared by driver mappings and ordinary memory.
 
 - "support kselftest on nommu platform" (Hajime Tazaki):
 
   Add opt-in mmap and mremap tests for NOMMU systems.  Teach the runner to
   avoid its fork-dependent timeout command and document the build and
   runtime requirements.
 
 - "mm/collapse: separate a collapse from its callers"
   (Kiryl Shutsemau (Meta)):
 
   Separate huge-page collapse from caller policy.  Replace khugepaged
   identity checks with explicit permissions, and separate scanning from
   collapse with the mmap_lock drop in one place.
 
 - "mm: implement and use vma_has_anon_rmap(), silence KCSAN"
   (Lorenzo Stoakes (ARM)):
 
   Provide a common helper for testing whether a VMA has anonymous reverse
   mappings.  Document the locking rules, annotate intentional concurrent
   reads for KCSAN, and convert the core MM callers.
 
 - "mm/sparse: remove SECTION_MARKED_PRESENT and further cleanups"
   (David Hildenbrand (Arm)):
 
   Remove SECTION_MARKED_PRESENT in favor of the early-section flag.
   Simplify sparse memory initialization, section metadata handling and
   related PFN validity checks.
 
 - "sh: remove NUMA and SPARSEMEM support" (Mike Rapoport (Microsoft)):
 
   Remove SuperH NUMA and SPARSEMEM support.  The extra memory banks have
   been unusable since the NO_BOOTMEM conversion, leaving only the code and
   data overhead.
 
 - "mm: Unify device DAX and HugeTLB vmemmap population paths"
   (Muchun Song):
 
   Unify the generic device DAX and HugeTLB vmemmap population paths and
   shared tail-page handling.  Remove the duplicate DAX machinery while
   retaining the powerpc radix implementation.
 
 - "kselftest: mm: fix some failure of split_huge_page_test" (Yeoreum Yun):
 
   Fix huge-page split tests racing with khugepaged recollapse.  Use pagemap
   and page flags instead of VMA-boundary assumptions which fail when glibc
   has already enabled THP.
 
 - "memcg: move memcgid refcount to objcg to unpin dying memcgs"
   (Bingfang Guo):
 
   Let dying memcgs be freed while swapped-out shmem still holds their IDs.
   Move ID references to reparentable objcgs, with the necessary swap
   accounting and RCU lifetime changes.
 
 - "mm/truncate: fix data loss when truncating straddling large folios"
   (Zhang Yi):
 
   Preserve out-of-range data when truncating straddling large folios.  Fix
   a lookup race and split-failure handling, and handle minimum folio orders
   for the forthcoming ext4 iomap buffered I/O path.
 
 - "mm/damon: introduce damos quota goal target metric complement flag"
   (SJ Park):
 
   Let DAMOS quota goals use a metric's complement, so utilization can also
   express free-memory goals without adding separate metrics.  Add the sysfs
   interface, documentation and tests.
 
 - "arm64/mm: Standardize printing for pgtable entries" (Anshuman Khandual):
 
   Use the generic formatter for arm64 page-table entries, ready for future
   wider entries.  Move the safe-PTE-update check out of the header to avoid
   an include cycle.
 
 - "mm: kmsan: fix iounmap metadata teardown" (Dima Koziuk):
 
   Fix KMSAN metadata leaks on iounmap and failed ioremap allocations.  Free
   backing pages before removing their mappings, and share the teardown with
   partial-allocation cleanup.
 
 - "mm/damon/core: preserve quota state when constructing schemes"
   (Karl Mehltretter):
 
   Preserve running DAMOS quota state while validating parameter updates.
   Even rejected updates could reset accounting and exceed the quota window;
   add tests for both accepted and rejected updates.
 
 - "mm/vmalloc: fix vmalloc_dump_obj VA lookup" (Ye Liu):
 
   Fix vmalloc_dump_obj() lookups for last-page addresses and allocations
   spanning vmap zones.  These allocations were being missed in diagnostic
   output.
 
 - "mm: various (urgent?) fixes" (David Hildenbrand (Arm)):
 
   Fix mmap charge leaks and hugetlb use-after-free, wrong-address
   unmapping, stuck locks and endless faults.  Also preserve reservations on
   failed mremap and handle stale userfaultfd bits.
 
 - "maple_tree: fix maple_range_64 crashes in RCU mode" (Dimitris Charisis):
 
   Fix pointer and metadata confusion during RCU destruction of
   maple_range_64 nodes, avoiding double frees and invalid accesses.  Add a
   regression test; no in-tree user currently uses this combination.
 
 - "mm: fix hugetlb NR_HUGETLB accounting on folio migration" (Hongfu Li):
 
   Fix hugetlb migration and preallocation accounting so /proc/vmstat
   retains the correct count and memory.numa_stat follows the folio to its
   new node.
 
 - "mm/damon: fix a minor bug, clean code, and add a test" (SJ Park):
 
   Fix 32-bit DAMON age overflow which made old regions look young.  Share
   hugetlb folio acquisition code and add a regression test for the
   previously fixed last-region skipping bug.
 
 - "mm/damon/core: cleanup code, reduce stack usage, and add kunit"
   (SJ Park):
 
   Reduce kdamond stack usage and remove unused enums.  Add deterministic
   PSI quota-goal tests which do not depend on the machine's current memory
   pressure.
 
 - "mm/damon: fix the temporal goal tuner's size quota conversion"
   (Donggeun Yoo):
 
   Bound the temporal tuner's quota conversion to prevent overflow and zero
   effective quotas, which could stop schemes making progress.  Add boundary
   tests.
 
 - "Don't use GFP_DMA when calling dma_alloc_coherent" (Baoquan He):
 
   Remove redundant GFP_DMA flags from coherent DMA allocation calls.  The
   DMA API already selects the zone from device limits and ignores the
   caller's flag.
 
 - "kselftest: mm: fix intermittent failure khugepaged test" (Yeoreum Yun):
 
   Propagate child-process failures in the khugepaged tests and prevent
   background collapse from racing their checks.  This removes false passes
   and intermittent failures.
 
 - "MAINTAINERS: cover all hugetlb headers under HUGETLB SUBSYSTEM"
   (Enze Li):
 
   Cover all hugetlb headers in MAINTAINERS so get_maintainer.pl finds the
   right maintainers.  Also label the closing hugetlb_cgroup.h include
   guard.
 
 Summary of the 65 singletons in this merge:
 
 The singletons include a few worthwhile performance fixes. Avoiding
 unnecessary reverse-map tree updates gave a reported 15.9% improvement
 in UnixBench's execl test on a 192-core x86 system. A reclaim retry fix
 stops defrag_mode from spinning under memory.low protection; a reported
 file-creation stress test ran 5.7 times faster, with far less memory
 pressure. Narrower hugetlb invalidations also spare KVM guests needless
 refaults: the reported Redis-in-VM P99 QPS penalty while punching holes
 fell from 7.09% to 1.45%.
 
 Several fixes prevent lost data or corrupted memory. Lazyfree huge-page
 races with mremap()/munmap() could lose data or access freed memory, and
 MADV_COLD could lose a concurrent write's dirty bit. Another fix
 prevents stale migration entries from outliving large folios. On
 filesystems with blocks smaller than a page, extending a file by 4 GiB
 or more could expose bytes written past the old EOF through mmap instead
 of zeroes. That is fixed, along with use-after-free races in
 PAGEMAP_SCAN during process exit and in memory-cgroup accounting on
 PREEMPT_RT kernels.
 
 Other fixes stop UFFDIO_MOVE spinning forever on pinned large folios,
 which could wedge other memory operations, and stop mremap() leaking
 commit charges until allocations fail under strict overcommit. A further
 fix keeps userfaultfd tracking intact on neighboring mappings. NUMA
 binding no longer prevents long-term pins when the chosen node has only
 movable memory, fixing QEMU/VFIO startup and io_uring buffer
 registration failures. MGLRU also gets a fix for early-boot crashes with
 memory cgroups disabled at boot, notably in small crash kernels.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCat66sAAKCRDdBJ7gKXxA
 jrQrAP99kgSXRdlmRZbHeRBHQ6KvI4XnLvQ78MDIzZ3zmBaOugEA5jiIsK2/snFD
 3VaV0oipVZpuwJkVJE6zFkh0tcHgTAo=
 =DHrN
 -----END PGP SIGNATURE-----

Merge tag 'mm-stable-2026-10-25-19-27' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull more MM updates from Andrew Morton:

 - "mm: make VMA flag semantics explicit, eliminate VM_SPECIAL" (Lorenzo
   Stoakes):

   Replace VM_SPECIAL with helpers describing mapping ownership and
   behavior. Enforce the mmap flag rules and convert affected drivers,
   removing ambiguous tests shared by driver mappings and ordinary
   memory.

 - "support kselftest on nommu platform" (Hajime Tazaki):

   Add opt-in mmap and mremap tests for NOMMU systems. Teach the runner
   to avoid its fork-dependent timeout command and document the build
   and runtime requirements.

 - "mm/collapse: separate a collapse from its callers" (Kiryl
   Shutsemau):

   Separate huge-page collapse from caller policy. Replace khugepaged
   identity checks with explicit permissions, and separate scanning from
   collapse with the mmap_lock drop in one place.

 - "mm: implement and use vma_has_anon_rmap(), silence KCSAN" (Lorenzo
   Stoakes):

   Provide a common helper for testing whether a VMA has anonymous
   reverse mappings. Document the locking rules, annotate intentional
   concurrent reads for KCSAN, and convert the core MM callers.

 - "mm/sparse: remove SECTION_MARKED_PRESENT and further cleanups"
   (David Hildenbrand):

   Remove SECTION_MARKED_PRESENT in favor of the early-section flag.
   Simplify sparse memory initialization, section metadata handling and
   related PFN validity checks.

 - "sh: remove NUMA and SPARSEMEM support" (Mike Rapoport):

   Remove SuperH NUMA and SPARSEMEM support. The extra memory banks have
   been unusable since the NO_BOOTMEM conversion, leaving only the code
   and data overhead.

 - "mm: Unify device DAX and HugeTLB vmemmap population paths" (Muchun
   Song):

   Unify the generic device DAX and HugeTLB vmemmap population paths and
   shared tail-page handling. Remove the duplicate DAX machinery while
   retaining the powerpc radix implementation.

 - "kselftest: mm: fix some failure of split_huge_page_test" (Yeoreum
   Yun):

   Fix huge-page split tests racing with khugepaged recollapse. Use
   pagemap and page flags instead of VMA-boundary assumptions which fail
   when glibc has already enabled THP.

 - "memcg: move memcgid refcount to objcg to unpin dying memcgs"
   (Bingfang Guo):

   Let dying memcgs be freed while swapped-out shmem still holds their
   IDs. Move ID references to reparentable objcgs, with the necessary
   swap accounting and RCU lifetime changes.

 - "mm/truncate: fix data loss when truncating straddling large folios"
   (Zhang Yi):

   Preserve out-of-range data when truncating straddling large folios.
   Fix a lookup race and split-failure handling, and handle minimum
   folio orders for the forthcoming ext4 iomap buffered I/O path.

 - "mm/damon: introduce damos quota goal target metric complement flag"
   (SJ Park):

   Let DAMOS quota goals use a metric's complement, so utilization can
   also express free-memory goals without adding separate metrics. Add
   the sysfs interface, documentation and tests.

 - "arm64/mm: Standardize printing for pgtable entries" (Anshuman
   Khandual):

   Use the generic formatter for arm64 page-table entries, ready for
   future wider entries. Move the safe-PTE-update check out of the
   header to avoid an include cycle.

 - "mm: kmsan: fix iounmap metadata teardown" (Dima Koziuk):

   Fix KMSAN metadata leaks on iounmap and failed ioremap allocations.
   Free backing pages before removing their mappings, and share the
   teardown with partial-allocation cleanup.

 - "mm/damon/core: preserve quota state when constructing schemes" (Karl
   Mehltretter):

   Preserve running DAMOS quota state while validating parameter
   updates. Even rejected updates could reset accounting and exceed the
   quota window; add tests for both accepted and rejected updates.

 - "mm/vmalloc: fix vmalloc_dump_obj VA lookup" (Ye Liu):

   Fix vmalloc_dump_obj() lookups for last-page addresses and
   allocations spanning vmap zones. These allocations were being missed
   in diagnostic output.

 - "mm: various (urgent?) fixes" (David Hildenbrand):

   Fix mmap charge leaks and hugetlb use-after-free, wrong-address
   unmapping, stuck locks and endless faults. Also preserve reservations
   on failed mremap and handle stale userfaultfd bits.

 - "maple_tree: fix maple_range_64 crashes in RCU mode" (Dimitris
   Charisis):

   Fix pointer and metadata confusion during RCU destruction of
   maple_range_64 nodes, avoiding double frees and invalid accesses. Add
   a regression test; no in-tree user currently uses this combination.

 - "mm: fix hugetlb NR_HUGETLB accounting on folio migration" (Hongfu
   Li):

   Fix hugetlb migration and preallocation accounting so /proc/vmstat
   retains the correct count and memory.numa_stat follows the folio to
   its new node.

 - "mm/damon: fix a minor bug, clean code, and add a test" (SJ Park):

   Fix 32-bit DAMON age overflow which made old regions look young.
   Share hugetlb folio acquisition code and add a regression test for
   the previously fixed last-region skipping bug.

 - "mm/damon/core: cleanup code, reduce stack usage, and add kunit" (SJ
   Park):

   Reduce kdamond stack usage and remove unused enums. Add deterministic
   PSI quota-goal tests which do not depend on the machine's current
   memory pressure.

 - "mm/damon: fix the temporal goal tuner's size quota conversion"
   (Donggeun Yoo):

   Bound the temporal tuner's quota conversion to prevent overflow and
   zero effective quotas, which could stop schemes making progress. Add
   boundary tests.

 - "Don't use GFP_DMA when calling dma_alloc_coherent" (Baoquan He):

   Remove redundant GFP_DMA flags from coherent DMA allocation calls.
   The DMA API already selects the zone from device limits and ignores
   the caller's flag.

 - "kselftest: mm: fix intermittent failure khugepaged test" (Yeoreum
   Yun):

   Propagate child-process failures in the khugepaged tests and prevent
   background collapse from racing their checks. This removes false
   passes and intermittent failures.

 - "MAINTAINERS: cover all hugetlb headers under HUGETLB SUBSYSTEM"
   (Enze Li):

   Cover all hugetlb headers in MAINTAINERS so get_maintainer.pl finds
   the right maintainers. Also label the closing hugetlb_cgroup.h
   include guard.

Summary of the 65 singletons in this merge:

  The singletons include a few worthwhile performance fixes. Avoiding
  unnecessary reverse-map tree updates gave a reported 15.9% improvement
  in UnixBench's execl test on a 192-core x86 system. A reclaim retry
  fix stops defrag_mode from spinning under memory.low protection; a
  reported file-creation stress test ran 5.7 times faster, with far less
  memory pressure. Narrower hugetlb invalidations also spare KVM guests
  needless refaults: the reported Redis-in-VM P99 QPS penalty while
  punching holes fell from 7.09% to 1.45%.

  Several fixes prevent lost data or corrupted memory. Lazyfree
  huge-page races with mremap()/munmap() could lose data or access freed
  memory, and MADV_COLD could lose a concurrent write's dirty bit.
  Another fix prevents stale migration entries from outliving large
  folios. On filesystems with blocks smaller than a page, extending a
  file by 4 GiB or more could expose bytes written past the old EOF
  through mmap instead of zeroes. That is fixed, along with
  use-after-free races in PAGEMAP_SCAN during process exit and in
  memory-cgroup accounting on PREEMPT_RT kernels.

  Other fixes stop UFFDIO_MOVE spinning forever on pinned large folios,
  which could wedge other memory operations, and stop mremap() leaking
  commit charges until allocations fail under strict overcommit. A
  further fix keeps userfaultfd tracking intact on neighboring mappings.
  NUMA binding no longer prevents long-term pins when the chosen node
  has only movable memory, fixing QEMU/VFIO startup and io_uring buffer
  registration failures. MGLRU also gets a fix for early-boot crashes
  with memory cgroups disabled at boot, notably in small crash kernels.

* tag 'mm-stable-2026-10-25-19-27' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (213 commits)
  mm: multi-gen LRU: fix NULL lruvec->pgdat deref with memcg disabled on cmdline
  mm/page_counter: use WRITE_ONCE() for emin/elow when parent is the root
  mm/memcontrol: publish null pointer before dropping css reference
  test_maple_tree: test maple_range_64 node in RCU mode
  maple_tree: fix maple_range_64 crashes in RCU mode
  mm/vma: avoid broken uffd merge on mremap
  tools/testing/shared: catch a failed posix_memalign()
  mm/damon/core: remove unreachable damos charge_{target,addr}_from
  mm/shrinker: allocate shrinker_info_unit from a dedicated kmem_cache
  riscv: mm: exclude invalid THP PMDs from page table check
  mm/damon/core: filter out damos address filter-split failed region
  fs/proc/task_mmu: pin mm_users in do_pagemap_scan()
  mm/mempolicy: apply bind policies against the scoped allocation zone
  mm/vmscan: reclaim every zone in per-node proactive reclaim
  mm/mremap: correctly uncharge accountable VMAs in error path
  mm/mremap: populate calculated fields in vrm state correctly
  MAINTAINERS: add an entry for MEMORY MANAGEMENT - MEMORY MAP
  mm: bdi: reset min_ratio after the sysfs attributes are gone
  mm/page_vma_mapped: continue past nonmatching huge PMDs
  selftests/mm: skip hugetlb cgroup v2 tests without the needed controllers
  ...
This commit is contained in:
Linus Torvalds 2026-10-27 12:23:17 -10:00
commit 8a36f53fd5
228 changed files with 4661 additions and 2470 deletions

View File

@ -282,6 +282,7 @@ ForEachMacros:
- 'for_each_dpcm_fe'
- 'for_each_drhd_unit'
- 'for_each_dss_dev'
- 'for_each_early_section_nr'
- 'for_each_efi_memory_desc'
- 'for_each_efi_memory_desc_in_map'
- 'for_each_element'
@ -403,7 +404,6 @@ ForEachMacros:
- 'for_each_possible_cpu_wrap'
- 'for_each_present_blessed_reg'
- 'for_each_present_cpu'
- 'for_each_present_section_nr'
- 'for_each_prime_number'
- 'for_each_prime_number_from'
- 'for_each_probe_cache_entry'

View File

@ -375,6 +375,12 @@ Contact: SJ Park <sj@kernel.org>
Description: Writing to and reading from this file sets and gets the quota
auto-tuning goal metric.
What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/quotas/goals/<G>/complement
Date: Sep 2026
Contact: SJ Park <sj@kernel.org>
Description: Writing to and reading from this file sets and gets whether to
use the complement value of the quota auto-tuning goal metric.
What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/quotas/goals/<G>/target_value
Date: Nov 2023
Contact: SJ Park <sj@kernel.org>

View File

@ -98,7 +98,8 @@ comma (",").
│ │ │ │ │ │ │ fail_charge_num,fail_charge_denom
│ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil
│ │ │ │ │ │ │ │ :ref:`goals <sysfs_schemes_quota_goals>`/nr_goals
│ │ │ │ │ │ │ │ │ 0/target_metric,target_value,current_value,nid,path
│ │ │ │ │ │ │ │ │ 0/target_metric,complement,target_value,
│ │ │ │ │ │ │ │ │ current_value,nid,path
│ │ │ │ │ │ │ :ref:`watermarks <sysfs_watermarks>`/metric,interval_us,high,mid,low
│ │ │ │ │ │ │ :ref:`{core_,ops_,}filters <sysfs_filters>`/nr_filters
│ │ │ │ │ │ │ │ 0/type,matching,allow,memcg_path,addr_start,addr_end,damon_target_idx,min,max
@ -492,12 +493,12 @@ number (``N``) to the file creates the number of child directories named ``0``
to ``N-1``. Each directory represents each goal and current achievement.
Among the multiple feedback, the best one is used.
Each goal directory contains five files, namely ``target_metric``,
``target_value``, ``current_value``, ``nid``, and ``path``. Users can set and
get the five parameters for the quota auto-tuning goals that specified on the
:ref:`design doc <damon_design_damos_quotas_auto_tuning>` by writing to and
reading from each of the files. Because the kernel does not update
``current_value``, reading it only makes sense when ``target_metric`` is
Each goal directory contains six files, namely ``target_metric``,
``complement``, ``target_value``, ``current_value``, ``nid``, and ``path``.
Users can set and get the six parameters for the quota auto-tuning goals that
specified on the :ref:`design doc <damon_design_damos_quotas_auto_tuning>` by
writing to and reading from each of the files. Because the kernel does not
update ``current_value``, reading it only makes sense when ``target_metric`` is
``user_input``. Note that users should further write
``commit_schemes_quota_goals`` to the ``state`` file of the :ref:`kdamond
directory <sysfs_kdamond>` to pass the feedback to DAMON.

View File

@ -373,9 +373,9 @@ contains the following attribute files::
free_hugepages
surplus_hugepages
The free\_' and surplus\_' attribute files are read-only. They return the number
of free and surplus [overcommitted] huge pages, respectively, on the parent
node.
The ``free_hugepages`` and ``surplus_hugepages`` attribute files are read-only.
They return the number of free and surplus [overcommitted] huge pages,
respectively, on the parent node.
The ``nr_hugepages`` attribute returns the total number of huge pages on the
specified node. When this attribute is written, the number of persistent huge

View File

@ -539,6 +539,13 @@ watermark[WMARK_MIN] value for each lowmem zone in the system.
Each lowmem zone gets a number of reserved free pages based
proportionally on its size.
By default, the kernel sets this value based on the amount of lowmem
and recalculates it on memory hotplug. When Transparent Hugepage (THP)
support is enabled through global or per-size controls, the kernel may
also raise it to help keep pageblocks free and reduce fragmentation for
THP allocations. Once a value is written to this file, the kernel no
longer adjusts it automatically.
Some minimal amount of memory is needed to satisfy PF_MEMALLOC
allocations; if you set this to lower than 1024KB, your system will
become subtly broken, and prone to deadlock under high loads.

View File

@ -268,6 +268,24 @@ section::
.. _tar's auto-compress: https://www.gnu.org/software/tar/manual/html_node/gzip.html#auto_002dcompress
Build and test on nommu target
==============================
The nommu selftests detect NOMMU at runtime by checking for the ``MmapCopy``
entry in ``/proc/meminfo``. Ensure procfs is mounted at ``/proc`` before
building and running the tests.
::
$ make ARCH=um O=build kselftest-all TARGETS=nommu # <= build-only
$ make ARCH=um O=build kselftest-install TARGETS=nommu
$ ./build/kselftest/kselftest_install/run_kselftest.sh -p -c nommu
The C tests report a skip if ``/proc/meminfo`` is unavailable. On a NOMMU
system, the runner needs that file to avoid wrapping the tests in ``timeout``
before they can report a skip. Mounting procfs is therefore a prerequisite
for running this target through the kselftest runner.
Contributing new tests
======================

View File

@ -164,5 +164,86 @@ pointer. These are:
sufficient entries in the page array to cover the entire range of the
described VMA.
* mmap_action_map_discontig_kernel_pages() - Maps a discontiguous range of
`struct page` pointers over the VMA. They must span from the start of the VMA,
but may terminate prior to the end (leaving the remainder unmapped).
**NOTE:** The ``action`` field should never normally be manipulated directly,
rather you ought to use one of these helpers.
Discontiguous Actions
=====================
Some actions can be performed across discontiguous ranges.
Map kernel pages
----------------
To map kernel pages discontiguously, you must provide hooks using ``struct
discontig_kernel_page_ops``:
.. code-block:: C
struct discontig_kernel_page_ops {
int (*init)(void *vm_private_data, void **private);
int (*get)(struct discontig_kernel_page_state *state);
};
The ``init`` hook is optional and allows state to be established before the
operation starts, for instance taking a reference count. Nothing is invoked
after the operation, so ``init`` must not leave locks held, and state that must
be released once the mapping goes away should be released in
``vm_ops->close``.
The ``init`` hook, if provided, is invoked prior to the operation starting. It
may update what is pointed to by ``vm_private_data`` and/or ``private``. If an
error is returned, then the operation is aborted. The ``private`` field can be
reassigned.
**NOTE:** The operation may sleep between invocations of ``get``, so locks
needed to stabilise state must be taken and released within each hook.
The ``get`` handler is the key means through which the operation is
executed. The current state of the operation is provided through ``struct
discontig_kernel_page_state``:
.. code-block:: C
struct discontig_kernel_page_state {
/* Map state. */
unsigned long start; /* Start address of VMA. */
unsigned long end; /* End address of VMA. */
unsigned long addr; /* The current address to be mapped. */
pgoff_t pgoff; /* The current pgoff to be mapped. */
unsigned long nr_pages_mapped; /* The number of pages mapped. */
unsigned long nr_pages_remain; /* The number of pages remaining. */
/* User-defined state. */
void *vm_private_data; /* VMA private data. */
void *private; /* Mapping private data. */
/* Users should not touch these, use discontig_kernel_map_*() helpers. */
... internal fields ...
};
With ``private`` being an additional user-controllable state variable,
initialised via ``mmap_action_map_discontig_kernel_pages()``, and
``vm_private_data`` being equal to the ``desc->private_data`` field set in
the ``mmap_prepare()`` hook.
In the ``get`` hook, the user must choose how to map kernel pages:
* ``discontig_kernel_map_abort()`` - Call this to abort the operation, whatever
has been mapped so far will be retained, the rest of the mapping will SIGBUS
if accessed.
* ``discontig_kernel_map_page()`` - Maps a single page, correctly handling
compound pages (if the compound page is bigger than the remaining pages in the
VMA, then only those pages that fit will be mapped). For a compound page, the
head page must be passed.
* ``discontig_kernel_map_pages()`` - Map an array of pages of a specified
size. As with a compound page, if more pages are specified than remain in
the VMA then only those that fit will be mapped.
If an error arises after ``init`` succeeded, the core unmaps the VMA, invoking
``vm_ops->close`` if set, which is therefore the place to release any state
that ``init`` established.

View File

@ -702,10 +702,10 @@ There are two such tuning algorithms that users can select as they need.
that the zero quota is a valid quota, and therefore ``qt_exceeds`` :ref:`stat
<damon_design_damos_stat>` will keep increasing in this case.
The goal can be specified with five parameters, namely ``target_metric``,
``target_value``, ``current_value``, ``nid`` and ``path``. The auto-tuning
mechanism tries to make ``current_value`` of ``target_metric`` be same to
``target_value``.
The goal can be specified with six parameters, namely ``target_metric``,
``complement``, ``target_value``, ``current_value``, ``nid`` and ``path``. The
auto-tuning mechanism tries to make ``current_value`` of ``complement``-ed
``target_metric`` be same to ``target_value``.
- ``user_input``: User-provided value. Users could use any metric that they
has interest in for the value. Use space main workload's latency or
@ -733,6 +733,13 @@ mechanism tries to make ``current_value`` of ``target_metric`` be same to
- ``hugepage_mem_bp``: Total huge page to total used memory ratio in bp
(1/10,000).
``complement`` is a boolean parameter that determines whether to use
complemented value of the target metric. For example, if ``complement`` is set
and target metric is ``active_mem_bp``, it is effectively same to
``inactive_mem_bp``. ``complement`` is no-op when the target metric type is
``user_input``. For the metric type, the user should be able to emit
complemented metric values on their own.
``nid`` is optionally required for ``node_mem_used_bp``, ``node_mem_free_bp``,
``node_memcg_used_bp``, ``node_memcg_free_bp`` and ``node_eligible_mem_bp`` to
point the specific NUMA node.

View File

@ -819,9 +819,17 @@ All this is achieved by the use of per-mm and per-VMA sequence counts, which are
used in order to reduce complexity, especially for operations which write-lock
multiple VMAs at once.
If the mm sequence count, :c:member:`!mm->mm_lock_seq` is equal to the VMA
sequence count :c:member:`!vma->vm_lock_seq` then the VMA is write-locked. If
they differ, then it is not.
The mm sequence count :c:member:`!mm->mm_lock_seq` is incremented on both mmap
write lock and unlock, so it is odd while the mmap write lock is held. If it is
equal to the VMA sequence count :c:member:`!vma->vm_lock_seq`, and that value
is odd, then the VMA is write-locked. If they differ, then it is not.
A VMA's sequence count is not updated on unlock, so after 2^31 write lock/unlock
cycles the mm sequence count would wrap and match stale VMA values again. To
prevent this, when the mm sequence count wraps to zero,
:c:func:`!vma_end_write_all` invokes :c:func:`!__mm_reset_vma_seqcounts` to
reset every VMA's sequence count to zero, an even value which can never
indicate a write lock.
Each time the mmap write lock is released in :c:func:`!mmap_write_unlock` or
:c:func:`!mmap_write_downgrade`, :c:func:`!vma_end_write_all` is invoked which

View File

@ -12337,7 +12337,7 @@ F: Documentation/admin-guide/mm/hugetlbpage.rst
F: Documentation/mm/hugetlbfs_reserv.rst
F: Documentation/mm/vmemmap_dedup.rst
F: fs/hugetlbfs/
F: include/linux/hugetlb.h
F: include/linux/hugetlb*
F: include/linux/vmemmap-optimization.h
F: include/trace/events/hugetlbfs.h
F: mm/hugetlb.c
@ -17496,9 +17496,6 @@ F: mm/mmzone.c
F: mm/pagewalk.c
F: mm/pgtable-generic.c
F: mm/ptdump.c
F: mm/sparse-vmemmap.c
F: mm/sparse.c
F: mm/sparse.h
F: mm/util.c
F: mm/vmpressure.c
F: mm/vmstat.c
@ -17546,6 +17543,21 @@ F: include/trace/events/ksm.h
F: mm/ksm.c
F: mm/mm_slot.h
MEMORY MANAGEMENT - MEMORY MAP
M: Muchun Song <muchun.song@linux.dev>
M: Mike Rapoport <rppt@kernel.org>
M: David Hildenbrand <david@kernel.org>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git memmap
F: Documentation/mm/memory-model.rst
F: arch/*/include/asm/sparsemem.h
F: include/asm-generic/memory_model.h
F: mm/sparse-vmemmap.c
F: mm/sparse.c
F: mm/sparse.h
K: (?i:vmemmap)
MEMORY MANAGEMENT - MGLRU (MULTI-GEN LRU)
M: Andrew Morton <akpm@linux-foundation.org>
R: Kairui Song <kasong@tencent.com>
@ -17607,6 +17619,8 @@ F: Documentation/admin-guide/mm/
F: Documentation/core-api/memory-allocation.rst
F: Documentation/core-api/mm-api.rst
F: Documentation/mm/
X: Documentation/admin-guide/mm/damon/
X: Documentation/mm/damon/
F: mm/char-mem.c
F: include/linux/cma.h
F: include/linux/dmapool.h
@ -17786,6 +17800,7 @@ F: Documentation/admin-guide/mm/transhuge.rst
F: include/linux/huge_mm.h
F: include/linux/khugepaged.h
F: include/trace/events/huge_memory.h
F: mm/collapse.h
F: mm/huge_memory.c
F: mm/khugepaged.c
F: mm/mm_slot.h

View File

@ -17,7 +17,7 @@ config ARM_PTDUMP_DEBUGFS
kernel.
If in doubt, say "N"
config ARM_DEBUG_WX
config ARM_CHECK_WX
bool "Warn on W+X mappings at boot"
depends on MMU
select ARM_PTDUMP_CORE

View File

@ -249,7 +249,7 @@ CONFIG_DEBUG_INFO_REDUCED=y
CONFIG_GDB_SCRIPTS=y
CONFIG_STRIP_ASM_SYMS=y
CONFIG_DEBUG_FS=y
CONFIG_ARM_DEBUG_WX=y
CONFIG_ARM_CHECK_WX=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=-1

View File

@ -300,7 +300,7 @@ CONFIG_DEBUG_INFO_REDUCED=y
CONFIG_GDB_SCRIPTS=y
CONFIG_STRIP_ASM_SYMS=y
CONFIG_DEBUG_FS=y
CONFIG_ARM_DEBUG_WX=y
CONFIG_ARM_CHECK_WX=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=-1

View File

@ -226,4 +226,4 @@ CONFIG_CMA_SIZE_MBYTES=64
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_FS=y
CONFIG_ARM_DEBUG_WX=y
CONFIG_ARM_CHECK_WX=y

View File

@ -32,10 +32,10 @@ void ptdump_check_wx(void);
#endif /* CONFIG_ARM_PTDUMP_CORE */
#ifdef CONFIG_ARM_DEBUG_WX
#define arm_debug_checkwx() ptdump_check_wx()
#ifdef CONFIG_ARM_CHECK_WX
#define arm_pgtable_checkwx() ptdump_check_wx()
#else
#define arm_debug_checkwx() do { } while (0)
#define arm_pgtable_checkwx() do { } while (0)
#endif
#endif /* __ASM_PTDUMP_H */

View File

@ -403,7 +403,7 @@ static int __mark_rodata_ro(void *unused)
void mark_rodata_ro(void)
{
stop_machine(__mark_rodata_ro, NULL, NULL);
arm_debug_checkwx();
arm_pgtable_checkwx();
}
#else

View File

@ -11,7 +11,7 @@ config ARM64
select ACPI_MCFG if (ACPI && PCI)
select ACPI_SPCR_TABLE if ACPI
select ACPI_PPTT if ACPI
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_CHECK_WX
select ARCH_BINFMT_ELF_EXTRA_PHDRS
select ARCH_BINFMT_ELF_STATE
select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION

View File

@ -387,52 +387,13 @@ static inline pte_t __ptep_get(pte_t *ptep)
extern void __sync_icache_dcache(pte_t pteval);
bool pgattr_change_is_safe(pteval_t old, pteval_t new);
/*
* PTE bits configuration in the presence of hardware Dirty Bit Management
* (PTE_WRITE == PTE_DBM):
*
* Dirty Writable | PTE_RDONLY PTE_WRITE PTE_DIRTY (sw)
* 0 0 | 1 0 0
* 0 1 | 1 1 0
* 1 0 | 1 0 1
* 1 1 | 0 1 x
*
* When hardware DBM is not present, the software PTE_DIRTY bit is updated via
* the page fault mechanism. Checking the dirty status of a pte becomes:
*
* PTE_DIRTY || (PTE_WRITE && !PTE_RDONLY)
*/
static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
pte_t pte)
#ifdef CONFIG_DEBUG_VM
void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep, pte_t pte);
#else
static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep, pte_t pte)
{
pte_t old_pte;
if (!IS_ENABLED(CONFIG_DEBUG_VM))
return;
old_pte = __ptep_get(ptep);
if (!pte_valid(old_pte) || !pte_valid(pte))
return;
if (mm != current->active_mm && atomic_read(&mm->mm_users) <= 1)
return;
/*
* Check for potential race with hardware updates of the pte
* (__ptep_set_access_flags safely changes valid ptes without going
* through an invalid entry).
*/
VM_WARN_ONCE(!pte_young(pte),
"%s: racy access flag clearing: 0x%016llx -> 0x%016llx",
__func__, pte_val(old_pte), pte_val(pte));
VM_WARN_ONCE(pte_write(old_pte) && !pte_dirty(pte),
"%s: racy dirty state clearing: 0x%016llx -> 0x%016llx",
__func__, pte_val(old_pte), pte_val(pte));
VM_WARN_ONCE(!pgattr_change_is_safe(pte_val(old_pte), pte_val(pte)),
"%s: unsafe attribute change: 0x%016llx -> 0x%016llx",
__func__, pte_val(old_pte), pte_val(pte));
}
#endif /* CONFIG_DEBUG_VM */
static inline void __sync_cache_and_tags(pte_t pte, unsigned int nr_pages)
{

View File

@ -1587,7 +1587,7 @@ transparent_hugepage_adjust(const struct kvm_s2_fault_desc *s2fd, kvm_pfn_t *pfn
static int get_vma_page_shift(struct vm_area_struct *vma)
{
if (is_vm_hugetlb_page(vma))
if (vma_is_hugetlb(vma))
return huge_page_shift(hstate_vma(vma));
return PAGE_SHIFT;

View File

@ -131,6 +131,7 @@ static inline unsigned long mm_to_pgd_phys(struct mm_struct *mm)
*/
static void show_pte(unsigned long addr)
{
char pxd_str[PTVAL_STR_MAX];
struct mm_struct *mm;
pgd_t *pgdp;
pgd_t pgd;
@ -160,7 +161,8 @@ static void show_pte(unsigned long addr)
pgdp = pgd_offset(mm, addr);
pgd = READ_ONCE(*pgdp);
pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
ptval_to_str(pxd_str, pgd_val(pgd));
pr_alert("[%016lx] pgd=%s", addr, pxd_str);
do {
p4d_t *p4dp, p4d;
@ -173,19 +175,22 @@ static void show_pte(unsigned long addr)
p4dp = p4d_offset_lockless(pgdp, pgd, addr);
p4d = READ_ONCE(*p4dp);
pr_cont(", p4d=%016llx", p4d_val(p4d));
ptval_to_str(pxd_str, p4d_val(p4d));
pr_cont(", p4d=%s", pxd_str);
if (p4d_none(p4d) || p4d_bad(p4d))
break;
pudp = pud_offset_lockless(p4dp, p4d, addr);
pud = READ_ONCE(*pudp);
pr_cont(", pud=%016llx", pud_val(pud));
ptval_to_str(pxd_str, pud_val(pud));
pr_cont(", pud=%s", pxd_str);
if (pud_none(pud) || pud_bad(pud))
break;
pmdp = pmd_offset_lockless(pudp, pud, addr);
pmd = READ_ONCE(*pmdp);
pr_cont(", pmd=%016llx", pmd_val(pmd));
ptval_to_str(pxd_str, pmd_val(pmd));
pr_cont(", pmd=%s", pxd_str);
if (pmd_none(pmd) || pmd_bad(pmd))
break;
@ -194,7 +199,8 @@ static void show_pte(unsigned long addr)
break;
pte = __ptep_get(ptep);
pr_cont(", pte=%016llx", pte_val(pte));
ptval_to_str(pxd_str, pte_val(pte));
pr_cont(", pte=%s", pxd_str);
pte_unmap(ptep);
} while(0);

View File

@ -2393,3 +2393,51 @@ int arch_set_user_pkey_access(int pkey, unsigned long init_val)
return 0;
}
#endif
/*
* PTE bits configuration in the presence of hardware Dirty Bit Management
* (PTE_WRITE == PTE_DBM):
*
* Dirty Writable | PTE_RDONLY PTE_WRITE PTE_DIRTY (sw)
* 0 0 | 1 0 0
* 0 1 | 1 1 0
* 1 0 | 1 0 1
* 1 1 | 0 1 x
*
* When hardware DBM is not present, the software PTE_DIRTY bit is updated via
* the page fault mechanism. Checking the dirty status of a pte becomes:
*
* PTE_DIRTY || (PTE_WRITE && !PTE_RDONLY)
*/
#ifdef CONFIG_DEBUG_VM
void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep, pte_t pte)
{
char pte_str_old[PTVAL_STR_MAX];
char pte_str[PTVAL_STR_MAX];
pte_t old_pte;
old_pte = __ptep_get(ptep);
if (!pte_valid(old_pte) || !pte_valid(pte))
return;
if (mm != current->active_mm && atomic_read(&mm->mm_users) <= 1)
return;
/*
* Check for potential race with hardware updates of the pte
* (__ptep_set_access_flags safely changes valid ptes without going
* through an invalid entry).
*/
ptval_to_str(pte_str, pte_val(pte));
ptval_to_str(pte_str_old, pte_val(old_pte));
VM_WARN_ONCE(!pte_young(pte),
"%s: racy access flag clearing: %s -> %s",
__func__, pte_str_old, pte_str);
VM_WARN_ONCE(pte_write(old_pte) && !pte_dirty(pte),
"%s: racy dirty state clearing: %s -> %s",
__func__, pte_str_old, pte_str);
VM_WARN_ONCE(!pgattr_change_is_safe(pte_val(old_pte), pte_val(pte)),
"%s: unsafe attribute change: %s -> %s",
__func__, pte_str_old, pte_str);
}
#endif /* CONFIG_DEBUG_VM */

View File

@ -130,7 +130,7 @@ config PPC
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEBUG_WX if STRICT_KERNEL_RWX
select ARCH_HAS_CHECK_WX if STRICT_KERNEL_RWX
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_MAP_DIRECT if PPC_PSERIES
select ARCH_HAS_DMA_OPS if PPC64

View File

@ -393,7 +393,7 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_PAGE_OWNER=y
CONFIG_PAGE_POISONING=y
CONFIG_DEBUG_RODATA_TEST=y
CONFIG_DEBUG_WX=y
CONFIG_CHECK_WX=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_VM=y
# CONFIG_DEBUG_VM_PGTABLE is not set

View File

@ -1126,7 +1126,10 @@ int __meminit radix__vmemmap_populate(unsigned long start, unsigned long end, in
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned long pfn = page_to_pfn((struct page *)start);
if (vmemmap_optimizable_order(pfn_to_section_compound_order(pfn)))
return vmemmap_populate_compound_pages(pfn, start, end, node, NULL);
/*
* If altmap is present, Make sure we align the start vmemmap addr
* to PAGE_SIZE so that we calculate the correct start_pfn in

View File

@ -627,7 +627,7 @@ void radix__local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmadd
{
#ifdef CONFIG_HUGETLB_PAGE
/* need the return fix for nohash.c */
if (is_vm_hugetlb_page(vma))
if (vma_is_hugetlb(vma))
return radix__local_flush_hugetlb_page(vma, vmaddr);
#endif
radix__local_flush_tlb_page_psize(vma->vm_mm, vmaddr, mmu_virtual_psize);
@ -945,7 +945,7 @@ void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr,
void radix__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
{
#ifdef CONFIG_HUGETLB_PAGE
if (is_vm_hugetlb_page(vma))
if (vma_is_hugetlb(vma))
return radix__flush_hugetlb_page(vma, vmaddr);
#endif
radix__flush_tlb_page_psize(vma->vm_mm, vmaddr, mmu_virtual_psize);
@ -1113,7 +1113,7 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
{
#ifdef CONFIG_HUGETLB_PAGE
if (is_vm_hugetlb_page(vma))
if (vma_is_hugetlb(vma))
return radix__flush_hugetlb_tlb_range(vma, start, end);
#endif

View File

@ -180,7 +180,7 @@ book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea, pte_t pte)
*/
void __update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
{
if (is_vm_hugetlb_page(vma))
if (vma_is_hugetlb(vma))
book3e_hugetlb_preload(vma, address, *ptep);
}

View File

@ -278,7 +278,7 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
{
#ifdef CONFIG_HUGETLB_PAGE
if (vma && is_vm_hugetlb_page(vma))
if (vma && vma_is_hugetlb(vma))
flush_hugetlb_page(vma, vmaddr);
#endif

View File

@ -191,7 +191,7 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
if (!pte_write(pte) || !pte_exec(pte))
return;
WARN_ONCE(IS_ENABLED(CONFIG_DEBUG_WX),
WARN_ONCE(IS_ENABLED(CONFIG_CHECK_WX),
"powerpc/mm: Found insecure W+X mapping at address %p/%pS\n",
(void *)st->start_address, (void *)st->start_address);

View File

@ -29,7 +29,7 @@ config RISCV
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_CHECK_WX
select ARCH_HAS_DELAY_TIMER
select ARCH_HAS_ELF_CORE_EFLAGS if BINFMT_ELF && ELF_CORE
select ARCH_HAS_FAST_MULTIPLIER

View File

@ -989,7 +989,14 @@ static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long
static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
{
return pmd_leaf(pmd) && pmd_user(pmd);
/*
* page_table_check() must ignore THP split invalidation entries created by
* pmd_mkinvalid(). These retain _PAGE_LEAF so pmd_present()/pmd_leaf() stay
* true during the split, but they no longer describe a user-accessible
* mapping once both _PAGE_PRESENT and _PAGE_PROT_NONE are cleared.
*/
return (pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROT_NONE)) &&
(pmd_val(pmd) & _PAGE_LEAF) && pmd_user(pmd);
}
static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)

View File

@ -665,7 +665,7 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
return -EFAULT;
}
is_hugetlb = is_vm_hugetlb_page(vma);
is_hugetlb = vma_is_hugetlb(vma);
if (is_hugetlb)
vma_pageshift = huge_page_shift(hstate_vma(vma));
else

View File

@ -149,7 +149,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
{
unsigned long stride_size;
if (!is_vm_hugetlb_page(vma)) {
if (!vma_is_hugetlb(vma)) {
stride_size = PAGE_SIZE;
} else {
stride_size = huge_page_size(hstate_vma(vma));

View File

@ -92,7 +92,7 @@ config S390
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_CHECK_WX
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_OPS if PCI
select ARCH_HAS_ELF_RANDOMIZE

View File

@ -855,7 +855,7 @@ CONFIG_DEBUG_PAGEALLOC=y
CONFIG_SLUB_DEBUG_ON=y
CONFIG_PAGE_OWNER=y
CONFIG_DEBUG_RODATA_TEST=y
CONFIG_DEBUG_WX=y
CONFIG_CHECK_WX=y
CONFIG_PTDUMP_DEBUGFS=y
CONFIG_DEBUG_OBJECTS=y
CONFIG_DEBUG_OBJECTS_SELFTEST=y

View File

@ -834,7 +834,7 @@ CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_GDB_SCRIPTS=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_WX=y
CONFIG_CHECK_WX=y
CONFIG_PTDUMP_DEBUGFS=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_PANIC_ON_OOPS=y

View File

@ -86,7 +86,7 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
*/
if (addr == PAGE_SIZE && (nospec_uses_trampoline() || !cpu_has_bear()))
return;
WARN_ONCE(IS_ENABLED(CONFIG_DEBUG_WX),
WARN_ONCE(IS_ENABLED(CONFIG_CHECK_WX),
"s390/mm: Found insecure W+X mapping at address %pS\n",
(void *)st->start_address);
st->wx_pages += (addr - st->start_address) / PAGE_SIZE;

View File

@ -102,7 +102,7 @@ __context_unsafe(/* pte_unmap_unlock() not instrumented */)
/* Find the vm address for the guest address */
vma = vma_lookup(mm, vmaddr);
if (!vma || is_vm_hugetlb_page(vma))
if (!vma || vma_is_hugetlb(vma))
return;
/* Get pointer to the page table entry */
@ -139,7 +139,7 @@ void gmap_helper_discard(struct mm_struct *mm, unsigned long vmaddr, unsigned lo
vma = find_vma_intersection(mm, vmaddr, end);
if (!vma)
return;
if (!is_vm_hugetlb_page(vma))
if (!vma_is_hugetlb(vma))
zap_vma_range(vma, vmaddr, min(end, vma->vm_end) - vmaddr);
vmaddr = vma->vm_end;
}
@ -247,7 +247,7 @@ static int __gmap_helper_unshare_zeropages(struct mm_struct *mm)
* proof to catch unexpected zeropages in other mappings and
* fail.
*/
if ((vma->vm_flags & VM_PFNMAP) || is_vm_hugetlb_page(vma))
if ((vma->vm_flags & VM_PFNMAP) || vma_is_hugetlb(vma))
continue;
addr = vma->vm_start;

View File

@ -108,9 +108,6 @@ config SYS_SUPPORTS_APM_EMULATION
config SYS_SUPPORTS_SMP
bool
config SYS_SUPPORTS_NUMA
bool
config STACKTRACE_SUPPORT
def_bool y
@ -199,7 +196,6 @@ config CPU_SHX3
bool
select DMA_COHERENT
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_NUMA
config ARCH_SHMOBILE
bool
@ -392,7 +388,6 @@ config CPU_SUBTYPE_SH7723
select CPU_SH4A
select CPU_SHX2
select ARCH_SHMOBILE
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_SH_CMT
select PINCTRL
help
@ -403,7 +398,6 @@ config CPU_SUBTYPE_SH7724
select CPU_SH4A
select CPU_SHX2
select ARCH_SHMOBILE
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_SH_CMT
select PINCTRL
help
@ -444,8 +438,6 @@ config CPU_SUBTYPE_SH7785
bool "Support SH7785 processor"
select CPU_SH4A
select CPU_SHX2
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_NUMA
select PINCTRL
config CPU_SUBTYPE_SH7786
@ -480,8 +472,6 @@ config CPU_SUBTYPE_SH7722
select CPU_SH4AL_DSP
select CPU_SHX2
select ARCH_SHMOBILE
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_NUMA
select SYS_SUPPORTS_SH_CMT
select PINCTRL
@ -490,8 +480,6 @@ config CPU_SUBTYPE_SH7366
select CPU_SH4AL_DSP
select CPU_SHX2
select ARCH_SHMOBILE
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_NUMA
select SYS_SUPPORTS_SH_CMT
endchoice

View File

@ -9,7 +9,6 @@ CONFIG_MODULES=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_CPU_SUBTYPE_SH7722=y
CONFIG_MEMORY_START=0x0c000000
CONFIG_NUMA=y
# CONFIG_MIGRATION is not set
CONFIG_SH_MIGOR=y
# CONFIG_SH_TIMER_CMT is not set

View File

@ -41,7 +41,6 @@ CONFIG_CPU_SUBTYPE_SH7786=y
CONFIG_MEMORY_START=0x40000000
CONFIG_MEMORY_SIZE=0x20000000
CONFIG_PMB=y
CONFIG_NUMA=y
CONFIG_HUGETLB_PAGE_SIZE_64MB=y
CONFIG_KSM=y
CONFIG_SH_STORE_QUEUES=y

View File

@ -10,7 +10,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_CPU_SUBTYPE_SH7722=y
CONFIG_MEMORY_START=0x0c000000
CONFIG_NUMA=y
CONFIG_SH_STORE_QUEUES=y
CONFIG_SH_7722_SOLUTION_ENGINE=y
# CONFIG_SH_TIMER_CMT is not set

View File

@ -29,7 +29,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_CPU_SUBTYPE_SHX3=y
CONFIG_MEMORY_START=0x0c000000
CONFIG_NUMA=y
CONFIG_PAGE_SIZE_64KB=y
CONFIG_SH_STORE_QUEUES=y
CONFIG_SH_X3PROTO=y

View File

@ -10,7 +10,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_CPU_SUBTYPE_SH7366=y
CONFIG_MEMORY_SIZE=0x01f00000
CONFIG_NUMA=y
# CONFIG_MIGRATION is not set
# CONFIG_SH_DSP is not set
# CONFIG_SH_TIMER_CMT is not set

View File

@ -2,6 +2,8 @@
#ifndef __MMU_H
#define __MMU_H
#define MAX_PHYSMEM_BITS 32
/*
* Privileged Space Mapping Buffer (PMB) definitions
*/

View File

@ -1,42 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_SH_MMZONE_H
#define __ASM_SH_MMZONE_H
#ifdef CONFIG_NUMA
#include <linux/numa.h>
static inline int pfn_to_nid(unsigned long pfn)
{
int nid;
for (nid = 0; nid < MAX_NUMNODES; nid++)
if (pfn >= node_start_pfn(nid) && pfn <= node_end_pfn(nid))
break;
return nid;
}
static inline struct pglist_data *pfn_to_pgdat(unsigned long pfn)
{
return NODE_DATA(pfn_to_nid(pfn));
}
/* arch/sh/mm/numa.c */
void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end);
#else
static inline void
setup_bootmem_node(int nid, unsigned long start, unsigned long end)
{
}
#endif /* CONFIG_NUMA */
/* Platform specific mem init */
void __init plat_mem_setup(void);
/* arch/sh/kernel/setup.c */
void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
unsigned long end_pfn);
/* arch/sh/mm/init.c */
void __init allocate_pgdat(unsigned int nid);
#endif /* __ASM_SH_MMZONE_H */

View File

@ -24,4 +24,7 @@ void check_for_initrd(void);
void per_cpu_trap_init(void);
void sh_fdt_init(phys_addr_t dt_phys);
void __add_active_range(unsigned int nid, unsigned long start_pfn,
unsigned long end_pfn);
#endif /* _SH_SETUP_H */

View File

@ -1,12 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_SH_SPARSEMEM_H
#define __ASM_SH_SPARSEMEM_H
/*
* SECTION_SIZE_BITS 2^N: how big each section will be
* MAX_PHYSMEM_BITS 2^N: how much physical address space we have
*/
#define SECTION_SIZE_BITS 26
#define MAX_PHYSMEM_BITS 32
#endif /* __ASM_SH_SPARSEMEM_H */

View File

@ -2,19 +2,6 @@
#ifndef _ASM_SH_TOPOLOGY_H
#define _ASM_SH_TOPOLOGY_H
#ifdef CONFIG_NUMA
#define cpu_to_node(cpu) ((void)(cpu),0)
#define cpumask_of_node(node) ((void)node, cpu_online_mask)
#define pcibus_to_node(bus) ((void)(bus), -1)
#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
cpu_all_mask : \
cpumask_of_node(pcibus_to_node(bus)))
#endif
#define mc_capable() (1)
const struct cpumask *cpu_coregroup_mask(int cpu);

View File

@ -381,8 +381,3 @@ void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
void __init plat_mem_setup(void)
{
/* TODO: Register Node 1 */
}

View File

@ -16,7 +16,6 @@
#include <linux/usb/m66592.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <asm/siu.h>
#include <asm/platform_early.h>
@ -658,9 +657,3 @@ void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
void __init plat_mem_setup(void)
{
/* Register the URAM space as Node 1 */
setup_bootmem_node(1, 0x055f0000, 0x05610000);
}

View File

@ -17,7 +17,6 @@
#include <asm/cacheflush.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <asm/platform_early.h>
#include <cpu/sh7723.h>

View File

@ -24,7 +24,6 @@
#include <asm/cacheflush.h>
#include <asm/suspend.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <asm/platform_early.h>
#include <cpu/dma-register.h>

View File

@ -21,7 +21,6 @@
#include <cpu/dma-register.h>
#include <cpu/sh7757.h>
#include <asm/mmzone.h>
#include <asm/platform_early.h>
static struct plat_sci_port scif2_platform_data = {
@ -1239,7 +1238,3 @@ void __init plat_irq_setup_pins(int mode)
BUG();
}
}
void __init plat_mem_setup(void)
{
}

View File

@ -13,7 +13,6 @@
#include <linux/sh_dma.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <asm/mmzone.h>
#include <asm/platform_early.h>
#include <cpu/dma-register.h>
@ -600,9 +599,3 @@ void __init plat_irq_setup_pins(int mode)
BUG();
}
}
void __init plat_mem_setup(void)
{
/* Register the URAM space as Node 1 */
setup_bootmem_node(1, 0xe55f0000, 0xe5610000);
}

View File

@ -22,7 +22,6 @@
#include <linux/sh_intc.h>
#include <linux/usb/ohci_pdriver.h>
#include <cpu/dma-register.h>
#include <asm/mmzone.h>
#include <asm/platform_early.h>
static struct plat_sci_port scif0_platform_data = {
@ -783,10 +782,6 @@ void __init plat_irq_setup_pins(int mode)
}
}
void __init plat_mem_setup(void)
{
}
static int __init sh7786_devices_setup(void)
{
int ret, irq;

View File

@ -13,7 +13,6 @@
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <cpu/shx3.h>
#include <asm/mmzone.h>
#include <asm/platform_early.h>
/*
@ -377,20 +376,3 @@ void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
void __init plat_mem_setup(void)
{
unsigned int nid = 1;
/* Register CPU#0 URAM space as Node 1 */
setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */
#if 0
/* XXX: Not yet.. */
setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */
setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */
setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */
#endif
setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */
}

View File

@ -23,7 +23,6 @@
#include <linux/smp.h>
#include <linux/err.h>
#include <linux/crash_dump.h>
#include <linux/mmzone.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
@ -41,9 +40,7 @@
#include <asm/clock.h>
#include <asm/smp.h>
#include <asm/mmu_context.h>
#include <asm/mmzone.h>
#include <asm/processor.h>
#include <asm/sparsemem.h>
#include <asm/platform_early.h>
/*
@ -227,13 +224,9 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
/*
* Also make sure that there is a PMB mapping that covers this
* range before we attempt to activate it, to avoid reset by MMU.
* We can hit this path with NUMA or memory hot-add.
*/
pmb_bolt_mapping((unsigned long)__va(start), start, end - start,
PAGE_KERNEL);
memblock_set_node(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn),
&memblock.memory, nid);
}
void __init __weak plat_early_device_setup(void)

View File

@ -57,18 +57,6 @@ static int __init topology_init(void)
__func__, i, ret);
}
#if defined(CONFIG_NUMA) && !defined(CONFIG_SMP)
/*
* In the UP case, make sure the CPU association is still
* registered under each node. Without this, sysfs fails
* to make the connection between nodes other than node0
* and cpu0.
*/
for_each_online_node(i)
if (i != numa_node_id())
register_cpu_under_node(raw_smp_processor_id(), i);
#endif
return 0;
}
subsys_initcall(topology_init);

View File

@ -5,10 +5,6 @@
void arch_crash_save_vmcoreinfo(void)
{
#ifdef CONFIG_NUMA
VMCOREINFO_SYMBOL(node_data);
VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
#endif
#ifdef CONFIG_X2TLB
VMCOREINFO_CONFIG(X2TLB);
#endif

View File

@ -112,37 +112,8 @@ config VSYSCALL
For systems with an MMU that can afford to give up a page,
(the default value) say Y.
config NUMA
bool "Non-Uniform Memory Access (NUMA) Support"
depends on MMU && SYS_SUPPORTS_NUMA
select ARCH_WANT_NUMA_VARIABLE_LOCALITY
default n
help
Some SH systems have many various memories scattered around
the address space, each with varying latencies. This enables
support for these blocks by binding them to nodes and allowing
memory policies to be used for prioritizing and controlling
allocation behaviour.
config NODES_SHIFT
int
default "3" if CPU_SUBTYPE_SHX3
default "1"
depends on NUMA
config ARCH_FLATMEM_ENABLE
def_bool y
depends on !NUMA
config ARCH_SPARSEMEM_ENABLE
def_bool y
select SPARSEMEM_STATIC
config ARCH_SPARSEMEM_DEFAULT
def_bool y
config ARCH_SELECT_MEMORY_MODEL
def_bool y
config IOREMAP_FIXED
def_bool y

View File

@ -37,7 +37,6 @@ endif
obj-$(CONFIG_DEBUG_FS) += $(debugfs-y)
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_PMB) += pmb.o
obj-$(CONFIG_NUMA) += numa.o
obj-$(CONFIG_IOREMAP_FIXED) += ioremap_fixed.o
obj-$(CONFIG_UNCACHED_MAPPING) += uncached.o
obj-$(CONFIG_HAVE_SRAM_POOL) += sram.o

View File

@ -20,7 +20,6 @@
#include <linux/dma-mapping.h>
#include <linux/export.h>
#include <asm/mmu_context.h>
#include <asm/mmzone.h>
#include <asm/kexec.h>
#include <asm/tlb.h>
#include <asm/cacheflush.h>
@ -38,11 +37,6 @@ void __init generic_mem_init(void)
memblock_add(__MEMORY_START, __MEMORY_SIZE);
}
void __init __weak plat_mem_setup(void)
{
/* Nothing to see here, move along. */
}
#ifdef CONFIG_MMU
static pte_t *__get_pte_phys(unsigned long addr)
{
@ -201,20 +195,6 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
}
#endif /* CONFIG_MMU */
void __init allocate_pgdat(unsigned int nid)
{
unsigned long start_pfn, end_pfn;
get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
#ifdef CONFIG_NUMA
alloc_node_data(nid);
#endif
NODE_DATA(nid)->node_start_pfn = start_pfn;
NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
}
static void __init do_init_bootmem(void)
{
unsigned long start_pfn, end_pfn;
@ -224,11 +204,7 @@ static void __init do_init_bootmem(void)
for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL)
__add_active_range(0, start_pfn, end_pfn);
/* All of system RAM sits in node 0 for the non-NUMA case */
allocate_pgdat(0);
node_set_online(0);
plat_mem_setup();
}
static void __init early_reserve_mem(void)

View File

@ -1,53 +0,0 @@
/*
* arch/sh/mm/numa.c - Multiple node support for SH machines
*
* Copyright (C) 2007 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/module.h>
#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/numa.h>
#include <linux/pfn.h>
#include <asm/sections.h>
/*
* On SH machines the conventional approach is to stash system RAM
* in node 0, and other memory blocks in to node 1 and up, ordered by
* latency. Each node's pgdat is node-local at the beginning of the node,
* immediately followed by the node mem map.
*/
void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
{
unsigned long start_pfn, end_pfn;
/* Don't allow bogus node assignment */
BUG_ON(nid >= MAX_NUMNODES || nid <= 0);
start_pfn = PFN_DOWN(start);
end_pfn = PFN_DOWN(end);
pmb_bolt_mapping((unsigned long)__va(start), start, end - start,
PAGE_KERNEL);
memblock_add(start, end - start);
__add_active_range(nid, start_pfn, end_pfn);
/* Node-local pgdat */
NODE_DATA(nid) = memblock_alloc_node(sizeof(struct pglist_data),
SMP_CACHE_BYTES, nid);
if (!NODE_DATA(nid))
panic("%s: Failed to allocate %zu bytes align=0x%x nid=%d\n",
__func__, sizeof(struct pglist_data), SMP_CACHE_BYTES,
nid);
NODE_DATA(nid)->node_start_pfn = start_pfn;
NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
/* It's up */
node_set_online(nid);
}

View File

@ -16,8 +16,7 @@
* This provides a standard SRAM pool for tiny memories that can be
* added either by the CPU or the platform code. Typical SRAM sizes
* to be inserted in to the pool will generally be less than the page
* size, with anything more reasonably sized handled as a NUMA memory
* node.
* size.
*/
struct gen_pool *sram_pool;

View File

@ -413,7 +413,7 @@ void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma,
if (mm->context.hugetlb_pte_count || mm->context.thp_pte_count) {
unsigned long hugepage_size = PAGE_SIZE;
if (is_vm_hugetlb_page(vma))
if (vma_is_hugetlb(vma))
hugepage_size = huge_page_size(hstate_vma(vma));
if (hugepage_size >= PUD_SIZE) {

View File

@ -109,7 +109,7 @@ config X86
select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
select ARCH_HAS_SYSCALL_WRAPPER
select ARCH_HAS_UBSAN
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_CHECK_WX
select ARCH_HAS_ZONE_DMA_SET if EXPERT
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_HAVE_EXTRA_ELF_NOTES

View File

@ -263,7 +263,7 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_WX=y
CONFIG_CHECK_WX=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_SCHEDSTATS=y
CONFIG_BLK_DEV_IO_TRACE=y

View File

@ -41,10 +41,10 @@ void ptdump_walk_user_pgd_level_checkwx(void);
#define pgprot_encrypted(prot) __pgprot(cc_mkenc(pgprot_val(prot)))
#define pgprot_decrypted(prot) __pgprot(cc_mkdec(pgprot_val(prot)))
#ifdef CONFIG_DEBUG_WX
#define debug_checkwx_user() ptdump_walk_user_pgd_level_checkwx()
#ifdef CONFIG_CHECK_WX
#define pgtable_checkwx_user() ptdump_walk_user_pgd_level_checkwx()
#else
#define debug_checkwx_user() do { } while (0)
#define pgtable_checkwx_user() do { } while (0)
#endif
extern spinlock_t pgd_lock;

View File

@ -715,7 +715,7 @@ static struct vm_area_struct *get_uprobe_trampoline(struct mm_struct *mm, unsign
*new_mapping = true;
return _install_special_mapping(mm, vaddr, PAGE_SIZE,
VM_READ|VM_EXEC|VM_MAYEXEC|VM_MAYREAD|VM_IO,
VM_READ|VM_EXEC|VM_MAYEXEC|VM_MAYREAD|VM_MIXEDMAP,
&tramp_mapping);
}

View File

@ -688,5 +688,5 @@ void pti_finalize(void)
pti_clone_entry_text(true);
pti_clone_kernel_text();
debug_checkwx_user();
pgtable_checkwx_user();
}

View File

@ -977,7 +977,7 @@ void __init memory_dev_init(void)
* block so that it can be covered.
*/
block_id = ULONG_MAX;
for_each_present_section_nr(0, nr) {
for_each_early_section_nr(0, nr) {
if (block_id != ULONG_MAX && memory_block_id(nr) == block_id)
continue;

View File

@ -1553,68 +1553,70 @@ static void zram_debugfs_destroy(void)
debugfs_remove_recursive(zram_debugfs_root);
}
static ssize_t read_block_state(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
static void *zram_block_state_start(struct seq_file *seq, loff_t *pos)
{
char *kbuf;
unsigned long index;
ssize_t written = 0;
struct zram *zram = file->private_data;
struct zram *zram = seq->private;
unsigned long nr_pages;
kbuf = kvmalloc(count, GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
guard(rwsem_read)(&zram->dev_lock);
if (!init_done(zram)) {
kvfree(kbuf);
return -EINVAL;
}
down_read(&zram->dev_lock);
if (!init_done(zram))
return ERR_PTR(-EINVAL);
nr_pages = zram->disksize >> PAGE_SHIFT;
if (*pos >= nr_pages)
return NULL;
for (index = *ppos; index < nr_pages; index++) {
int copied;
slot_lock(zram, index);
if (!slot_allocated(zram, index))
goto next;
copied = snprintf(kbuf + written, count,
"%12lu %12u.%06d %c%c%c%c%c%c\n",
index, zram->table[index].attr.ac_time, 0,
test_slot_flag(zram, index, ZRAM_SAME) ? 's' : '.',
test_slot_flag(zram, index, ZRAM_WB) ? 'w' : '.',
test_slot_flag(zram, index, ZRAM_HUGE) ? 'h' : '.',
test_slot_flag(zram, index, ZRAM_IDLE) ? 'i' : '.',
get_slot_comp_priority(zram, index) ? 'r' : '.',
test_slot_flag(zram, index,
ZRAM_INCOMPRESSIBLE) ? 'n' : '.');
if (count <= copied) {
slot_unlock(zram, index);
break;
}
written += copied;
count -= copied;
next:
slot_unlock(zram, index);
*ppos += 1;
}
if (copy_to_user(buf, kbuf, written))
written = -EFAULT;
kvfree(kbuf);
return written;
return pos;
}
static const struct file_operations proc_zram_block_state_op = {
.open = simple_open,
.read = read_block_state,
.llseek = default_llseek,
static void *zram_block_state_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct zram *zram = seq->private;
unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
++*pos;
if (*pos >= nr_pages)
return NULL;
return pos;
}
static void zram_block_state_stop(struct seq_file *seq, void *v)
{
struct zram *zram = seq->private;
up_read(&zram->dev_lock);
}
static int zram_block_state_show(struct seq_file *seq, void *v)
{
struct zram *zram = seq->private;
unsigned long index = *(loff_t *)v;
slot_lock(zram, index);
if (slot_allocated(zram, index)) {
seq_printf(seq, "%12lu %12u.%06d %c%c%c%c%c%c\n",
index, zram->table[index].attr.ac_time, 0,
test_slot_flag(zram, index, ZRAM_SAME) ? 's' : '.',
test_slot_flag(zram, index, ZRAM_WB) ? 'w' : '.',
test_slot_flag(zram, index, ZRAM_HUGE) ? 'h' : '.',
test_slot_flag(zram, index, ZRAM_IDLE) ? 'i' : '.',
get_slot_comp_priority(zram, index) ? 'r' : '.',
test_slot_flag(zram, index,
ZRAM_INCOMPRESSIBLE) ? 'n' : '.');
}
slot_unlock(zram, index);
return 0;
}
static const struct seq_operations zram_block_state_sops = {
.start = zram_block_state_start,
.next = zram_block_state_next,
.stop = zram_block_state_stop,
.show = zram_block_state_show,
};
DEFINE_SEQ_ATTRIBUTE(zram_block_state);
static void zram_debugfs_register(struct zram *zram)
{
@ -1624,7 +1626,7 @@ static void zram_debugfs_register(struct zram *zram)
zram->debugfs_dir = debugfs_create_dir(zram->disk->disk_name,
zram_debugfs_root);
debugfs_create_file("block_state", 0400, zram->debugfs_dir,
zram, &proc_zram_block_state_op);
zram, &zram_block_state_fops);
}
static void zram_debugfs_unregister(struct zram *zram)

View File

@ -9,9 +9,9 @@
#include <linux/dma-mapping.h>
#include <linux/export.h>
#include <linux/hmm.h>
#include <linux/hugetlb_inline.h>
#include <linux/memremap.h>
#include <linux/mm_types.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <drm/drm_device.h>
@ -1170,8 +1170,7 @@ drm_gpusvm_range_find_or_insert(struct drm_gpusvm *gpusvm,
* limitations. If/when migrate_vma_* add more support, this logic will
* have to change.
*/
migrate_devmem = ctx->devmem_possible &&
vma_is_anonymous(vas) && !is_vm_hugetlb_page(vas);
migrate_devmem = ctx->devmem_possible && vma_is_anonymous(vas);
chunk_size = drm_gpusvm_range_chunk_size(gpusvm, notifier, vas,
fault_addr, gpuva_start,

View File

@ -240,7 +240,7 @@ static int sti_cursor_atomic_check(struct drm_plane *drm_plane,
cursor->pixmap.base = dma_alloc_wc(cursor->dev,
cursor->pixmap.size,
&cursor->pixmap.paddr,
GFP_KERNEL | GFP_DMA);
GFP_KERNEL);
if (!cursor->pixmap.base) {
DRM_ERROR("Failed to allocate memory for pixmap\n");
return -EINVAL;
@ -380,7 +380,7 @@ struct drm_plane *sti_cursor_create(struct drm_device *drm_dev,
/* Allocate clut buffer */
size = 0x100 * sizeof(unsigned short);
cursor->clut = dma_alloc_wc(dev, size, &cursor->clut_paddr,
GFP_KERNEL | GFP_DMA);
GFP_KERNEL);
if (!cursor->clut) {
DRM_ERROR("Failed to allocate memory for cursor clut\n");

View File

@ -860,7 +860,7 @@ static void sti_hqvdp_init(struct sti_hqvdp *hqvdp)
size = NB_VDP_CMD * sizeof(struct sti_hqvdp_cmd);
hqvdp->hqvdp_cmd = dma_alloc_wc(hqvdp->dev, size,
&dma_addr,
GFP_KERNEL | GFP_DMA);
GFP_KERNEL);
if (!hqvdp->hqvdp_cmd) {
DRM_ERROR("Failed to allocate memory for VDP cmd\n");
return;

View File

@ -371,7 +371,7 @@ static int alloc_dma_buf(struct ipu_image_convert_priv *priv,
{
buf->len = PAGE_ALIGN(size);
buf->virt = dma_alloc_coherent(priv->ipu->dev, buf->len, &buf->phys,
GFP_DMA | GFP_KERNEL);
GFP_KERNEL);
if (!buf->virt) {
dev_err(priv->ipu->dev, "failed to alloc dma buffer\n");
return -ENOMEM;

View File

@ -1084,22 +1084,6 @@ static void cs_hsi_stop(struct cs_hsi_iface *hi)
kfree(hi);
}
static vm_fault_t cs_char_vma_fault(struct vm_fault *vmf)
{
struct cs_char *csdata = vmf->vma->vm_private_data;
struct page *page;
page = virt_to_page((void *)csdata->mmap_base);
get_page(page);
vmf->page = page;
return 0;
}
static const struct vm_operations_struct cs_char_vm_ops = {
.fault = cs_char_vma_fault,
};
static int cs_char_fasync(int fd, struct file *file, int on)
{
struct cs_char *csdata = file->private_data;
@ -1256,18 +1240,19 @@ static long cs_char_ioctl(struct file *file, unsigned int cmd,
return r;
}
static int cs_char_mmap(struct file *file, struct vm_area_struct *vma)
static int cs_char_mmap_prepare(struct vm_area_desc *desc)
{
if (vma->vm_end < vma->vm_start)
struct file *file = desc->file;
struct cs_char *csdata = file->private_data;
struct page **pages = (struct page **)&desc->private_data;
if (vma_desc_pages(desc) != 1)
return -EINVAL;
if (vma_pages(vma) != 1)
return -EINVAL;
vm_flags_set(vma, VM_IO | VM_DONTDUMP | VM_DONTEXPAND);
vma->vm_ops = &cs_char_vm_ops;
vma->vm_private_data = file->private_data;
vma_desc_set_flags(desc, VMA_DONTDUMP_BIT, VMA_DONTEXPAND_BIT);
*pages = virt_to_page((void *)csdata->mmap_base);
mmap_action_map_kernel_pages_full(desc, pages);
return 0;
}
@ -1353,7 +1338,7 @@ static const struct file_operations cs_char_fops = {
.write = cs_char_write,
.poll = cs_char_poll,
.unlocked_ioctl = cs_char_ioctl,
.mmap = cs_char_mmap,
.mmap_prepare = cs_char_mmap_prepare,
.open = cs_char_open,
.release = cs_char_release,
.fasync = cs_char_fasync,

View File

@ -70,7 +70,6 @@ static int set_ctxt_pkey(struct hfi1_ctxtdata *uctxt, unsigned long arg);
static int ctxt_reset(struct hfi1_ctxtdata *uctxt);
static int manage_rcvq(struct hfi1_ctxtdata *uctxt, u16 subctxt,
unsigned long arg);
static vm_fault_t vma_fault(struct vm_fault *vmf);
static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
unsigned long arg);
@ -85,10 +84,6 @@ static const struct file_operations hfi1_file_ops = {
.llseek = noop_llseek,
};
static const struct vm_operations_struct vm_ops = {
.fault = vma_fault,
};
/*
* Types of memories mapped into user processes' space
*/
@ -304,13 +299,13 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from)
return reqs;
}
static inline void mmap_cdbg(u16 ctxt, u8 subctxt, u8 type, u8 mapio, u8 vmf,
static inline void mmap_cdbg(u16 ctxt, u8 subctxt, u8 type, u8 mapio, u8 is_vmalloc,
u64 memaddr, void *memvirt, dma_addr_t memdma,
ssize_t memlen, struct vm_area_struct *vma)
{
hfi1_cdbg(PROC,
"%u:%u type:%u io/vf/dma:%d/%d/%d, addr:0x%llx, len:%lu(%lu), flags:0x%lx",
ctxt, subctxt, type, mapio, vmf, !!memdma,
"%u:%u type:%u io/vmalloc/dma:%d/%d/%d, addr:0x%llx, len:%lu(%lu), flags:0x%lx",
ctxt, subctxt, type, mapio, is_vmalloc, !!memdma,
memaddr ?: (u64)memvirt, memlen,
vma->vm_end - vma->vm_start, vma->vm_flags);
}
@ -325,7 +320,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
memaddr = 0;
void *memvirt = NULL;
dma_addr_t memdma = 0;
u8 subctxt, mapio = 0, vmf = 0, type;
u8 subctxt, mapio = 0, is_vmalloc = 0, type;
size_t memdmalen = 0;
ssize_t memlen = 0;
int ret = 0;
@ -348,7 +343,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
/*
* vm_pgoff is used as a buffer selector cookie. Always mmap from
* the beginning.
*/
*/
vma->vm_pgoff = 0;
flags = vma->vm_flags;
@ -367,7 +362,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
*/
memlen = PAGE_ALIGN(uctxt->sc->credits * PIO_BLOCK_SIZE);
flags &= ~VM_MAYREAD;
flags |= VM_DONTCOPY | VM_DONTEXPAND;
flags |= VM_DONTCOPY;
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
mapio = 1;
break;
@ -411,6 +406,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
memlen = rcvhdrq_size(uctxt);
memvirt = uctxt->rcvhdrq;
memdma = uctxt->rcvhdrq_dma;
flags |= VM_DONTEXPAND;
break;
case RCV_EGRBUF: {
unsigned long vm_start_save;
@ -432,7 +428,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
ret = -EPERM;
goto done;
}
vm_flags_clear(vma, VM_MAYWRITE);
vm_flags_mod(vma, VM_DONTEXPAND, VM_MAYWRITE);
/*
* Mmap multiple separate allocations into a single vma. From
* here, dma_mmap_coherent() calls dma_direct_mmap(), which
@ -448,7 +444,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
memvirt = uctxt->egrbufs.buffers[i].addr;
memdma = uctxt->egrbufs.buffers[i].dma;
vma->vm_end += memlen;
mmap_cdbg(ctxt, subctxt, type, mapio, vmf, memaddr,
mmap_cdbg(ctxt, subctxt, type, mapio, is_vmalloc, memaddr,
memvirt, memdma, memlen, vma);
ret = dma_mmap_coherent(&dd->pcidev->dev, vma,
memvirt, memdma, memlen);
@ -477,7 +473,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
* user registers.
*/
memlen = PAGE_SIZE;
flags |= VM_DONTCOPY | VM_DONTEXPAND;
flags |= VM_DONTCOPY;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
mapio = 1;
break;
@ -486,15 +482,10 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
* Use the page where this context's flags are. User level
* knows where it's own bitmap is within the page.
*/
memaddr = (unsigned long)
(dd->events + uctxt_offset(uctxt)) & PAGE_MASK;
memvirt = dd->events + uctxt_offset(uctxt);
memvirt = (void *)(((uintptr_t)memvirt) & PAGE_MASK);
memlen = PAGE_SIZE;
/*
* v3.7 removes VM_RESERVED but the effect is kept by
* using VM_IO.
*/
flags |= VM_IO | VM_DONTEXPAND;
vmf = 1;
is_vmalloc = 1;
break;
case STATUS:
if (flags & VM_WRITE) {
@ -503,7 +494,6 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
}
memaddr = kvirt_to_phys((void *)dd->status);
memlen = PAGE_SIZE;
flags |= VM_IO | VM_DONTEXPAND;
break;
case RTAIL:
if (!HFI1_CAP_IS_USET(DMA_RTAIL)) {
@ -522,25 +512,23 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
memvirt = (void *)hfi1_rcvhdrtail_kvaddr(uctxt);
memdma = uctxt->rcvhdrqtailaddr_dma;
flags &= ~VM_MAYWRITE;
flags |= VM_DONTEXPAND;
break;
case SUBCTXT_UREGS:
memaddr = (u64)uctxt->subctxt_uregbase;
memvirt = uctxt->subctxt_uregbase;
memlen = PAGE_SIZE;
flags |= VM_IO | VM_DONTEXPAND;
vmf = 1;
is_vmalloc = 1;
break;
case SUBCTXT_RCV_HDRQ:
memaddr = (u64)uctxt->subctxt_rcvhdr_base;
memvirt = uctxt->subctxt_rcvhdr_base;
memlen = rcvhdrq_size(uctxt) * uctxt->subctxt_cnt;
flags |= VM_IO | VM_DONTEXPAND;
vmf = 1;
is_vmalloc = 1;
break;
case SUBCTXT_EGRBUF:
memaddr = (u64)uctxt->subctxt_rcvegrbuf;
memvirt = uctxt->subctxt_rcvegrbuf;
memlen = uctxt->egrbufs.size * uctxt->subctxt_cnt;
flags |= VM_IO | VM_DONTEXPAND;
flags &= ~VM_MAYWRITE;
vmf = 1;
is_vmalloc = 1;
break;
case SDMA_COMP: {
struct hfi1_user_sdma_comp_q *cq = fd->cq;
@ -549,10 +537,9 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
ret = -EFAULT;
goto done;
}
memaddr = (u64)cq->comps;
memvirt = cq->comps;
memlen = PAGE_ALIGN(sizeof(*cq->comps) * cq->nentries);
flags |= VM_IO | VM_DONTEXPAND;
vmf = 1;
is_vmalloc = 1;
break;
}
default:
@ -569,12 +556,10 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
}
vm_flags_reset(vma, flags);
mmap_cdbg(ctxt, subctxt, type, mapio, vmf, memaddr, memvirt, memdma,
mmap_cdbg(ctxt, subctxt, type, mapio, is_vmalloc, memaddr, memvirt, memdma,
memlen, vma);
if (vmf) {
vma->vm_pgoff = PFN_DOWN(memaddr);
vma->vm_ops = &vm_ops;
ret = 0;
if (is_vmalloc) {
ret = remap_vmalloc_range(vma, memvirt, 0);
} else if (memdma) {
ret = dma_mmap_coherent(&dd->pcidev->dev, vma,
memvirt, memdma,
@ -599,24 +584,6 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
return ret;
}
/*
* Local (non-chip) user memory is not mapped right away but as it is
* accessed by the user-level code.
*/
static vm_fault_t vma_fault(struct vm_fault *vmf)
{
struct page *page;
page = vmalloc_to_page((void *)(vmf->pgoff << PAGE_SHIFT));
if (!page)
return VM_FAULT_SIGBUS;
get_page(page);
vmf->page = page;
return 0;
}
static __poll_t hfi1_poll(struct file *fp, struct poll_table_struct *pt)
{
struct hfi1_ctxtdata *uctxt;

View File

@ -466,7 +466,7 @@ static int imx7_csi_alloc_dma_buf(struct imx7_csi *csi,
buf->len = PAGE_ALIGN(size);
buf->virt = dma_alloc_coherent(csi->dev, buf->len, &buf->dma_addr,
GFP_DMA | GFP_KERNEL);
GFP_KERNEL);
if (!buf->virt)
return -ENOMEM;

View File

@ -773,7 +773,7 @@ static int mxc_isi_video_alloc_discard_buffers(struct mxc_isi_video *video)
buf->size = PAGE_ALIGN(video->pix.plane_fmt[i].sizeimage);
buf->addr = dma_alloc_coherent(video->pipe->isi->dev, buf->size,
&buf->dma, GFP_DMA | GFP_KERNEL);
&buf->dma, GFP_KERNEL);
if (!buf->addr) {
mxc_isi_video_free_discard_buffers(video);
return -ENOMEM;

View File

@ -1387,7 +1387,7 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this)
goto error_alloc;
this->auxiliary_virt = dma_alloc_coherent(dev, geo->auxiliary_size,
&this->auxiliary_phys, GFP_DMA);
&this->auxiliary_phys, GFP_KERNEL);
if (!this->auxiliary_virt)
goto error_alloc;

View File

@ -1212,85 +1212,72 @@ sg_fasync(int fd, struct file *filp, int mode)
return fasync_helper(fd, filp, mode, &sfp->async_qp);
}
static vm_fault_t
sg_vma_fault(struct vm_fault *vmf)
static int sg_discontig_init(void *vm_private_data, void **private)
{
struct vm_area_struct *vma = vmf->vma;
Sg_fd *sfp;
unsigned long offset, len, sa;
Sg_scatter_hold *rsv_schp;
int k, length;
const unsigned long req_sz = (unsigned long)*private;
Sg_fd *sfp = vm_private_data;
Sg_scatter_hold *rsv_schp = &sfp->reserve;
int err = 0;
if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data)))
return VM_FAULT_SIGBUS;
rsv_schp = &sfp->reserve;
offset = vmf->pgoff << PAGE_SHIFT;
if (offset >= rsv_schp->bufflen)
return VM_FAULT_SIGBUS;
SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp,
"sg_vma_fault: offset=%lu, scatg=%d\n",
offset, rsv_schp->k_use_sg));
sa = vma->vm_start;
length = 1 << (PAGE_SHIFT + rsv_schp->page_order);
for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) {
len = vma->vm_end - sa;
len = (len < length) ? len : length;
if (offset < len) {
struct page *page = rsv_schp->pages[k] + (offset >> PAGE_SHIFT);
get_page(page); /* increment page count */
vmf->page = page;
return 0; /* success */
}
sa += len;
offset -= len;
mutex_lock(&sfp->f_mutex);
if (req_sz > rsv_schp->bufflen) {
err = -ENOMEM; /* cannot map more than reserved buffer */
goto out;
}
return VM_FAULT_SIGBUS;
sfp->mmap_called = 1; /* Prevents changes to buffer size. */
out:
mutex_unlock(&sfp->f_mutex);
return err;
}
static const struct vm_operations_struct sg_mmap_vm_ops = {
.fault = sg_vma_fault,
static int
sg_discontig_get(struct discontig_kernel_page_state *state)
{
Sg_fd *sfp = state->vm_private_data;
Sg_scatter_hold *rsv_schp = &sfp->reserve;
const unsigned int order = rsv_schp->page_order;
const pgoff_t nr_pages = state->nr_pages_mapped;
if (nr_pages >= (rsv_schp->bufflen >> PAGE_SHIFT)) {
discontig_kernel_map_abort(state);
return 0;
}
SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp,
"%s: offset=%lu, scatg=%d\n", __func__,
nr_pages << PAGE_SHIFT, rsv_schp->k_use_sg));
discontig_kernel_map_page(state, rsv_schp->pages[nr_pages >> order]);
return 0;
}
static const struct discontig_kernel_page_ops sg_discontig_ops = {
.init = sg_discontig_init,
.get = sg_discontig_get,
};
static int
sg_mmap(struct file *filp, struct vm_area_struct *vma)
sg_mmap_prepare(struct vm_area_desc *desc)
{
Sg_fd *sfp;
unsigned long req_sz, len, sa;
Sg_scatter_hold *rsv_schp;
int k, length;
int ret = 0;
Sg_fd *sfp = desc->file->private_data;
const unsigned long req_sz = vma_desc_size(desc);
if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
if (!sfp)
return -ENXIO;
req_sz = vma->vm_end - vma->vm_start;
SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp,
"sg_mmap starting, vm_start=%p, len=%d\n",
(void *) vma->vm_start, (int) req_sz));
if (vma->vm_pgoff)
(void *) desc->start, (int) req_sz));
if (desc->pgoff)
return -EINVAL; /* want no offset */
rsv_schp = &sfp->reserve;
mutex_lock(&sfp->f_mutex);
if (req_sz > rsv_schp->bufflen) {
ret = -ENOMEM; /* cannot map more than reserved buffer */
goto out;
}
sa = vma->vm_start;
length = 1 << (PAGE_SHIFT + rsv_schp->page_order);
for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) {
len = vma->vm_end - sa;
len = (len < length) ? len : length;
sa += len;
}
vma_desc_set_flags(desc, VMA_DONTEXPAND_BIT, VMA_DONTDUMP_BIT);
desc->private_data = sfp;
sfp->mmap_called = 1;
vm_flags_set(vma, VM_IO | VM_DONTEXPAND | VM_DONTDUMP);
vma->vm_private_data = sfp;
vma->vm_ops = &sg_mmap_vm_ops;
out:
mutex_unlock(&sfp->f_mutex);
return ret;
mmap_action_map_discontig_kernel_pages(desc, (void *)req_sz,
&sg_discontig_ops);
return 0;
}
static void
@ -1415,7 +1402,7 @@ static const struct file_operations sg_fops = {
.unlocked_ioctl = sg_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.open = sg_open,
.mmap = sg_mmap,
.mmap_prepare = sg_mmap_prepare,
.release = sg_release,
.fasync = sg_fasync,
};

View File

@ -624,7 +624,7 @@ static int atmel_spi_configure_dma(struct spi_controller *host,
if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) {
as->addr_tx_bbuf = dma_alloc_coherent(dev, SPI_MAX_DMA_XFER,
&as->dma_addr_tx_bbuf,
GFP_KERNEL | GFP_DMA);
GFP_KERNEL);
if (!as->addr_tx_bbuf) {
err = -ENOMEM;
goto err_release_dma;
@ -632,7 +632,7 @@ static int atmel_spi_configure_dma(struct spi_controller *host,
as->addr_rx_bbuf = dma_alloc_coherent(dev, SPI_MAX_DMA_XFER,
&as->dma_addr_rx_bbuf,
GFP_KERNEL | GFP_DMA);
GFP_KERNEL);
if (!as->addr_rx_bbuf) {
err = -ENOMEM;
goto err_release_dma;

View File

@ -855,7 +855,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
qspi->rx_bb_addr = dma_alloc_coherent(qspi->dev,
QSPI_DMA_BUFFER_SIZE,
&qspi->rx_bb_dma_addr,
GFP_KERNEL | GFP_DMA);
GFP_KERNEL);
if (!qspi->rx_bb_addr) {
dev_err(qspi->dev,
"dma_alloc_coherent failed, using PIO mode\n");

View File

@ -588,7 +588,7 @@ int imx_media_alloc_dma_buf(struct device *dev,
buf->len = PAGE_ALIGN(size);
buf->virt = dma_alloc_coherent(dev, buf->len, &buf->phys,
GFP_DMA | GFP_KERNEL);
GFP_KERNEL);
if (!buf->virt)
return -ENOMEM;

View File

@ -3380,7 +3380,7 @@ static int cdns3_gadget_start(struct cdns *cdns)
/* allocate memory for setup packet buffer */
priv_dev->setup_buf = dma_alloc_coherent(priv_dev->sysdev, 8,
&priv_dev->setup_dma, GFP_DMA);
&priv_dev->setup_dma, GFP_KERNEL);
if (!priv_dev->setup_buf) {
ret = -ENOMEM;
goto err2;

View File

@ -2341,7 +2341,7 @@ static int cdns2_gadget_start(struct cdns2_device *pdev)
/* Allocate memory for setup packet buffer. */
buf = dma_alloc_coherent(pdev->dev, 8, &pdev->ep0_preq.request.dma,
GFP_DMA);
GFP_KERNEL);
pdev->ep0_preq.request.buf = buf;
if (!pdev->ep0_preq.request.buf) {

View File

@ -3079,7 +3079,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)
/* Allocate memory for the UDCA */
udc->udca_v_base = dma_alloc_coherent(&pdev->dev, UDCA_BUFF_SIZE,
&dma_handle,
(GFP_KERNEL | GFP_DMA));
GFP_KERNEL);
if (!udc->udca_v_base) {
dev_err(udc->dev, "error getting UDCA region\n");
retval = -ENOMEM;

View File

@ -1219,13 +1219,8 @@ mon_bin_poll(struct file *file, struct poll_table_struct *wait)
return mask;
}
/*
* open and close: just keep track of how many times the device is
* mapped, to use the proper memory allocation function.
*/
static void mon_bin_vma_open(struct vm_area_struct *vma)
static void __mon_bin_vma_open(struct mon_reader_bin *rp)
{
struct mon_reader_bin *rp = vma->vm_private_data;
unsigned long flags;
spin_lock_irqsave(&rp->b_lock, flags);
@ -1233,57 +1228,86 @@ static void mon_bin_vma_open(struct vm_area_struct *vma)
spin_unlock_irqrestore(&rp->b_lock, flags);
}
static void mon_bin_vma_close(struct vm_area_struct *vma)
/*
* open and close: just keep track of how many times the device is
* mapped, to use the proper memory allocation function.
*/
static void mon_bin_vma_open(struct vm_area_struct *vma)
{
struct mon_reader_bin *rp = vma->vm_private_data;
__mon_bin_vma_open(rp);
}
static void __mon_bin_vma_close(struct mon_reader_bin *rp)
{
unsigned long flags;
struct mon_reader_bin *rp = vma->vm_private_data;
spin_lock_irqsave(&rp->b_lock, flags);
rp->mmap_active--;
spin_unlock_irqrestore(&rp->b_lock, flags);
}
/*
* Map ring pages to user space.
*/
static vm_fault_t mon_bin_vma_fault(struct vm_fault *vmf)
static void mon_bin_vma_close(struct vm_area_struct *vma)
{
struct mon_reader_bin *rp = vmf->vma->vm_private_data;
unsigned long offset, chunk_idx;
struct page *pageptr;
unsigned long flags;
struct mon_reader_bin *rp = vma->vm_private_data;
spin_lock_irqsave(&rp->b_lock, flags);
offset = vmf->pgoff << PAGE_SHIFT;
if (offset >= rp->b_size) {
spin_unlock_irqrestore(&rp->b_lock, flags);
return VM_FAULT_SIGBUS;
}
chunk_idx = offset / CHUNK_SIZE;
pageptr = rp->b_vec[chunk_idx].pg;
get_page(pageptr);
vmf->page = pageptr;
spin_unlock_irqrestore(&rp->b_lock, flags);
return 0;
__mon_bin_vma_close(rp);
}
static const struct vm_operations_struct mon_bin_vm_ops = {
.open = mon_bin_vma_open,
.close = mon_bin_vma_close,
.fault = mon_bin_vma_fault,
};
static int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma)
static int mon_bin_discontig_init(void *vm_private_data, void **private)
{
/* don't do anything here: "fault" will set up page table entries */
vma->vm_ops = &mon_bin_vm_ops;
struct mon_reader_bin *rp = vm_private_data;
if (vma->vm_flags & VM_WRITE)
/* Dropped by mon_bin_vma_close() on unmap, including on error. */
__mon_bin_vma_open(rp);
return 0;
}
static int mon_bin_discontig_get(struct discontig_kernel_page_state *state)
{
struct mon_reader_bin *rp = state->vm_private_data;
unsigned long offset, chunk_idx;
unsigned long flags;
spin_lock_irqsave(&rp->b_lock, flags);
offset = state->pgoff << PAGE_SHIFT;
if (offset >= rp->b_size) {
spin_unlock_irqrestore(&rp->b_lock, flags);
discontig_kernel_map_abort(state);
return 0;
}
chunk_idx = offset / CHUNK_SIZE;
discontig_kernel_map_page(state, rp->b_vec[chunk_idx].pg);
spin_unlock_irqrestore(&rp->b_lock, flags);
return 0;
}
static const struct discontig_kernel_page_ops mon_discontig_ops = {
.init = mon_bin_discontig_init,
.get = mon_bin_discontig_get,
};
static int mon_bin_mmap_prepare(struct vm_area_desc *desc)
{
const struct file *filp = desc->file;
if (vma_desc_test(desc, VMA_WRITE_BIT))
return -EPERM;
vm_flags_mod(vma, VM_DONTEXPAND | VM_DONTDUMP, VM_MAYWRITE);
vma->vm_private_data = filp->private_data;
mon_bin_vma_open(vma);
desc->vm_ops = &mon_bin_vm_ops;
vma_desc_clear_flags(desc, VMA_MAYWRITE_BIT);
vma_desc_set_flags(desc, VMA_DONTEXPAND_BIT, VMA_DONTDUMP_BIT);
desc->private_data = filp->private_data;
mmap_action_map_discontig_kernel_pages(desc, NULL, &mon_discontig_ops);
return 0;
}
@ -1298,7 +1322,7 @@ static const struct file_operations mon_fops_binary = {
.compat_ioctl = mon_bin_compat_ioctl,
#endif
.release = mon_bin_release,
.mmap = mon_bin_mmap,
.mmap_prepare = mon_bin_mmap_prepare,
};
static int mon_bin_wait_event(struct file *file, struct mon_reader_bin *rp)

View File

@ -366,13 +366,13 @@ int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
if (WARN_ON_ONCE(!(info->flags & FBINFO_VIRTFB)))
return -EINVAL;
if (!try_module_get(THIS_MODULE))
return -EINVAL;
vma->vm_ops = &fb_deferred_io_vm_ops;
vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
if (!(info->flags & FBINFO_VIRTFB))
vm_flags_set(vma, VM_IO);
vm_flags_set(vma, VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP);
vma->vm_private_data = info->fbdefio_state;
fb_deferred_io_state_get(info->fbdefio_state); /* released in vma->vm_ops->close() */

View File

@ -1690,7 +1690,7 @@ static int fsl_diu_probe(struct platform_device *pdev)
int ret;
data = dmam_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
&dma_addr, GFP_DMA | __GFP_ZERO);
&dma_addr, __GFP_ZERO);
if (!data)
return -ENOMEM;
data->dma_addr = dma_addr;

View File

@ -767,6 +767,8 @@ static int ssd1307fb_probe(struct i2c_client *client)
info->fix.smem_start = __pa(vmem);
info->fix.smem_len = vmem_size;
info->flags = FBINFO_VIRTFB;
ret = fb_deferred_io_init(info);
if (ret) {
dev_err(dev, "failed to init fb deferred io: %d\n", ret);

View File

@ -1850,7 +1850,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
}
/* Hugetlb memory check */
if (is_vm_hugetlb_page(vma)) {
if (vma_is_hugetlb(vma)) {
if ((vma->vm_flags & VM_SHARED) &&
COREDUMP_MEMORY_TYPE_INCLUDE(memory_types, HUGETLB_SHARED))
goto whole;

View File

@ -826,7 +826,7 @@ int fuse_vdax_mmap(struct file *file, struct vm_area_struct *vma)
{
file_accessed(file);
vma->vm_ops = &fuse_dax_vm_ops;
vm_flags_set(vma, VM_MIXEDMAP | VM_HUGEPAGE);
vma_set_flags(vma, VMA_HUGEPAGE_BIT);
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
return 0;
}

View File

@ -106,11 +106,10 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
/*
* vma address alignment (but not the pgoff alignment) has
* already been checked by prepare_hugepage_range. If you add
* any error returns here, do so after setting VM_HUGETLB, so
* is_vm_hugetlb_page tests below unmap_region go the right
* way when do_mmap unwinds (may be important on powerpc
* and ia64).
* already been checked by hugetlb_get_unmapped_area(). If you
* add any error returns here, do so after setting VM_HUGETLB,
* so vma_is_hugetlb tests below unmap_region go the right
* way when do_mmap unwinds (may be important on powerpc).
*/
vma_set_flags(vma, VMA_HUGETLB_BIT, VMA_DONTEXPAND_BIT);
vma->vm_ops = &hugetlb_vm_ops;
@ -921,6 +920,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb,
simple_inode_init_ts(inode);
info->resv_map = resv_map;
info->seals = F_SEAL_SEAL;
hugetlbfs_pmd_sharing_init(inode);
switch (mode & S_IFMT) {
default:
init_special_inode(inode, mode, dev);

View File

@ -31,10 +31,9 @@ static inline unsigned long get_max_dump_pfn(void)
{
#ifdef CONFIG_SPARSEMEM
/*
* The memmap of early sections is completely populated and marked
* online even if max_pfn does not fall on a section boundary -
* pfn_to_online_page() will succeed on all pages. Allow inspecting
* these memmaps.
* If max_pfn does not fall on a section boundary, pfn_to_online_page()
* can succeed on PFNs beyond max_pfn within the same section. Allow
* inspection of these memmaps.
*/
return round_up(max_pfn, PAGES_PER_SECTION);
#else

View File

@ -2986,7 +2986,7 @@ static int pagemap_scan_pte_hole(unsigned long addr, unsigned long end,
* hugetlb differs, see pagemap_hugetlb_category().
*/
categories = p->cur_vma_category;
if (userfaultfd_wp(vma) && !is_vm_hugetlb_page(vma))
if (userfaultfd_wp(vma) && !vma_is_hugetlb(vma))
categories |= PAGE_IS_WRITTEN;
if (!pagemap_scan_is_interesting_page(categories, p))
@ -2999,7 +2999,7 @@ static int pagemap_scan_pte_hole(unsigned long addr, unsigned long end,
if (~p->arg.flags & PM_SCAN_WP_MATCHING)
return ret;
if (is_vm_hugetlb_page(vma))
if (vma_is_hugetlb(vma))
err = pagemap_scan_hugetlb_hole_wp(vma, addr, end);
else
err = uffd_wp_range(vma, addr, end - addr, true);
@ -3120,15 +3120,18 @@ static long do_pagemap_scan(struct mm_struct *mm, unsigned long uarg)
size_t n_ranges_out = 0;
int ret;
if (!mmget_not_zero(mm))
return -ESRCH;
ret = pagemap_scan_get_args(&p.arg, uarg);
if (ret)
return ret;
goto out_mmput;
p.masks_of_interest = p.arg.category_mask | p.arg.category_anyof_mask |
p.arg.return_mask;
ret = pagemap_scan_init_bounce_buffer(&p);
if (ret)
return ret;
goto out_mmput;
for (walk_start = p.arg.start; walk_start < p.arg.end;
walk_start = p.arg.walk_end) {
@ -3183,6 +3186,8 @@ static long do_pagemap_scan(struct mm_struct *mm, unsigned long uarg)
ret = -EFAULT;
kfree(p.vec_buf);
out_mmput:
mmput(mm);
return ret;
}
@ -3441,7 +3446,7 @@ static int show_numa_map(struct seq_file *m, void *v)
seq_puts(m, " stack");
}
if (is_vm_hugetlb_page(vma))
if (vma_is_hugetlb(vma))
seq_puts(m, " huge");
/* Skip walking pages if gate VMA */
@ -3470,7 +3475,7 @@ static int show_numa_map(struct seq_file *m, void *v)
if (md->swapcache)
seq_printf(m, " swapcache=%lu", md->swapcache);
if (md->active < md->pages && !is_vm_hugetlb_page(vma))
if (md->active < md->pages && !vma_is_hugetlb(vma))
seq_printf(m, " active=%lu", md->active);
if (md->writeback)

View File

@ -11,9 +11,9 @@
#ifndef _ASM_GENERIC__TLB_H
#define _ASM_GENERIC__TLB_H
#include <linux/mm.h>
#include <linux/mmu_notifier.h>
#include <linux/swap.h>
#include <linux/hugetlb_inline.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
@ -438,7 +438,7 @@ tlb_update_vma_flags(struct mmu_gather *tlb, struct vm_area_struct *vma)
* We rely on tlb_end_vma() to issue a flush, such that when we reset
* these values the batch is empty.
*/
tlb->vma_huge = is_vm_hugetlb_page(vma);
tlb->vma_huge = vma_is_hugetlb(vma);
tlb->vma_exec = !!(vma->vm_flags & VM_EXEC);
/*

View File

@ -89,6 +89,7 @@
*/
#ifndef INTERNODE_CACHE_SHIFT
#define INTERNODE_CACHE_SHIFT L1_CACHE_SHIFT
#define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT)
#endif
#if !defined(____cacheline_internodealigned_in_smp)

View File

@ -117,7 +117,6 @@ struct damon_target {
* @DAMOS_MIGRATE_HOT: Migrate the regions prioritizing warmer regions.
* @DAMOS_MIGRATE_COLD: Migrate the regions prioritizing colder regions.
* @DAMOS_STAT: Do nothing but count the stat.
* @NR_DAMOS_ACTIONS: Total number of DAMOS actions
*
* The support of each action is up to running &struct damon_operations.
* Refer to 'Operation Action' section of Documentation/mm/damon/design.rst for
@ -137,7 +136,6 @@ enum damos_action {
DAMOS_MIGRATE_HOT,
DAMOS_MIGRATE_COLD,
DAMOS_STAT, /* Do nothing but only record the stat */
NR_DAMOS_ACTIONS,
};
/**
@ -154,9 +152,6 @@ enum damos_action {
* @DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP: Scheme-eligible memory ratio of a
* node in basis points (0-10000).
* @DAMOS_QUOTA_HUGEPAGE_MEM_BP: Huge page to total used memory ratio.
* @NR_DAMOS_QUOTA_GOAL_METRICS: Number of DAMOS quota goal metrics.
*
* Metrics equal to larger than @NR_DAMOS_QUOTA_GOAL_METRICS are unsupported.
*/
enum damos_quota_goal_metric {
DAMOS_QUOTA_USER_INPUT,
@ -169,12 +164,12 @@ enum damos_quota_goal_metric {
DAMOS_QUOTA_INACTIVE_MEM_BP,
DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP,
DAMOS_QUOTA_HUGEPAGE_MEM_BP,
NR_DAMOS_QUOTA_GOAL_METRICS,
};
/**
* struct damos_quota_goal - DAMOS scheme quota auto-tuning goal.
* @metric: Metric to be used for representing the goal.
* @complement: Use the complement of the metric.
* @target_value: Target value of @metric to achieve with the tuning.
* @current_value: Current value of @metric.
* @nid: Node id.
@ -197,6 +192,7 @@ enum damos_quota_goal_metric {
*/
struct damos_quota_goal {
enum damos_quota_goal_metric metric;
bool complement;
unsigned long target_value;
unsigned long current_value;
/* metric-dependent fields */
@ -313,12 +309,10 @@ struct damos_quota {
*
* @DAMOS_WMARK_NONE: Ignore the watermarks of the given scheme.
* @DAMOS_WMARK_FREE_MEM_RATE: Free memory rate of the system in [0,1000].
* @NR_DAMOS_WMARK_METRICS: Total number of DAMOS watermark metrics
*/
enum damos_wmark_metric {
DAMOS_WMARK_NONE,
DAMOS_WMARK_FREE_MEM_RATE,
NR_DAMOS_WMARK_METRICS,
};
/**
@ -1096,7 +1090,7 @@ bool damos_filter_for_ops(enum damos_filter_type type);
void damos_destroy_filter(struct damos_filter *f);
struct damos_quota_goal *damos_new_quota_goal(
enum damos_quota_goal_metric metric,
enum damos_quota_goal_metric metric, bool complement,
unsigned long target_value);
void damos_add_quota_goal(struct damos_quota *q, struct damos_quota_goal *g);
void damos_destroy_quota_goal(struct damos_quota_goal *goal);

Some files were not shown because too many files have changed in this diff Show More