15 hotfixes. 6 are cc:stable. 14 are for MM.
Singletons, with one doubleton - please see the changelogs for details. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCaa9ZkgAKCRDdBJ7gKXxA jpfeAQDAj+Sn3bRdJWCUVNgWPdNLrmZnZRw5VdipioAnfmZHZQEAqBXnm7ehn1BA JgQvx6zTlsyqy4FhW+Q6uLmBpKmMTQw= =kbLH -----END PGP SIGNATURE----- Merge tag 'mm-hotfixes-stable-2026-03-09-16-36' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull misc fixes from Andrew Morton: "15 hotfixes. 6 are cc:stable. 14 are for MM. Singletons, with one doubleton - please see the changelogs for details" * tag 'mm-hotfixes-stable-2026-03-09-16-36' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: MAINTAINERS, mailmap: update email address for Lorenzo Stoakes mm/mmu_notifier: clean up mmu_notifier.h kernel-doc uaccess: correct kernel-doc parameter format mm/huge_memory: fix a folio_split() race condition with folio_try_get() MAINTAINERS: add co-maintainer and reviewer for SLAB ALLOCATOR MAINTAINERS: add RELAY entry memcg: fix slab accounting in refill_obj_stock() trylock path mm/hugetlb.c: use __pa() instead of virt_to_phys() in early bootmem alloc code zram: rename writeback_compressed device attr tools/testing: fix testing/vma and testing/radix-tree build Revert "ptdesc: remove references to folios from __pagetable_ctor() and pagetable_dtor()" mm/cma: move put_page_testzero() out of VM_WARN_ON in cma_release() mm/damon/core: clear walk_control on inactive context in damos_walk() mm: memfd_luo: always dirty all folios mm: memfd_luo: always make all folios uptodate
This commit is contained in:
commit
b4f0dd314b
3
.mailmap
3
.mailmap
|
|
@ -498,7 +498,8 @@ Lior David <quic_liord@quicinc.com> <liord@codeaurora.org>
|
|||
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@linaro.org>
|
||||
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@intel.com>
|
||||
Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com>
|
||||
Lorenzo Stoakes <lorenzo.stoakes@oracle.com> <lstoakes@gmail.com>
|
||||
Lorenzo Stoakes <ljs@kernel.org> <lstoakes@gmail.com>
|
||||
Lorenzo Stoakes <ljs@kernel.org> <lorenzo.stoakes@oracle.com>
|
||||
Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net>
|
||||
Luca Weiss <luca@lucaweiss.eu> <luca@z3ntu.xyz>
|
||||
Lucas De Marchi <demarchi@kernel.org> <lucas.demarchi@intel.com>
|
||||
|
|
|
|||
|
|
@ -151,11 +151,11 @@ Description:
|
|||
The algorithm_params file is write-only and is used to setup
|
||||
compression algorithm parameters.
|
||||
|
||||
What: /sys/block/zram<id>/writeback_compressed
|
||||
What: /sys/block/zram<id>/compressed_writeback
|
||||
Date: Decemeber 2025
|
||||
Contact: Richard Chang <richardycc@google.com>
|
||||
Description:
|
||||
The writeback_compressed device atrribute toggles compressed
|
||||
The compressed_writeback device atrribute toggles compressed
|
||||
writeback feature.
|
||||
|
||||
What: /sys/block/zram<id>/writeback_batch_size
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ writeback_limit WO specifies the maximum amount of write IO zram
|
|||
writeback_limit_enable RW show and set writeback_limit feature
|
||||
writeback_batch_size RW show and set maximum number of in-flight
|
||||
writeback operations
|
||||
writeback_compressed RW show and set compressed writeback feature
|
||||
compressed_writeback RW show and set compressed writeback feature
|
||||
comp_algorithm RW show and change the compression algorithm
|
||||
algorithm_params WO setup compression algorithm parameters
|
||||
compact WO trigger memory compaction
|
||||
|
|
@ -439,11 +439,11 @@ budget in next setting is user's job.
|
|||
By default zram stores written back pages in decompressed (raw) form, which
|
||||
means that writeback operation involves decompression of the page before
|
||||
writing it to the backing device. This behavior can be changed by enabling
|
||||
`writeback_compressed` feature, which causes zram to write compressed pages
|
||||
`compressed_writeback` feature, which causes zram to write compressed pages
|
||||
to the backing device, thus avoiding decompression overhead. To enable
|
||||
this feature, execute::
|
||||
|
||||
$ echo yes > /sys/block/zramX/writeback_compressed
|
||||
$ echo yes > /sys/block/zramX/compressed_writeback
|
||||
|
||||
Note that this feature should be configured before the `zramX` device is
|
||||
initialized.
|
||||
|
|
|
|||
33
MAINTAINERS
33
MAINTAINERS
|
|
@ -16643,7 +16643,7 @@ F: mm/balloon.c
|
|||
MEMORY MANAGEMENT - CORE
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Mike Rapoport <rppt@kernel.org>
|
||||
|
|
@ -16773,7 +16773,7 @@ F: mm/workingset.c
|
|||
MEMORY MANAGEMENT - MISC
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Mike Rapoport <rppt@kernel.org>
|
||||
|
|
@ -16864,7 +16864,7 @@ R: David Hildenbrand <david@kernel.org>
|
|||
R: Michal Hocko <mhocko@kernel.org>
|
||||
R: Qi Zheng <zhengqi.arch@bytedance.com>
|
||||
R: Shakeel Butt <shakeel.butt@linux.dev>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: mm/vmscan.c
|
||||
|
|
@ -16873,7 +16873,7 @@ F: mm/workingset.c
|
|||
MEMORY MANAGEMENT - RMAP (REVERSE MAPPING)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Rik van Riel <riel@surriel.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
|
|
@ -16918,7 +16918,7 @@ F: mm/swapfile.c
|
|||
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Zi Yan <ziy@nvidia.com>
|
||||
R: Baolin Wang <baolin.wang@linux.alibaba.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
|
|
@ -16958,7 +16958,7 @@ F: tools/testing/selftests/mm/uffd-*.[ch]
|
|||
|
||||
MEMORY MANAGEMENT - RUST
|
||||
M: Alice Ryhl <aliceryhl@google.com>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
L: linux-mm@kvack.org
|
||||
L: rust-for-linux@vger.kernel.org
|
||||
|
|
@ -16974,7 +16974,7 @@ F: rust/kernel/page.rs
|
|||
MEMORY MAPPING
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
R: Pedro Falcato <pfalcato@suse.de>
|
||||
|
|
@ -17004,7 +17004,7 @@ MEMORY MAPPING - LOCKING
|
|||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Suren Baghdasaryan <surenb@google.com>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Shakeel Butt <shakeel.butt@linux.dev>
|
||||
L: linux-mm@kvack.org
|
||||
|
|
@ -17019,7 +17019,7 @@ F: mm/mmap_lock.c
|
|||
MEMORY MAPPING - MADVISE (MEMORY ADVICE)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
|
|
@ -22267,6 +22267,16 @@ L: linux-wireless@vger.kernel.org
|
|||
S: Orphan
|
||||
F: drivers/net/wireless/rsi/
|
||||
|
||||
RELAY
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Jens Axboe <axboe@kernel.dk>
|
||||
M: Jason Xing <kernelxing@tencent.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/filesystems/relay.rst
|
||||
F: include/linux/relay.h
|
||||
F: kernel/relay.c
|
||||
|
||||
REGISTER MAP ABSTRACTION
|
||||
M: Mark Brown <broonie@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
|
|
@ -23156,7 +23166,7 @@ K: \b(?i:rust)\b
|
|||
|
||||
RUST [ALLOC]
|
||||
M: Danilo Krummrich <dakr@kernel.org>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Uladzislau Rezki <urezki@gmail.com>
|
||||
|
|
@ -24333,11 +24343,12 @@ F: drivers/nvmem/layouts/sl28vpd.c
|
|||
|
||||
SLAB ALLOCATOR
|
||||
M: Vlastimil Babka <vbabka@kernel.org>
|
||||
M: Harry Yoo <harry.yoo@oracle.com>
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
R: Hao Li <hao.li@linux.dev>
|
||||
R: Christoph Lameter <cl@gentwo.org>
|
||||
R: David Rientjes <rientjes@google.com>
|
||||
R: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
R: Harry Yoo <harry.yoo@oracle.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git
|
||||
|
|
|
|||
|
|
@ -549,7 +549,7 @@ static ssize_t bd_stat_show(struct device *dev, struct device_attribute *attr,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t writeback_compressed_store(struct device *dev,
|
||||
static ssize_t compressed_writeback_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
|
|
@ -564,12 +564,12 @@ static ssize_t writeback_compressed_store(struct device *dev,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
zram->wb_compressed = val;
|
||||
zram->compressed_wb = val;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t writeback_compressed_show(struct device *dev,
|
||||
static ssize_t compressed_writeback_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
|
|
@ -577,7 +577,7 @@ static ssize_t writeback_compressed_show(struct device *dev,
|
|||
struct zram *zram = dev_to_zram(dev);
|
||||
|
||||
guard(rwsem_read)(&zram->dev_lock);
|
||||
val = zram->wb_compressed;
|
||||
val = zram->compressed_wb;
|
||||
|
||||
return sysfs_emit(buf, "%d\n", val);
|
||||
}
|
||||
|
|
@ -946,7 +946,7 @@ static int zram_writeback_complete(struct zram *zram, struct zram_wb_req *req)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (zram->wb_compressed) {
|
||||
if (zram->compressed_wb) {
|
||||
/*
|
||||
* ZRAM_WB slots get freed, we need to preserve data required
|
||||
* for read decompression.
|
||||
|
|
@ -960,7 +960,7 @@ static int zram_writeback_complete(struct zram *zram, struct zram_wb_req *req)
|
|||
set_slot_flag(zram, index, ZRAM_WB);
|
||||
set_slot_handle(zram, index, req->blk_idx);
|
||||
|
||||
if (zram->wb_compressed) {
|
||||
if (zram->compressed_wb) {
|
||||
if (huge)
|
||||
set_slot_flag(zram, index, ZRAM_HUGE);
|
||||
set_slot_size(zram, index, size);
|
||||
|
|
@ -1100,7 +1100,7 @@ static int zram_writeback_slots(struct zram *zram,
|
|||
*/
|
||||
if (!test_slot_flag(zram, index, ZRAM_PP_SLOT))
|
||||
goto next;
|
||||
if (zram->wb_compressed)
|
||||
if (zram->compressed_wb)
|
||||
err = read_from_zspool_raw(zram, req->page, index);
|
||||
else
|
||||
err = read_from_zspool(zram, req->page, index);
|
||||
|
|
@ -1429,7 +1429,7 @@ static void zram_async_read_endio(struct bio *bio)
|
|||
*
|
||||
* Keep the existing behavior for now.
|
||||
*/
|
||||
if (zram->wb_compressed == false) {
|
||||
if (zram->compressed_wb == false) {
|
||||
/* No decompression needed, complete the parent IO */
|
||||
bio_endio(req->parent);
|
||||
bio_put(bio);
|
||||
|
|
@ -1508,7 +1508,7 @@ static int read_from_bdev_sync(struct zram *zram, struct page *page, u32 index,
|
|||
flush_work(&req.work);
|
||||
destroy_work_on_stack(&req.work);
|
||||
|
||||
if (req.error || zram->wb_compressed == false)
|
||||
if (req.error || zram->compressed_wb == false)
|
||||
return req.error;
|
||||
|
||||
return decompress_bdev_page(zram, page, index);
|
||||
|
|
@ -3007,7 +3007,7 @@ static DEVICE_ATTR_WO(writeback);
|
|||
static DEVICE_ATTR_RW(writeback_limit);
|
||||
static DEVICE_ATTR_RW(writeback_limit_enable);
|
||||
static DEVICE_ATTR_RW(writeback_batch_size);
|
||||
static DEVICE_ATTR_RW(writeback_compressed);
|
||||
static DEVICE_ATTR_RW(compressed_writeback);
|
||||
#endif
|
||||
#ifdef CONFIG_ZRAM_MULTI_COMP
|
||||
static DEVICE_ATTR_RW(recomp_algorithm);
|
||||
|
|
@ -3031,7 +3031,7 @@ static struct attribute *zram_disk_attrs[] = {
|
|||
&dev_attr_writeback_limit.attr,
|
||||
&dev_attr_writeback_limit_enable.attr,
|
||||
&dev_attr_writeback_batch_size.attr,
|
||||
&dev_attr_writeback_compressed.attr,
|
||||
&dev_attr_compressed_writeback.attr,
|
||||
#endif
|
||||
&dev_attr_io_stat.attr,
|
||||
&dev_attr_mm_stat.attr,
|
||||
|
|
@ -3091,7 +3091,7 @@ static int zram_add(void)
|
|||
init_rwsem(&zram->dev_lock);
|
||||
#ifdef CONFIG_ZRAM_WRITEBACK
|
||||
zram->wb_batch_size = 32;
|
||||
zram->wb_compressed = false;
|
||||
zram->compressed_wb = false;
|
||||
#endif
|
||||
|
||||
/* gendisk structure */
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ struct zram {
|
|||
#ifdef CONFIG_ZRAM_WRITEBACK
|
||||
struct file *backing_dev;
|
||||
bool wb_limit_enable;
|
||||
bool wb_compressed;
|
||||
bool compressed_wb;
|
||||
u32 wb_batch_size;
|
||||
u64 bd_wb_limit;
|
||||
struct block_device *bdev;
|
||||
|
|
|
|||
|
|
@ -3514,26 +3514,21 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) { return true; }
|
|||
static inline void ptlock_free(struct ptdesc *ptdesc) {}
|
||||
#endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */
|
||||
|
||||
static inline unsigned long ptdesc_nr_pages(const struct ptdesc *ptdesc)
|
||||
{
|
||||
return compound_nr(ptdesc_page(ptdesc));
|
||||
}
|
||||
|
||||
static inline void __pagetable_ctor(struct ptdesc *ptdesc)
|
||||
{
|
||||
pg_data_t *pgdat = NODE_DATA(memdesc_nid(ptdesc->pt_flags));
|
||||
struct folio *folio = ptdesc_folio(ptdesc);
|
||||
|
||||
__SetPageTable(ptdesc_page(ptdesc));
|
||||
mod_node_page_state(pgdat, NR_PAGETABLE, ptdesc_nr_pages(ptdesc));
|
||||
__folio_set_pgtable(folio);
|
||||
lruvec_stat_add_folio(folio, NR_PAGETABLE);
|
||||
}
|
||||
|
||||
static inline void pagetable_dtor(struct ptdesc *ptdesc)
|
||||
{
|
||||
pg_data_t *pgdat = NODE_DATA(memdesc_nid(ptdesc->pt_flags));
|
||||
struct folio *folio = ptdesc_folio(ptdesc);
|
||||
|
||||
ptlock_free(ptdesc);
|
||||
__ClearPageTable(ptdesc_page(ptdesc));
|
||||
mod_node_page_state(pgdat, NR_PAGETABLE, -ptdesc_nr_pages(ptdesc));
|
||||
__folio_clear_pgtable(folio);
|
||||
lruvec_stat_sub_folio(folio, NR_PAGETABLE);
|
||||
}
|
||||
|
||||
static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ struct mmu_notifier {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct mmu_interval_notifier_ops
|
||||
* struct mmu_interval_notifier_ops - callback for range notification
|
||||
* @invalidate: Upon return the caller must stop using any SPTEs within this
|
||||
* range. This function can sleep. Return false only if sleeping
|
||||
* was required but mmu_notifier_range_blockable(range) is false.
|
||||
|
|
@ -309,8 +309,8 @@ void mmu_interval_notifier_remove(struct mmu_interval_notifier *interval_sub);
|
|||
|
||||
/**
|
||||
* mmu_interval_set_seq - Save the invalidation sequence
|
||||
* @interval_sub - The subscription passed to invalidate
|
||||
* @cur_seq - The cur_seq passed to the invalidate() callback
|
||||
* @interval_sub: The subscription passed to invalidate
|
||||
* @cur_seq: The cur_seq passed to the invalidate() callback
|
||||
*
|
||||
* This must be called unconditionally from the invalidate callback of a
|
||||
* struct mmu_interval_notifier_ops under the same lock that is used to call
|
||||
|
|
@ -329,8 +329,8 @@ mmu_interval_set_seq(struct mmu_interval_notifier *interval_sub,
|
|||
|
||||
/**
|
||||
* mmu_interval_read_retry - End a read side critical section against a VA range
|
||||
* interval_sub: The subscription
|
||||
* seq: The return of the paired mmu_interval_read_begin()
|
||||
* @interval_sub: The subscription
|
||||
* @seq: The return of the paired mmu_interval_read_begin()
|
||||
*
|
||||
* This MUST be called under a user provided lock that is also held
|
||||
* unconditionally by op->invalidate() when it calls mmu_interval_set_seq().
|
||||
|
|
@ -338,7 +338,7 @@ mmu_interval_set_seq(struct mmu_interval_notifier *interval_sub,
|
|||
* Each call should be paired with a single mmu_interval_read_begin() and
|
||||
* should be used to conclude the read side.
|
||||
*
|
||||
* Returns true if an invalidation collided with this critical section, and
|
||||
* Returns: true if an invalidation collided with this critical section, and
|
||||
* the caller should retry.
|
||||
*/
|
||||
static inline bool
|
||||
|
|
@ -350,20 +350,21 @@ mmu_interval_read_retry(struct mmu_interval_notifier *interval_sub,
|
|||
|
||||
/**
|
||||
* mmu_interval_check_retry - Test if a collision has occurred
|
||||
* interval_sub: The subscription
|
||||
* seq: The return of the matching mmu_interval_read_begin()
|
||||
* @interval_sub: The subscription
|
||||
* @seq: The return of the matching mmu_interval_read_begin()
|
||||
*
|
||||
* This can be used in the critical section between mmu_interval_read_begin()
|
||||
* and mmu_interval_read_retry(). A return of true indicates an invalidation
|
||||
* has collided with this critical region and a future
|
||||
* mmu_interval_read_retry() will return true.
|
||||
*
|
||||
* False is not reliable and only suggests a collision may not have
|
||||
* occurred. It can be called many times and does not have to hold the user
|
||||
* provided lock.
|
||||
* and mmu_interval_read_retry().
|
||||
*
|
||||
* This call can be used as part of loops and other expensive operations to
|
||||
* expedite a retry.
|
||||
* It can be called many times and does not have to hold the user
|
||||
* provided lock.
|
||||
*
|
||||
* Returns: true indicates an invalidation has collided with this critical
|
||||
* region and a future mmu_interval_read_retry() will return true.
|
||||
* False is not reliable and only suggests a collision may not have
|
||||
* occurred.
|
||||
*/
|
||||
static inline bool
|
||||
mmu_interval_check_retry(struct mmu_interval_notifier *interval_sub,
|
||||
|
|
|
|||
|
|
@ -792,7 +792,7 @@ for (bool done = false; !done; done = true) \
|
|||
|
||||
/**
|
||||
* scoped_user_rw_access_size - Start a scoped user read/write access with given size
|
||||
* @uptr Pointer to the user space address to read from and write to
|
||||
* @uptr: Pointer to the user space address to read from and write to
|
||||
* @size: Size of the access starting from @uptr
|
||||
* @elbl: Error label to goto when the access region is rejected
|
||||
*
|
||||
|
|
@ -803,7 +803,7 @@ for (bool done = false; !done; done = true) \
|
|||
|
||||
/**
|
||||
* scoped_user_rw_access - Start a scoped user read/write access
|
||||
* @uptr Pointer to the user space address to read from and write to
|
||||
* @uptr: Pointer to the user space address to read from and write to
|
||||
* @elbl: Error label to goto when the access region is rejected
|
||||
*
|
||||
* The size of the access starting from @uptr is determined via sizeof(*@uptr)).
|
||||
|
|
|
|||
5
mm/cma.c
5
mm/cma.c
|
|
@ -1013,6 +1013,7 @@ bool cma_release(struct cma *cma, const struct page *pages,
|
|||
unsigned long count)
|
||||
{
|
||||
struct cma_memrange *cmr;
|
||||
unsigned long ret = 0;
|
||||
unsigned long i, pfn;
|
||||
|
||||
cmr = find_cma_memrange(cma, pages, count);
|
||||
|
|
@ -1021,7 +1022,9 @@ bool cma_release(struct cma *cma, const struct page *pages,
|
|||
|
||||
pfn = page_to_pfn(pages);
|
||||
for (i = 0; i < count; i++, pfn++)
|
||||
VM_WARN_ON(!put_page_testzero(pfn_to_page(pfn)));
|
||||
ret += !put_page_testzero(pfn_to_page(pfn));
|
||||
|
||||
WARN(ret, "%lu pages are still in use!\n", ret);
|
||||
|
||||
__cma_release_frozen(cma, cmr, pages, count);
|
||||
|
||||
|
|
|
|||
|
|
@ -1562,8 +1562,13 @@ int damos_walk(struct damon_ctx *ctx, struct damos_walk_control *control)
|
|||
}
|
||||
ctx->walk_control = control;
|
||||
mutex_unlock(&ctx->walk_control_lock);
|
||||
if (!damon_is_running(ctx))
|
||||
if (!damon_is_running(ctx)) {
|
||||
mutex_lock(&ctx->walk_control_lock);
|
||||
if (ctx->walk_control == control)
|
||||
ctx->walk_control = NULL;
|
||||
mutex_unlock(&ctx->walk_control_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
wait_for_completion(&control->completion);
|
||||
if (control->canceled)
|
||||
return -ECANCELED;
|
||||
|
|
|
|||
|
|
@ -3631,6 +3631,7 @@ static int __split_unmapped_folio(struct folio *folio, int new_order,
|
|||
const bool is_anon = folio_test_anon(folio);
|
||||
int old_order = folio_order(folio);
|
||||
int start_order = split_type == SPLIT_TYPE_UNIFORM ? new_order : old_order - 1;
|
||||
struct folio *old_folio = folio;
|
||||
int split_order;
|
||||
|
||||
/*
|
||||
|
|
@ -3651,12 +3652,16 @@ static int __split_unmapped_folio(struct folio *folio, int new_order,
|
|||
* uniform split has xas_split_alloc() called before
|
||||
* irq is disabled to allocate enough memory, whereas
|
||||
* non-uniform split can handle ENOMEM.
|
||||
* Use the to-be-split folio, so that a parallel
|
||||
* folio_try_get() waits on it until xarray is updated
|
||||
* with after-split folios and the original one is
|
||||
* unfrozen.
|
||||
*/
|
||||
if (split_type == SPLIT_TYPE_UNIFORM)
|
||||
xas_split(xas, folio, old_order);
|
||||
else {
|
||||
if (split_type == SPLIT_TYPE_UNIFORM) {
|
||||
xas_split(xas, old_folio, old_order);
|
||||
} else {
|
||||
xas_set_order(xas, folio->index, split_order);
|
||||
xas_try_split(xas, folio, old_order);
|
||||
xas_try_split(xas, old_folio, old_order);
|
||||
if (xas_error(xas))
|
||||
return xas_error(xas);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3101,7 +3101,7 @@ static __init void *alloc_bootmem(struct hstate *h, int nid, bool node_exact)
|
|||
* extract the actual node first.
|
||||
*/
|
||||
if (m)
|
||||
listnode = early_pfn_to_nid(PHYS_PFN(virt_to_phys(m)));
|
||||
listnode = early_pfn_to_nid(PHYS_PFN(__pa(m)));
|
||||
}
|
||||
|
||||
if (m) {
|
||||
|
|
@ -3160,7 +3160,7 @@ found:
|
|||
* The head struct page is used to get folio information by the HugeTLB
|
||||
* subsystem like zone id and node id.
|
||||
*/
|
||||
memblock_reserved_mark_noinit(virt_to_phys((void *)m + PAGE_SIZE),
|
||||
memblock_reserved_mark_noinit(__pa((void *)m + PAGE_SIZE),
|
||||
huge_page_size(h) - PAGE_SIZE);
|
||||
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -3086,7 +3086,7 @@ static void refill_obj_stock(struct obj_cgroup *objcg, unsigned int nr_bytes,
|
|||
|
||||
if (!local_trylock(&obj_stock.lock)) {
|
||||
if (pgdat)
|
||||
mod_objcg_mlstate(objcg, pgdat, idx, nr_bytes);
|
||||
mod_objcg_mlstate(objcg, pgdat, idx, nr_acct);
|
||||
nr_pages = nr_bytes >> PAGE_SHIFT;
|
||||
nr_bytes = nr_bytes & (PAGE_SIZE - 1);
|
||||
atomic_add(nr_bytes, &objcg->nr_charged_bytes);
|
||||
|
|
|
|||
|
|
@ -146,19 +146,56 @@ static int memfd_luo_preserve_folios(struct file *file,
|
|||
for (i = 0; i < nr_folios; i++) {
|
||||
struct memfd_luo_folio_ser *pfolio = &folios_ser[i];
|
||||
struct folio *folio = folios[i];
|
||||
unsigned int flags = 0;
|
||||
|
||||
err = kho_preserve_folio(folio);
|
||||
if (err)
|
||||
goto err_unpreserve;
|
||||
|
||||
if (folio_test_dirty(folio))
|
||||
flags |= MEMFD_LUO_FOLIO_DIRTY;
|
||||
if (folio_test_uptodate(folio))
|
||||
flags |= MEMFD_LUO_FOLIO_UPTODATE;
|
||||
folio_lock(folio);
|
||||
|
||||
/*
|
||||
* A dirty folio is one which has been written to. A clean folio
|
||||
* is its opposite. Since a clean folio does not carry user
|
||||
* data, it can be freed by page reclaim under memory pressure.
|
||||
*
|
||||
* Saving the dirty flag at prepare() time doesn't work since it
|
||||
* can change later. Saving it at freeze() also won't work
|
||||
* because the dirty bit is normally synced at unmap and there
|
||||
* might still be a mapping of the file at freeze().
|
||||
*
|
||||
* To see why this is a problem, say a folio is clean at
|
||||
* preserve, but gets dirtied later. The pfolio flags will mark
|
||||
* it as clean. After retrieve, the next kernel might try to
|
||||
* reclaim this folio under memory pressure, losing user data.
|
||||
*
|
||||
* Unconditionally mark it dirty to avoid this problem. This
|
||||
* comes at the cost of making clean folios un-reclaimable after
|
||||
* live update.
|
||||
*/
|
||||
folio_mark_dirty(folio);
|
||||
|
||||
/*
|
||||
* If the folio is not uptodate, it was fallocated but never
|
||||
* used. Saving this flag at prepare() doesn't work since it
|
||||
* might change later when someone uses the folio.
|
||||
*
|
||||
* Since we have taken the performance penalty of allocating,
|
||||
* zeroing, and pinning all the folios in the holes, take a bit
|
||||
* more and zero all non-uptodate folios too.
|
||||
*
|
||||
* NOTE: For someone looking to improve preserve performance,
|
||||
* this is a good place to look.
|
||||
*/
|
||||
if (!folio_test_uptodate(folio)) {
|
||||
folio_zero_range(folio, 0, folio_size(folio));
|
||||
flush_dcache_folio(folio);
|
||||
folio_mark_uptodate(folio);
|
||||
}
|
||||
|
||||
folio_unlock(folio);
|
||||
|
||||
pfolio->pfn = folio_pfn(folio);
|
||||
pfolio->flags = flags;
|
||||
pfolio->flags = MEMFD_LUO_FOLIO_DIRTY | MEMFD_LUO_FOLIO_UPTODATE;
|
||||
pfolio->index = folio->index;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/gfp_types.h>
|
||||
|
||||
/* Helper macro to avoid gfp flags if they are the default one */
|
||||
#define __default_gfp(a,...) a
|
||||
#define default_gfp(...) __default_gfp(__VA_ARGS__ __VA_OPT__(,) GFP_KERNEL)
|
||||
|
||||
static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags)
|
||||
{
|
||||
return !!(gfp_flags & __GFP_DIRECT_RECLAIM);
|
||||
|
|
|
|||
|
|
@ -68,6 +68,25 @@
|
|||
__builtin_mul_overflow(__a, __b, __d); \
|
||||
})
|
||||
|
||||
/**
|
||||
* size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX
|
||||
* @factor1: first factor
|
||||
* @factor2: second factor
|
||||
*
|
||||
* Returns: calculate @factor1 * @factor2, both promoted to size_t,
|
||||
* with any overflow causing the return value to be SIZE_MAX. The
|
||||
* lvalue must be size_t to avoid implicit type conversion.
|
||||
*/
|
||||
static inline size_t __must_check size_mul(size_t factor1, size_t factor2)
|
||||
{
|
||||
size_t bytes;
|
||||
|
||||
if (check_mul_overflow(factor1, factor2, &bytes))
|
||||
return SIZE_MAX;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* array_size() - Calculate size of 2-dimensional array.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -202,4 +202,13 @@ static inline unsigned int kmem_cache_sheaf_size(struct slab_sheaf *sheaf)
|
|||
return sheaf->size;
|
||||
}
|
||||
|
||||
#define __alloc_objs(KMALLOC, GFP, TYPE, COUNT) \
|
||||
({ \
|
||||
const size_t __obj_size = size_mul(sizeof(TYPE), COUNT); \
|
||||
(TYPE *)KMALLOC(__obj_size, GFP); \
|
||||
})
|
||||
|
||||
#define kzalloc_obj(P, ...) \
|
||||
__alloc_objs(kzalloc, default_gfp(__VA_ARGS__), typeof(P), 1)
|
||||
|
||||
#endif /* _TOOLS_SLAB_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue