History

Merge branch 'akpm' (patches from Andrew)

Merge misc fixes from Andrew Morton: "8 patches. Subsystems affected by this patch series: mm (hugetlb, pagemap, and userfaultfd), memfd, selftests, and kconfig" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: configs/debug: set CONFIG_DEBUG_INFO=y properly proc: fix documentation and description of pagemap kselftest/vm: fix tests build with old libc memfd: fix F_SEAL_WRITE after shmem huge page allocated mm: fix use-after-free when anon vma name is used after vma is freed mm: prevent vm_area_struct::anon_name refcount saturation mm: refactor vm_area_struct::anon_vma_name usage code selftests/vm: cleanup hugetlb file after mremap test

Linus Torvalds committed 4 years ago

Commit 00144042 parents f9026e1 d1eff1618 files · +194 −137Browse files

Unified · Split

18 files
  1. Documentation/admin-guide/mm/pagemap.rst +1 −1
  2. fs/proc/task_mmu.c +5 −4
  3. fs/userfaultfd.c +3 −3
  4. include/linux/mm.h +4 −3
  5. include/linux/mm_inline.h +69 −28
  6. include/linux/mm_types.h +4 −1
  7. kernel/configs/debug.config +1 −1
  8. kernel/fork.c +2 −2
  9. kernel/sys.c +12 −7
  10. mm/madvise.c +34 −58
  11. mm/memfd.c +28 −12
  12. mm/mempolicy.c +1 −1
  13. mm/mlock.c +1 −1
  14. mm/mmap.c +6 −6
  15. mm/mprotect.c +1 −1
  16. tools/testing/selftests/vm/hugepage-mremap.c +19 −7
  17. tools/testing/selftests/vm/run_vmtests.sh +2 −1
  18. tools/testing/selftests/vm/userfaultfd.c +1 −0
