13 hotfixes, 7 are cc:stable.
All are MM related apart from a MAINTAINERS update. There is no identifiable theme here - just singleton patches in various places. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCZnyyJAAKCRDdBJ7gKXxA jkcPAQDEsU/erozYjwo2Qq+B03micPCNGLJ6M4pG5t57snwnngEAkQClTiUCjmgK Xb0H1KkV8ZJUt1gBUnlODXDSf1bhsAE= =Uj0R -----END PGP SIGNATURE----- Merge tag 'mm-hotfixes-stable-2024-06-26-17-28' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull misc fixes from Andrew Morton: "13 hotfixes, 7 are cc:stable. All are MM related apart from a MAINTAINERS update. There is no identifiable theme here - just singleton patches in various places" * tag 'mm-hotfixes-stable-2024-06-26-17-28' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mm/memory: don't require head page for do_set_pmd() mm/page_alloc: Separate THP PCP into movable and non-movable categories nfs: drop the incorrect assertion in nfs_swap_rw() mm/migrate: make migrate_pages_batch() stats consistent MAINTAINERS: TPM DEVICE DRIVER: update the W-tag selftests/mm:fix test_prctl_fork_exec return failure mm: convert page type macros to enum ocfs2: fix DIO failure due to insufficient transaction credits kasan: fix bad call to unpoison_slab_object mm: handle profiling for fake memory allocations during compaction mm/slab: fix 'variable obj_exts set but not used' warning /proc/pid/smaps: add mseal info for vma mm: fix incorrect vbq reference in purge_fragmented_block
This commit is contained in:
commit
afcd48134c
@ -571,6 +571,7 @@ encoded manner. The codes are the following:
|
||||
um userfaultfd missing tracking
|
||||
uw userfaultfd wr-protect tracking
|
||||
ss shadow stack page
|
||||
sl sealed
|
||||
== =======================================
|
||||
|
||||
Note that there is no guarantee that every flag and associated mnemonic will
|
||||
|
@ -22745,7 +22745,7 @@ M: Jarkko Sakkinen <jarkko@kernel.org>
|
||||
R: Jason Gunthorpe <jgg@ziepe.ca>
|
||||
L: linux-integrity@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://gitlab.com/jarkkojs/linux-tpmdd-test
|
||||
W: https://codeberg.org/jarkko/linux-tpmdd-test
|
||||
Q: https://patchwork.kernel.org/project/linux-integrity/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git
|
||||
F: Documentation/devicetree/bindings/tpm/
|
||||
|
@ -141,8 +141,6 @@ int nfs_swap_rw(struct kiocb *iocb, struct iov_iter *iter)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE);
|
||||
|
||||
if (iov_iter_rw(iter) == READ)
|
||||
ret = nfs_file_direct_read(iocb, iter, true);
|
||||
else
|
||||
|
@ -2366,6 +2366,11 @@ static int ocfs2_dio_end_io_write(struct inode *inode,
|
||||
}
|
||||
|
||||
list_for_each_entry(ue, &dwc->dw_zero_list, ue_node) {
|
||||
ret = ocfs2_assure_trans_credits(handle, credits);
|
||||
if (ret < 0) {
|
||||
mlog_errno(ret);
|
||||
break;
|
||||
}
|
||||
ret = ocfs2_mark_extent_written(inode, &et, handle,
|
||||
ue->ue_cpos, 1,
|
||||
ue->ue_phys,
|
||||
|
@ -445,6 +445,23 @@ bail:
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure handle has at least 'nblocks' credits available. If it does not
|
||||
* have that many credits available, we will try to extend the handle to have
|
||||
* enough credits. If that fails, we will restart transaction to have enough
|
||||
* credits. Similar notes regarding data consistency and locking implications
|
||||
* as for ocfs2_extend_trans() apply here.
|
||||
*/
|
||||
int ocfs2_assure_trans_credits(handle_t *handle, int nblocks)
|
||||
{
|
||||
int old_nblks = jbd2_handle_buffer_credits(handle);
|
||||
|
||||
trace_ocfs2_assure_trans_credits(old_nblks);
|
||||
if (old_nblks >= nblocks)
|
||||
return 0;
|
||||
return ocfs2_extend_trans(handle, nblocks - old_nblks);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have fewer than thresh credits, extend by OCFS2_MAX_TRANS_DATA.
|
||||
* If that fails, restart the transaction & regain write access for the
|
||||
|
@ -243,6 +243,8 @@ handle_t *ocfs2_start_trans(struct ocfs2_super *osb,
|
||||
int ocfs2_commit_trans(struct ocfs2_super *osb,
|
||||
handle_t *handle);
|
||||
int ocfs2_extend_trans(handle_t *handle, int nblocks);
|
||||
int ocfs2_assure_trans_credits(handle_t *handle,
|
||||
int nblocks);
|
||||
int ocfs2_allocate_extend_trans(handle_t *handle,
|
||||
int thresh);
|
||||
|
||||
|
@ -2577,6 +2577,8 @@ DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_commit_cache_end);
|
||||
|
||||
DEFINE_OCFS2_INT_INT_EVENT(ocfs2_extend_trans);
|
||||
|
||||
DEFINE_OCFS2_INT_EVENT(ocfs2_assure_trans_credits);
|
||||
|
||||
DEFINE_OCFS2_INT_EVENT(ocfs2_extend_trans_restart);
|
||||
|
||||
DEFINE_OCFS2_INT_INT_EVENT(ocfs2_allocate_extend_trans);
|
||||
|
@ -706,6 +706,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
|
||||
#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
|
||||
#ifdef CONFIG_X86_USER_SHADOW_STACK
|
||||
[ilog2(VM_SHADOW_STACK)] = "ss",
|
||||
#endif
|
||||
#ifdef CONFIG_64BIT
|
||||
[ilog2(VM_SEALED)] = "sl",
|
||||
#endif
|
||||
};
|
||||
size_t i;
|
||||
|
@ -406,6 +406,11 @@ extern unsigned int kobjsize(const void *objp);
|
||||
#define VM_ALLOW_ANY_UNCACHED VM_NONE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
/* VM is sealed, in vm_flags */
|
||||
#define VM_SEALED _BITUL(63)
|
||||
#endif
|
||||
|
||||
/* Bits set in the VMA until the stack is in its final location */
|
||||
#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
|
||||
|
||||
|
@ -654,13 +654,12 @@ enum zone_watermarks {
|
||||
};
|
||||
|
||||
/*
|
||||
* One per migratetype for each PAGE_ALLOC_COSTLY_ORDER. One additional list
|
||||
* for THP which will usually be GFP_MOVABLE. Even if it is another type,
|
||||
* it should not contribute to serious fragmentation causing THP allocation
|
||||
* failures.
|
||||
* One per migratetype for each PAGE_ALLOC_COSTLY_ORDER. Two additional lists
|
||||
* are added for THP. One PCP list is used by GPF_MOVABLE, and the other PCP list
|
||||
* is used by GFP_UNMOVABLE and GFP_RECLAIMABLE.
|
||||
*/
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
#define NR_PCP_THP 1
|
||||
#define NR_PCP_THP 2
|
||||
#else
|
||||
#define NR_PCP_THP 0
|
||||
#endif
|
||||
|
@ -944,15 +944,18 @@ PAGEFLAG_FALSE(HasHWPoisoned, has_hwpoisoned)
|
||||
* mistaken for a page type value.
|
||||
*/
|
||||
|
||||
#define PAGE_TYPE_BASE 0xf0000000
|
||||
/* Reserve 0x0000007f to catch underflows of _mapcount */
|
||||
#define PAGE_MAPCOUNT_RESERVE -128
|
||||
#define PG_buddy 0x00000080
|
||||
#define PG_offline 0x00000100
|
||||
#define PG_table 0x00000200
|
||||
#define PG_guard 0x00000400
|
||||
#define PG_hugetlb 0x00000800
|
||||
#define PG_slab 0x00001000
|
||||
enum pagetype {
|
||||
PG_buddy = 0x00000080,
|
||||
PG_offline = 0x00000100,
|
||||
PG_table = 0x00000200,
|
||||
PG_guard = 0x00000400,
|
||||
PG_hugetlb = 0x00000800,
|
||||
PG_slab = 0x00001000,
|
||||
|
||||
PAGE_TYPE_BASE = 0xf0000000,
|
||||
/* Reserve 0x0000007f to catch underflows of _mapcount */
|
||||
PAGE_MAPCOUNT_RESERVE = -128,
|
||||
};
|
||||
|
||||
#define PageType(page, flag) \
|
||||
((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
|
||||
|
@ -79,6 +79,13 @@ static inline bool is_via_compact_memory(int order) { return false; }
|
||||
#define COMPACTION_HPAGE_ORDER (PMD_SHIFT - PAGE_SHIFT)
|
||||
#endif
|
||||
|
||||
static struct page *mark_allocated_noprof(struct page *page, unsigned int order, gfp_t gfp_flags)
|
||||
{
|
||||
post_alloc_hook(page, order, __GFP_MOVABLE);
|
||||
return page;
|
||||
}
|
||||
#define mark_allocated(...) alloc_hooks(mark_allocated_noprof(__VA_ARGS__))
|
||||
|
||||
static void split_map_pages(struct list_head *freepages)
|
||||
{
|
||||
unsigned int i, order;
|
||||
@ -93,7 +100,7 @@ static void split_map_pages(struct list_head *freepages)
|
||||
|
||||
nr_pages = 1 << order;
|
||||
|
||||
post_alloc_hook(page, order, __GFP_MOVABLE);
|
||||
mark_allocated(page, order, __GFP_MOVABLE);
|
||||
if (order)
|
||||
split_page(page, order);
|
||||
|
||||
@ -122,7 +129,7 @@ static unsigned long release_free_list(struct list_head *freepages)
|
||||
* Convert free pages into post allocation pages, so
|
||||
* that we can free them via __free_page.
|
||||
*/
|
||||
post_alloc_hook(page, order, __GFP_MOVABLE);
|
||||
mark_allocated(page, order, __GFP_MOVABLE);
|
||||
__free_pages(page, order);
|
||||
if (pfn > high_pfn)
|
||||
high_pfn = pfn;
|
||||
|
@ -1434,11 +1434,6 @@ void __meminit __init_single_page(struct page *page, unsigned long pfn,
|
||||
unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct mem_cgroup *memcg,
|
||||
int priority);
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
/* VM is sealed, in vm_flags */
|
||||
#define VM_SEALED _BITUL(63)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
static inline int can_do_mseal(unsigned long flags)
|
||||
{
|
||||
|
@ -532,7 +532,7 @@ void __kasan_mempool_unpoison_object(void *ptr, size_t size, unsigned long ip)
|
||||
return;
|
||||
|
||||
/* Unpoison the object and save alloc info for non-kmalloc() allocations. */
|
||||
unpoison_slab_object(slab->slab_cache, ptr, size, flags);
|
||||
unpoison_slab_object(slab->slab_cache, ptr, flags, false);
|
||||
|
||||
/* Poison the redzone and save alloc info for kmalloc() allocations. */
|
||||
if (is_kmalloc_cache(slab->slab_cache))
|
||||
|
@ -4608,8 +4608,9 @@ vm_fault_t do_set_pmd(struct vm_fault *vmf, struct page *page)
|
||||
if (!thp_vma_suitable_order(vma, haddr, PMD_ORDER))
|
||||
return ret;
|
||||
|
||||
if (page != &folio->page || folio_order(folio) != HPAGE_PMD_ORDER)
|
||||
if (folio_order(folio) != HPAGE_PMD_ORDER)
|
||||
return ret;
|
||||
page = &folio->page;
|
||||
|
||||
/*
|
||||
* Just backoff if any subpage of a THP is corrupted otherwise
|
||||
|
@ -1659,6 +1659,10 @@ static int migrate_pages_batch(struct list_head *from,
|
||||
* migrate_pages() may report success with (split but
|
||||
* unmigrated) pages still on its fromlist; whereas it
|
||||
* always reports success when its fromlist is empty.
|
||||
* stats->nr_thp_failed should be increased too,
|
||||
* otherwise stats inconsistency will happen when
|
||||
* migrate_pages_batch is called via migrate_pages()
|
||||
* with MIGRATE_SYNC and MIGRATE_ASYNC.
|
||||
*
|
||||
* Only check it without removing it from the list.
|
||||
* Since the folio can be on deferred_split_scan()
|
||||
@ -1675,6 +1679,7 @@ static int migrate_pages_batch(struct list_head *from,
|
||||
!list_empty(&folio->_deferred_list)) {
|
||||
if (try_split_folio(folio, split_folios) == 0) {
|
||||
nr_failed++;
|
||||
stats->nr_thp_failed += is_thp;
|
||||
stats->nr_thp_split += is_thp;
|
||||
stats->nr_split++;
|
||||
continue;
|
||||
|
@ -504,10 +504,15 @@ out:
|
||||
|
||||
static inline unsigned int order_to_pindex(int migratetype, int order)
|
||||
{
|
||||
bool __maybe_unused movable;
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
if (order > PAGE_ALLOC_COSTLY_ORDER) {
|
||||
VM_BUG_ON(order != HPAGE_PMD_ORDER);
|
||||
return NR_LOWORDER_PCP_LISTS;
|
||||
|
||||
movable = migratetype == MIGRATE_MOVABLE;
|
||||
|
||||
return NR_LOWORDER_PCP_LISTS + movable;
|
||||
}
|
||||
#else
|
||||
VM_BUG_ON(order > PAGE_ALLOC_COSTLY_ORDER);
|
||||
@ -521,7 +526,7 @@ static inline int pindex_to_order(unsigned int pindex)
|
||||
int order = pindex / MIGRATE_PCPTYPES;
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
if (pindex == NR_LOWORDER_PCP_LISTS)
|
||||
if (pindex >= NR_LOWORDER_PCP_LISTS)
|
||||
order = HPAGE_PMD_ORDER;
|
||||
#else
|
||||
VM_BUG_ON(order > PAGE_ALLOC_COSTLY_ORDER);
|
||||
|
@ -3902,7 +3902,6 @@ bool slab_post_alloc_hook(struct kmem_cache *s, struct list_lru *lru,
|
||||
unsigned int orig_size)
|
||||
{
|
||||
unsigned int zero_size = s->object_size;
|
||||
struct slabobj_ext *obj_exts;
|
||||
bool kasan_init = init;
|
||||
size_t i;
|
||||
gfp_t init_flags = flags & gfp_allowed_mask;
|
||||
@ -3945,9 +3944,11 @@ bool slab_post_alloc_hook(struct kmem_cache *s, struct list_lru *lru,
|
||||
kmemleak_alloc_recursive(p[i], s->object_size, 1,
|
||||
s->flags, init_flags);
|
||||
kmsan_slab_alloc(s, p[i], init_flags);
|
||||
if (need_slab_obj_ext()) {
|
||||
obj_exts = prepare_slab_obj_exts_hook(s, flags, p[i]);
|
||||
#ifdef CONFIG_MEM_ALLOC_PROFILING
|
||||
if (need_slab_obj_ext()) {
|
||||
struct slabobj_ext *obj_exts;
|
||||
|
||||
obj_exts = prepare_slab_obj_exts_hook(s, flags, p[i]);
|
||||
/*
|
||||
* Currently obj_exts is used only for allocation profiling.
|
||||
* If other users appear then mem_alloc_profiling_enabled()
|
||||
@ -3955,8 +3956,8 @@ bool slab_post_alloc_hook(struct kmem_cache *s, struct list_lru *lru,
|
||||
*/
|
||||
if (likely(obj_exts))
|
||||
alloc_tag_add(&obj_exts->ref, current->alloc_tag, s->size);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return memcg_slab_post_alloc_hook(s, lru, flags, size, p);
|
||||
|
21
mm/vmalloc.c
21
mm/vmalloc.c
@ -2498,6 +2498,7 @@ struct vmap_block {
|
||||
struct list_head free_list;
|
||||
struct rcu_head rcu_head;
|
||||
struct list_head purge;
|
||||
unsigned int cpu;
|
||||
};
|
||||
|
||||
/* Queue of free and dirty vmap blocks, for allocation and flushing purposes */
|
||||
@ -2625,8 +2626,15 @@ static void *new_vmap_block(unsigned int order, gfp_t gfp_mask)
|
||||
free_vmap_area(va);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
vbq = raw_cpu_ptr(&vmap_block_queue);
|
||||
/*
|
||||
* list_add_tail_rcu could happened in another core
|
||||
* rather than vb->cpu due to task migration, which
|
||||
* is safe as list_add_tail_rcu will ensure the list's
|
||||
* integrity together with list_for_each_rcu from read
|
||||
* side.
|
||||
*/
|
||||
vb->cpu = raw_smp_processor_id();
|
||||
vbq = per_cpu_ptr(&vmap_block_queue, vb->cpu);
|
||||
spin_lock(&vbq->lock);
|
||||
list_add_tail_rcu(&vb->free_list, &vbq->free);
|
||||
spin_unlock(&vbq->lock);
|
||||
@ -2654,9 +2662,10 @@ static void free_vmap_block(struct vmap_block *vb)
|
||||
}
|
||||
|
||||
static bool purge_fragmented_block(struct vmap_block *vb,
|
||||
struct vmap_block_queue *vbq, struct list_head *purge_list,
|
||||
bool force_purge)
|
||||
struct list_head *purge_list, bool force_purge)
|
||||
{
|
||||
struct vmap_block_queue *vbq = &per_cpu(vmap_block_queue, vb->cpu);
|
||||
|
||||
if (vb->free + vb->dirty != VMAP_BBMAP_BITS ||
|
||||
vb->dirty == VMAP_BBMAP_BITS)
|
||||
return false;
|
||||
@ -2704,7 +2713,7 @@ static void purge_fragmented_blocks(int cpu)
|
||||
continue;
|
||||
|
||||
spin_lock(&vb->lock);
|
||||
purge_fragmented_block(vb, vbq, &purge, true);
|
||||
purge_fragmented_block(vb, &purge, true);
|
||||
spin_unlock(&vb->lock);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
@ -2841,7 +2850,7 @@ static void _vm_unmap_aliases(unsigned long start, unsigned long end, int flush)
|
||||
* not purgeable, check whether there is dirty
|
||||
* space to be flushed.
|
||||
*/
|
||||
if (!purge_fragmented_block(vb, vbq, &purge_list, false) &&
|
||||
if (!purge_fragmented_block(vb, &purge_list, false) &&
|
||||
vb->dirty_max && vb->dirty != VMAP_BBMAP_BITS) {
|
||||
unsigned long va_start = vb->va->va_start;
|
||||
unsigned long s, e;
|
||||
|
@ -656,24 +656,8 @@ unmap:
|
||||
munmap(map, size);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
static void init_global_file_handles(void)
|
||||
{
|
||||
unsigned int tests = 8;
|
||||
int err;
|
||||
|
||||
if (argc > 1 && !strcmp(argv[1], FORK_EXEC_CHILD_PRG_NAME)) {
|
||||
exit(test_child_ksm());
|
||||
}
|
||||
|
||||
#ifdef __NR_userfaultfd
|
||||
tests++;
|
||||
#endif
|
||||
|
||||
ksft_print_header();
|
||||
ksft_set_plan(tests);
|
||||
|
||||
pagesize = getpagesize();
|
||||
|
||||
mem_fd = open("/proc/self/mem", O_RDWR);
|
||||
if (mem_fd < 0)
|
||||
ksft_exit_fail_msg("opening /proc/self/mem failed\n");
|
||||
@ -688,8 +672,30 @@ int main(int argc, char **argv)
|
||||
ksft_exit_skip("open(\"/proc/self/pagemap\") failed\n");
|
||||
proc_self_ksm_stat_fd = open("/proc/self/ksm_stat", O_RDONLY);
|
||||
proc_self_ksm_merging_pages_fd = open("/proc/self/ksm_merging_pages",
|
||||
O_RDONLY);
|
||||
O_RDONLY);
|
||||
ksm_use_zero_pages_fd = open("/sys/kernel/mm/ksm/use_zero_pages", O_RDWR);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned int tests = 8;
|
||||
int err;
|
||||
|
||||
if (argc > 1 && !strcmp(argv[1], FORK_EXEC_CHILD_PRG_NAME)) {
|
||||
init_global_file_handles();
|
||||
exit(test_child_ksm());
|
||||
}
|
||||
|
||||
#ifdef __NR_userfaultfd
|
||||
tests++;
|
||||
#endif
|
||||
|
||||
ksft_print_header();
|
||||
ksft_set_plan(tests);
|
||||
|
||||
pagesize = getpagesize();
|
||||
|
||||
init_global_file_handles();
|
||||
|
||||
test_unmerge();
|
||||
test_unmerge_zero_pages();
|
||||
|
Loading…
x
Reference in New Issue
Block a user