ANDROID: add vendor hook of add/delete/iterate node for swap_avail_heads
Our Android phones occur Panic as follows: [77522.303024][ T9734] Call trace: [77522.303039][ T9734] dump_backtrace.cfi_jt+0x0/0x8 [77522.303052][ T9734] dump_stack_lvl+0xc4/0x140 [77522.303061][ T9734] dump_stack+0x1c/0x2c [77522.303123][ T9734] mrdump_common_die+0x3a8/0x544 [mrdump] [77522.303177][ T9734] ipanic_die+0x24/0x38 [mrdump] [77522.303189][ T9734] die+0x340/0x698 [77522.303199][ T9734] bug_handler+0x48/0x108 [77522.303210][ T9734] brk_handler+0xac/0x1a8 [77522.303221][ T9734] do_debug_exception+0xe0/0x1e0 [77522.303233][ T9734] el1_dbg+0x38/0x54 [77522.303242][ T9734] el1_sync_handler+0x40/0x88 [77522.303255][ T9734] el1_sync+0x8c/0x140 [77522.303264][ T9734] plist_requeue+0xd4/0x110 [77522.303297][ T9734] tran_get_swap_pages+0xc8/0x364 [memfusion] [77522.303329][ T9734] probe_android_vh_get_swap_page+0x1b4/0x220 [memfusion] [77522.303342][ T9734] get_swap_page+0x258/0x304 [77522.303352][ T9734] shrink_page_list+0xe00/0x1e0c [77522.303361][ T9734] shrink_inactive_list+0x2f4/0xac8 [77522.303373][ T9734] shrink_lruvec+0x1a4/0x34c [77522.303383][ T9734] shrink_node_memcgs+0x84/0x3b0 [77522.303391][ T9734] shrink_node+0x2c4/0x6e4 [77522.303400][ T9734] shrink_zones+0x16c/0x29c [77522.303410][ T9734] do_try_to_free_pages+0xe4/0x2bc [77522.303418][ T9734] try_to_free_pages+0x388/0x7b4 [77522.303429][ T9734] __alloc_pages_direct_reclaim+0x88/0x278 [77522.303438][ T9734] __alloc_pages_slowpath+0x464/0xb24 [77522.303447][ T9734] __alloc_pages_nodemask+0x1f4/0x3dc [77522.303458][ T9734] do_anonymous_page+0x164/0x914 [77522.303466][ T9734] handle_pte_fault+0x15c/0x9f8 [77522.303476][ T9734] ___handle_speculative_fault+0x234/0xe18 [77522.303485][ T9734] __handle_speculative_fault+0x78/0x21c [77522.303497][ T9734] do_page_fault+0x36c/0x754 [77522.303506][ T9734] do_translation_fault+0x48/0x64 [77522.303514][ T9734] do_mem_abort+0x6c/0x164 [77522.303522][ T9734] el0_da+0x24/0x34 [77522.303531][ T9734] el0_sync_handler+0xc8/0xf0 [77522.303539][ T9734] el0_sync+0x1b4/0x1c0 The analysis shows that when we iterate the swap_avail_heads list, we get node A, but before we access node A, node A is maybe deleted, and by the time we actually access node A, it no longer exists, as follows: CPU1 thread1 CPU2 thread2 plist_for_each_entry_safe() get si->avail_lists[node] from swap_avail_heads remove si->avail_lists[node] from swap_avail_heads plist_requeue(&si->avail_lists[node]) BUG_ON(plist_node_empty(node)); // trigger Due to when we use vendor hook of get_swap_page, the get_swap_pages() function is overridden, use our own spin_lock to protect when iterate swap_avail_heads list, but now use native swap_avail_lock spin_lock protect when the swap_avail_heads list to add and delete nodes, so there will be concurrent access. So add vendor hook of add/delete/iterate node for avail_list, in this way, we can use our own spin_lock to protect the swap_avail_heads list to add, delete and iterate node. Due to enable_swap_info function to call vendor hook of add_to_avail_list, need first init swap_avail_heads, so also add vendor hook of swap_avail_heads_init. Due to the vendor hook of __cgroup_throttle_swaprate need to call blkcg_schedule_throttle function, so export it also. Bug: 225795494 Change-Id: I03107cbda6310fa7ae85e41b8cf1fa8225cafe78 Signed-off-by: Lincheng Yang <lincheng.yang@transsion.com> Suggested-by: Bing Han <bing.han@transsion.com>
This commit is contained in:
parent
bd34b88730
commit
6356ed35b9
@ -1794,6 +1794,7 @@ void blkcg_schedule_throttle(struct request_queue *q, bool use_memdelay)
|
||||
current->use_memdelay = use_memdelay;
|
||||
set_notify_resume(current);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkcg_schedule_throttle);
|
||||
|
||||
/**
|
||||
* blkcg_add_delay - add delay to this blkg
|
||||
|
@ -468,12 +468,16 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_free_swap_slot);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_swap_slot);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_get_swap_page);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_swap_page);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_add_to_avail_list);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_del_from_avail_list);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh___cgroup_throttle_swaprate);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_cold_or_pageout);
|
||||
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_snapshot_refaults);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_account_swap_pages);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_unuse_swap_page);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_swap_avail_heads_init);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_init_swap_info_struct);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_si_swapinfo);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_alloc_si);
|
||||
|
@ -287,6 +287,15 @@ DECLARE_HOOK(android_vh_get_swap_page,
|
||||
TP_PROTO(struct page *page, swp_entry_t *entry,
|
||||
struct swap_slots_cache *cache, bool *found),
|
||||
TP_ARGS(page, entry, cache, found));
|
||||
DECLARE_HOOK(android_vh_add_to_avail_list,
|
||||
TP_PROTO(struct swap_info_struct *p, bool *skip),
|
||||
TP_ARGS(p, skip));
|
||||
DECLARE_HOOK(android_vh_del_from_avail_list,
|
||||
TP_PROTO(struct swap_info_struct *p, bool *skip),
|
||||
TP_ARGS(p, skip));
|
||||
DECLARE_HOOK(android_vh___cgroup_throttle_swaprate,
|
||||
TP_PROTO(int nid, bool *skip),
|
||||
TP_ARGS(nid, skip));
|
||||
DECLARE_HOOK(android_vh_madvise_cold_or_pageout,
|
||||
TP_PROTO(struct vm_area_struct *vma, bool *allow_shared),
|
||||
TP_ARGS(vma, allow_shared));
|
||||
@ -299,6 +308,9 @@ DECLARE_HOOK(android_vh_account_swap_pages,
|
||||
DECLARE_HOOK(android_vh_unuse_swap_page,
|
||||
TP_PROTO(struct swap_info_struct *si, struct page *page),
|
||||
TP_ARGS(si, page));
|
||||
DECLARE_HOOK(android_vh_swap_avail_heads_init,
|
||||
TP_PROTO(struct plist_head *swap_avail_heads),
|
||||
TP_ARGS(swap_avail_heads));
|
||||
DECLARE_HOOK(android_vh_init_swap_info_struct,
|
||||
TP_PROTO(struct swap_info_struct *p, struct plist_head *swap_avail_heads),
|
||||
TP_ARGS(p, swap_avail_heads));
|
||||
|
@ -675,6 +675,12 @@ static void __del_from_avail_list(struct swap_info_struct *p)
|
||||
|
||||
static void del_from_avail_list(struct swap_info_struct *p)
|
||||
{
|
||||
bool skip = false;
|
||||
|
||||
trace_android_vh_del_from_avail_list(p, &skip);
|
||||
if (skip)
|
||||
return;
|
||||
|
||||
spin_lock(&swap_avail_lock);
|
||||
__del_from_avail_list(p);
|
||||
spin_unlock(&swap_avail_lock);
|
||||
@ -700,6 +706,11 @@ static void swap_range_alloc(struct swap_info_struct *si, unsigned long offset,
|
||||
static void add_to_avail_list(struct swap_info_struct *p)
|
||||
{
|
||||
int nid;
|
||||
bool skip = false;
|
||||
|
||||
trace_android_vh_add_to_avail_list(p, &skip);
|
||||
if (skip)
|
||||
return;
|
||||
|
||||
spin_lock(&swap_avail_lock);
|
||||
for_each_node(nid) {
|
||||
@ -3394,6 +3405,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
|
||||
if (swap_flags & SWAP_FLAG_PREFER)
|
||||
prio =
|
||||
(swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT;
|
||||
|
||||
trace_android_vh_swap_avail_heads_init(swap_avail_heads);
|
||||
enable_swap_info(p, prio, swap_map, cluster_info, frontswap_map);
|
||||
|
||||
trace_android_vh_init_swap_info_struct(p, swap_avail_heads);
|
||||
@ -3848,6 +3861,7 @@ void __cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask)
|
||||
{
|
||||
struct swap_info_struct *si, *next;
|
||||
int nid = page_to_nid(page);
|
||||
bool skip = false;
|
||||
|
||||
if (!(gfp_mask & __GFP_IO))
|
||||
return;
|
||||
@ -3862,6 +3876,10 @@ void __cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask)
|
||||
if (current->throttle_queue)
|
||||
return;
|
||||
|
||||
trace_android_vh___cgroup_throttle_swaprate(nid, &skip);
|
||||
if (skip)
|
||||
return;
|
||||
|
||||
spin_lock(&swap_avail_lock);
|
||||
plist_for_each_entry_safe(si, next, &swap_avail_heads[nid],
|
||||
avail_lists[nid]) {
|
||||
|
Loading…
Reference in New Issue
Block a user