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:
Linus Torvalds 2024-06-26 17:51:39 -07:00
commit afcd48134c
20 changed files with 120 additions and 56 deletions

View File

@ -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

View File

@ -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/

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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)
{

View File

@ -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))

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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();