Documentation/admin-guide/mm/pagemap.rst+1−1
@@ -23,7 +23,7 @@ There are four components to pagemap: · 22 unmodified lines
2323 * Bit 56 page exclusively mapped (since 4.2)
2424 * Bit 57 pte is uffd-wp write-protected (since 5.13) (see
2525 :ref:`Documentation/admin-guide/mm/userfaultfd.rst <userfaultfd>`)
26− * Bits 57-60 zero
26+ * Bits 58-60 zero
2727 * Bit 61 page is file-page or shared-anon (since 3.5)
2828 * Bit 62 page swapped
2929 * Bit 63 page present
fs/proc/task_mmu.c+5−4
@@ -309,7 +309,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) · 308 unmodified lines
309309
310310 name = arch_vma_name(vma);
311311 if (!name) {
312− const char *anon_name;
312+ struct anon_vma_name *anon_name;
313313
314314 if (!mm) {
315315 name = "[vdso]";
@@ -327,10 +327,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) · 11 unmodified lines
327327 goto done;
328328 }
329329
330− anon_name = vma_anon_name(vma);
330+ anon_name = anon_vma_name(vma);
331331 if (anon_name) {
332332 seq_pad(m, ' ');
333− seq_printf(m, "[anon:%s]", anon_name);
333+ seq_printf(m, "[anon:%s]", anon_name->name);
334334 }
335335 }
336336
@@ -1597,7 +1597,8 @@ static const struct mm_walk_ops pagemap_ops = { · 1260 unmodified lines
15971597 * Bits 5-54 swap offset if swapped
15981598 * Bit 55 pte is soft-dirty (see Documentation/admin-guide/mm/soft-dirty.rst)
15991599 * Bit 56 page exclusively mapped
1600− * Bits 57-60 zero
1600+ * Bit 57 pte is uffd-wp write-protected
1601+ * Bits 58-60 zero
16011602 * Bit 61 page is file-page or shared-anon
16021603 * Bit 62 page swapped
16031604 * Bit 63 page present
fs/userfaultfd.c+3−3
@@ -878,7 +878,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file) · 877 unmodified lines
878878 new_flags, vma->anon_vma,
879879 vma->vm_file, vma->vm_pgoff,
880880 vma_policy(vma),
881− NULL_VM_UFFD_CTX, vma_anon_name(vma));
881+ NULL_VM_UFFD_CTX, anon_vma_name(vma));
882882 if (prev)
883883 vma = prev;
884884 else
@@ -1438,7 +1438,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 553 unmodified lines
14381438 vma->anon_vma, vma->vm_file, vma->vm_pgoff,
14391439 vma_policy(vma),
14401440 ((struct vm_userfaultfd_ctx){ ctx }),
1441− vma_anon_name(vma));
1441+ anon_vma_name(vma));
14421442 if (prev) {
14431443 vma = prev;
14441444 goto next;
@@ -1615,7 +1615,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, · 170 unmodified lines
16151615 prev = vma_merge(mm, prev, start, vma_end, new_flags,
16161616 vma->anon_vma, vma->vm_file, vma->vm_pgoff,
16171617 vma_policy(vma),
1618− NULL_VM_UFFD_CTX, vma_anon_name(vma));
1618+ NULL_VM_UFFD_CTX, anon_vma_name(vma));
16191619 if (prev) {
16201620 vma = prev;
16211621 goto next;
include/linux/mm.h+4−3
@@ -2626,7 +2626,7 @@ static inline int vma_adjust(struct vm_area_struct *vma, unsigned long start, · 2625 unmodified lines
26262626 extern struct vm_area_struct *vma_merge(struct mm_struct *,
26272627 struct vm_area_struct *prev, unsigned long addr, unsigned long end,
26282628 unsigned long vm_flags, struct anon_vma *, struct file *, pgoff_t,
2629− struct mempolicy *, struct vm_userfaultfd_ctx, const char *);
2629+ struct mempolicy *, struct vm_userfaultfd_ctx, struct anon_vma_name *);
26302630 extern struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *);
26312631 extern int __split_vma(struct mm_struct *, struct vm_area_struct *,
26322632 unsigned long addr, int new_below);
@@ -3372,11 +3372,12 @@ static inline int seal_check_future_write(int seals, struct vm_area_struct *vma) · 739 unmodified lines
33723372
33733373 #ifdef CONFIG_ANON_VMA_NAME
33743374 int madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
3375− unsigned long len_in, const char *name);
3375+ unsigned long len_in,
3376+ struct anon_vma_name *anon_name);
33763377 #else
33773378 static inline int
33783379 madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
3379− unsigned long len_in, const char *name) {
3380+ unsigned long len_in, struct anon_vma_name *anon_name) {
33803381 return 0;
33813382 }
33823383 #endif
include/linux/mm_inline.h+69−28
@@ -140,50 +140,91 @@ static __always_inline void del_page_from_lru_list(struct page *page, · 139 unmodified lines
140140
141141 #ifdef CONFIG_ANON_VMA_NAME
142142 /*
143− * mmap_lock should be read-locked when calling vma_anon_name() and while using
144− * the returned pointer.
143+ * mmap_lock should be read-locked when calling anon_vma_name(). Caller should
144+ * either keep holding the lock while using the returned pointer or it should
145+ * raise anon_vma_name refcount before releasing the lock.
145146 */
146−extern const char *vma_anon_name(struct vm_area_struct *vma);
147+extern struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma);
148+extern struct anon_vma_name *anon_vma_name_alloc(const char *name);
149+extern void anon_vma_name_free(struct kref *kref);
147150
148−/*
149− * mmap_lock should be read-locked for orig_vma->vm_mm.
150− * mmap_lock should be write-locked for new_vma->vm_mm or new_vma should be
151− * isolated.
152− */
153−extern void dup_vma_anon_name(struct vm_area_struct *orig_vma,
154− struct vm_area_struct *new_vma);
151+/* mmap_lock should be read-locked */
152+static inline void anon_vma_name_get(struct anon_vma_name *anon_name)
153+{
154+ if (anon_name)
155+ kref_get(&anon_name->kref);
156+}
155157
156−/*
157− * mmap_lock should be write-locked or vma should have been isolated under
158− * write-locked mmap_lock protection.
159− */
160−extern void free_vma_anon_name(struct vm_area_struct *vma);
158+static inline void anon_vma_name_put(struct anon_vma_name *anon_name)
159+{
160+ if (anon_name)
161+ kref_put(&anon_name->kref, anon_vma_name_free);
162+}
161163
162−/* mmap_lock should be read-locked */
163−static inline bool is_same_vma_anon_name(struct vm_area_struct *vma,
164− const char *name)
164+static inline
165+struct anon_vma_name *anon_vma_name_reuse(struct anon_vma_name *anon_name)
166+{
167+ /* Prevent anon_name refcount saturation early on */
168+ if (kref_read(&anon_name->kref) < REFCOUNT_MAX) {
169+ anon_vma_name_get(anon_name);
170+ return anon_name;
171+
172+ }
173+ return anon_vma_name_alloc(anon_name->name);
174+}
175+
176+static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma,
177+ struct vm_area_struct *new_vma)
178+{
179+ struct anon_vma_name *anon_name = anon_vma_name(orig_vma);
180+
181+ if (anon_name)
182+ new_vma->anon_name = anon_vma_name_reuse(anon_name);
183+}
184+
185+static inline void free_anon_vma_name(struct vm_area_struct *vma)
165186 {
166− const char *vma_name = vma_anon_name(vma);
187+ /*
188+ * Not using anon_vma_name because it generates a warning if mmap_lock
189+ * is not held, which might be the case here.
190+ */
191+ if (!vma->vm_file)
192+ anon_vma_name_put(vma->anon_name);
193+}
167194
168− /* either both NULL, or pointers to same string */
169− if (vma_name == name)
195+static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1,
196+ struct anon_vma_name *anon_name2)
197+{
198+ if (anon_name1 == anon_name2)
170199 return true;
171200
172− return name && vma_name && !strcmp(name, vma_name);
201+ return anon_name1 && anon_name2 &&
202+ !strcmp(anon_name1->name, anon_name2->name);
173203 }
204+
174205 #else /* CONFIG_ANON_VMA_NAME */
175−static inline const char *vma_anon_name(struct vm_area_struct *vma)
206+static inline struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma)
176207 {
177208 return NULL;
178209 }
179−static inline void dup_vma_anon_name(struct vm_area_struct *orig_vma,
180− struct vm_area_struct *new_vma) {}
181−static inline void free_vma_anon_name(struct vm_area_struct *vma) {}
182−static inline bool is_same_vma_anon_name(struct vm_area_struct *vma,
183− const char *name)
210+
211+static inline struct anon_vma_name *anon_vma_name_alloc(const char *name)
212+{
213+ return NULL;
214+}
215+
216+static inline void anon_vma_name_get(struct anon_vma_name *anon_name) {}
217+static inline void anon_vma_name_put(struct anon_vma_name *anon_name) {}
218+static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma,
219+ struct vm_area_struct *new_vma) {}
220+static inline void free_anon_vma_name(struct vm_area_struct *vma) {}
221+
222+static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1,
223+ struct anon_vma_name *anon_name2)
184224 {
185225 return true;
186226 }
227+
187228 #endif /* CONFIG_ANON_VMA_NAME */
188229
189230 static inline void init_tlb_flush_pending(struct mm_struct *mm)
include/linux/mm_types.h+4−1
@@ -416,7 +416,10 @@ struct vm_area_struct { · 415 unmodified lines
416416 struct rb_node rb;
417417 unsigned long rb_subtree_last;
418418 } shared;
419− /* Serialized by mmap_sem. */
419+ /*
420+ * Serialized by mmap_sem. Never use directly because it is
421+ * valid only when vm_file is NULL. Use anon_vma_name instead.
422+ */
420423 struct anon_vma_name *anon_name;
421424 };
422425
kernel/configs/debug.config+1−1
@@ -16,7 +16,7 @@ CONFIG_SYMBOLIC_ERRNAME=y · 15 unmodified lines
1616 #
1717 # Compile-time checks and compiler options
1818 #
19−CONFIG_DEBUG_INFO=y
19+CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
2020 CONFIG_DEBUG_SECTION_MISMATCH=y
2121 CONFIG_FRAME_WARN=2048
2222 CONFIG_SECTION_MISMATCH_WARN_ONLY=y
kernel/fork.c+2−2
@@ -366,14 +366,14 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) · 365 unmodified lines
366366 *new = data_race(*orig);
367367 INIT_LIST_HEAD(&new->anon_vma_chain);
368368 new->vm_next = new->vm_prev = NULL;
369− dup_vma_anon_name(orig, new);
369+ dup_anon_vma_name(orig, new);
370370 }
371371 return new;
372372 }
373373
374374 void vm_area_free(struct vm_area_struct *vma)
375375 {
376− free_vma_anon_name(vma);
376+ free_anon_vma_name(vma);
377377 kmem_cache_free(vm_area_cachep, vma);
378378 }
379379
kernel/sys.c+12−7
@@ -7,6 +7,7 @@ · 6 unmodified lines
77
88 #include <linux/export.h>
99 #include <linux/mm.h>
10+#include <linux/mm_inline.h>
1011 #include <linux/utsname.h>
1112 #include <linux/mman.h>
1213 #include <linux/reboot.h>
@@ -2286,15 +2287,16 @@ static int prctl_set_vma(unsigned long opt, unsigned long addr, · 2273 unmodified lines
22862287 {
22872288 struct mm_struct *mm = current->mm;
22882289 const char __user *uname;
2289− char *name, *pch;
2290+ struct anon_vma_name *anon_name = NULL;
22902291 int error;
22912292
22922293 switch (opt) {
22932294 case PR_SET_VMA_ANON_NAME:
22942295 uname = (const char __user *)arg;
22952296 if (uname) {
2296− name = strndup_user(uname, ANON_VMA_NAME_MAX_LEN);
2297+ char *name, *pch;
22972298
2299+ name = strndup_user(uname, ANON_VMA_NAME_MAX_LEN);
22982300 if (IS_ERR(name))
22992301 return PTR_ERR(name);
23002302
@@ -2304,15 +2306,18 @@ static int prctl_set_vma(unsigned long opt, unsigned long addr, · 3 unmodified lines
23042306 return -EINVAL;
23052307 }
23062308 }
2307− } else {
2308− /* Reset the name */
2309− name = NULL;
2309+ /* anon_vma has its own copy */
2310+ anon_name = anon_vma_name_alloc(name);
2311+ kfree(name);
2312+ if (!anon_name)
2313+ return -ENOMEM;
2314+
23102315 }
23112316
23122317 mmap_write_lock(mm);
2313− error = madvise_set_anon_name(mm, addr, size, name);
2318+ error = madvise_set_anon_name(mm, addr, size, anon_name);
23142319 mmap_write_unlock(mm);
2315− kfree(name);
2320+ anon_vma_name_put(anon_name);
23162321 break;
23172322 default:
23182323 error = -EINVAL;
mm/madvise.c+34−58
@@ -65,7 +65,7 @@ static int madvise_need_mmap_write(int behavior) · 64 unmodified lines
6565 }
6666
6767 #ifdef CONFIG_ANON_VMA_NAME
68−static struct anon_vma_name *anon_vma_name_alloc(const char *name)
68+struct anon_vma_name *anon_vma_name_alloc(const char *name)
6969 {
7070 struct anon_vma_name *anon_name;
7171 size_t count;
@@ -81,78 +81,48 @@ static struct anon_vma_name *anon_vma_name_alloc(const char *name) · 9 unmodified lines
8181 return anon_name;
8282 }
8383
84−static void vma_anon_name_free(struct kref *kref)
84+void anon_vma_name_free(struct kref *kref)
8585 {
8686 struct anon_vma_name *anon_name =
8787 container_of(kref, struct anon_vma_name, kref);
8888 kfree(anon_name);
8989 }
9090
91−static inline bool has_vma_anon_name(struct vm_area_struct *vma)
91+struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma)
9292 {
93− return !vma->vm_file && vma->anon_name;
94−}
95−
96−const char *vma_anon_name(struct vm_area_struct *vma)
97−{
98− if (!has_vma_anon_name(vma))
99− return NULL;
100−
10193 mmap_assert_locked(vma->vm_mm);
10294
103− return vma->anon_name->name;
104−}
105−
106−void dup_vma_anon_name(struct vm_area_struct *orig_vma,
107− struct vm_area_struct *new_vma)
108−{
109− if (!has_vma_anon_name(orig_vma))
110− return;
111−
112− kref_get(&orig_vma->anon_name->kref);
113− new_vma->anon_name = orig_vma->anon_name;
114−}
115−
116−void free_vma_anon_name(struct vm_area_struct *vma)
117−{
118− struct anon_vma_name *anon_name;
119−
120− if (!has_vma_anon_name(vma))
121− return;
95+ if (vma->vm_file)
96+ return NULL;
12297
123− anon_name = vma->anon_name;
124− vma->anon_name = NULL;
125− kref_put(&anon_name->kref, vma_anon_name_free);
98+ return vma->anon_name;
12699 }
127100
128101 /* mmap_lock should be write-locked */
129−static int replace_vma_anon_name(struct vm_area_struct *vma, const char *name)
102+static int replace_anon_vma_name(struct vm_area_struct *vma,
103+ struct anon_vma_name *anon_name)
130104 {
131− const char *anon_name;
105+ struct anon_vma_name *orig_name = anon_vma_name(vma);
132106
133− if (!name) {
134− free_vma_anon_name(vma);
107+ if (!anon_name) {
108+ vma->anon_name = NULL;
109+ anon_vma_name_put(orig_name);
135110 return 0;
136111 }
137112
138− anon_name = vma_anon_name(vma);
139− if (anon_name) {
140− /* Same name, nothing to do here */
141− if (!strcmp(name, anon_name))
142− return 0;
113+ if (anon_vma_name_eq(orig_name, anon_name))
114+ return 0;
143115
144− free_vma_anon_name(vma);
145− }
146− vma->anon_name = anon_vma_name_alloc(name);
147− if (!vma->anon_name)
148− return -ENOMEM;
116+ vma->anon_name = anon_vma_name_reuse(anon_name);
117+ anon_vma_name_put(orig_name);
149118
150119 return 0;
151120 }
152121 #else /* CONFIG_ANON_VMA_NAME */
153−static int replace_vma_anon_name(struct vm_area_struct *vma, const char *name)
122+static int replace_anon_vma_name(struct vm_area_struct *vma,
123+ struct anon_vma_name *anon_name)
154124 {
155− if (name)
125+ if (anon_name)
156126 return -EINVAL;
157127
158128 return 0;
@@ -161,17 +131,19 @@ static int replace_vma_anon_name(struct vm_area_struct *vma, const char *name) · 2 unmodified lines
161131 /*
162132 * Update the vm_flags on region of a vma, splitting it or merging it as
163133 * necessary. Must be called with mmap_sem held for writing;
134+ * Caller should ensure anon_name stability by raising its refcount even when
135+ * anon_name belongs to a valid vma because this function might free that vma.
164136 */
165137 static int madvise_update_vma(struct vm_area_struct *vma,
166138 struct vm_area_struct **prev, unsigned long start,
167139 unsigned long end, unsigned long new_flags,
168− const char *name)
140+ struct anon_vma_name *anon_name)
169141 {
170142 struct mm_struct *mm = vma->vm_mm;
171143 int error;
172144 pgoff_t pgoff;
173145
174− if (new_flags == vma->vm_flags && is_same_vma_anon_name(vma, name)) {
146+ if (new_flags == vma->vm_flags && anon_vma_name_eq(anon_vma_name(vma), anon_name)) {
175147 *prev = vma;
176148 return 0;
177149 }
@@ -179,7 +151,7 @@ static int madvise_update_vma(struct vm_area_struct *vma, · 1 unmodified line
179151 pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
180152 *prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma,
181153 vma->vm_file, pgoff, vma_policy(vma),
182− vma->vm_userfaultfd_ctx, name);
154+ vma->vm_userfaultfd_ctx, anon_name);
183155 if (*prev) {
184156 vma = *prev;
185157 goto success;
@@ -209,7 +181,7 @@ success: · 23 unmodified lines
209181 */
210182 vma->vm_flags = new_flags;
211183 if (!vma->vm_file) {
212− error = replace_vma_anon_name(vma, name);
184+ error = replace_anon_vma_name(vma, anon_name);
213185 if (error)
214186 return error;
215187 }
@@ -975,6 +947,7 @@ static int madvise_vma_behavior(struct vm_area_struct *vma, · 759 unmodified lines
975947 unsigned long behavior)
976948 {
977949 int error;
950+ struct anon_vma_name *anon_name;
978951 unsigned long new_flags = vma->vm_flags;
979952
980953 switch (behavior) {
@@ -1040,8 +1013,11 @@ static int madvise_vma_behavior(struct vm_area_struct *vma, · 59 unmodified lines
10401013 break;
10411014 }
10421015
1016+ anon_name = anon_vma_name(vma);
1017+ anon_vma_name_get(anon_name);
10431018 error = madvise_update_vma(vma, prev, start, end, new_flags,
1044− vma_anon_name(vma));
1019+ anon_name);
1020+ anon_vma_name_put(anon_name);
10451021
10461022 out:
10471023 /*
@@ -1225,7 +1201,7 @@ int madvise_walk_vmas(struct mm_struct *mm, unsigned long start, · 177 unmodified lines
12251201 static int madvise_vma_anon_name(struct vm_area_struct *vma,
12261202 struct vm_area_struct **prev,
12271203 unsigned long start, unsigned long end,
1228− unsigned long name)
1204+ unsigned long anon_name)
12291205 {
12301206 int error;
12311207
@@ -1234,7 +1210,7 @@ static int madvise_vma_anon_name(struct vm_area_struct *vma, · 2 unmodified lines
12341210 return -EBADF;
12351211
12361212 error = madvise_update_vma(vma, prev, start, end, vma->vm_flags,
1237− (const char *)name);
1213+ (struct anon_vma_name *)anon_name);
12381214
12391215 /*
12401216 * madvise() returns EAGAIN if kernel resources, such as
@@ -1246,7 +1222,7 @@ static int madvise_vma_anon_name(struct vm_area_struct *vma, · 5 unmodified lines
12461222 }
12471223
12481224 int madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
1249− unsigned long len_in, const char *name)
1225+ unsigned long len_in, struct anon_vma_name *anon_name)
12501226 {
12511227 unsigned long end;
12521228 unsigned long len;
@@ -1266,7 +1242,7 @@ int madvise_set_anon_name(struct mm_struct *mm, unsigned long start, · 13 unmodified lines
12661242 if (end == start)
12671243 return 0;
12681244
1269− return madvise_walk_vmas(mm, start, end, (unsigned long)name,
1245+ return madvise_walk_vmas(mm, start, end, (unsigned long)anon_name,
12701246 madvise_vma_anon_name);
12711247 }
12721248 #endif /* CONFIG_ANON_VMA_NAME */
mm/memfd.c+28−12
@@ -31,20 +31,28 @@ · 30 unmodified lines
3131 static void memfd_tag_pins(struct xa_state *xas)
3232 {
3333 struct page *page;
34− unsigned int tagged = 0;
34+ int latency = 0;
35+ int cache_count;
3536
3637 lru_add_drain();
3738
3839 xas_lock_irq(xas);
3940 xas_for_each(xas, page, ULONG_MAX) {
40− if (xa_is_value(page))
41− continue;
42− page = find_subpage(page, xas->xa_index);
43− if (page_count(page) - page_mapcount(page) > 1)
41+ cache_count = 1;
42+ if (!xa_is_value(page) &&
43+ PageTransHuge(page) && !PageHuge(page))
44+ cache_count = HPAGE_PMD_NR;
45+
46+ if (!xa_is_value(page) &&
47+ page_count(page) - total_mapcount(page) != cache_count)
4448 xas_set_mark(xas, MEMFD_TAG_PINNED);
49+ if (cache_count != 1)
50+ xas_set(xas, page->index + cache_count);
4551
46− if (++tagged % XA_CHECK_SCHED)
52+ latency += cache_count;
53+ if (latency < XA_CHECK_SCHED)
4754 continue;
55+ latency = 0;
4856
4957 xas_pause(xas);
5058 xas_unlock_irq(xas);
@@ -73,7 +81,8 @@ static int memfd_wait_for_pins(struct address_space *mapping) · 22 unmodified lines
7381
7482 error = 0;
7583 for (scan = 0; scan <= LAST_SCAN; scan++) {
76− unsigned int tagged = 0;
84+ int latency = 0;
85+ int cache_count;
7786
7887 if (!xas_marked(&xas, MEMFD_TAG_PINNED))
7988 break;
@@ -87,10 +96,14 @@ static int memfd_wait_for_pins(struct address_space *mapping) · 7 unmodified lines
8796 xas_lock_irq(&xas);
8897 xas_for_each_marked(&xas, page, ULONG_MAX, MEMFD_TAG_PINNED) {
8998 bool clear = true;
90− if (xa_is_value(page))
91− continue;
92− page = find_subpage(page, xas.xa_index);
93− if (page_count(page) - page_mapcount(page) != 1) {
99+
100+ cache_count = 1;
101+ if (!xa_is_value(page) &&
102+ PageTransHuge(page) && !PageHuge(page))
103+ cache_count = HPAGE_PMD_NR;
104+
105+ if (!xa_is_value(page) && cache_count !=
106+ page_count(page) - total_mapcount(page)) {
94107 /*
95108 * On the last scan, we clean up all those tags
96109 * we inserted; but make a note that we still
@@ -103,8 +116,11 @@ static int memfd_wait_for_pins(struct address_space *mapping) · 6 unmodified lines
103116 }
104117 if (clear)
105118 xas_clear_mark(&xas, MEMFD_TAG_PINNED);
106− if (++tagged % XA_CHECK_SCHED)
119+
120+ latency += cache_count;
121+ if (latency < XA_CHECK_SCHED)
107122 continue;
123+ latency = 0;
108124
109125 xas_pause(&xas);
110126 xas_unlock_irq(&xas);
mm/mempolicy.c+1−1
@@ -814,7 +814,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, · 813 unmodified lines
814814 prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
815815 vma->anon_vma, vma->vm_file, pgoff,
816816 new_pol, vma->vm_userfaultfd_ctx,
817− vma_anon_name(vma));
817+ anon_vma_name(vma));
818818 if (prev) {
819819 vma = prev;
820820 next = vma->vm_next;
mm/mlock.c+1−1
@@ -512,7 +512,7 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev, · 511 unmodified lines
512512 pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
513513 *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
514514 vma->vm_file, pgoff, vma_policy(vma),
515− vma->vm_userfaultfd_ctx, vma_anon_name(vma));
515+ vma->vm_userfaultfd_ctx, anon_vma_name(vma));
516516 if (*prev) {
517517 vma = *prev;
518518 goto success;
mm/mmap.c+6−6
@@ -1031,7 +1031,7 @@ again: · 1030 unmodified lines
10311031 static inline int is_mergeable_vma(struct vm_area_struct *vma,
10321032 struct file *file, unsigned long vm_flags,
10331033 struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
1034− const char *anon_name)
1034+ struct anon_vma_name *anon_name)
10351035 {
10361036 /*
10371037 * VM_SOFTDIRTY should not prevent from VMA merging, if we
@@ -1049,7 +1049,7 @@ static inline int is_mergeable_vma(struct vm_area_struct *vma, · 11 unmodified lines
10491049 return 0;
10501050 if (!is_mergeable_vm_userfaultfd_ctx(vma, vm_userfaultfd_ctx))
10511051 return 0;
1052− if (!is_same_vma_anon_name(vma, anon_name))
1052+ if (!anon_vma_name_eq(anon_vma_name(vma), anon_name))
10531053 return 0;
10541054 return 1;
10551055 }
@@ -1084,7 +1084,7 @@ can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags, · 28 unmodified lines
10841084 struct anon_vma *anon_vma, struct file *file,
10851085 pgoff_t vm_pgoff,
10861086 struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
1087− const char *anon_name)
1087+ struct anon_vma_name *anon_name)
10881088 {
10891089 if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) &&
10901090 is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
@@ -1106,7 +1106,7 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, · 15 unmodified lines
11061106 struct anon_vma *anon_vma, struct file *file,
11071107 pgoff_t vm_pgoff,
11081108 struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
1109− const char *anon_name)
1109+ struct anon_vma_name *anon_name)
11101110 {
11111111 if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) &&
11121112 is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
@@ -1167,7 +1167,7 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, · 54 unmodified lines
11671167 struct anon_vma *anon_vma, struct file *file,
11681168 pgoff_t pgoff, struct mempolicy *policy,
11691169 struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
1170− const char *anon_name)
1170+ struct anon_vma_name *anon_name)
11711171 {
11721172 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
11731173 struct vm_area_struct *area, *next;
@@ -3256,7 +3256,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, · 2082 unmodified lines
32563256 return NULL; /* should never get here */
32573257 new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags,
32583258 vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
3259− vma->vm_userfaultfd_ctx, vma_anon_name(vma));
3259+ vma->vm_userfaultfd_ctx, anon_vma_name(vma));
32603260 if (new_vma) {
32613261 /*
32623262 * Source vma may have been merged into new_vma
mm/mprotect.c+1−1
@@ -464,7 +464,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, · 463 unmodified lines
464464 pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
465465 *pprev = vma_merge(mm, *pprev, start, end, newflags,
466466 vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
467− vma->vm_userfaultfd_ctx, vma_anon_name(vma));
467+ vma->vm_userfaultfd_ctx, anon_vma_name(vma));
468468 if (*pprev) {
469469 vma = *pprev;
470470 VM_WARN_ON((vma->vm_flags ^ newflags) & ~VM_SOFTDIRTY);
tools/testing/selftests/vm/hugepage-mremap.c+19−7
@@ -3,9 +3,10 @@ · 2 unmodified lines
33 * hugepage-mremap:
44 *
55 * Example of remapping huge page memory in a user application using the
6− * mremap system call. Code assumes a hugetlbfs filesystem is mounted
7− * at './huge'. The amount of memory used by this test is decided by a command
8− * line argument in MBs. If missing, the default amount is 10MB.
6+ * mremap system call. The path to a file in a hugetlbfs filesystem must
7+ * be passed as the last argument to this test. The amount of memory used
8+ * by this test in MBs can optionally be passed as an argument. If no memory
9+ * amount is passed, the default amount is 10MB.
910 *
1011 * To make sure the test triggers pmd sharing and goes through the 'unshare'
1112 * path in the mremap code use 1GB (1024) or more.
@@ -25,7 +26,6 @@ · 13 unmodified lines
2526 #define DEFAULT_LENGTH_MB 10UL
2627 #define MB_TO_BYTES(x) (x * 1024 * 1024)
2728
28−#define FILE_NAME "huge/hugepagefile"
2929 #define PROTECTION (PROT_READ | PROT_WRITE | PROT_EXEC)
3030 #define FLAGS (MAP_SHARED | MAP_ANONYMOUS)
3131
@@ -107,17 +107,26 @@ static void register_region_with_uffd(char *addr, size_t len) · 75 unmodified lines
107107
108108 int main(int argc, char *argv[])
109109 {
110+ size_t length;
111+
112+ if (argc != 2 && argc != 3) {
113+ printf("Usage: %s [length_in_MB] <hugetlb_file>\n", argv[0]);
114+ exit(1);
115+ }
116+
110117 /* Read memory length as the first arg if valid, otherwise fallback to
111− * the default length. Any additional args are ignored.
118+ * the default length.
112119 */
113− size_t length = argc > 1 ? (size_t)atoi(argv[1]) : 0UL;
120+ if (argc == 3)
121+ length = argc > 2 ? (size_t)atoi(argv[1]) : 0UL;
114122
115123 length = length > 0 ? length : DEFAULT_LENGTH_MB;
116124 length = MB_TO_BYTES(length);
117125
118126 int ret = 0;
119127
120− int fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
128+ /* last arg is the hugetlb file name */
129+ int fd = open(argv[argc-1], O_CREAT | O_RDWR, 0755);
121130
122131 if (fd < 0) {
123132 perror("Open failed");
@@ -169,5 +178,8 @@ int main(int argc, char *argv[]) · 45 unmodified lines
169178
170179 munmap(addr, length);
171180
181+ close(fd);
182+ unlink(argv[argc-1]);
183+
172184 return ret;
173185 }
tools/testing/selftests/vm/run_vmtests.sh+2−1
@@ -111,13 +111,14 @@ fi · 110 unmodified lines
111111 echo "-----------------------"
112112 echo "running hugepage-mremap"
113113 echo "-----------------------"
114−./hugepage-mremap 256
114+./hugepage-mremap $mnt/huge_mremap
115115 if [ $? -ne 0 ]; then
116116 echo "[FAIL]"
117117 exitcode=1
118118 else
119119 echo "[PASS]"
120120 fi
121+rm -f $mnt/huge_mremap
121122
122123 echo "NOTE: The above hugetlb tests provide minimal coverage. Use"
123124 echo " https://github.com/libhugetlbfs/libhugetlbfs.git for"
tools/testing/selftests/vm/userfaultfd.c+1−0
@@ -46,6 +46,7 @@ · 45 unmodified lines
4646 #include <signal.h>
4747 #include <poll.h>
4848 #include <string.h>
49+#include <linux/mman.h>
4950 #include <sys/mman.h>
5051 #include <sys/syscall.h>
5152 #include <sys/ioctl.h>