mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
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:
@@ -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
|
* backed by tags-capable memory. The vm_flags may be overridden by a
|
||||||
* filesystem supporting MTE (RAM-based).
|
* filesystem supporting MTE (RAM-based).
|
||||||
*/
|
*/
|
||||||
if (system_supports_mte() &&
|
if (system_supports_mte()) {
|
||||||
((flags & MAP_ANONYMOUS) || shmem_file(file)))
|
if ((flags & MAP_ANONYMOUS) && !(flags & MAP_HUGETLB))
|
||||||
return VM_MTE_ALLOWED;
|
return VM_MTE_ALLOWED;
|
||||||
|
if (shmem_file(file))
|
||||||
|
return VM_MTE_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2022,33 +2022,29 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot);
|
EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot);
|
||||||
|
|
||||||
|
int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats)
|
||||||
void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap)
|
|
||||||
{
|
{
|
||||||
unsigned long chunk_kb;
|
|
||||||
struct bitmap_counts *counts;
|
struct bitmap_counts *counts;
|
||||||
|
bitmap_super_t *sb;
|
||||||
|
|
||||||
if (!bitmap)
|
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;
|
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;
|
return 0;
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(md_bitmap_get_stats);
|
||||||
|
|
||||||
int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
|
int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
|
||||||
int chunksize, int init)
|
int chunksize, int init)
|
||||||
|
|||||||
@@ -233,6 +233,13 @@ struct bitmap {
|
|||||||
int cluster_slot; /* Slot offset for clustered env */
|
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 */
|
/* the bitmap API */
|
||||||
|
|
||||||
/* these are used only by md/bitmap */
|
/* 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_print_sb(struct bitmap *bitmap);
|
||||||
void md_bitmap_update_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);
|
int md_bitmap_setallbits(struct bitmap *bitmap);
|
||||||
void md_bitmap_write_all(struct bitmap *bitmap);
|
void md_bitmap_write_all(struct bitmap *bitmap);
|
||||||
|
|||||||
@@ -1185,18 +1185,21 @@ out:
|
|||||||
*/
|
*/
|
||||||
static int cluster_check_sync_size(struct mddev *mddev)
|
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 current_slot = md_cluster_ops->slot_number(mddev);
|
||||||
|
int node_num = mddev->bitmap_info.nodes;
|
||||||
struct bitmap *bitmap = mddev->bitmap;
|
struct bitmap *bitmap = mddev->bitmap;
|
||||||
char str[64];
|
|
||||||
struct dlm_lock_resource *bm_lockres;
|
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);
|
rv = md_bitmap_get_stats(bitmap, &stats);
|
||||||
my_sync_size = sb->sync_size;
|
if (rv)
|
||||||
kunmap_atomic(sb);
|
return rv;
|
||||||
|
|
||||||
|
my_sync_size = stats.sync_size;
|
||||||
|
|
||||||
for (i = 0; i < node_num; i++) {
|
for (i = 0; i < node_num; i++) {
|
||||||
if (i == current_slot)
|
if (i == current_slot)
|
||||||
@@ -1225,15 +1228,18 @@ static int cluster_check_sync_size(struct mddev *mddev)
|
|||||||
md_bitmap_update_sb(bitmap);
|
md_bitmap_update_sb(bitmap);
|
||||||
lockres_free(bm_lockres);
|
lockres_free(bm_lockres);
|
||||||
|
|
||||||
sb = kmap_atomic(bitmap->storage.sb_page);
|
rv = md_bitmap_get_stats(bitmap, &stats);
|
||||||
if (sync_size == 0)
|
if (rv) {
|
||||||
sync_size = sb->sync_size;
|
md_bitmap_free(bitmap);
|
||||||
else if (sync_size != sb->sync_size) {
|
return rv;
|
||||||
kunmap_atomic(sb);
|
}
|
||||||
|
|
||||||
|
if (sync_size == 0) {
|
||||||
|
sync_size = stats.sync_size;
|
||||||
|
} else if (sync_size != stats.sync_size) {
|
||||||
md_bitmap_free(bitmap);
|
md_bitmap_free(bitmap);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
kunmap_atomic(sb);
|
|
||||||
md_bitmap_free(bitmap);
|
md_bitmap_free(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8318,6 +8318,33 @@ static void md_seq_stop(struct seq_file *seq, void *v)
|
|||||||
mddev_put(mddev);
|
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)
|
static int md_seq_show(struct seq_file *seq, void *v)
|
||||||
{
|
{
|
||||||
struct mddev *mddev = v;
|
struct mddev *mddev = v;
|
||||||
@@ -8341,6 +8368,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* prevent bitmap to be freed after checking */
|
||||||
|
mutex_lock(&mddev->bitmap_info.mutex);
|
||||||
|
|
||||||
spin_lock(&mddev->lock);
|
spin_lock(&mddev->lock);
|
||||||
if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
|
if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
|
||||||
seq_printf(seq, "%s : %sactive", mdname(mddev),
|
seq_printf(seq, "%s : %sactive", mdname(mddev),
|
||||||
@@ -8406,11 +8436,12 @@ static int md_seq_show(struct seq_file *seq, void *v)
|
|||||||
} else
|
} else
|
||||||
seq_printf(seq, "\n ");
|
seq_printf(seq, "\n ");
|
||||||
|
|
||||||
md_bitmap_status(seq, mddev->bitmap);
|
md_bitmap_status(seq, mddev);
|
||||||
|
|
||||||
seq_printf(seq, "\n");
|
seq_printf(seq, "\n");
|
||||||
}
|
}
|
||||||
spin_unlock(&mddev->lock);
|
spin_unlock(&mddev->lock);
|
||||||
|
mutex_unlock(&mddev->bitmap_info.mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1264,6 +1264,7 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
|
|||||||
{
|
{
|
||||||
struct mem_cgroup *iter;
|
struct mem_cgroup *iter;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
BUG_ON(memcg == root_mem_cgroup);
|
BUG_ON(memcg == root_mem_cgroup);
|
||||||
|
|
||||||
@@ -1272,8 +1273,12 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
|
|||||||
struct task_struct *task;
|
struct task_struct *task;
|
||||||
|
|
||||||
css_task_iter_start(&iter->css, CSS_TASK_ITER_PROCS, &it);
|
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);
|
ret = fn(task, arg);
|
||||||
|
}
|
||||||
css_task_iter_end(&it);
|
css_task_iter_end(&it);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mem_cgroup_iter_break(memcg, iter);
|
mem_cgroup_iter_break(memcg, iter);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/mmu_notifier.h>
|
#include <linux/mmu_notifier.h>
|
||||||
|
#include <linux/nmi.h>
|
||||||
#include <linux/cred.h>
|
#include <linux/cred.h>
|
||||||
|
|
||||||
#include <asm/tlb.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);
|
mem_cgroup_scan_tasks(oc->memcg, dump_task, oc);
|
||||||
else {
|
else {
|
||||||
struct task_struct *p;
|
struct task_struct *p;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
rcu_read_lock();
|
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);
|
dump_task(p, oc);
|
||||||
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user