瀏覽代碼

dsp-kernel: Handle the spinlock recursion

Currently, in print_debug_data, kref_put is being called inside the
global lock, and the same lock is taken in the release callback of
kref_put, leading to spinlock recursion. There is no need to get and
put the reference for the fastrpce file inside this function because
we have already taken the reference inside the update_ramdump_status
while adding the init memory entry to the chan->initmems list.
Moreover, the same list will be used in print_debug_data.

Signed-off-by: Abhishek Singh <[email protected]>
Change-Id: Ifdc8b3e0c2bbc5cc4237eedaa24c8cd766262dfe
(cherry picked from commit 3463a894b83c5c567f1741190aa22faae4d73c4d)
Abhishek Singh 9 月之前
父節點
當前提交
dab8bb801d
共有 2 個文件被更改,包括 7 次插入20 次删除
  1. 7 18
      dsp/adsprpc.c
  2. 0 2
      dsp/adsprpc_shared.h

+ 7 - 18
dsp/adsprpc.c

@@ -5991,6 +5991,7 @@ skip_dmainvoke_wait:
 		spin_lock_irqsave(&fl->apps->hlock, irq_flags);
 		is_locked = true;
 	}
+	hlist_del_init(&fl->hn);
 	fl->is_dma_invoke_pend = false;
 	fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
 	is_locked = false;
@@ -6102,7 +6103,6 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
 	struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
 	struct fastrpc_apps *me = &gfa;
 	unsigned int ii;
-	unsigned long irq_flags = 0;
 
 	if (!fl)
 		return 0;
@@ -6115,9 +6115,6 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
 		}
 	}
 	debugfs_remove(fl->debugfs_file);
-	spin_lock_irqsave(&me->hlock, irq_flags);
-	hlist_del_init(&fl->hn);
-	spin_unlock_irqrestore(&me->hlock, irq_flags);
 	fastrpc_file_put(fl);
 	file->private_data = NULL;
 
@@ -6508,7 +6505,6 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
 	fl->exit_async = false;
 	fl->multi_session_support = false;
 	fl->set_session_info = false;
-	init_completion(&fl->work);
 	init_completion(&fl->dma_invoke);
 	fl->file_close = FASTRPC_PROCESS_DEFAULT_STATE;
 	filp->private_data = fl;
@@ -7733,7 +7729,7 @@ static void  fastrpc_print_debug_data(int cid)
 	struct hlist_node *n = NULL;
 	struct smq_invoke_ctx *ictx = NULL;
 	struct fastrpc_tx_msg *tx_msg = NULL;
-	struct fastrpc_buf *buf = NULL;
+	struct fastrpc_buf *buf = NULL, *iter = NULL;
 	struct fastrpc_mmap *map = NULL;
 	unsigned long irq_flags = 0;
 
@@ -7759,15 +7755,10 @@ static void  fastrpc_print_debug_data(int cid)
 		tx_index = chan->gmsg_log.tx_index;
 		rx_index = chan->gmsg_log.rx_index;
 	}
-	spin_lock_irqsave(&me->hlock, irq_flags);
-	hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
-		err = fastrpc_file_get(fl);
-		if (err) {
-			spin_unlock_irqrestore(&me->hlock, irq_flags);
-			ADSPRPC_ERR("Failed to get user process reference for fl (%pK)\n", fl);
-			goto free_buf;
-		}
-		if (fl->cid == cid) {
+
+	hlist_for_each_entry_safe(iter, n, &chan->initmems, hn_init) {
+		fl = iter->fl;
+		if ( fl && (fl->cid == cid)) {
 			scnprintf(mini_dump_buff +
 					strlen(mini_dump_buff),
 					MINI_DUMP_DBG_SIZE -
@@ -7795,6 +7786,7 @@ static void  fastrpc_print_debug_data(int cid)
 					MINI_DUMP_DBG_SIZE -
 					strlen(mini_dump_buff),
 					"\nSession Maps\n");
+			spin_lock_irqsave(&me->hlock, irq_flags);
 			hlist_for_each_entry_safe(map, n, &me->maps, hn) {
 				fastrpc_print_map(map, mini_dump_buff);
 			}
@@ -7804,7 +7796,6 @@ static void  fastrpc_print_debug_data(int cid)
 				fastrpc_print_map(map, mini_dump_buff);
 			}
 			mutex_unlock(&fl->map_mutex);
-			spin_lock_irqsave(&me->hlock, irq_flags);
 			spin_lock(&fl->hlock);
 			scnprintf(mini_dump_buff + strlen(mini_dump_buff),
 					MINI_DUMP_DBG_SIZE - strlen(mini_dump_buff),
@@ -7864,9 +7855,7 @@ static void  fastrpc_print_debug_data(int cid)
 			}
 			spin_unlock(&fl->hlock);
 		}
-		fastrpc_file_put(fl);
 	}
-	spin_unlock_irqrestore(&me->hlock, irq_flags);
 	spin_lock_irqsave(&chan->gmsg_log.lock, flags);
 	if (rx_index) {
 		for (i = rx_index, count = 0, len = 0 ; i > 0 &&

+ 0 - 2
dsp/adsprpc_shared.h

@@ -898,8 +898,6 @@ struct fastrpc_file {
 	uint32_t ws_timeout;
 	bool untrusted_process;
 	struct fastrpc_device *device;
-	/* Process kill will wait on work when ram dump collection in progress */
-	struct completion work;
 	/* Process kill will wait on bus driver invoke thread to complete its process */
 	struct completion dma_invoke;
 	/* Flag to indicate invoke pending */