14 hotfixes. 9 are for MM. 10 are cc:stable and the remainder are for
post-7.1 issues or aren't deemed suitable for backporting. There's a 2 patch MAINTAINERS series from Mike Rapoport which updates us for the new KEXEC/KDUMP/crash/LUO/etc arrangements. And a 2 patch series from Muchun Song to fix a couple of memory-hotplug issues. Otherwise singletons, please see the changelogs for details. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCagviKQAKCRDdBJ7gKXxA jlbsAP9SEShHxXEYcRMVQtXb+8/iJDe7J3KwVDP4e0VOlQKTPAD/c+C2bx4nllOG 77wl9Qkr++KqTSmoPbzA7Q02gJC2ngQ= =2qN3 -----END PGP SIGNATURE----- Merge tag 'mm-hotfixes-stable-2026-05-18-21-07' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull misc fixes from Andrew Morton: "14 hotfixes. 9 are for MM. 10 are cc:stable and the remainder are for post-7.1 issues or aren't deemed suitable for backporting. There's a two-patch MAINTAINERS series from Mike Rapoport which updates us for the new KEXEC/KDUMP/crash/LUO/etc arrangements. And another two-patch series from Muchun Song to fix a couple of memory-hotplug issues. Otherwise singletons, please see the changelogs for details" * tag 'mm-hotfixes-stable-2026-05-18-21-07' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mm/memory: fix spurious warning when unmapping device-private/exclusive pages mm: fix __vm_normal_page() to handle missing support for pmd_special()/pud_special() drivers/base/memory: fix memory block reference leak in poison accounting mm/memory_hotplug: fix memory block reference leak on remove lib: kunit_iov_iter: fix test fail on powerpc mm/page_alloc: fix initialization of tags of the huge zero folio with init_on_free MAINTAINERS: add kexec@ list to LIVE UPDATE ENTRY MAINTAINERS: add tree for KDUMP and KEXEC selftests/mm: run_vmtests.sh: fix destructive tests invocation scripts/gdb: slab: update field names of struct kmem_cache scripts/gdb: mm: cast untyped symbols in x86_page_ops mm/damon: fix damos_stat tracepoint format for sz_applied mm/damon/sysfs-schemes: call missing mem_cgroup_iter_break() mm/migrate_device: fix spinlock leak in migrate_vma_insert_huge_pmd_pagemaster
commit
c6e99c10fd
|
|
@ -13869,6 +13869,7 @@ M: Pratyush Yadav <pratyush@kernel.org>
|
||||||
R: Dave Young <ruirui.yang@linux.dev>
|
R: Dave Young <ruirui.yang@linux.dev>
|
||||||
L: kexec@lists.infradead.org
|
L: kexec@lists.infradead.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
|
||||||
F: Documentation/admin-guide/kdump/
|
F: Documentation/admin-guide/kdump/
|
||||||
F: fs/proc/vmcore.c
|
F: fs/proc/vmcore.c
|
||||||
F: include/linux/crash_core.h
|
F: include/linux/crash_core.h
|
||||||
|
|
@ -14186,6 +14187,7 @@ M: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||||
M: Pratyush Yadav <pratyush@kernel.org>
|
M: Pratyush Yadav <pratyush@kernel.org>
|
||||||
L: kexec@lists.infradead.org
|
L: kexec@lists.infradead.org
|
||||||
W: http://kernel.org/pub/linux/utils/kernel/kexec/
|
W: http://kernel.org/pub/linux/utils/kernel/kexec/
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
|
||||||
F: include/linux/kexec.h
|
F: include/linux/kexec.h
|
||||||
F: include/uapi/linux/kexec.h
|
F: include/uapi/linux/kexec.h
|
||||||
F: kernel/kexec*
|
F: kernel/kexec*
|
||||||
|
|
@ -14902,6 +14904,7 @@ LIVE UPDATE
|
||||||
M: Pasha Tatashin <pasha.tatashin@soleen.com>
|
M: Pasha Tatashin <pasha.tatashin@soleen.com>
|
||||||
M: Mike Rapoport <rppt@kernel.org>
|
M: Mike Rapoport <rppt@kernel.org>
|
||||||
M: Pratyush Yadav <pratyush@kernel.org>
|
M: Pratyush Yadav <pratyush@kernel.org>
|
||||||
|
L: kexec@lists.infradead.org
|
||||||
L: linux-kernel@vger.kernel.org
|
L: linux-kernel@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma,
|
||||||
unsigned long vaddr);
|
unsigned long vaddr);
|
||||||
#define vma_alloc_zeroed_movable_folio vma_alloc_zeroed_movable_folio
|
#define vma_alloc_zeroed_movable_folio vma_alloc_zeroed_movable_folio
|
||||||
|
|
||||||
bool tag_clear_highpages(struct page *to, int numpages);
|
bool tag_clear_highpages(struct page *to, int numpages, bool clear_pages);
|
||||||
#define __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
|
#define __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
|
||||||
|
|
||||||
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
|
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
|
||||||
|
|
|
||||||
|
|
@ -1018,7 +1018,7 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma,
|
||||||
return vma_alloc_folio(flags, 0, vma, vaddr);
|
return vma_alloc_folio(flags, 0, vma, vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tag_clear_highpages(struct page *page, int numpages)
|
bool tag_clear_highpages(struct page *page, int numpages, bool clear_pages)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Check if MTE is supported and fall back to clear_highpage().
|
* Check if MTE is supported and fall back to clear_highpage().
|
||||||
|
|
@ -1026,13 +1026,16 @@ bool tag_clear_highpages(struct page *page, int numpages)
|
||||||
* post_alloc_hook() will invoke tag_clear_highpages().
|
* post_alloc_hook() will invoke tag_clear_highpages().
|
||||||
*/
|
*/
|
||||||
if (!system_supports_mte())
|
if (!system_supports_mte())
|
||||||
return false;
|
return clear_pages;
|
||||||
|
|
||||||
/* Newly allocated pages, shouldn't have been tagged yet */
|
/* Newly allocated pages, shouldn't have been tagged yet */
|
||||||
for (int i = 0; i < numpages; i++, page++) {
|
for (int i = 0; i < numpages; i++, page++) {
|
||||||
WARN_ON_ONCE(!try_page_mte_tagging(page));
|
WARN_ON_ONCE(!try_page_mte_tagging(page));
|
||||||
|
if (clear_pages)
|
||||||
mte_zero_clear_page_tags(page_address(page));
|
mte_zero_clear_page_tags(page_address(page));
|
||||||
|
else
|
||||||
|
mte_clear_page_tags(page_address(page));
|
||||||
set_page_mte_tagged(page);
|
set_page_mte_tagged(page);
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1230,8 +1230,10 @@ void memblk_nr_poison_inc(unsigned long pfn)
|
||||||
const unsigned long block_id = pfn_to_block_id(pfn);
|
const unsigned long block_id = pfn_to_block_id(pfn);
|
||||||
struct memory_block *mem = find_memory_block_by_id(block_id);
|
struct memory_block *mem = find_memory_block_by_id(block_id);
|
||||||
|
|
||||||
if (mem)
|
if (mem) {
|
||||||
atomic_long_inc(&mem->nr_hwpoison);
|
atomic_long_inc(&mem->nr_hwpoison);
|
||||||
|
put_device(&mem->dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void memblk_nr_poison_sub(unsigned long pfn, long i)
|
void memblk_nr_poison_sub(unsigned long pfn, long i)
|
||||||
|
|
@ -1239,8 +1241,10 @@ void memblk_nr_poison_sub(unsigned long pfn, long i)
|
||||||
const unsigned long block_id = pfn_to_block_id(pfn);
|
const unsigned long block_id = pfn_to_block_id(pfn);
|
||||||
struct memory_block *mem = find_memory_block_by_id(block_id);
|
struct memory_block *mem = find_memory_block_by_id(block_id);
|
||||||
|
|
||||||
if (mem)
|
if (mem) {
|
||||||
atomic_long_sub(i, &mem->nr_hwpoison);
|
atomic_long_sub(i, &mem->nr_hwpoison);
|
||||||
|
put_device(&mem->dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long memblk_nr_poison(struct memory_block *mem)
|
static unsigned long memblk_nr_poison(struct memory_block *mem)
|
||||||
|
|
|
||||||
|
|
@ -273,11 +273,11 @@ enum {
|
||||||
*
|
*
|
||||||
* %__GFP_ZERO returns a zeroed page on success.
|
* %__GFP_ZERO returns a zeroed page on success.
|
||||||
*
|
*
|
||||||
* %__GFP_ZEROTAGS zeroes memory tags at allocation time if the memory itself
|
* %__GFP_ZEROTAGS zeroes memory tags at allocation time. Setting memory tags at
|
||||||
* is being zeroed (either via __GFP_ZERO or via init_on_alloc, provided that
|
* the same time as zeroing memory (e.g., with __GFP_ZERO) has minimal
|
||||||
* __GFP_SKIP_ZERO is not set). This flag is intended for optimization: setting
|
* additional performance impact. However, __GFP_ZEROTAGS also zeroes the tags
|
||||||
* memory tags at the same time as zeroing memory has minimal additional
|
* even if memory is not getting zeroed at allocation time (e.g.,
|
||||||
* performance impact.
|
* with init_on_free).
|
||||||
*
|
*
|
||||||
* %__GFP_SKIP_KASAN makes KASAN skip unpoisoning on page allocation.
|
* %__GFP_SKIP_KASAN makes KASAN skip unpoisoning on page allocation.
|
||||||
* Used for userspace and vmalloc pages; the latter are unpoisoned by
|
* Used for userspace and vmalloc pages; the latter are unpoisoned by
|
||||||
|
|
|
||||||
|
|
@ -347,10 +347,11 @@ static inline void clear_highpage_kasan_tagged(struct page *page)
|
||||||
|
|
||||||
#ifndef __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
|
#ifndef __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
|
||||||
|
|
||||||
/* Return false to let people know we did not initialize the pages */
|
/* Returns true if the caller has to initialize the pages */
|
||||||
static inline bool tag_clear_highpages(struct page *page, int numpages)
|
static inline bool tag_clear_highpages(struct page *page, int numpages,
|
||||||
|
bool clear_pages)
|
||||||
{
|
{
|
||||||
return false;
|
return clear_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ TRACE_EVENT(damos_stat_after_apply_interval,
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("ctx_idx=%u scheme_idx=%u nr_tried=%lu sz_tried=%lu "
|
TP_printk("ctx_idx=%u scheme_idx=%u nr_tried=%lu sz_tried=%lu "
|
||||||
"nr_applied=%lu sz_tried=%lu sz_ops_filter_passed=%lu "
|
"nr_applied=%lu sz_applied=%lu sz_ops_filter_passed=%lu "
|
||||||
"qt_exceeds=%lu nr_snapshots=%lu",
|
"qt_exceeds=%lu nr_snapshots=%lu",
|
||||||
__entry->context_idx, __entry->scheme_idx,
|
__entry->context_idx, __entry->scheme_idx,
|
||||||
__entry->nr_tried, __entry->sz_tried,
|
__entry->nr_tried, __entry->sz_tried,
|
||||||
|
|
|
||||||
|
|
@ -1128,7 +1128,7 @@ static void __init iov_kunit_iter_to_sg_kvec(struct kunit *test)
|
||||||
struct kvec kvec;
|
struct kvec kvec;
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
|
|
||||||
bufsize = 0x100000;
|
bufsize = 0x200000;
|
||||||
iov_kunit_iter_to_sg_init(test, bufsize, false, &data);
|
iov_kunit_iter_to_sg_init(test, bufsize, false, &data);
|
||||||
|
|
||||||
kvec.iov_base = data.buffer;
|
kvec.iov_base = data.buffer;
|
||||||
|
|
@ -1146,7 +1146,7 @@ static void __init iov_kunit_iter_to_sg_bvec(struct kunit *test)
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
struct iov_iter iter;
|
struct iov_iter iter;
|
||||||
|
|
||||||
bufsize = 0x100000;
|
bufsize = 0x200000;
|
||||||
iov_kunit_iter_to_sg_init(test, bufsize, false, &data);
|
iov_kunit_iter_to_sg_init(test, bufsize, false, &data);
|
||||||
|
|
||||||
bvec = kunit_kmalloc_array(test, data.npages, sizeof(*bvec),
|
bvec = kunit_kmalloc_array(test, data.npages, sizeof(*bvec),
|
||||||
|
|
@ -1173,7 +1173,7 @@ static void __init iov_kunit_iter_to_sg_folioq(struct kunit *test)
|
||||||
struct iov_iter iter;
|
struct iov_iter iter;
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
|
|
||||||
bufsize = 0x100000;
|
bufsize = 0x200000;
|
||||||
iov_kunit_iter_to_sg_init(test, bufsize, false, &data);
|
iov_kunit_iter_to_sg_init(test, bufsize, false, &data);
|
||||||
|
|
||||||
folioq = iov_kunit_create_folioq(test);
|
folioq = iov_kunit_create_folioq(test);
|
||||||
|
|
@ -1190,7 +1190,7 @@ static void __init iov_kunit_iter_to_sg_xarray(struct kunit *test)
|
||||||
struct iov_iter iter;
|
struct iov_iter iter;
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
|
|
||||||
bufsize = 0x100000;
|
bufsize = 0x200000;
|
||||||
iov_kunit_iter_to_sg_init(test, bufsize, false, &data);
|
iov_kunit_iter_to_sg_init(test, bufsize, false, &data);
|
||||||
|
|
||||||
xarray = iov_kunit_create_xarray(test);
|
xarray = iov_kunit_create_xarray(test);
|
||||||
|
|
@ -1206,7 +1206,7 @@ static void __init iov_kunit_iter_to_sg_ubuf(struct kunit *test)
|
||||||
struct iov_iter iter;
|
struct iov_iter iter;
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
|
|
||||||
bufsize = 0x100000;
|
bufsize = 0x200000;
|
||||||
iov_kunit_iter_to_sg_init(test, bufsize, true, &data);
|
iov_kunit_iter_to_sg_init(test, bufsize, true, &data);
|
||||||
|
|
||||||
iov_iter_ubuf(&iter, READ, data.ubuf, bufsize);
|
iov_iter_ubuf(&iter, READ, data.ubuf, bufsize);
|
||||||
|
|
|
||||||
|
|
@ -2594,6 +2594,7 @@ static int damon_sysfs_memcg_path_to_id(char *memcg_path, u64 *id)
|
||||||
if (damon_sysfs_memcg_path_eq(memcg, path, memcg_path)) {
|
if (damon_sysfs_memcg_path_eq(memcg, path, memcg_path)) {
|
||||||
*id = mem_cgroup_id(memcg);
|
*id = mem_cgroup_id(memcg);
|
||||||
found = true;
|
found = true;
|
||||||
|
mem_cgroup_iter_break(NULL, memcg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
24
mm/memory.c
24
mm/memory.c
|
|
@ -612,6 +612,21 @@ static void print_bad_page_map(struct vm_area_struct *vma,
|
||||||
dump_stack();
|
dump_stack();
|
||||||
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
|
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool pgtable_level_has_pxx_special(enum pgtable_level level)
|
||||||
|
{
|
||||||
|
switch (level) {
|
||||||
|
case PGTABLE_LEVEL_PTE:
|
||||||
|
return IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL);
|
||||||
|
case PGTABLE_LEVEL_PMD:
|
||||||
|
return IS_ENABLED(CONFIG_ARCH_SUPPORTS_PMD_PFNMAP);
|
||||||
|
case PGTABLE_LEVEL_PUD:
|
||||||
|
return IS_ENABLED(CONFIG_ARCH_SUPPORTS_PUD_PFNMAP);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define print_bad_pte(vma, addr, pte, page) \
|
#define print_bad_pte(vma, addr, pte, page) \
|
||||||
print_bad_page_map(vma, addr, pte_val(pte), page, PGTABLE_LEVEL_PTE)
|
print_bad_page_map(vma, addr, pte_val(pte), page, PGTABLE_LEVEL_PTE)
|
||||||
|
|
||||||
|
|
@ -684,7 +699,7 @@ static inline struct page *__vm_normal_page(struct vm_area_struct *vma,
|
||||||
unsigned long addr, unsigned long pfn, bool special,
|
unsigned long addr, unsigned long pfn, bool special,
|
||||||
unsigned long long entry, enum pgtable_level level)
|
unsigned long long entry, enum pgtable_level level)
|
||||||
{
|
{
|
||||||
if (IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL)) {
|
if (pgtable_level_has_pxx_special(level)) {
|
||||||
if (unlikely(special)) {
|
if (unlikely(special)) {
|
||||||
#ifdef CONFIG_FIND_NORMAL_PAGE
|
#ifdef CONFIG_FIND_NORMAL_PAGE
|
||||||
if (vma->vm_ops && vma->vm_ops->find_normal_page)
|
if (vma->vm_ops && vma->vm_ops->find_normal_page)
|
||||||
|
|
@ -699,8 +714,9 @@ static inline struct page *__vm_normal_page(struct vm_area_struct *vma,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* With CONFIG_ARCH_HAS_PTE_SPECIAL, any special page table
|
* With working pte_special()/pmd_special()..., any special page
|
||||||
* mappings (incl. shared zero folios) are marked accordingly.
|
* table mappings (incl. shared zero folios) are marked
|
||||||
|
* accordingly.
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
if (unlikely(vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))) {
|
if (unlikely(vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))) {
|
||||||
|
|
@ -1739,7 +1755,7 @@ static inline int zap_nonpresent_ptes(struct mmu_gather *tlb,
|
||||||
* consider uffd-wp bit when zap. For more information,
|
* consider uffd-wp bit when zap. For more information,
|
||||||
* see zap_install_uffd_wp_if_needed().
|
* see zap_install_uffd_wp_if_needed().
|
||||||
*/
|
*/
|
||||||
WARN_ON_ONCE(!vma_is_anonymous(vma));
|
WARN_ON_ONCE(!folio_test_anon(folio));
|
||||||
rss[mm_counter(folio)]--;
|
rss[mm_counter(folio)]--;
|
||||||
folio_remove_rmap_pte(folio, page, vma);
|
folio_remove_rmap_pte(folio, page, vma);
|
||||||
folio_put(folio);
|
folio_put(folio);
|
||||||
|
|
|
||||||
|
|
@ -1422,6 +1422,8 @@ static void remove_memory_blocks_and_altmaps(u64 start, u64 size)
|
||||||
|
|
||||||
altmap = mem->altmap;
|
altmap = mem->altmap;
|
||||||
mem->altmap = NULL;
|
mem->altmap = NULL;
|
||||||
|
/* drop the ref. we got via find_memory_block() */
|
||||||
|
put_device(&mem->dev);
|
||||||
|
|
||||||
remove_memory_block_devices(cur_start, memblock_size);
|
remove_memory_block_devices(cur_start, memblock_size);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -850,7 +850,7 @@ static int migrate_vma_insert_huge_pmd_page(struct migrate_vma *migrate,
|
||||||
ptl = pmd_lock(vma->vm_mm, pmdp);
|
ptl = pmd_lock(vma->vm_mm, pmdp);
|
||||||
csa_ret = check_stable_address_space(vma->vm_mm);
|
csa_ret = check_stable_address_space(vma->vm_mm);
|
||||||
if (csa_ret)
|
if (csa_ret)
|
||||||
goto abort;
|
goto unlock_abort;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for userfaultfd but do not deliver the fault. Instead,
|
* Check for userfaultfd but do not deliver the fault. Instead,
|
||||||
|
|
|
||||||
|
|
@ -1808,9 +1808,9 @@ static inline bool should_skip_init(gfp_t flags)
|
||||||
inline void post_alloc_hook(struct page *page, unsigned int order,
|
inline void post_alloc_hook(struct page *page, unsigned int order,
|
||||||
gfp_t gfp_flags)
|
gfp_t gfp_flags)
|
||||||
{
|
{
|
||||||
|
const bool zero_tags = gfp_flags & __GFP_ZEROTAGS;
|
||||||
bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags) &&
|
bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags) &&
|
||||||
!should_skip_init(gfp_flags);
|
!should_skip_init(gfp_flags);
|
||||||
bool zero_tags = init && (gfp_flags & __GFP_ZEROTAGS);
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
set_page_private(page, 0);
|
set_page_private(page, 0);
|
||||||
|
|
@ -1832,11 +1832,11 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If memory tags should be zeroed
|
* Clearing tags can efficiently clear the memory for us as well, if
|
||||||
* (which happens only when memory should be initialized as well).
|
* required.
|
||||||
*/
|
*/
|
||||||
if (zero_tags)
|
if (zero_tags)
|
||||||
init = !tag_clear_highpages(page, 1 << order);
|
init = tag_clear_highpages(page, 1 << order, /* clear_pages= */init);
|
||||||
|
|
||||||
if (!should_skip_kasan_unpoison(gfp_flags) &&
|
if (!should_skip_kasan_unpoison(gfp_flags) &&
|
||||||
kasan_unpoison_pages(page, order, init)) {
|
kasan_unpoison_pages(page, order, init)) {
|
||||||
|
|
|
||||||
|
|
@ -40,11 +40,11 @@ class x86_page_ops():
|
||||||
|
|
||||||
self.PAGE_OFFSET = int(gdb.parse_and_eval("page_offset_base"))
|
self.PAGE_OFFSET = int(gdb.parse_and_eval("page_offset_base"))
|
||||||
self.VMEMMAP_START = int(gdb.parse_and_eval("vmemmap_base"))
|
self.VMEMMAP_START = int(gdb.parse_and_eval("vmemmap_base"))
|
||||||
self.PHYS_BASE = int(gdb.parse_and_eval("phys_base"))
|
self.PHYS_BASE = int(gdb.parse_and_eval("(unsigned long) phys_base"))
|
||||||
self.START_KERNEL_map = 0xffffffff80000000
|
self.START_KERNEL_map = 0xffffffff80000000
|
||||||
|
|
||||||
self.KERNEL_START = gdb.parse_and_eval("_text")
|
self.KERNEL_START = gdb.parse_and_eval("(unsigned long) &_text")
|
||||||
self.KERNEL_END = gdb.parse_and_eval("_end")
|
self.KERNEL_END = gdb.parse_and_eval("(unsigned long) &_end")
|
||||||
|
|
||||||
self.VMALLOC_START = int(gdb.parse_and_eval("vmalloc_base"))
|
self.VMALLOC_START = int(gdb.parse_and_eval("vmalloc_base"))
|
||||||
if self.VMALLOC_START == 0xffffc90000000000:
|
if self.VMALLOC_START == 0xffffc90000000000:
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ def slabtrace(alloc, cache_name):
|
||||||
|
|
||||||
if target_cache['flags'] & SLAB_STORE_USER:
|
if target_cache['flags'] & SLAB_STORE_USER:
|
||||||
for i in range(0, nr_node_ids):
|
for i in range(0, nr_node_ids):
|
||||||
cache_node = target_cache['node'][i]
|
cache_node = target_cache['per_node']['node'][i]
|
||||||
if cache_node['nr_slabs']['counter'] == 0:
|
if cache_node['nr_slabs']['counter'] == 0:
|
||||||
continue
|
continue
|
||||||
process_slab(loc_track, cache_node['partial'], alloc, target_cache)
|
process_slab(loc_track, cache_node['partial'], alloc, target_cache)
|
||||||
|
|
@ -300,7 +300,7 @@ def slabinfo():
|
||||||
nr_free = 0
|
nr_free = 0
|
||||||
nr_slabs = 0
|
nr_slabs = 0
|
||||||
for i in range(0, nr_node_ids):
|
for i in range(0, nr_node_ids):
|
||||||
cache_node = cache['node'][i]
|
cache_node = cache['per_node']['node'][i]
|
||||||
try:
|
try:
|
||||||
nr_slabs += cache_node['nr_slabs']['counter']
|
nr_slabs += cache_node['nr_slabs']['counter']
|
||||||
nr_objs = int(cache_node['total_objects']['counter'])
|
nr_objs = int(cache_node['total_objects']['counter'])
|
||||||
|
|
|
||||||
|
|
@ -985,6 +985,56 @@ TEST_F(hmm, migrate)
|
||||||
hmm_buffer_free(buffer);
|
hmm_buffer_free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Migrate private file memory to device private memory.
|
||||||
|
*/
|
||||||
|
TEST_F(hmm, migrate_file_private)
|
||||||
|
{
|
||||||
|
struct hmm_buffer *buffer;
|
||||||
|
unsigned long npages;
|
||||||
|
unsigned long size;
|
||||||
|
unsigned long i;
|
||||||
|
int *ptr;
|
||||||
|
int ret;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
|
||||||
|
ASSERT_NE(npages, 0);
|
||||||
|
size = npages << self->page_shift;
|
||||||
|
|
||||||
|
fd = hmm_create_file(size);
|
||||||
|
ASSERT_GE(fd, 0);
|
||||||
|
|
||||||
|
buffer = malloc(sizeof(*buffer));
|
||||||
|
ASSERT_NE(buffer, NULL);
|
||||||
|
|
||||||
|
buffer->fd = fd;
|
||||||
|
buffer->size = size;
|
||||||
|
buffer->mirror = malloc(size);
|
||||||
|
ASSERT_NE(buffer->mirror, NULL);
|
||||||
|
|
||||||
|
buffer->ptr = mmap(NULL, size,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE,
|
||||||
|
buffer->fd, 0);
|
||||||
|
ASSERT_NE(buffer->ptr, MAP_FAILED);
|
||||||
|
|
||||||
|
/* Initialize buffer in system memory. */
|
||||||
|
for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
|
||||||
|
ptr[i] = i;
|
||||||
|
|
||||||
|
/* Migrate memory to device. */
|
||||||
|
ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(buffer->cpages, npages);
|
||||||
|
|
||||||
|
/* Check what the device read. */
|
||||||
|
for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
|
||||||
|
ASSERT_EQ(ptr[i], i);
|
||||||
|
|
||||||
|
hmm_buffer_free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Migrate anonymous memory to device private memory and fault some of it back
|
* Migrate anonymous memory to device private memory and fault some of it back
|
||||||
* to system memory, then try migrating the resulting mix of system and device
|
* to system memory, then try migrating the resulting mix of system and device
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ RUN_ALL=false
|
||||||
RUN_DESTRUCTIVE=false
|
RUN_DESTRUCTIVE=false
|
||||||
TAP_PREFIX="# "
|
TAP_PREFIX="# "
|
||||||
|
|
||||||
while getopts "aht:n" OPT; do
|
while getopts "aht:nd" OPT; do
|
||||||
case ${OPT} in
|
case ${OPT} in
|
||||||
"a") RUN_ALL=true ;;
|
"a") RUN_ALL=true ;;
|
||||||
"h") usage ;;
|
"h") usage ;;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue