Skip to content

Commit

Permalink
Merge tag 'mm-hotfixes-stable-2024-02-10-11-16' of git://git.kernel.o…
Browse files Browse the repository at this point in the history
…rg/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()
  ...
  • Loading branch information
torvalds committed Feb 10, 2024
2 parents a5b6244 + 5bc09b3 commit 7521f25
Show file tree
Hide file tree
Showing 17 changed files with 162 additions and 101 deletions.
2 changes: 2 additions & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ Johan Hovold <[email protected]> <[email protected]>
John Crispin <[email protected]> <[email protected]>
John Fastabend <[email protected]> <[email protected]>
John Keeping <[email protected]> <[email protected]>
John Moon <[email protected]> <[email protected]>
John Paul Adrian Glaubitz <[email protected]>
John Stultz <[email protected]>
<[email protected]> <[email protected]>
Expand Down Expand Up @@ -344,6 +345,7 @@ Leonid I Ananiev <[email protected]>
Leon Romanovsky <[email protected]> <[email protected]>
Leon Romanovsky <[email protected]> <[email protected]>
Leon Romanovsky <[email protected]> <[email protected]>
Leo Yan <[email protected]> <[email protected]>
Liam Mark <[email protected]> <[email protected]>
Linas Vepstas <[email protected]>
Linus Lüssing <[email protected]> <[email protected]>
Expand Down
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -17182,7 +17182,7 @@ R: John Garry <[email protected]>
R: Will Deacon <[email protected]>
R: James Clark <[email protected]>
R: Mike Leach <[email protected]>
R: Leo Yan <leo.yan@linaro.org>
R: Leo Yan <leo.yan@linux.dev>
L: [email protected] (moderated for non-subscribers)
S: Supported
F: tools/build/feature/test-libopencsd.c
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
goto done;
}
count_vm_vma_lock_event(VMA_LOCK_RETRY);
if (fault & VM_FAULT_MAJOR)
flags |= FAULT_FLAG_TRIED;

/* Quick path to respond to signals */
if (fault_signal_pending(fault, regs)) {
Expand Down
19 changes: 16 additions & 3 deletions fs/hugetlbfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
loff_t len, vma_len;
int ret;
struct hstate *h = hstate_file(file);
vm_flags_t vm_flags;

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

ret = -ENOMEM;

vm_flags = vma->vm_flags;
/*
* for SHM_HUGETLB, the pages are reserved in the shmget() call so skip
* reserving here. Note: only for SHM hugetlbfs file, the inode
* flag S_PRIVATE is set.
*/
if (inode->i_flags & S_PRIVATE)
vm_flags |= VM_NORESERVE;

if (!hugetlb_reserve_pages(inode,
vma->vm_pgoff >> huge_page_order(h),
len >> huge_page_shift(h), vma,
vma->vm_flags))
vm_flags))
goto out;

