ANDROID: vendor hooks: Add hooks to support bootloader based hibernation
Add vendor hooks to disable randomization of swap slot allocation for swap partition used for saving hibernation image. Another level of randomization of swap slots takes place at the firmware level as well in order to address the wear leveling for UFS/MMC devices, so this vendor hook checks if a block device represents the swap partition being used for saving hibernation image, if yes, the swap slot allocation for such partition is serialized at kernel level. There is a performance advantage of reading contiguous pages of hibernation image, it makes the restore logic of hibernation image simpler and faster as there are no seeks involved in the secondary storage to read multiple contiguous pages of the image. Bug: 279879797 Change-Id: I8258b5166d8c6952fe9eb91a5a9826f33b836f00 Signed-off-by: Vivek Kumar <quic_vivekuma@quicinc.com> Signed-off-by: Shreyas K K <quic_shrekk@quicinc.com>
This commit is contained in:
parent
d57acebb45
commit
d7e1f4f021
@ -33,6 +33,7 @@
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/trans_pgd.h>
|
||||
#include <asm/virt.h>
|
||||
#include <trace/hooks/bl_hib.h>
|
||||
|
||||
/*
|
||||
* Hibernate core relies on this value being 0 on resume, and marks it
|
||||
@ -80,6 +81,8 @@ static struct arch_hibernate_hdr {
|
||||
phys_addr_t __hyp_stub_vectors;
|
||||
|
||||
u64 sleep_cpu_mpidr;
|
||||
|
||||
ANDROID_VENDOR_DATA(1);
|
||||
} resume_hdr;
|
||||
|
||||
static inline void arch_hdr_invariants(struct arch_hibernate_hdr_invariants *i)
|
||||
@ -117,6 +120,9 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size)
|
||||
hdr->ttbr1_el1 = __pa_symbol(swapper_pg_dir);
|
||||
hdr->reenter_kernel = _cpu_resume;
|
||||
|
||||
trace_android_vh_save_cpu_resume(&hdr->android_vendor_data1,
|
||||
__pa(cpu_resume));
|
||||
|
||||
/* We can't use __hyp_get_vectors() because kvm may still be loaded */
|
||||
if (el2_reset_needed())
|
||||
hdr->__hyp_stub_vectors = __pa_symbol(__hyp_stub_vectors);
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include <trace/hooks/signal.h>
|
||||
#include <trace/hooks/psci.h>
|
||||
#include <trace/hooks/psi.h>
|
||||
#include <trace/hooks/bl_hib.h>
|
||||
|
||||
/*
|
||||
* Export tracepoints that act as a bare tracehook (ie: have no trace event
|
||||
@ -293,3 +294,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_process_madvise_end);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_smaps_pte_entry);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_smap);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_ctl_dirty_rate);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_hibernation_swap);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_save_cpu_resume);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_save_hib_resume_bdev);
|
||||
|
28
include/trace/hooks/bl_hib.h
Normal file
28
include/trace/hooks/bl_hib.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM bl_hib
|
||||
|
||||
#define TRACE_INCLUDE_PATH trace/hooks
|
||||
|
||||
#if !defined(_TRACE_HOOK_BL_HIB_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_HOOK_BL_HIB_H
|
||||
|
||||
#include <trace/hooks/vendor_hooks.h>
|
||||
|
||||
struct block_device;
|
||||
|
||||
DECLARE_HOOK(android_vh_check_hibernation_swap,
|
||||
TP_PROTO(struct block_device *resume_block, bool *hib_swap),
|
||||
TP_ARGS(resume_block, hib_swap));
|
||||
|
||||
DECLARE_HOOK(android_vh_save_cpu_resume,
|
||||
TP_PROTO(u64 *addr, u64 phys_addr),
|
||||
TP_ARGS(addr, phys_addr));
|
||||
|
||||
DECLARE_HOOK(android_vh_save_hib_resume_bdev,
|
||||
TP_PROTO(struct block_device *hib_resume_bdev),
|
||||
TP_ARGS(hib_resume_bdev));
|
||||
|
||||
#endif /* _TRACE_HOOK_BL_HIB_H */
|
||||
/* This part must be outside protection */
|
||||
#include <trace/define_trace.h>
|
@ -30,6 +30,7 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <trace/hooks/bl_hib.h>
|
||||
|
||||
#include "power.h"
|
||||
|
||||
@ -1524,6 +1525,7 @@ int swsusp_check(void)
|
||||
FMODE_READ | FMODE_EXCL, &holder);
|
||||
if (!IS_ERR(hib_resume_bdev)) {
|
||||
set_blocksize(hib_resume_bdev, PAGE_SIZE);
|
||||
trace_android_vh_save_hib_resume_bdev(hib_resume_bdev);
|
||||
clear_page(swsusp_header);
|
||||
error = hib_submit_io(REQ_OP_READ, swsusp_resume_block,
|
||||
swsusp_header, NULL);
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <linux/swapops.h>
|
||||
#include <linux/swap_cgroup.h>
|
||||
#include "swap.h"
|
||||
#include <trace/hooks/bl_hib.h>
|
||||
|
||||
static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
|
||||
unsigned char);
|
||||
@ -2399,6 +2400,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
|
||||
struct filename *pathname;
|
||||
int err, found = 0;
|
||||
unsigned int old_block_size;
|
||||
bool hibernation_swap = false;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
@ -2488,10 +2490,14 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
|
||||
flush_work(&p->discard_work);
|
||||
|
||||
destroy_swap_extents(p);
|
||||
|
||||
trace_android_vh_check_hibernation_swap(p->bdev, &hibernation_swap);
|
||||
|
||||
if (p->flags & SWP_CONTINUED)
|
||||
free_swap_count_continuations(p);
|
||||
|
||||
if (!p->bdev || !bdev_nonrot(p->bdev))
|
||||
if (!p->bdev || hibernation_swap ||
|
||||
!bdev_nonrot(p->bdev))
|
||||
atomic_dec(&nr_rotate_swap);
|
||||
|
||||
mutex_lock(&swapon_mutex);
|
||||
@ -3001,6 +3007,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
|
||||
struct page *page = NULL;
|
||||
struct inode *inode = NULL;
|
||||
bool inced_nr_rotate_swap = false;
|
||||
bool hibernation_swap = false;
|
||||
|
||||
if (swap_flags & ~SWAP_FLAGS_VALID)
|
||||
return -EINVAL;
|
||||
@ -3076,13 +3083,16 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
|
||||
goto bad_swap_unlock_inode;
|
||||
}
|
||||
|
||||
trace_android_vh_check_hibernation_swap(p->bdev, &hibernation_swap);
|
||||
|
||||
if (p->bdev && bdev_stable_writes(p->bdev))
|
||||
p->flags |= SWP_STABLE_WRITES;
|
||||
|
||||
if (p->bdev && p->bdev->bd_disk->fops->rw_page)
|
||||
p->flags |= SWP_SYNCHRONOUS_IO;
|
||||
|
||||
if (p->bdev && bdev_nonrot(p->bdev)) {
|
||||
if (p->bdev && !hibernation_swap &&
|
||||
bdev_nonrot(p->bdev)) {
|
||||
int cpu;
|
||||
unsigned long ci, nr_cluster;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user