History

Merge tag 'mm-hotfixes-stable-2022-12-22-14-34' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull hotfixes from Andrew Morton: "Eight fixes, all cc:stable. One is for gcov and the remainder are MM" * tag 'mm-hotfixes-stable-2022-12-22-14-34' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: gcov: add support for checksum field test_maple_tree: add test for mas_spanning_rebalance() on insufficient data maple_tree: fix mas_spanning_rebalance() on insufficient data hugetlb: really allocate vma lock for all sharable vmas kmsan: export kmsan_handle_urb kmsan: include linux/vmalloc.h mm/mempolicy: fix memory leak in set_mempolicy_home_node system call mm, mremap: fix mremap() expanding vma with addr inside vma

Linus Torvalds committed 3 years ago

Commit 699aee72 parents 8395ae0 e96b95c8 files · +184 −187Browse files

Unified · Split

8 files
  1. kernel/gcov/gcc_4_7.c +5 −0
  2. lib/maple_tree.c +3 −1
  3. lib/test_maple_tree.c +23 −0
  4. mm/hugetlb.c +148 −185
  5. mm/kmsan/hooks.c +1 −0
  6. mm/kmsan/kmsan_test.c +1 −0
  7. mm/mempolicy.c +1 −0
  8. mm/mremap.c +2 −1
