Skip to content

Commit 7521f25

Browse files
committed
Merge tag 'mm-hotfixes-stable-2024-02-10-11-16' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc fixes from Andrew Morton: "21 hotfixes. 12 are cc:stable and the remainder pertain to post-6.7 issues or aren't considered to be needed in earlier kernel versions" * tag 'mm-hotfixes-stable-2024-02-10-11-16' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (21 commits) nilfs2: fix potential bug in end_buffer_async_write mm/damon/sysfs-schemes: fix wrong DAMOS tried regions update timeout setup nilfs2: fix hang in nilfs_lookup_dirty_data_buffers() MAINTAINERS: Leo Yan has moved mm/zswap: don't return LRU_SKIP if we have dropped lru lock fs,hugetlb: fix NULL pointer dereference in hugetlbs_fill_super mailmap: switch email address for John Moon mm: zswap: fix objcg use-after-free in entry destruction mm/madvise: don't forget to leave lazy MMU mode in madvise_cold_or_pageout_pte_range() arch/arm/mm: fix major fault accounting when retrying under per-VMA lock selftests: core: include linux/close_range.h for CLOSE_RANGE_* macros mm/memory-failure: fix crash in split_huge_page_to_list from soft_offline_page mm: memcg: optimize parent iteration in memcg_rstat_updated() nilfs2: fix data corruption in dsync block recovery for small block sizes mm/userfaultfd: UFFDIO_MOVE implementation should use ptep_get() exit: wait_task_zombie: kill the no longer necessary spin_lock_irq(siglock) fs/proc: do_task_stat: use sig->stats_lock to gather the threads/children stats fs/proc: do_task_stat: move thread_group_cputime_adjusted() outside of lock_task_sighand() getrusage: use sig->stats_lock rather than lock_task_sighand() getrusage: move thread_group_cputime_adjusted() outside of lock_task_sighand() ...
2 parents a5b6244 + 5bc09b3 commit 7521f25

File tree

17 files changed

+162
-101
lines changed

17 files changed

+162
-101
lines changed

.mailmap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
289289
John Crispin <john@phrozen.org> <blogic@openwrt.org>
290290
John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com>
291291
John Keeping <john@keeping.me.uk> <john@metanate.com>
292+
John Moon <john@jmoon.dev> <quic_johmoo@quicinc.com>
292293
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
293294
John Stultz <johnstul@us.ibm.com>
294295
<jon.toppins+linux@gmail.com> <jtoppins@cumulusnetworks.com>
@@ -344,6 +345,7 @@ Leonid I Ananiev <leonid.i.ananiev@intel.com>
344345
Leon Romanovsky <leon@kernel.org> <leon@leon.nu>
345346
Leon Romanovsky <leon@kernel.org> <leonro@mellanox.com>
346347
Leon Romanovsky <leon@kernel.org> <leonro@nvidia.com>
348+
Leo Yan <leo.yan@linux.dev> <leo.yan@linaro.org>
347349
Liam Mark <quic_lmark@quicinc.com> <lmark@codeaurora.org>
348350
Linas Vepstas <linas@austin.ibm.com>
349351
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch>

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17182,7 +17182,7 @@ R: John Garry <john.g.garry@oracle.com>
1718217182
R: Will Deacon <will@kernel.org>
1718317183
R: James Clark <james.clark@arm.com>
1718417184
R: Mike Leach <mike.leach@linaro.org>
17185-
R: Leo Yan <leo.yan@linaro.org>
17185+
R: Leo Yan <leo.yan@linux.dev>
1718617186
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
1718717187
S: Supported
1718817188
F: tools/build/feature/test-libopencsd.c

arch/arm/mm/fault.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
298298
goto done;
299299
}
300300
count_vm_vma_lock_event(VMA_LOCK_RETRY);
301+
if (fault & VM_FAULT_MAJOR)
302+
flags |= FAULT_FLAG_TRIED;
301303

