Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d609e24 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mm: process_reclaim: allow nomap-only reclaim"

parents a930d0b9 3b957b5e
Loading
Loading
Loading
Loading
+91 −0
Original line number Diff line number Diff line
@@ -1668,6 +1668,74 @@ const struct file_operations proc_pagemap_operations = {
#endif /* CONFIG_PROC_PAGE_MONITOR */

#ifdef CONFIG_PROCESS_RECLAIM
static BLOCKING_NOTIFIER_HEAD(proc_reclaim_notifier);

int proc_reclaim_notifier_register(struct notifier_block *nb)
{
	return blocking_notifier_chain_register(&proc_reclaim_notifier, nb);
}

int proc_reclaim_notifier_unregister(struct notifier_block *nb)
{
	return blocking_notifier_chain_unregister(&proc_reclaim_notifier, nb);
}

static void proc_reclaim_notify(unsigned long pid, void *rp)
{
	blocking_notifier_call_chain(&proc_reclaim_notifier, pid, rp);
}

int reclaim_address_space(struct address_space *mapping,
			struct reclaim_param *rp, struct vm_area_struct *vma)
{
	struct radix_tree_iter iter;
	void __rcu **slot;
	pgoff_t start;
	struct page *page;
	LIST_HEAD(page_list);
	int reclaimed;
	int ret = NOTIFY_OK;

	lru_add_drain();
	start = 0;
	rcu_read_lock();

	radix_tree_for_each_slot(slot, &mapping->i_pages, &iter, start) {

		page = radix_tree_deref_slot(slot);

		if (radix_tree_deref_retry(page)) {
			slot = radix_tree_iter_retry(&iter);
			continue;
		}

		if (radix_tree_exceptional_entry(page))
			continue;

		if (isolate_lru_page(page))
			continue;

		rp->nr_scanned++;

		list_add(&page->lru, &page_list);
		inc_node_page_state(page, NR_ISOLATED_ANON +
				page_is_file_cache(page));

		if (need_resched()) {
			slot = radix_tree_iter_resume(slot, &iter);
			cond_resched_rcu();
		}
	}
	rcu_read_unlock();
	reclaimed = reclaim_pages_from_list(&page_list, vma);
	rp->nr_reclaimed += reclaimed;

	if (rp->nr_scanned >= rp->nr_to_reclaim)
		ret = NOTIFY_DONE;

	return ret;
}

static int reclaim_pte_range(pmd_t *pmd, unsigned long addr,
				unsigned long end, struct mm_walk *walk)
{
@@ -1739,6 +1807,29 @@ enum reclaim_type {
	RECLAIM_RANGE,
};

struct reclaim_param reclaim_task_nomap(struct task_struct *task,
		int nr_to_reclaim)
{
	struct mm_struct *mm;
	struct reclaim_param rp = {
		.nr_to_reclaim = nr_to_reclaim,
	};

	get_task_struct(task);
	mm = get_task_mm(task);
	if (!mm)
		goto out;
	down_read(&mm->mmap_sem);

	proc_reclaim_notify(task_tgid_nr(task), (void *)&rp);

	up_read(&mm->mmap_sem);
	mmput(mm);
out:
	put_task_struct(task);
	return rp;
}

struct reclaim_param reclaim_task_anon(struct task_struct *task,
		int nr_to_reclaim)
{
+6 −0
Original line number Diff line number Diff line
@@ -3028,6 +3028,12 @@ struct reclaim_param {
};
extern struct reclaim_param reclaim_task_anon(struct task_struct *task,
		int nr_to_reclaim);
extern struct reclaim_param reclaim_task_nomap(struct task_struct *task,
		int nr_to_reclaim);
extern int reclaim_address_space(struct address_space *mapping,
		struct reclaim_param *rp, struct vm_area_struct *vma);
extern int proc_reclaim_notifier_register(struct notifier_block *nb);
extern int proc_reclaim_notifier_unregister(struct notifier_block *nb);
#endif

#endif /* __KERNEL__ */
+32 −3
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -29,9 +29,19 @@ module_param_named(enable_process_reclaim, enable_process_reclaim, int, 0644);
int per_swap_size = SWAP_CLUSTER_MAX * 32;
module_param_named(per_swap_size, per_swap_size, int, 0644);

/* The per task max number of nomap pages to be reclaimed */
int tsk_nomap_swap_sz;
module_param_named(tsk_nomap_swap_sz, tsk_nomap_swap_sz, int, 0644);

int reclaim_avg_efficiency;
module_param_named(reclaim_avg_efficiency, reclaim_avg_efficiency, int, 0444);

static unsigned long reclaimed_anon;
module_param_named(reclaimed_anon, reclaimed_anon, ulong, 0444);

static unsigned long reclaimed_nomap;
module_param_named(reclaimed_nomap, reclaimed_nomap, ulong, 0444);

/* The vmpressure region where process reclaim operates */
static unsigned long pressure_min = 50;
static unsigned long pressure_max = 90;
@@ -102,7 +112,7 @@ static void swap_fn(struct work_struct *work)
	struct selected_task selected[MAX_SWAP_TASKS] = {{0, 0, 0},};
	int si = 0;
	int i;
	int tasksize;
	int tasksize = 0;
	int total_sz = 0;
	short min_score_adj = 360;
	int total_scan = 0;
@@ -110,6 +120,9 @@ static void swap_fn(struct work_struct *work)
	int nr_to_reclaim;
	int efficiency;

	if (!tsk_nomap_swap_sz && !per_swap_size)
		return;

	rcu_read_lock();
	for_each_process(tsk) {
		struct task_struct *p;
@@ -131,7 +144,11 @@ static void swap_fn(struct work_struct *work)
			continue;
		}

		if (per_swap_size)
			tasksize = get_mm_counter(p->mm, MM_ANONPAGES);
		else if (tsk_nomap_swap_sz)
			tasksize = get_mm_rss(p->mm);

		task_unlock(p);

		if (tasksize <= 0)
@@ -169,6 +186,9 @@ static void swap_fn(struct work_struct *work)
	rcu_read_unlock();

	while (si--) {
		if (!per_swap_size)
			goto nomap;

		nr_to_reclaim =
			(selected[si].tasksize * per_swap_size) / total_sz;
		/* scan atleast a page */
@@ -183,6 +203,15 @@ static void swap_fn(struct work_struct *work)
				nr_to_reclaim);
		total_scan += rp.nr_scanned;
		total_reclaimed += rp.nr_reclaimed;
		reclaimed_anon += rp.nr_reclaimed;
nomap:
		if (tsk_nomap_swap_sz)
			nr_to_reclaim = tsk_nomap_swap_sz;
		rp = reclaim_task_nomap(selected[si].p, nr_to_reclaim);
		total_scan += rp.nr_scanned;
		total_reclaimed += rp.nr_reclaimed;
		reclaimed_nomap += rp.nr_reclaimed;

		put_task_struct(selected[si].p);
	}