ret = 0;
Expand Down Expand Up @@ -1354,6 +1365,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
{
struct hugetlbfs_fs_context *ctx = fc->fs_private;
struct fs_parse_result result;
struct hstate *h;
char *rest;
unsigned long ps;
int opt;
Expand Down Expand Up @@ -1398,11 +1410,12 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par

case Opt_pagesize:
ps = memparse(param->string, &rest);
ctx->hstate = size_to_hstate(ps);
if (!ctx->hstate) {
h = size_to_hstate(ps);
if (!h) {
pr_err("Unsupported page size %lu MB\n", ps / SZ_1M);
return -EINVAL;
}
ctx->hstate = h;
return 0;

case Opt_min_size:
Expand Down
8 changes: 7 additions & 1 deletion fs/nilfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@ static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
nilfs_transaction_commit(inode->i_sb);

mapped:
folio_wait_stable(folio);
/*
* Since checksumming including data blocks is performed to determine
* the validity of the log to be written and used for recovery, it is
* necessary to wait for writeback to finish here, regardless of the
* stable write requirement of the backing device.
*/
folio_wait_writeback(folio);
out:
sb_end_pagefault(inode->i_sb);
return vmf_fs_error(ret);
Expand Down
7 changes: 4 additions & 3 deletions fs/nilfs2/recovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,17 +472,18 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,

static int nilfs_recovery_copy_block(struct the_nilfs *nilfs,
struct nilfs_recovery_block *rb,
struct page *page)
loff_t pos, struct page *page)
{
struct buffer_head *bh_org;
size_t from = pos & ~PAGE_MASK;
void *kaddr;

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

kaddr = kmap_atomic(page);
memcpy(kaddr + bh_offset(bh_org), bh_org->b_data, bh_org->b_size);
memcpy(kaddr + from, bh_org->b_data, bh_org->b_size);
kunmap_atomic(kaddr);
brelse(bh_org);
return 0;
Expand Down Expand Up @@ -521,7 +522,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs,
goto failed_inode;
}

err = nilfs_recovery_copy_block(nilfs, rb, page);
err = nilfs_recovery_copy_block(nilfs, rb, pos, page);
if (unlikely(err))
goto failed_page;

Expand Down
8 changes: 5 additions & 3 deletions fs/nilfs2/segment.c
Original file line number Diff line number Diff line change
Expand Up @@ -1703,7 +1703,6 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)

