Merge 0a09d56e16 ("memcg: fix soft lockup in the OOM process") into android14-6.1-lts

Steps on the way to 6.1.130

Resolves merge conflicts in:
	mm/oom_kill.c

Change-Id: Ie3ed449d29a900921d671f9338017da73ea61dc0
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2025-03-12 16:29:25 +00:00
7 changed files with 94 additions and 40 deletions

View File

@@ -33,9 +33,12 @@ static inline unsigned long arch_calc_vm_flag_bits(struct file *file,
* backed by tags-capable memory. The vm_flags may be overridden by a
* filesystem supporting MTE (RAM-based).
*/
if (system_supports_mte() &&
((flags & MAP_ANONYMOUS) || shmem_file(file)))
return VM_MTE_ALLOWED;
if (system_supports_mte()) {
if ((flags & MAP_ANONYMOUS) && !(flags & MAP_HUGETLB))
return VM_MTE_ALLOWED;
if (shmem_file(file))
return VM_MTE_ALLOWED;
}
return 0;
}

View File

@@ -2022,33 +2022,29 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot,
}
EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot);
void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap)
int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats)
{
unsigned long chunk_kb;
struct bitmap_counts *counts;
bitmap_super_t *sb;
if (!bitmap)
return;
return -ENOENT;
if (bitmap->mddev->bitmap_info.external)
return -ENOENT;
if (!bitmap->storage.sb_page) /* no superblock */
return -EINVAL;
sb = kmap_local_page(bitmap->storage.sb_page);
stats->sync_size = le64_to_cpu(sb->sync_size);
kunmap_local(sb);
counts = &bitmap->counts;
stats->missing_pages = counts->missing_pages;
stats->pages = counts->pages;
stats->file = bitmap->storage.file;
chunk_kb = bitmap->mddev->bitmap_info.chunksize >> 10;
seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], "
"%lu%s chunk",
counts->pages - counts->missing_pages,
counts->pages,
(counts->pages - counts->missing_pages)
<< (PAGE_SHIFT - 10),
chunk_kb ? chunk_kb : bitmap->mddev->bitmap_info.chunksize,
chunk_kb ? "KB" : "B");
if (bitmap->storage.file) {
seq_printf(seq, ", file: ");
seq_file_path(seq, bitmap->storage.file, " \t\n");
}
seq_printf(seq, "\n");
return 0;
}
EXPORT_SYMBOL_GPL(md_bitmap_get_stats);
int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
int chunksize, int init)

View File

@@ -233,6 +233,13 @@ struct bitmap {
int cluster_slot; /* Slot offset for clustered env */
};
struct md_bitmap_stats {
unsigned long missing_pages;
unsigned long sync_size;
unsigned long pages;
struct file *file;
};
/* the bitmap API */
/* these are used only by md/bitmap */
@@ -243,7 +250,7 @@ void md_bitmap_destroy(struct mddev *mddev);
void md_bitmap_print_sb(struct bitmap *bitmap);
void md_bitmap_update_sb(struct bitmap *bitmap);
void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap);
int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats);
int md_bitmap_setallbits(struct bitmap *bitmap);
void md_bitmap_write_all(struct bitmap *bitmap);

View File

