drivers: shs: Fix deadlock in receive path
This fixes the deadlock between the ep lock and ht lock. This occurs
when there are multiple streams which are being assigned a new
CPU while existing flows are pruned by the workqueue.
Fixes the following deadlock-
CORE 1
-000|queued_spin_lock_slowpath(lock = 0xFFFFFFAD4F837968, ?)
-001|queued_spin_lock(inline)
-001|do_raw_spin_lock_flags(inline)
-001|__raw_spin_lock_irqsave(inline)
-001|raw_spin_lock_irqsave(?)
-002|rmnet_shs_wq_get_lpwr_cpu_new_flow(dev = 0xFFFFFFE22813A000) //acquires rmnet_shs_ep_lock
-003|rmnet_shs_new_flow_cpu(burst_size = 0, dev = 0xFFFFFFE22813A000)
-004|rmnet_shs_assign(skb = 0xFFFFFFE1DE425400, ?) //acquires rmnet_shs_ht_splock
-005|rcu_read_unlock(inline)
-005|rmnet_deliver_skb(skb = 0xFFFFFFE1DE425400, port = 0xFFFFFFE228138000)
-006|rmnet_frag_deliver(frag_desc = 0xFFFFFFE1F0A7D700, ?)
-007|rmnet_perf_core_flush_curr_pkt(pkt_info = 0xFFFFFF800800BB60, ?, ?, skip_hash = FALSE)
-008|rmnet_perf_tcp_opt_ingress(?, pkt_info = 0xFFFFFF800800BB60, ?)
-009|rmnet_perf_opt_ingress(pkt_info = 0xFFFFFF800800BB60)
-010|rmnet_perf_core_desc_entry(frag_desc = 0xFFFFFFE1F0A7D700, ?)
-011|__rmnet_frag_ingress_handler(inline)
-011|rmnet_frag_ingress_handler(skb = 0xFFFFFFE1DB2A2F00, ?)
-012|rmnet_map_ingress_handler(inline)
-012|rmnet_rx_handler(?)
-013|__netif_receive_skb_core(skb = 0xFFFFFFE1DB2A2F00, pfmemalloc = FALSE, ?)
-014|__netif_receive_skb_one_core(inline)
-014|__netif_receive_skb(inline)
-014|process_backlog(napi = 0xFFFFFFE27A966850, quota = 64)
-015|__read_once_size(inline)
-015|static_key_count(inline)
-015|static_key_false(inline)
-015|trace_napi_poll(inline)
-015|napi_poll(inline)
-015|net_rx_action(?)
CORE 7
-000|queued_spin_lock_slowpath(lock = 0xFFFFFFAD4F8356B8, ?)
-001|queued_spin_lock(inline)
-001|do_raw_spin_lock_flags(inline)
-001|__raw_spin_lock_irqsave(inline)
-001|raw_spin_lock_irqsave(?)
-002|rmnet_shs_wq_cleanup_hash_tbl(?) //acquires rmnet_shs_ht_splock
-003|rmnet_shs_wq_update_stats()
-004|spin_unlock_irqrestore(inline)
-004|rmnet_shs_wq_process_wq() //acquires rmnet_shs_ep_lock
-005|__read_once_size(inline)
-005|static_key_count(inline)
-005|static_key_false(inline)
-005|trace_workqueue_execute_end(inline)
-005|process_one_work(worker = 0xFFFFFFE2787B1600, work = 0xFFFFFFE1F31DE580)
-006|__read_once_size(inline)
-006|list_empty(inline)
-006|worker_thread(__worker = 0xFFFFFFE2787B1600)
-007|kthread(_create = 0xFFFFFFE278639900)
-008|ret_from_fork(asm)
CRs-fixed: 2595421
Change-Id: I760a51f7ff998ab610858f38cf76e577d026ff41
Signed-off-by:
Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Loading
Please sign in to comment