list_for_each_entry(bh, &segbuf->sb_payload_buffers,
b_assoc_buffers) {
set_buffer_async_write(bh);
if (bh == segbuf->sb_super_root) {
if (bh->b_folio != bd_folio) {
folio_lock(bd_folio);
Expand All @@ -1714,6 +1713,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
}
break;
}
set_buffer_async_write(bh);
if (bh->b_folio != fs_folio) {
nilfs_begin_folio_io(fs_folio);
fs_folio = bh->b_folio;
Expand Down Expand Up @@ -1800,7 +1800,6 @@ static void nilfs_abort_logs(struct list_head *logs, int err)

list_for_each_entry(bh, &segbuf->sb_payload_buffers,
b_assoc_buffers) {
clear_buffer_async_write(bh);
if (bh == segbuf->sb_super_root) {
clear_buffer_uptodate(bh);
if (bh->b_folio != bd_folio) {
Expand All @@ -1809,6 +1808,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err)
}
break;
}
clear_buffer_async_write(bh);
if (bh->b_folio != fs_folio) {
nilfs_end_folio_io(fs_folio, err);
fs_folio = bh->b_folio;
Expand Down Expand Up @@ -1896,15 +1896,17 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
BIT(BH_Delay) | BIT(BH_NILFS_Volatile) |
BIT(BH_NILFS_Redirected));

set_mask_bits(&bh->b_state, clear_bits, set_bits);
if (bh == segbuf->sb_super_root) {
set_buffer_uptodate(bh);
clear_buffer_dirty(bh);
if (bh->b_folio != bd_folio) {
folio_end_writeback(bd_folio);
bd_folio = bh->b_folio;
}
update_sr = true;
break;
}
set_mask_bits(&bh->b_state, clear_bits, set_bits);
if (bh->b_folio != fs_folio) {
nilfs_end_folio_io(fs_folio, 0);
fs_folio = bh->b_folio;
Expand Down
66 changes: 37 additions & 29 deletions fs/proc/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,13 +477,13 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
int permitted;
struct mm_struct *mm;
unsigned long long start_time;
unsigned long cmin_flt = 0, cmaj_flt = 0;
unsigned long min_flt = 0, maj_flt = 0;
u64 cutime, cstime, utime, stime;
u64 cgtime, gtime;
unsigned long cmin_flt, cmaj_flt, min_flt, maj_flt;
u64 cutime, cstime, cgtime, utime, stime, gtime;
unsigned long rsslim = 0;
unsigned long flags;
int exit_code = task->exit_code;
struct signal_struct *sig = task->signal;
unsigned int seq = 1;

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

sigemptyset(&sigign);
sigemptyset(&sigcatch);
cutime = cstime = utime = stime = 0;
cgtime = gtime = 0;

if (lock_task_sighand(task, &flags)) {
struct signal_struct *sig = task->signal;

if (sig->tty) {
struct pid *pgrp = tty_get_pgrp(sig->tty);
tty_pgrp = pid_nr_ns(pgrp, ns);
Expand All @@ -527,28 +523,9 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
num_threads = get_nr_threads(task);
collect_sigign_sigcatch(task, &sigign, &sigcatch);

cmin_flt = sig->cmin_flt;
cmaj_flt = sig->cmaj_flt;
cutime = sig->cutime;
cstime = sig->cstime;
cgtime = sig->cgtime;
rsslim = READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);

/* add up live thread stats at the group level */
if (whole) {
struct task_struct *t;

__for_each_thread(sig, t) {
min_flt += t->min_flt;
maj_flt += t->maj_flt;
gtime += task_gtime(t);
}

min_flt += sig->min_flt;
maj_flt += sig->maj_flt;
thread_group_cputime_adjusted(task, &utime, &stime);
gtime += sig->gtime;

if (sig->flags & (SIGNAL_GROUP_EXIT | SIGNAL_STOP_STOPPED))
exit_code = sig->group_exit_code;
}
Expand All @@ -562,10 +539,41 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,

if (permitted && (!whole || num_threads < 2))
wchan = !task_is_running(task);
if (!whole) {

do {
seq++; /* 2 on the 1st/lockless path, otherwise odd */
flags = read_seqbegin_or_lock_irqsave(&sig->stats_lock, &seq);

cmin_flt = sig->cmin_flt;
cmaj_flt = sig->cmaj_flt;
cutime = sig->cutime;
cstime = sig->cstime;
cgtime = sig->cgtime;

if (whole) {
struct task_struct *t;

min_flt = sig->min_flt;
maj_flt = sig->maj_flt;
gtime = sig->gtime;

rcu_read_lock();
__for_each_thread(sig, t) {
min_flt += t->min_flt;
maj_flt += t->maj_flt;
gtime += task_gtime(t);
}
rcu_read_unlock();
}
} while (need_seqretry(&sig->stats_lock, seq));
done_seqretry_irqrestore(&sig->stats_lock, seq, flags);

if (whole) {
thread_group_cputime_adjusted(task, &utime, &stime);
} else {
task_cputime_adjusted(task, &utime, &stime);
min_flt = task->min_flt;
maj_flt = task->maj_flt;
task_cputime_adjusted(task, &utime, &stime);
gtime = task_gtime(task);
}

Expand Down
10 changes: 3 additions & 7 deletions kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,17 +1127,14 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
* and nobody can change them.
*
* psig->stats_lock also protects us from our sub-threads
* which can reap other children at the same time. Until
* we change k_getrusage()-like users to rely on this lock
* we have to take ->siglock as well.
* which can reap other children at the same time.
*
* We use thread_group_cputime_adjusted() to get times for
* the thread group, which consolidates times for all threads
* in the group including the group leader.
*/
thread_group_cputime_adjusted(p, &tgutime, &tgstime);
spin_lock_irq(&current->sighand->siglock);
write_seqlock(&psig->stats_lock);
write_seqlock_irq(&psig->stats_lock);
psig->cutime += tgutime + sig->cutime;
psig->cstime += tgstime + sig->cstime;
psig->cgtime += task_gtime(p) + sig->gtime + sig->cgtime;
Expand All @@ -1160,8 +1157,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
psig->cmaxrss = maxrss;
task_io_accounting_add(&psig->ioac, &p->ioac);
task_io_accounting_add(&psig->ioac, &sig->ioac);
write_sequnlock(&psig->stats_lock);
spin_unlock_irq(&current->sighand->siglock);
write_sequnlock_irq(&psig->stats_lock);
}

if (wo->wo_rusage)
Expand Down
Loading

0 comments on commit 7521f25

Please sign in to comment.