ANDROID: vendor_hook: Add hook to update nr_swap_pages and total_swap_pages

The specified swap is regarded as reserved extended memory.
So nr_swap_pages and total_swap_pages should not be affected
by the specified swap.

Provide a vendor hook android_vh_account_swap_pages to replace
the updating process of nr_swap_pages and total_swap_pages.
When the page is swapped to the specified swap location,
nr_swap_pages and total_swap_pages should not be updated.

Bug: 234214858
Signed-off-by: Bing Han <bing.han@transsion.com>
Change-Id: Ib8dfb355d190399a037b9d9eda478a81c436e224
This commit is contained in:
Bing Han
2022-05-30 16:00:22 +08:00
committed by Treehugger Robot
parent 1aa26f0017
commit d2fea0ba9a
3 changed files with 26 additions and 7 deletions

View File

@@ -419,3 +419,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_swpout_vm_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_isolated_for_reclaim); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_isolated_for_reclaim);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_inactive_is_low); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_inactive_is_low);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_snapshot_refaults); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_snapshot_refaults);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_account_swap_pages);

View File

@@ -179,6 +179,9 @@ DECLARE_HOOK(android_vh_count_swpout_vm_event,
DECLARE_HOOK(android_vh_page_isolated_for_reclaim, DECLARE_HOOK(android_vh_page_isolated_for_reclaim,
TP_PROTO(struct mm_struct *mm, struct page *page), TP_PROTO(struct mm_struct *mm, struct page *page),
TP_ARGS(mm, page)); TP_ARGS(mm, page));
DECLARE_HOOK(android_vh_account_swap_pages,
TP_PROTO(struct swap_info_struct *si, bool *skip),
TP_ARGS(si, skip));
/* macro versions of hooks are no longer required */ /* macro versions of hooks are no longer required */
#endif /* _TRACE_HOOK_MM_H */ #endif /* _TRACE_HOOK_MM_H */

View File

@@ -43,6 +43,7 @@
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <linux/swapops.h> #include <linux/swapops.h>
#include <linux/swap_cgroup.h> #include <linux/swap_cgroup.h>
#include <trace/hooks/mm.h>
static bool swap_count_continued(struct swap_info_struct *, pgoff_t, static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
unsigned char); unsigned char);
@@ -712,6 +713,7 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
unsigned long begin = offset; unsigned long begin = offset;
unsigned long end = offset + nr_entries - 1; unsigned long end = offset + nr_entries - 1;
void (*swap_slot_free_notify)(struct block_device *, unsigned long); void (*swap_slot_free_notify)(struct block_device *, unsigned long);
bool skip = false;
if (offset < si->lowest_bit) if (offset < si->lowest_bit)
si->lowest_bit = offset; si->lowest_bit = offset;
@@ -722,7 +724,9 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
if (was_full && (si->flags & SWP_WRITEOK)) if (was_full && (si->flags & SWP_WRITEOK))
add_to_avail_list(si); add_to_avail_list(si);
} }
atomic_long_add(nr_entries, &nr_swap_pages); trace_android_vh_account_swap_pages(si, &skip);
if (!skip)
atomic_long_add(nr_entries, &nr_swap_pages);
si->inuse_pages -= nr_entries; si->inuse_pages -= nr_entries;
if (si->flags & SWP_BLKDEV) if (si->flags & SWP_BLKDEV)
swap_slot_free_notify = swap_slot_free_notify =
@@ -1137,6 +1141,7 @@ swp_entry_t get_swap_page_of_type(int type)
{ {
struct swap_info_struct *si = swap_type_to_swap_info(type); struct swap_info_struct *si = swap_type_to_swap_info(type);
pgoff_t offset; pgoff_t offset;
bool skip = false;
if (!si) if (!si)
goto fail; goto fail;
@@ -1146,7 +1151,9 @@ swp_entry_t get_swap_page_of_type(int type)
/* This is called for allocating swap entry, not cache */ /* This is called for allocating swap entry, not cache */
offset = scan_swap_map(si, 1); offset = scan_swap_map(si, 1);
if (offset) { if (offset) {
atomic_long_dec(&nr_swap_pages); trace_android_vh_account_swap_pages(si, &skip);
if (!skip)
atomic_long_dec(&nr_swap_pages);
spin_unlock(&si->lock); spin_unlock(&si->lock);
return swp_entry(type, offset); return swp_entry(type, offset);
} }
@@ -2499,10 +2506,14 @@ static void setup_swap_info(struct swap_info_struct *p, int prio,
static void _enable_swap_info(struct swap_info_struct *p) static void _enable_swap_info(struct swap_info_struct *p)
{ {
p->flags |= SWP_WRITEOK | SWP_VALID; bool skip = false;
atomic_long_add(p->pages, &nr_swap_pages);
total_swap_pages += p->pages;
p->flags |= SWP_WRITEOK | SWP_VALID;
trace_android_vh_account_swap_pages(p, &skip);
if (!skip) {
atomic_long_add(p->pages, &nr_swap_pages);
total_swap_pages += p->pages;
}
assert_spin_locked(&swap_lock); assert_spin_locked(&swap_lock);
/* /*
* both lists are plists, and thus priority ordered. * both lists are plists, and thus priority ordered.
@@ -2574,6 +2585,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
struct filename *pathname; struct filename *pathname;
int err, found = 0; int err, found = 0;
unsigned int old_block_size; unsigned int old_block_size;
bool skip = false;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
@@ -2628,8 +2640,11 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
least_priority++; least_priority++;
} }
plist_del(&p->list, &swap_active_head); plist_del(&p->list, &swap_active_head);
atomic_long_sub(p->pages, &nr_swap_pages); trace_android_vh_account_swap_pages(p, &skip);
total_swap_pages -= p->pages; if (!skip) {
atomic_long_sub(p->pages, &nr_swap_pages);
total_swap_pages -= p->pages;
}
p->flags &= ~SWP_WRITEOK; p->flags &= ~SWP_WRITEOK;
spin_unlock(&p->lock); spin_unlock(&p->lock);
spin_unlock(&swap_lock); spin_unlock(&swap_lock);