kernel/gcov/gcc_4_7.c+5−0
@@ -82,6 +82,7 @@ struct gcov_fn_info { · 81 unmodified lines
82 * @version: gcov version magic indicating the gcc version used for compilation82 * @version: gcov version magic indicating the gcc version used for compilation
83 * @next: list head for a singly-linked list83 * @next: list head for a singly-linked list
84 * @stamp: uniquifying time stamp84 * @stamp: uniquifying time stamp
85 * @checksum: unique object checksum
85 * @filename: name of the associated gcov data file86 * @filename: name of the associated gcov data file
86 * @merge: merge functions (null for unused counter type)87 * @merge: merge functions (null for unused counter type)
87 * @n_functions: number of instrumented functions88 * @n_functions: number of instrumented functions
@@ -94,6 +95,10 @@ struct gcov_info { · 6 unmodified lines
94 unsigned int version;95 unsigned int version;
95 struct gcov_info *next;96 struct gcov_info *next;
96 unsigned int stamp;97 unsigned int stamp;
98 /* Since GCC 12.1 a checksum field is added. */
99#if (__GNUC__ >= 12)
100 unsigned int checksum;
101#endif
97 const char *filename;102 const char *filename;
98 void (*merge[GCOV_COUNTERS])(gcov_type *, unsigned int);103 void (*merge[GCOV_COUNTERS])(gcov_type *, unsigned int);
99 unsigned int n_functions;104 unsigned int n_functions;
lib/maple_tree.c+3−1
@@ -2994,7 +2994,9 @@ static int mas_spanning_rebalance(struct ma_state *mas, · 2993 unmodified lines
2994 mast->free = &free;2994 mast->free = &free;
2995 mast->destroy = &destroy;2995 mast->destroy = &destroy;
2996 l_mas.node = r_mas.node = m_mas.node = MAS_NONE;2996 l_mas.node = r_mas.node = m_mas.node = MAS_NONE;
2997 if (!(mast->orig_l->min && mast->orig_r->max == ULONG_MAX) &&2997
2998 /* Check if this is not root and has sufficient data. */
2999 if (((mast->orig_l->min != 0) || (mast->orig_r->max != ULONG_MAX)) &&
2998 unlikely(mast->bn->b_end <= mt_min_slots[mast->bn->type]))3000 unlikely(mast->bn->b_end <= mt_min_slots[mast->bn->type]))
2999 mast_spanning_rebalance(mast);3001 mast_spanning_rebalance(mast);
3000 3002
lib/test_maple_tree.c+23−0
@@ -2498,6 +2498,25 @@ static noinline void check_dup(struct maple_tree *mt) · 2497 unmodified lines
2498 }2498 }
2499}2499}
2500 2500
2501static noinline void check_bnode_min_spanning(struct maple_tree *mt)
2502{
2503 int i = 50;
2504 MA_STATE(mas, mt, 0, 0);
2505
2506 mt_set_non_kernel(9999);
2507 mas_lock(&mas);
2508 do {
2509 mas_set_range(&mas, i*10, i*10+9);
2510 mas_store(&mas, check_bnode_min_spanning);
2511 } while (i--);
2512
2513 mas_set_range(&mas, 240, 509);
2514 mas_store(&mas, NULL);
2515 mas_unlock(&mas);
2516 mas_destroy(&mas);
2517 mt_set_non_kernel(0);
2518}
2519
2501static DEFINE_MTREE(tree);2520static DEFINE_MTREE(tree);
2502static int maple_tree_seed(void)2521static int maple_tree_seed(void)
2503{2522{
@@ -2742,6 +2761,10 @@ static int maple_tree_seed(void) · 238 unmodified lines
2742 check_dup(&tree);2761 check_dup(&tree);
2743 mtree_destroy(&tree);2762 mtree_destroy(&tree);
2744 2763
2764 mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE);
2765 check_bnode_min_spanning(&tree);
2766 mtree_destroy(&tree);
2767
2745#if defined(BENCH)2768#if defined(BENCH)
2746skip:2769skip:
2747#endif2770#endif
mm/hugetlb.c+148−185
@@ -255,6 +255,152 @@ static inline struct hugepage_subpool *subpool_vma(struct vm_area_struct *vma) · 254 unmodified lines
255 return subpool_inode(file_inode(vma->vm_file));255 return subpool_inode(file_inode(vma->vm_file));
256}256}
257 257
258/*
259 * hugetlb vma_lock helper routines
260 */
261static bool __vma_shareable_lock(struct vm_area_struct *vma)
262{
263 return vma->vm_flags & (VM_MAYSHARE | VM_SHARED) &&
264 vma->vm_private_data;
265}
266
267void hugetlb_vma_lock_read(struct vm_area_struct *vma)
268{
269 if (__vma_shareable_lock(vma)) {
270 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
271
272 down_read(&vma_lock->rw_sema);
273 }
274}
275
276void hugetlb_vma_unlock_read(struct vm_area_struct *vma)
277{
278 if (__vma_shareable_lock(vma)) {
279 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
280
281 up_read(&vma_lock->rw_sema);
282 }
283}
284
285void hugetlb_vma_lock_write(struct vm_area_struct *vma)
286{
287 if (__vma_shareable_lock(vma)) {
288 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
289
290 down_write(&vma_lock->rw_sema);
291 }
292}
293
294void hugetlb_vma_unlock_write(struct vm_area_struct *vma)
295{
296 if (__vma_shareable_lock(vma)) {
297 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
298
299 up_write(&vma_lock->rw_sema);
300 }
301}
302
303int hugetlb_vma_trylock_write(struct vm_area_struct *vma)
304{
305 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
306
307 if (!__vma_shareable_lock(vma))
308 return 1;
309
310 return down_write_trylock(&vma_lock->rw_sema);
311}
312
313void hugetlb_vma_assert_locked(struct vm_area_struct *vma)
314{
315 if (__vma_shareable_lock(vma)) {
316 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
317
318 lockdep_assert_held(&vma_lock->rw_sema);
319 }
320}
321
322void hugetlb_vma_lock_release(struct kref *kref)
323{
324 struct hugetlb_vma_lock *vma_lock = container_of(kref,
325 struct hugetlb_vma_lock, refs);
326
327 kfree(vma_lock);
328}
329
330static void __hugetlb_vma_unlock_write_put(struct hugetlb_vma_lock *vma_lock)
331{
332 struct vm_area_struct *vma = vma_lock->vma;
333
334 /*
335 * vma_lock structure may or not be released as a result of put,
336 * it certainly will no longer be attached to vma so clear pointer.
337 * Semaphore synchronizes access to vma_lock->vma field.
338 */
339 vma_lock->vma = NULL;
340 vma->vm_private_data = NULL;
341 up_write(&vma_lock->rw_sema);
342 kref_put(&vma_lock->refs, hugetlb_vma_lock_release);
343}
344
345static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma)
346{
347 if (__vma_shareable_lock(vma)) {
348 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
349
350 __hugetlb_vma_unlock_write_put(vma_lock);
351 }
352}
353
354static void hugetlb_vma_lock_free(struct vm_area_struct *vma)
355{
356 /*
357 * Only present in sharable vmas.
358 */
359 if (!vma || !__vma_shareable_lock(vma))
360 return;
361
362 if (vma->vm_private_data) {
363 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
364
365 down_write(&vma_lock->rw_sema);
366 __hugetlb_vma_unlock_write_put(vma_lock);
367 }
368}
369
370static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma)
371{
372 struct hugetlb_vma_lock *vma_lock;
373
374 /* Only establish in (flags) sharable vmas */
375 if (!vma || !(vma->vm_flags & VM_MAYSHARE))
376 return;
377
378 /* Should never get here with non-NULL vm_private_data */
379 if (vma->vm_private_data)
380 return;
381
382 vma_lock = kmalloc(sizeof(*vma_lock), GFP_KERNEL);
383 if (!vma_lock) {
384 /*
385 * If we can not allocate structure, then vma can not
386 * participate in pmd sharing. This is only a possible
387 * performance enhancement and memory saving issue.
388 * However, the lock is also used to synchronize page
389 * faults with truncation. If the lock is not present,
390 * unlikely races could leave pages in a file past i_size
391 * until the file is removed. Warn in the unlikely case of
392 * allocation failure.
393 */
394 pr_warn_once("HugeTLB: unable to allocate vma specific lock\n");
395 return;
396 }
397
398 kref_init(&vma_lock->refs);
399 init_rwsem(&vma_lock->rw_sema);
400 vma_lock->vma = vma;
401 vma->vm_private_data = vma_lock;
402}
403
258/* Helper that removes a struct file_region from the resv_map cache and returns404/* Helper that removes a struct file_region from the resv_map cache and returns
259 * it for use.405 * it for use.
260 */406 */
@@ -6613,7 +6759,8 @@ bool hugetlb_reserve_pages(struct inode *inode, · 6352 unmodified lines
6613 }6759 }
6614 6760
6615 /*6761 /*
6616 * vma specific semaphore used for pmd sharing synchronization6762 * vma specific semaphore used for pmd sharing and fault/truncation
6763 * synchronization
6617 */6764 */
6618 hugetlb_vma_lock_alloc(vma);6765 hugetlb_vma_lock_alloc(vma);
6619 6766
@@ -6869,149 +7016,6 @@ void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, · 249 unmodified lines
6869 *end = ALIGN(*end, PUD_SIZE);7016 *end = ALIGN(*end, PUD_SIZE);
6870}7017}
6871 7018
6872static bool __vma_shareable_flags_pmd(struct vm_area_struct *vma)
6873{
6874 return vma->vm_flags & (VM_MAYSHARE | VM_SHARED) &&
6875 vma->vm_private_data;
6876}
6877
6878void hugetlb_vma_lock_read(struct vm_area_struct *vma)
6879{
6880 if (__vma_shareable_flags_pmd(vma)) {
6881 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
6882
6883 down_read(&vma_lock->rw_sema);
6884 }
6885}
6886
6887void hugetlb_vma_unlock_read(struct vm_area_struct *vma)
6888{
6889 if (__vma_shareable_flags_pmd(vma)) {
6890 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
6891
6892 up_read(&vma_lock->rw_sema);
6893 }
6894}
6895
6896void hugetlb_vma_lock_write(struct vm_area_struct *vma)
6897{
6898 if (__vma_shareable_flags_pmd(vma)) {
6899 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
6900
6901 down_write(&vma_lock->rw_sema);
6902 }
6903}
6904
6905void hugetlb_vma_unlock_write(struct vm_area_struct *vma)
6906{
6907 if (__vma_shareable_flags_pmd(vma)) {
6908 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
6909
6910 up_write(&vma_lock->rw_sema);
6911 }
6912}
6913
6914int hugetlb_vma_trylock_write(struct vm_area_struct *vma)
6915{
6916 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
6917
6918 if (!__vma_shareable_flags_pmd(vma))
6919 return 1;
6920
6921 return down_write_trylock(&vma_lock->rw_sema);
6922}
6923
6924void hugetlb_vma_assert_locked(struct vm_area_struct *vma)
6925{
6926 if (__vma_shareable_flags_pmd(vma)) {
6927 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
6928
6929 lockdep_assert_held(&vma_lock->rw_sema);
6930 }
6931}
6932
6933void hugetlb_vma_lock_release(struct kref *kref)
6934{
6935 struct hugetlb_vma_lock *vma_lock = container_of(kref,
6936 struct hugetlb_vma_lock, refs);
6937
6938 kfree(vma_lock);
6939}
6940
6941static void __hugetlb_vma_unlock_write_put(struct hugetlb_vma_lock *vma_lock)
6942{
6943 struct vm_area_struct *vma = vma_lock->vma;
6944
6945 /*
6946 * vma_lock structure may or not be released as a result of put,
6947 * it certainly will no longer be attached to vma so clear pointer.
6948 * Semaphore synchronizes access to vma_lock->vma field.
6949 */
6950 vma_lock->vma = NULL;
6951 vma->vm_private_data = NULL;
6952 up_write(&vma_lock->rw_sema);
6953 kref_put(&vma_lock->refs, hugetlb_vma_lock_release);
6954}
6955
6956static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma)
6957{
6958 if (__vma_shareable_flags_pmd(vma)) {
6959 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
6960
6961 __hugetlb_vma_unlock_write_put(vma_lock);
6962 }
6963}
6964
6965static void hugetlb_vma_lock_free(struct vm_area_struct *vma)
6966{
6967 /*
6968 * Only present in sharable vmas.
6969 */
6970 if (!vma || !__vma_shareable_flags_pmd(vma))
6971 return;
6972
6973 if (vma->vm_private_data) {
6974 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;
6975
6976 down_write(&vma_lock->rw_sema);
6977 __hugetlb_vma_unlock_write_put(vma_lock);
6978 }
6979}
6980
6981static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma)
6982{
6983 struct hugetlb_vma_lock *vma_lock;
6984
6985 /* Only establish in (flags) sharable vmas */
6986 if (!vma || !(vma->vm_flags & VM_MAYSHARE))
6987 return;
6988
6989 /* Should never get here with non-NULL vm_private_data */
6990 if (vma->vm_private_data)
6991 return;
6992
6993 vma_lock = kmalloc(sizeof(*vma_lock), GFP_KERNEL);
6994 if (!vma_lock) {
6995 /*
6996 * If we can not allocate structure, then vma can not
6997 * participate in pmd sharing. This is only a possible
6998 * performance enhancement and memory saving issue.
6999 * However, the lock is also used to synchronize page
7000 * faults with truncation. If the lock is not present,
7001 * unlikely races could leave pages in a file past i_size
7002 * until the file is removed. Warn in the unlikely case of
7003 * allocation failure.
7004 */
7005 pr_warn_once("HugeTLB: unable to allocate vma specific lock\n");
7006 return;
7007 }
7008
7009 kref_init(&vma_lock->refs);
7010 init_rwsem(&vma_lock->rw_sema);
7011 vma_lock->vma = vma;
7012 vma->vm_private_data = vma_lock;
7013}
7014
7015/*7019/*
7016 * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc()7020 * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc()
7017 * and returns the corresponding pte. While this is not necessary for the7021 * and returns the corresponding pte. While this is not necessary for the
@@ -7100,47 +7104,6 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, · 82 unmodified lines
7100 7104
7101#else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */7105#else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
7102 7106
7103void hugetlb_vma_lock_read(struct vm_area_struct *vma)
7104{
7105}
7106
7107void hugetlb_vma_unlock_read(struct vm_area_struct *vma)
7108{
7109}
7110
7111void hugetlb_vma_lock_write(struct vm_area_struct *vma)
7112{
7113}
7114
7115void hugetlb_vma_unlock_write(struct vm_area_struct *vma)
7116{
7117}
7118
7119int hugetlb_vma_trylock_write(struct vm_area_struct *vma)
7120{
7121 return 1;
7122}
7123
7124void hugetlb_vma_assert_locked(struct vm_area_struct *vma)
7125{
7126}
7127
7128void hugetlb_vma_lock_release(struct kref *kref)
7129{
7130}
7131
7132static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma)
7133{
7134}
7135
7136static void hugetlb_vma_lock_free(struct vm_area_struct *vma)
7137{
7138}
7139
7140static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma)
7141{
7142}
7143
7144pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,7107pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
7145 unsigned long addr, pud_t *pud)7108 unsigned long addr, pud_t *pud)
7146{7109{
mm/kmsan/hooks.c+1−0
@@ -260,6 +260,7 @@ void kmsan_handle_urb(const struct urb *urb, bool is_out) · 259 unmodified lines
260 urb->transfer_buffer_length,260 urb->transfer_buffer_length,
261 /*checked*/ false);261 /*checked*/ false);
262}262}
263EXPORT_SYMBOL_GPL(kmsan_handle_urb);
263 264
264static void kmsan_handle_dma_page(const void *addr, size_t size,265static void kmsan_handle_dma_page(const void *addr, size_t size,
265 enum dma_data_direction dir)266 enum dma_data_direction dir)
mm/kmsan/kmsan_test.c+1−0
@@ -22,6 +22,7 @@ · 21 unmodified lines
22#include <linux/spinlock.h>22#include <linux/spinlock.h>
23#include <linux/string.h>23#include <linux/string.h>
24#include <linux/tracepoint.h>24#include <linux/tracepoint.h>
25#include <linux/vmalloc.h>
25#include <trace/events/printk.h>26#include <trace/events/printk.h>
26 27
27static DEFINE_PER_CPU(int, per_cpu_var);28static DEFINE_PER_CPU(int, per_cpu_var);
mm/mempolicy.c+1−0
@@ -1540,6 +1540,7 @@ SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, le · 1539 unmodified lines
1540 * the home node for vmas we already updated before.1540 * the home node for vmas we already updated before.
1541 */1541 */
1542 if (new->mode != MPOL_BIND && new->mode != MPOL_PREFERRED_MANY) {1542 if (new->mode != MPOL_BIND && new->mode != MPOL_PREFERRED_MANY) {
1543 mpol_put(new);
1543 err = -EOPNOTSUPP;1544 err = -EOPNOTSUPP;
1544 break;1545 break;
1545 }1546 }
mm/mremap.c+2−1
@@ -1016,7 +1016,8 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, · 1015 unmodified lines
1016 long pages = (new_len - old_len) >> PAGE_SHIFT;1016 long pages = (new_len - old_len) >> PAGE_SHIFT;
1017 unsigned long extension_start = addr + old_len;1017 unsigned long extension_start = addr + old_len;
1018 unsigned long extension_end = addr + new_len;1018 unsigned long extension_end = addr + new_len;
1019 pgoff_t extension_pgoff = vma->vm_pgoff + (old_len >> PAGE_SHIFT);1019 pgoff_t extension_pgoff = vma->vm_pgoff +
1020 ((extension_start - vma->vm_start) >> PAGE_SHIFT);
1020 1021
1021 if (vma->vm_flags & VM_ACCOUNT) {1022 if (vma->vm_flags & VM_ACCOUNT) {
1022 if (security_vm_enough_memory_mm(mm, pages)) {1023 if (security_vm_enough_memory_mm(mm, pages)) {