@@ -1185,18 +1185,21 @@ out:
*/
static int cluster_check_sync_size(struct mddev *mddev)
{
int i, rv;
bitmap_super_t *sb;
unsigned long my_sync_size, sync_size = 0;
int node_num = mddev->bitmap_info.nodes;
int current_slot = md_cluster_ops->slot_number(mddev);
int node_num = mddev->bitmap_info.nodes;
struct bitmap *bitmap = mddev->bitmap;
char str[64];
struct dlm_lock_resource *bm_lockres;
struct md_bitmap_stats stats;
unsigned long sync_size = 0;
unsigned long my_sync_size;
char str[64];
int i, rv;
sb = kmap_atomic(bitmap->storage.sb_page);
my_sync_size = sb->sync_size;
kunmap_atomic(sb);
rv = md_bitmap_get_stats(bitmap, &stats);
if (rv)
return rv;
my_sync_size = stats.sync_size;
for (i = 0; i < node_num; i++) {
if (i == current_slot)
@@ -1225,15 +1228,18 @@ static int cluster_check_sync_size(struct mddev *mddev)
md_bitmap_update_sb(bitmap);
lockres_free(bm_lockres);
sb = kmap_atomic(bitmap->storage.sb_page);
if (sync_size == 0)
sync_size = sb->sync_size;
else if (sync_size != sb->sync_size) {
kunmap_atomic(sb);
rv = md_bitmap_get_stats(bitmap, &stats);
if (rv) {
md_bitmap_free(bitmap);
return rv;
}
if (sync_size == 0) {
sync_size = stats.sync_size;
} else if (sync_size != stats.sync_size) {
md_bitmap_free(bitmap);
return -1;
}
kunmap_atomic(sb);
md_bitmap_free(bitmap);
}

View File

@@ -8318,6 +8318,33 @@ static void md_seq_stop(struct seq_file *seq, void *v)
mddev_put(mddev);
}
static void md_bitmap_status(struct seq_file *seq, struct mddev *mddev)
{
struct md_bitmap_stats stats;
unsigned long used_pages;
unsigned long chunk_kb;
int err;
err = md_bitmap_get_stats(mddev->bitmap, &stats);
if (err)
return;
chunk_kb = mddev->bitmap_info.chunksize >> 10;
used_pages = stats.pages - stats.missing_pages;
seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], %lu%s chunk",
used_pages, stats.pages, used_pages << (PAGE_SHIFT - 10),
chunk_kb ? chunk_kb : mddev->bitmap_info.chunksize,
chunk_kb ? "KB" : "B");
if (stats.file) {
seq_puts(seq, ", file: ");
seq_file_path(seq, stats.file, " \t\n");
}
seq_putc(seq, '\n');
}
static int md_seq_show(struct seq_file *seq, void *v)
{
struct mddev *mddev = v;
@@ -8341,6 +8368,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
return 0;
}
/* prevent bitmap to be freed after checking */
mutex_lock(&mddev->bitmap_info.mutex);
spin_lock(&mddev->lock);
if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
seq_printf(seq, "%s : %sactive", mdname(mddev),
@@ -8406,11 +8436,12 @@ static int md_seq_show(struct seq_file *seq, void *v)
} else
seq_printf(seq, "\n ");
md_bitmap_status(seq, mddev->bitmap);
md_bitmap_status(seq, mddev);
seq_printf(seq, "\n");
}
spin_unlock(&mddev->lock);
mutex_unlock(&mddev->bitmap_info.mutex);
return 0;
}

View File

@@ -1264,6 +1264,7 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
{
struct mem_cgroup *iter;
int ret = 0;
int i = 0;
BUG_ON(memcg == root_mem_cgroup);
@@ -1272,8 +1273,12 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
struct task_struct *task;
css_task_iter_start(&iter->css, CSS_TASK_ITER_PROCS, &it);
while (!ret && (task = css_task_iter_next(&it)))
while (!ret && (task = css_task_iter_next(&it))) {
/* Avoid potential softlockup warning */
if ((++i & 1023) == 0)
cond_resched();
ret = fn(task, arg);
}
css_task_iter_end(&it);
if (ret) {
mem_cgroup_iter_break(memcg, iter);

View File

@@ -44,6 +44,7 @@
#include <linux/kthread.h>
#include <linux/init.h>
#include <linux/mmu_notifier.h>
#include <linux/nmi.h>
#include <linux/cred.h>
#include <asm/tlb.h>
@@ -433,10 +434,15 @@ void dump_tasks(struct oom_control *oc)
mem_cgroup_scan_tasks(oc->memcg, dump_task, oc);
else {
struct task_struct *p;
int i = 0;
rcu_read_lock();
for_each_process(p)
for_each_process(p) {
/* Avoid potential softlockup warning */
if ((++i & 1023) == 0)
touch_softlockup_watchdog();
dump_task(p, oc);
}
rcu_read_unlock();
}
}