ion: Ensure ION system secure heap shrinker doesn't deadlock
When the ION system secure heap shrinker runs it attempts to free
secure ION page pool pages back to the system. It does this by first HYP
assigning these pages back to the system via the hyp_assign_table call.
However it is possible that the shrinker was called as a result of
somebody else calling hyp_assign_table, this is bad because the
hyp_assign_table call holds the secure_buffer_mutex mutex so when the ION
system secure heap shrinker recursively calls into hyp_assign_table it
will attempt to take the secure_buffer_mutex mutex and the system will
deadlock.
Example of deadlock callstack
-001|__schedule()
-002|schedule()
-003|schedule_preempt_disabled()
-004|__mutex_lock_common()
-005|__mutex_lock()
-006|__mutex_lock_slowpath()
-007|__cmpxchg_acq(inline)
-007|__mutex_trylock_fast(inline)
-007|mutex_lock()
-008|get_info_list_from_table(inline)
-008|hyp_assign_table()
-009|ion_hyp_unassign_sg()
-010|sg_set_page(inline)
-010|ion_secure_page_pool_shrink()
-011|ion_system_heap_shrink()
-012|ion_system_secure_heap_shrink()
-013|ion_heap_shrink_scan()
-014|shrink_slab()
-015|shrink_node()
-016|do_try_to_free_pages()
-017|__read_once_size(inline)
-017|static_key_count(inline)
-017|static_key_false(inline)
-017|trace_mm_vmscan_direct_reclaim_end(inline)
-017|try_to_free_pages()
-018|memalloc_noreclaim_restore(inline)
-018|__perform_reclaim(inline)
-018|__alloc_pages_direct_reclaim(inline)
-018|__alloc_pages_slowpath(inline)
-018|__alloc_pages_nodemask()
-019|__alloc_pages(inline)
-019|__alloc_pages_node(inline)
-019|alloc_slab_page(inline)
-019|allocate_slab(inline)
-019|new_slab()
-020|___slab_alloc()
-021|__slab_alloc(inline)
-021|slab_alloc_node(inline)
-021|slab_alloc(inline)
-021|__kmalloc()
-022|allocate_extra_arg_buffer()
-023|__scm_call2()
-024|scm_call2()
-025|hyp_assign_table()
-026|kcalloc(inline)
-026|ion_hyp_assign_sg()
-027|ion_system_secure_heap_prefetch_work()
-028|__read_once_size(inline)
-028|static_key_count(inline)
-028|static_key_false(inline)
-028|trace_workqueue_execute_end(inline)
-028|process_one_work()
-029|__read_once_size(inline)
-029|list_empty(inline)
-029|worker_thread()
-030|kthread()
-031|ret_from_fork(asm)
---|end of frame
To prevent this deadlock from happening ensure that the ION system secure
heap shrinker only tries to acquire he secure_buffer_mutex mutex with a
try_lock call.
Change-Id: I0e108b181ba36c57c382517d5916131f9c9b92eb
Signed-off-by:
Liam Mark <lmark@codeaurora.org>
Loading
Please register or sign in to comment