302304
/* Quick path to respond to signals */
303305
if (fault_signal_pending(fault, regs)) {

fs/hugetlbfs/inode.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
100100
loff_t len, vma_len;
101101
int ret;
102102
struct hstate *h = hstate_file(file);
103+
vm_flags_t vm_flags;
103104

104105
/*
105106
* vma address alignment (but not the pgoff alignment) has
@@ -141,10 +142,20 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
141142
file_accessed(file);
142143

143144
ret = -ENOMEM;
145+
146+
vm_flags = vma->vm_flags;
147+
/*
148+
* for SHM_HUGETLB, the pages are reserved in the shmget() call so skip
149+
* reserving here. Note: only for SHM hugetlbfs file, the inode
150+
* flag S_PRIVATE is set.
151+
*/
152+
if (inode->i_flags & S_PRIVATE)
153+
vm_flags |= VM_NORESERVE;
154+
144155
if (!hugetlb_reserve_pages(inode,
145156
vma->vm_pgoff >> huge_page_order(h),
146157
len >> huge_page_shift(h), vma,
147-
vma->vm_flags))
158+
vm_flags))
148159
goto out;
149160

150161
ret = 0;
@@ -1354,6 +1365,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
13541365
{
13551366
struct hugetlbfs_fs_context *ctx = fc->fs_private;
13561367
struct fs_parse_result result;
1368+
struct hstate *h;
13571369
char *rest;
13581370
unsigned long ps;
13591371
int opt;
@@ -1398,11 +1410,12 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
13981410

13991411
case Opt_pagesize:
14001412
ps = memparse(param->string, &rest);
1401-
ctx->hstate = size_to_hstate(ps);
1402-
if (!ctx->hstate) {
1413+
h = size_to_hstate(ps);
1414+
if (!h) {
14031415
pr_err("Unsupported page size %lu MB\n", ps / SZ_1M);
14041416
return -EINVAL;
14051417
}
1418+
ctx->hstate = h;
14061419
return 0;
14071420

14081421
case Opt_min_size:

fs/nilfs2/file.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,13 @@ static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
107107
nilfs_transaction_commit(inode->i_sb);
108108

109109
mapped:
110-
folio_wait_stable(folio);
110+
/*
111+
* Since checksumming including data blocks is performed to determine
112+
* the validity of the log to be written and used for recovery, it is
113+
* necessary to wait for writeback to finish here, regardless of the
114+
* stable write requirement of the backing device.
115+
*/
116+
folio_wait_writeback(folio);
111117
out:
112118
sb_end_pagefault(inode->i_sb);
113119
return vmf_fs_error(ret);

fs/nilfs2/recovery.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -472,17 +472,18 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
472472

473473
static int nilfs_recovery_copy_block(struct the_nilfs *nilfs,
474474
struct nilfs_recovery_block *rb,
475-
struct page *page)
475+
loff_t pos, struct page *page)
476476
{
477477
struct buffer_head *bh_org;
478+
size_t from = pos & ~PAGE_MASK;
478479
void *kaddr;
479480

480481
bh_org = __bread(nilfs->ns_bdev, rb->blocknr, nilfs->ns_blocksize);
481482
if (unlikely(!bh_org))
482483
return -EIO;
483484

484485
kaddr = kmap_atomic(page);
485-
memcpy(kaddr + bh_offset(bh_org), bh_org->b_data, bh_org->b_size);
486+
memcpy(kaddr + from, bh_org->b_data, bh_org->b_size);
486487
kunmap_atomic(kaddr);
487488
brelse(bh_org);
488489
return 0;
@@ -521,7 +522,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs,
521522
goto failed_inode;
522523
}
523524

524-
err = nilfs_recovery_copy_block(nilfs, rb, page);
525+
err = nilfs_recovery_copy_block(nilfs, rb, pos, page);
525526
if (unlikely(err))
526527
goto failed_page;
527528

fs/nilfs2/segment.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,7 +1703,6 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
17031703

17041704
list_for_each_entry(bh, &segbuf->sb_payload_buffers,
17051705
b_assoc_buffers) {
1706-
set_buffer_async_write(bh);
17071706
if (bh == segbuf->sb_super_root) {
17081707
if (bh->b_folio != bd_folio) {
17091708
folio_lock(bd_folio);
@@ -1714,6 +1713,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
17141713
}
17151714
break;
17161715
}
1716+
set_buffer_async_write(bh);
17171717
if (bh->b_folio != fs_folio) {
17181718
nilfs_begin_folio_io(fs_folio);
17191719
fs_folio = bh->b_folio;
@@ -1800,7 +1800,6 @@ static void nilfs_abort_logs(struct list_head *logs, int err)
18001800

18011801
list_for_each_entry(bh, &segbuf->sb_payload_buffers,
18021802
b_assoc_buffers) {
1803-
clear_buffer_async_write(bh);
18041803
if (bh == segbuf->sb_super_root) {
18051804
clear_buffer_uptodate(bh);
18061805
if (bh->b_folio != bd_folio) {
@@ -1809,6 +1808,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err)
18091808
}
18101809
break;
18111810
}
1811+
clear_buffer_async_write(bh);
18121812
if (bh->b_folio != fs_folio) {
18131813
nilfs_end_folio_io(fs_folio, err);
18141814
fs_folio = bh->b_folio;
@@ -1896,15 +1896,17 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
18961896
BIT(BH_Delay) | BIT(BH_NILFS_Volatile) |
18971897
BIT(BH_NILFS_Redirected));
18981898

1899-
set_mask_bits(&bh->b_state, clear_bits, set_bits);
19001899
if (bh == segbuf->sb_super_root) {
1900+
set_buffer_uptodate(bh);
1901+
clear_buffer_dirty(bh);
19011902
if (bh->b_folio != bd_folio) {
19021903
folio_end_writeback(bd_folio);
19031904
bd_folio = bh->b_folio;
19041905
}
19051906
update_sr = true;
19061907
break;
19071908
}
1909+
set_mask_bits(&bh->b_state, clear_bits, set_bits);
19081910
if (bh->b_folio != fs_folio) {
19091911
nilfs_end_folio_io(fs_folio, 0);
19101912
fs_folio = bh->b_folio;

fs/proc/array.c

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -477,13 +477,13 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
477477
int permitted;
478478
struct mm_struct *mm;
479479
unsigned long long start_time;
480-
unsigned long cmin_flt = 0, cmaj_flt = 0;
481-
unsigned long min_flt = 0, maj_flt = 0;
482-
u64 cutime, cstime, utime, stime;
483-
u64 cgtime, gtime;
480+
unsigned long cmin_flt, cmaj_flt, min_flt, maj_flt;
481+
u64 cutime, cstime, cgtime, utime, stime, gtime;
484482
unsigned long rsslim = 0;
485483
unsigned long flags;
486484
int exit_code = task->exit_code;
485+
struct signal_struct *sig = task->signal;
486+
unsigned int seq = 1;
487487

488488
state = *get_task_state(task);
489489
vsize = eip = esp = 0;
@@ -511,12 +511,8 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
511511

512512
sigemptyset(&sigign);
513513
sigemptyset(&sigcatch);
514-
cutime = cstime = utime = stime = 0;
515-
cgtime = gtime = 0;
516514

517515
if (lock_task_sighand(task, &flags)) {
518-
struct signal_struct *sig = task->signal;
519-
520516
if (sig->tty) {
521517
struct pid *pgrp = tty_get_pgrp(sig->tty);
522518
tty_pgrp = pid_nr_ns(pgrp, ns);
@@ -527,28 +523,9 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
527523
num_threads = get_nr_threads(task);
528524
collect_sigign_sigcatch(task, &sigign, &sigcatch);
529525

530-
cmin_flt = sig->cmin_flt;
531-
cmaj_flt = sig->cmaj_flt;
532-
cutime = sig->cutime;
533-
cstime = sig->cstime;
534-
cgtime = sig->cgtime;
535526
rsslim = READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
536527

537-
/* add up live thread stats at the group level */
538528
if (whole) {
539-
struct task_struct *t;
540-
541-
__for_each_thread(sig, t) {
542-
min_flt += t->min_flt;
543-
maj_flt += t->maj_flt;
544-
gtime += task_gtime(t);
545-
}
546-
547-
min_flt += sig->min_flt;
548-
maj_flt += sig->maj_flt;
549-
thread_group_cputime_adjusted(task, &utime, &stime);
550-
gtime += sig->gtime;
551-
552529
if (sig->flags & (SIGNAL_GROUP_EXIT | SIGNAL_STOP_STOPPED))
553530
exit_code = sig->group_exit_code;
554531
}
@@ -562,10 +539,41 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
562539

563540
if (permitted && (!whole || num_threads < 2))
564541
wchan = !task_is_running(task);
565-
if (!whole) {
542+
543+
do {
544+
seq++; /* 2 on the 1st/lockless path, otherwise odd */
545+
flags = read_seqbegin_or_lock_irqsave(&sig->stats_lock, &seq);
546+
547+
cmin_flt = sig->cmin_flt;
548+
cmaj_flt = sig->cmaj_flt;
549+
cutime = sig->cutime;
550+
cstime = sig->cstime;
551+
cgtime = sig->cgtime;
552+
553+
if (whole) {
554+
struct task_struct *t;
555+
556+
min_flt = sig->min_flt;
557+
maj_flt = sig->maj_flt;
558+
gtime = sig->gtime;
559+
560+
rcu_read_lock();
561+
__for_each_thread(sig, t) {
562+
min_flt += t->min_flt;
563+
maj_flt += t->maj_flt;
564+
gtime += task_gtime(t);
565+
}
566+
rcu_read_unlock();
567+
}
568+
} while (need_seqretry(&sig->stats_lock, seq));
569+
done_seqretry_irqrestore(&sig->stats_lock, seq, flags);
570+
571+
if (whole) {
572+
thread_group_cputime_adjusted(task, &utime, &stime);
573+
} else {
574+
task_cputime_adjusted(task, &utime, &stime);
566575
min_flt = task->min_flt;
567576
maj_flt = task->maj_flt;
568-
task_cputime_adjusted(task, &utime, &stime);
569577
gtime = task_gtime(task);
570578
}
571579

kernel/exit.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,17 +1127,14 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
11271127
* and nobody can change them.
11281128
*
11291129
* psig->stats_lock also protects us from our sub-threads
1130-
* which can reap other children at the same time. Until
1131-
* we change k_getrusage()-like users to rely on this lock
1132-
* we have to take ->siglock as well.
1130+
* which can reap other children at the same time.
11331131
*
11341132
* We use thread_group_cputime_adjusted() to get times for
11351133
* the thread group, which consolidates times for all threads
11361134
* in the group including the group leader.
11371135
*/
11381136
thread_group_cputime_adjusted(p, &tgutime, &tgstime);
1139-
spin_lock_irq(&current->sighand->siglock);
1140-
write_seqlock(&psig->stats_lock);
1137+
write_seqlock_irq(&psig->stats_lock);
11411138
psig->cutime += tgutime + sig->cutime;
11421139
psig->cstime += tgstime + sig->cstime;
11431140
psig->cgtime += task_gtime(p) + sig->gtime + sig->cgtime;
@@ -1160,8 +1157,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
11601157
psig->cmaxrss = maxrss;
11611158
task_io_accounting_add(&psig->ioac, &p->ioac);
11621159
task_io_accounting_add(&psig->ioac, &sig->ioac);
1163-
write_sequnlock(&psig->stats_lock);
1164-
spin_unlock_irq(&current->sighand->siglock);
1160+
write_sequnlock_irq(&psig->stats_lock);
11651161
}
11661162

11671163
if (wo->wo_rusage)

0 commit comments

Comments
 (0)