projects/linux·commit bc35965f

Merge tag 'mm-hotfixes-stable-2026-09-03-17-45' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

bc35965f · Linus Torvalds <[email protected]> · 2026-09-03 17:59:19 -07:00

Pull misc fixes from Andrew Morton:
 "18 hotfixes.  13 are cc:stable.  15 are for MM.

  All are singletons - please see the changelogs for details.

  There are no fixes (yet) for all the stuff we added in the most recent
  merge window. Hopefully a good sign"

* tag 'mm-hotfixes-stable-2026-09-03-17-45' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
  mm/secretmem: properly account locked pages
  mm/mremap: reset unfaulted VMA page offset for MREMAP_DONTUNMAP
  MAINTAINERS: add Kiryl as a THP reviewer
  MAINTAINERS: cover all of RAID
  MAINTAINERS: mailmap: update entries for Thorsten Blum
  MAINTAINERS: remove Lorenzo as THP co-maintainer
  Revert "once: don't use a work queue to reset sleepable static key"
  mm/hugetlb: fix missing migratable flag on same-node hugetlb migration
  mm/mempolicy: fix sleeping allocation in alloc_pages_bulk_weighted_interleave()
  mm/huge_memory: transfer the pmd dirty bit to the folio on zap
  MAINTAINERS: add Lance Yang as a hung task detector co-maintainer
  userfaultfd: reset err to be 0 when move_pages_ptes succeeded
  mm: fix incorrect vm_flags usage when checking allowable orders for tmpfs
  mm/hugetlb: keep max_huge_pages when dissolving surplus folios
  mm/migrate_device: avoid out-of-bounds writes for compound folios
  mm/hugetlb_cgroup: call page_counter_set_max() outside VM_BUG_ON()
  memcg: make the v1 soft limit knob inert
  mm/hugetlb_cma: fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
Commit
bc35965f6940a9bf834d54187b6088b8eb09206d
Parents
a500db78 · 97d34aa6

Merge commit. Changes below are compared with the first parent: a500db78.

Changes

18 files changed · +233 −133

Only the first 600 diff lines are shown. Download the complete patch.

.mailmap

View file
diff --git a/.mailmap b/.mailmap
index 0e672a6..4f6c77a 100644
--- a/.mailmap
+++ b/.mailmap
@@ -899,7 +899,8 @@ Thomas Graf <[email protected]>
Thomas Pedersen <[email protected]>

Documentation/admin-guide/cgroup-v1/memory.rst

View file
diff --git a/Documentation/admin-guide/cgroup-v1/memory.rst b/Documentation/admin-guide/cgroup-v1/memory.rst
index 7db63c0..7d2a44a 100644
--- a/Documentation/admin-guide/cgroup-v1/memory.rst
+++ b/Documentation/admin-guide/cgroup-v1/memory.rst
@@ -47,7 +47,6 @@ Features:
- pages are linked to per-memcg LRU exclusively, and there is no global LRU.
- optionally, memory+swap usage can be accounted and limited.
- hierarchical accounting
- - soft limit
- moving (recharging) account at moving a task is selectable.
- usage threshold notifier
- memory pressure notifier
@@ -76,10 +75,9 @@ Brief summary of control files.
memory.memsw.failcnt show the number of memory+Swap hits limits
memory.max_usage_in_bytes show max memory usage recorded
memory.memsw.max_usage_in_bytes show max memory+Swap usage recorded
- memory.soft_limit_in_bytes set/show soft limit of memory usage
- This knob is not available on CONFIG_PREEMPT_RT systems.
- This knob is deprecated and shouldn't be
- used.
+ memory.soft_limit_in_bytes This knob is deprecated and has no effect.
+ Writes are ignored and reads always
+ return the maximum value.
memory.stat show various statistics
memory.use_hierarchy set/show hierarchical account enabled
This knob is deprecated and shouldn't be
@@ -340,9 +338,6 @@ memory.kmem.usage_in_bytes, or in a separate counter when it makes sense.
The main "kmem" counter is fed into the main counter, so kmem charges will
also be visible from the user counter.
-Currently no soft limit is implemented for kernel memory. It is future work
-to trigger slab reclaim when those limits are reached.
-
2.7.1 Current Kernel Memory resources accounted
-----------------------------------------------
@@ -710,42 +705,10 @@ For compatibility reasons writing 1 to memory.use_hierarchy will always pass::
THIS IS DEPRECATED!
-Soft limits allow for greater sharing of memory. The idea behind soft limits
-is to allow control groups to use as much of the memory as needed, provided
-
-a. There is no memory contention
-b. They do not exceed their hard limit
-
-When the system detects memory contention or low memory, control groups
-are pushed back to their soft limits. If the soft limit of each control
-group is very high, they are pushed back as much as possible to make
-sure that one control group does not starve the others of memory.
-
-Please note that soft limits is a best-effort feature; it comes with
-no guarantees, but it does its best to make sure that when memory is
-heavily contended for, memory is allocated based on the soft limit
-hints/setup. Currently soft limit based reclaim is set up such that
-it gets invoked from balance_pgdat (kswapd).
-
-7.1 Interface
--------------
-
-Soft limits can be setup by using the following commands (in this example we
-assume a soft limit of 256 MiB)::
-
- # echo 256M > memory.soft_limit_in_bytes
-
-If we want to change this to 1G, we can at any time use::
+Writing to memory.soft_limit_in_bytes has no effect and reading it will
+always return the maximum value.
- # echo 1G > memory.soft_limit_in_bytes
-
-.. note::
- Soft limits take effect over a long period of time, since they involve
- reclaiming memory for balancing between memory cgroups
-
-.. note::
- It is recommended to set the soft limit always below the hard limit,
- otherwise the hard limit will take precedence.
+Use memory.low and memory.min in cgroup v2 instead.
.. _cgroup-v1-memory-move-charges:

MAINTAINERS

View file
diff --git a/MAINTAINERS b/MAINTAINERS
index 875d0ba..627595e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12221,7 +12221,7 @@ F: drivers/tty/hvc/
HUNG TASK DETECTOR
M: Andrew Morton <[email protected]>
-R: Lance Yang <[email protected]>
+M: Lance Yang <[email protected]>
R: Masami Hiramatsu <[email protected]>
R: Petr Mladek <[email protected]>
@@ -17410,7 +17410,6 @@ F: mm/swapfile.c
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
M: Andrew Morton <[email protected]>
M: David Hildenbrand <[email protected]>
-M: Lorenzo Stoakes <[email protected]>
R: Zi Yan <[email protected]>
R: Baolin Wang <[email protected]>
R: Liam R. Howlett <[email protected]>
@@ -17420,6 +17419,7 @@ R: Dev Jain <[email protected]>
R: Barry Song <[email protected]>
R: Lance Yang <[email protected]>
R: Usama Arif <[email protected]>
+R: Kiryl Shutsemau <[email protected]>
S: Maintained
W: http://www.linux-mm.org
@@ -17692,7 +17692,7 @@ F: Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
F: drivers/spi/spi-at91-usart.c
MICROCHIP ATSHA204A DRIVER
-M: Thorsten Blum <[email protected]>
+M: Thorsten Blum <[email protected]>
S: Maintained
F: drivers/crypto/atmel-sha204a.c
@@ -17716,7 +17716,7 @@ F: Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
F: drivers/media/platform/microchip/microchip-csi2dc.c
MICROCHIP ECC DRIVER
-M: Thorsten Blum <[email protected]>
+M: Thorsten Blum <[email protected]>
S: Maintained
F: drivers/crypto/atmel-ecc.c
@@ -25403,7 +25403,7 @@ F: drivers/md/md*
F: drivers/md/raid*
F: include/linux/raid/
F: include/uapi/linux/raid/
-F: lib/raid/raid6/
+F: lib/raid/
SOLIDRUN CLEARFOG SUPPORT
M: Russell King <[email protected]>

include/linux/sched/user.h

View file
diff --git a/include/linux/sched/user.h b/include/linux/sched/user.h
index 4cc5269..8d7e552 100644
--- a/include/linux/sched/user.h
+++ b/include/linux/sched/user.h
@@ -25,7 +25,8 @@ struct user_struct {
#if defined(CONFIG_PERF_EVENTS) || defined(CONFIG_BPF_SYSCALL) || \
defined(CONFIG_NET) || defined(CONFIG_IO_URING) || \
- defined(CONFIG_VFIO_PCI_ZDEV_KVM) || IS_ENABLED(CONFIG_IOMMUFD)
+ defined(CONFIG_VFIO_PCI_ZDEV_KVM) || IS_ENABLED(CONFIG_IOMMUFD) || \
+ defined(CONFIG_SECRETMEM)
atomic_long_t locked_vm;
#endif
#ifdef CONFIG_WATCH_QUEUE

lib/once.c

View file
diff --git a/lib/once.c b/lib/once.c
index d801bfa..0a0a919 100644
--- a/lib/once.c
+++ b/lib/once.c
@@ -93,6 +93,6 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
{
*done = true;
mutex_unlock(&once_mutex);
- static_branch_disable(once_key);
+ once_disable_jump(once_key, mod);
}
EXPORT_SYMBOL(__do_once_sleepable_done);

mm/huge_memory.c

View file
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index ced400f..afbb597 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2449,6 +2449,8 @@ static void zap_huge_pmd_folio(struct mm_struct *mm, struct vm_area_struct *vma,
add_mm_counter(mm, mm_counter_file(folio),
-HPAGE_PMD_NR);
+ if (is_present && pmd_dirty(pmdval))
+ folio_mark_dirty(folio);
if (is_present && pmd_young(pmdval) &&
likely(vma_has_recency(vma)))
folio_mark_accessed(folio);

mm/hugetlb.c

View file
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 7857728..4f6f58b 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1992,7 +1992,8 @@ retry:
if (h->surplus_huge_pages_node[folio_nid(folio)])
adjust_surplus = true;
remove_hugetlb_folio(h, folio, adjust_surplus);
- h->max_huge_pages--;
+ if (!adjust_surplus)
+ h->max_huge_pages--;
spin_unlock_irq(&hugetlb_lock);
/*
@@ -2012,7 +2013,8 @@ retry:
if (rc) {
spin_lock_irq(&hugetlb_lock);
add_hugetlb_folio(h, folio, adjust_surplus);
- h->max_huge_pages++;
+ if (!adjust_surplus)
+ h->max_huge_pages++;
goto out;
}
} else {
@@ -7330,14 +7332,14 @@ void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio,
* There is no need to transfer the per-node surplus state
* when we do not cross the node.
*/
- if (new_nid == old_nid)
- return;
- spin_lock_irq(&hugetlb_lock);
- if (h->surplus_huge_pages_node[old_nid]) {
- h->surplus_huge_pages_node[old_nid]--;
- h->surplus_huge_pages_node[new_nid]++;
+ if (new_nid != old_nid) {
+ spin_lock_irq(&hugetlb_lock);
+ if (h->surplus_huge_pages_node[old_nid]) {
+ h->surplus_huge_pages_node[old_nid]--;
+ h->surplus_huge_pages_node[new_nid]++;
+ }
+ spin_unlock_irq(&hugetlb_lock);
}
- spin_unlock_irq(&hugetlb_lock);
}
/*

mm/hugetlb_cgroup.c

View file
diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c
index e0083de..ecb6e0b 100644
--- a/mm/hugetlb_cgroup.c
+++ b/mm/hugetlb_cgroup.c
@@ -97,6 +97,7 @@ static void hugetlb_cgroup_init(struct hugetlb_cgroup *h_cgroup,
struct page_counter *fault, *fault_parent = NULL;
struct page_counter *rsvd, *rsvd_parent = NULL;
unsigned long limit;
+ int ret;
if (parent_h_cgroup) {
fault_parent = hugetlb_cgroup_counter_from_cgroup(
@@ -118,8 +119,10 @@ static void hugetlb_cgroup_init(struct hugetlb_cgroup *h_cgroup,
limit = round_down(PAGE_COUNTER_MAX,
pages_per_huge_page(&hstates[idx]));
- VM_BUG_ON(page_counter_set_max(fault, limit));
- VM_BUG_ON(page_counter_set_max(rsvd, limit));
+ ret = page_counter_set_max(fault, limit);
+ VM_WARN_ON_ONCE(ret);
+ ret = page_counter_set_max(rsvd, limit);
+ VM_WARN_ON_ONCE(ret);
}
}

mm/hugetlb_cma.c

View file
diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
index db0680e..95fd2d1 100644
--- a/mm/hugetlb_cma.c
+++ b/mm/hugetlb_cma.c
@@ -3,6 +3,7 @@
#include <linux/mm.h>
#include <linux/cma.h>
#include <linux/compiler.h>
+#include <linux/cpuset.h>
#include <linux/mm_inline.h>
#include <asm/page.h>
@@ -55,15 +56,25 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
int node;
struct folio *folio;
struct page *page = NULL;
+ const nodemask_t *nmask;
+ unsigned int cpuset_mems_cookie;
if (!hugetlb_cma_size)
return NULL;
- if (hugetlb_cma[nid])
+retry_cpuset:
+ if (!nodemask) {
+ cpuset_mems_cookie = read_mems_allowed_begin();
+ nmask = &cpuset_current_mems_allowed;
+ } else {
+ nmask = nodemask;
+ }
+
+ if (hugetlb_cma[nid] && node_isset(nid, *nmask))
page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
if (!page && !(gfp_mask & __GFP_THISNODE)) {
- for_each_node_mask(node, *nodemask) {
+ for_each_node_mask(node, *nmask) {
if (node == nid || !hugetlb_cma[node])
continue;
@@ -73,8 +84,12 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
}
}
- if (!page)
+ if (!page) {
+ if (!nodemask &&
+ unlikely(read_mems_allowed_retry(cpuset_mems_cookie)))
+ goto retry_cpuset;
return NULL;
+ }
folio = page_folio(page);
folio_set_hugetlb_cma(folio);

mm/khugepaged.c

View file
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 11ff98d..7563929 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -454,12 +454,6 @@ int hugepage_madvise(struct vm_area_struct *vma,
case MADV_HUGEPAGE:
*vm_flags &= ~VM_NOHUGEPAGE;
*vm_flags |= VM_HUGEPAGE;
- /*
- * If the vma become good for khugepaged to scan,
- * register it here without waiting a page fault that
- * may not happen any time soon.
- */
- khugepaged_enter_vma(vma, *vm_flags);
break;
case MADV_NOHUGEPAGE:
*vm_flags &= ~VM_HUGEPAGE;

mm/madvise.c

View file
diff --git a/mm/madvise.c b/mm/madvise.c
index 96f2387..eeee82c 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -178,6 +178,14 @@ static int madvise_update_vma(vm_flags_t new_flags,
/* vm_flags is protected by the mmap_lock held in write mode. */
vma_start_write(vma);
vma->flags = new_vma_flags;
+ /*
+ * If the vma become good for khugepaged to scan,
+ * register it here without waiting a page fault that
+ * may not happen any time soon.
+ */
+ if (vma_flags_test(&new_vma_flags, VMA_HUGEPAGE_BIT))
+ khugepaged_enter_vma(vma, vma_flags_to_legacy(new_vma_flags));
+
if (set_new_anon_name)
return replace_anon_vma_name(vma, anon_name);

mm/memcontrol-v1.c

View file
diff --git a/mm/memcontrol-v1.c b/mm/memcontrol-v1.c
index 835fc8e..05ef55c 100644
--- a/mm/memcontrol-v1.c
+++ b/mm/memcontrol-v1.c
@@ -96,7 +96,6 @@ enum {
RES_LIMIT,
RES_MAX_USAGE,
RES_FAILCNT,
- RES_SOFT_LIMIT,
};
#ifdef CONFIG_LOCKDEP
@@ -1888,6 +1887,30 @@ static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css,
return -EINVAL;
}
+static u64 mem_cgroup_soft_limit_read(struct cgroup_subsys_state *css,
+ struct cftype *cft)
+{
+ return (u64)PAGE_COUNTER_MAX * PAGE_SIZE;
+}
+
+static ssize_t mem_cgroup_soft_limit_write(struct kernfs_open_file *of,
+ char *buf, size_t nbytes, loff_t off)
+{
+ unsigned long nr_pages;
+ int ret;
+
+ ret = page_counter_memparse(strstrip(buf), "-1", &nr_pages);
+ if (ret)
+ return ret;
+
+ pr_warn_once("soft_limit_in_bytes is deprecated and will be removed. "
+ "Writing any value to this file has no effect. "
+ "Please report your usecase to [email protected] if you "
+ "depend on this functionality.\n");
+
+ return nbytes;
+}
+
static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
struct cftype *cft)
{
@@ -1924,8 +1947,6 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
return (u64)counter->watermark * PAGE_SIZE;
case RES_FAILCNT:
return counter->failcnt;
- case RES_SOFT_LIMIT:
- return (u64)READ_ONCE(memcg->soft_limit) * PAGE_SIZE;
default:
BUG();
}
@@ -2020,17 +2041,6 @@ static ssize_t mem_cgroup_write(struct kernfs_open_file *of,
break;
}
break;
- case RES_SOFT_LIMIT:
- if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
- ret = -EOPNOTSUPP;
- } else {
- pr_warn_once("soft_limit_in_bytes is deprecated and will be removed. "
- "Please report your usecase to [email protected] if you "
- "depend on this functionality.\n");
- WRITE_ONCE(memcg->soft_limit, nr_pages);
- ret = 0;
- }
- break;
}
return ret ?: nbytes;
}
@@ -2384,9 +2394,8 @@ struct cftype mem_cgroup_legacy_files[] = {
},
{
.name = "soft_limit_in_bytes",
- .private = MEMFILE_PRIVATE(_MEM, RES_SOFT_LIMIT),
- .write = mem_cgroup_write,
- .read_u64 = mem_cgroup_read_u64,
+ .write = mem_cgroup_soft_limit_write,
+ .read_u64 = mem_cgroup_soft_limit_read,
},
{
.name = "failcnt",

mm/mempolicy.c

View file
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 3498a56..79053ec 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2679,7 +2679,7 @@ static unsigned long alloc_pages_bulk_weighted_interleave(gfp_t gfp,
prev_node = node;
/* create a local copy of node weights to operate on outside rcu */
- weights = kzalloc(nr_node_ids, GFP_KERNEL);
+ weights = kmalloc(nr_node_ids, gfp & GFP_RECLAIM_MASK);
if (!weights)
return total_allocated;

mm/migrate_device.c

View file
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 762c5ce..009bfa8 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -1423,6 +1423,15 @@ int migrate_device_range(unsigned long *src_pfns, unsigned long start,
src_pfns[i] = migrate_device_pfn_lock(pfn);
nr = folio_nr_pages(folio);
+ if (nr > npages - i) {
+ if (src_pfns[i] & MIGRATE_PFN_MIGRATE) {
+ folio_unlock(folio);
+ folio_put(folio);
+ }
+ memset(&src_pfns[i], 0,
+ (npages - i) * sizeof(*src_pfns));
+ break;
+ }
if (nr > 1) {
src_pfns[i] |= MIGRATE_PFN_COMPOUND;
for (j = 1; j < nr; j++)
@@ -1457,6 +1466,15 @@ int migrate_device_pfns(unsigned long *src_pfns, unsigned long npages)
src_pfns[i] = migrate_device_pfn_lock(src_pfns[i]);
nr = folio_nr_pages(folio);
+ if (nr > npages - i) {
+ if (src_pfns[i] & MIGRATE_PFN_MIGRATE) {
+ folio_unlock(folio);
+ folio_put(folio);
+ }
+ memset(&src_pfns[i], 0,
+ (npages - i) * sizeof(*src_pfns));
+ break;
+ }
if (nr > 1) {
src_pfns[i] |= MIGRATE_PFN_COMPOUND;
for (j = 1; j < nr; j++)

mm/mremap.c

View file
diff --git a/mm/mremap.c b/mm/mremap.c
index e8df5cd..2b4b523 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -1331,18 +1331,30 @@ static void dontunmap_complete(struct vma_remap_struct *vrm,
{
unsigned long start = vrm->addr;
unsigned long end = vrm->addr + vrm->old_len;
- unsigned long old_start = vrm->vma->vm_start;
- unsigned long old_end = vrm->vma->vm_end;
+ struct vm_area_struct *vma = vrm->vma;
+ unsigned long old_start = vma->vm_start;
+ unsigned long old_end = vma->vm_end;
/* We always clear VMA_LOCKED[ONFAULT]_BIT on the old VMA. */
- vma_clear_flags_mask(vrm->vma, VMA_LOCKED_MASK);
+ vma_clear_flags_mask(vma, VMA_LOCKED_MASK);
/*
* anon_vma links of the old vma is no longer needed after its page
* table has been moved.
*/
- if (new_vma != vrm->vma && start == old_start && end == old_end)
- unlink_anon_vmas(vrm->vma);
+ if (new_vma != vma && start == old_start && end == old_end) {
+ const pgoff_t pgoff_unfaulted = vma->vm_start >> PAGE_SHIFT;
+
+ unlink_anon_vmas(vma);
+ /*
+ * The VMA is now unfaulted and it is an invariant that
+ * unfaulted anonymous VMAs have page offset equal to
+ * vma->vm_start >> PAGE_SHIFT.
+ */
+ vma_set_anon_pgoff(vma, pgoff_unfaulted);
+ if (vma_is_anonymous(vma) && !vma->vm_file)
+ vma_set_pgoff(vma, pgoff_unfaulted);
+ }
/* Because we won't unmap we don't need to touch locked_vm. */
}

mm/secretmem.c

View file
diff --git a/mm/secretmem.c b/mm/secretmem.c
index d298650..384f5cf 100644
--- a/mm/secretmem.c
+++ b/mm/secretmem.c
@@ -18,6 +18,8 @@
#include <linux/secretmem.h>
#include <linux/set_memory.h>
#include <linux/sched/signal.h>
+#include <linux/sched/user.h>
+#include <linux/cred.h>
#include <uapi/linux/magic.h>
@@ -47,10 +49,69 @@ bool secretmem_active(void)
return !!atomic_read(&secretmem_users);
}
+struct secretmem_inode_state {
+ struct user_struct *user;
+ atomic_long_t nr_pages_accounted;
+};
+
+static bool __secretmem_account_pages(struct user_struct *user,
+ unsigned long nr_pages)
+{
+ unsigned long page_limit, cur_pages, new_pages;
+
+ if (!nr_pages)
+ return true;
+
+ page_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+
+ cur_pages = atomic_long_read(&user->locked_vm);
+ do {
+ new_pages = cur_pages + nr_pages;
+ if (new_pages > page_limit)
+ return false;
+ } while (!atomic_long_try_cmpxchg(&user->locked_vm,
+ &cur_pages, new_pages));
+ return true;
+}
+
+static bool secretmem_account_folio(struct secretmem_inode_state *state,
+ const struct folio *folio)
+{
+ const unsigned long nr_pages = folio_nr_pages(folio);
+
+ if (!__secretmem_account_pages(state->user, nr_pages))
+ return false;
+
+ atomic_long_add(nr_pages, &state->nr_pages_accounted);
+ return true;
+}
+
+static void __secretmem_unaccount_pages(struct secretmem_inode_state *state,
+ unsigned long nr_pages)
+{
+ atomic_long_sub(nr_pages, &state->user->locked_vm);
+ atomic_long_sub(nr_pages, &state->nr_pages_accounted);
+}
+
+static void secretmem_unaccount_folio(struct secretmem_inode_state *state,
+ struct folio *folio)
+{
+ __secretmem_unaccount_pages(state, folio_nr_pages(folio));
+}
+
+static void secretmem_unaccount_all_folios(struct secretmem_inode_state *state)
+{
+ const unsigned long nr_pages_accounted =
+ atomic_long_read(&state->nr_pages_accounted);
+
+ __secretmem_unaccount_pages(state, nr_pages_accounted);
+}
+
static vm_fault_t secretmem_fault(struct vm_fault *vmf)
{

This diff is incomplete. Download the complete patch.

mm/userfaultfd.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/mm/memfd_secret.c

View file

This diff is incomplete. Download the complete patch.