kernel/0162-fix-check_mc_cmdbuf_irq.patch

210 lines
7.2 KiB
Diff
Raw Permalink Normal View History

2025-01-03 03:30:57 +00:00
From 2535e4da2417b6061dd0d5fff1e9fec6199cbf60 Mon Sep 17 00:00:00 2001
2024-12-15 18:29:23 +00:00
From: tangdaoyong <tangdaoyong@eswincomputing.com>
Date: Thu, 29 Aug 2024 17:26:10 +0800
2024-12-27 22:35:16 +00:00
Subject: [PATCH 162/222] fix:check_mc_cmdbuf_irq
2024-12-15 18:29:23 +00:00
Changelogs:
1. Decoder uses a thread to periodically check the vcmd status for
multicore decoding, if vcmd node is released, the driver may be exception.
Signed-off-by: tangdaoyong <tangdaoyong@eswincomputing.com>
---
.../staging/media/eswin/vdec/hantro_vcmd.c | 66 +++++++++----------
drivers/staging/media/eswin/vdec/hantrodec.h | 1 -
2 files changed, 31 insertions(+), 36 deletions(-)
diff --git a/drivers/staging/media/eswin/vdec/hantro_vcmd.c b/drivers/staging/media/eswin/vdec/hantro_vcmd.c
index 3e07e4a1f5cb..80b75ffc9d78 100644
--- a/drivers/staging/media/eswin/vdec/hantro_vcmd.c
+++ b/drivers/staging/media/eswin/vdec/hantro_vcmd.c
@@ -788,6 +788,13 @@ static int vcmd_type_core_num[MAX_VCMD_TYPE];
static struct semaphore vcmd_reserve_cmdbuf_sem[MAX_VCMD_TYPE]; //for reserve
+#define CMDBUF_LOCK_NUM 8
+static spinlock_t cmdbuf_lock[CMDBUF_LOCK_NUM];
+#define LOCK_CMDBUF_NODE(cmdbuf_id, flags) \
+ spin_lock_irqsave(&cmdbuf_lock[(cmdbuf_id) % CMDBUF_LOCK_NUM], flags)
+#define UNLOCK_CMDBUF_NODE(cmdbuf_id, flags) \
+ spin_unlock_irqrestore(&cmdbuf_lock[(cmdbuf_id) % CMDBUF_LOCK_NUM], flags)
+
/* PCI base register address (memalloc) */
//extern unsigned long gBaseDDRHw;
//extern unsigned int mmu_enable;
@@ -1569,7 +1576,10 @@ static long reserve_cmdbuf(struct file *filp,
cmdbuf_obj->process_manager_obj = process_manager_obj;
input_para->cmdbuf_id = cmdbuf_obj->cmdbuf_id;
+
+ LOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
global_cmdbuf_node[input_para->cmdbuf_id] = new_cmdbuf_node;
+ UNLOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
return 0;
}
@@ -1622,13 +1632,10 @@ static long release_cmdbuf(struct file *filp, u16 cmdbuf_id)
list, new_cmdbuf_node);
if (new_cmdbuf_node) {
//free node
-#ifdef SUPPORT_DMA_HEAP
- spin_lock_irqsave(&fp_priv->vcmdlock, flags);
-#endif
+ LOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
global_cmdbuf_node[cmdbuf_obj->cmdbuf_id] = NULL;
-#ifdef SUPPORT_DMA_HEAP
- spin_unlock_irqrestore(&fp_priv->vcmdlock, flags);
-#endif
+ UNLOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
+
if (cmdbuf_obj->process_manager_obj) {
spin_lock_irqsave(&cmdbuf_obj->process_manager_obj->spinlock,
flags);
@@ -1660,6 +1667,7 @@ static long release_cmdbuf_node(bi_list *list, bi_list_node *cmdbuf_node)
{
bi_list_node *new_cmdbuf_node = NULL;
struct cmdbuf_obj *cmdbuf_obj = NULL;
+ unsigned long flags = 0;
/*get cmdbuf object according to cmdbuf_id*/
new_cmdbuf_node = cmdbuf_node;
if (!new_cmdbuf_node)
@@ -1669,7 +1677,9 @@ static long release_cmdbuf_node(bi_list *list, bi_list_node *cmdbuf_node)
if (new_cmdbuf_node) {
//free node
cmdbuf_obj = (struct cmdbuf_obj *)new_cmdbuf_node->data;
+ LOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
global_cmdbuf_node[cmdbuf_obj->cmdbuf_id] = NULL;
+ UNLOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
free_cmdbuf_node(new_cmdbuf_node);
return 0;
}
@@ -1680,6 +1690,7 @@ static long release_cmdbuf_node_cleanup(bi_list *list)
{
bi_list_node *new_cmdbuf_node = NULL;
struct cmdbuf_obj *cmdbuf_obj = NULL;
+ unsigned long flags = 0;
while (1) {
new_cmdbuf_node = list->head;
@@ -1689,7 +1700,9 @@ static long release_cmdbuf_node_cleanup(bi_list *list)
bi_list_remove_node(list, new_cmdbuf_node);
//free node
cmdbuf_obj = (struct cmdbuf_obj *)new_cmdbuf_node->data;
+ LOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
global_cmdbuf_node[cmdbuf_obj->cmdbuf_id] = NULL;
+ UNLOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
free_cmdbuf_node(new_cmdbuf_node);
}
return 0;
@@ -1913,38 +1926,19 @@ static int check_mc_cmdbuf_irq(struct file *filp, struct cmdbuf_obj *cmdbuf_obj,
int k;
bi_list_node *new_cmdbuf_node = NULL;
struct hantrovcmd_dev *dev = NULL;
-#ifdef SUPPORT_DMA_HEAP
unsigned long flags = 0;
- struct filp_priv *fp_priv = NULL;
- if (!filp || !filp->private_data) {
- LOG_ERR("check mc: invalid filp\n");
- return 0;
- }
- fp_priv = (struct filp_priv *)filp->private_data;
-#endif
for (k = 0; k < TOTAL_DISCRETE_CMDBUF_NUM; k++) {
+ LOCK_CMDBUF_NODE(k, flags);
new_cmdbuf_node = global_cmdbuf_node[k];
if (!new_cmdbuf_node) {
- continue;
- }
-
-#ifdef SUPPORT_DMA_HEAP
- spin_lock_irqsave(&fp_priv->vcmdlock, flags);
-#endif
- new_cmdbuf_node = global_cmdbuf_node[k];
- if (!new_cmdbuf_node) {
-#ifdef SUPPORT_DMA_HEAP
- spin_unlock_irqrestore(&fp_priv->vcmdlock, flags);
-#endif
+ UNLOCK_CMDBUF_NODE(k, flags);
continue;
}
cmdbuf_obj = (struct cmdbuf_obj *)new_cmdbuf_node->data;
if (!cmdbuf_obj || cmdbuf_obj->filp != filp) {
-#ifdef SUPPORT_DMA_HEAP
- spin_unlock_irqrestore(&fp_priv->vcmdlock, flags);
-#endif
+ UNLOCK_CMDBUF_NODE(k, flags);
continue;
}
dev = &hantrovcmd_data[cmdbuf_obj->core_id];
@@ -1953,15 +1947,11 @@ static int check_mc_cmdbuf_irq(struct file *filp, struct cmdbuf_obj *cmdbuf_obj,
if (!cmdbuf_obj->waited) {
*irq_status_ret = cmdbuf_obj->cmdbuf_id;
cmdbuf_obj->waited = 1;
-#ifdef SUPPORT_DMA_HEAP
- spin_unlock_irqrestore(&fp_priv->vcmdlock, flags);
-#endif
+ UNLOCK_CMDBUF_NODE(k, flags);
return 1;
}
}
-#ifdef SUPPORT_DMA_HEAP
- spin_unlock_irqrestore(&fp_priv->vcmdlock, flags);
-#endif
+ UNLOCK_CMDBUF_NODE(k, flags);
}
return 0;
@@ -2590,6 +2580,7 @@ static void vcmd_delink_rm_cmdbuf(struct hantrovcmd_dev *dev,
struct cmdbuf_obj *cmdbuf_obj = (struct cmdbuf_obj *)cmdbuf_node->data;
bi_list_node *prev = cmdbuf_node->previous;
bi_list_node *next = cmdbuf_node->next;
+ unsigned long flags = 0;
LOG_DBG("Delink and remove cmdbuf [%d] from vcmd list.\n",
cmdbuf_obj->cmdbuf_id);
@@ -2609,7 +2600,9 @@ static void vcmd_delink_rm_cmdbuf(struct hantrovcmd_dev *dev,
#endif
bi_list_remove_node(list, cmdbuf_node);
+ LOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
global_cmdbuf_node[cmdbuf_obj->cmdbuf_id] = NULL;
+ UNLOCK_CMDBUF_NODE(cmdbuf_obj->cmdbuf_id, flags);
free_cmdbuf_node(cmdbuf_node);
cmdbuf_update_jmp_cmd(dev->hw_version_id, prev ? prev->data : NULL,
@@ -2627,7 +2620,6 @@ int hantrovcmd_open(struct inode *inode, struct file *filp)
struct process_manager_obj *process_manager_obj = NULL;
struct filp_priv *fp_priv = (struct filp_priv *)filp->private_data;
- spin_lock_init(&fp_priv->vcmdlock);
fp_priv->dev = (void *)dev;
process_manager_node = create_process_manager_node();
@@ -4182,6 +4174,10 @@ int hantrovcmd_init(void)
cmdbuf_used[0] = 1;
cmdbuf_used_residual -= 1;
+ for (i = 0; i < CMDBUF_LOCK_NUM; i++) {
+ spin_lock_init(&cmdbuf_lock[i]);
+ }
+
create_kernel_process_manager();
for (i = 0; i < MAX_VCMD_TYPE; i++) {
if (vcmd_type_core_num[i] == 0)
diff --git a/drivers/staging/media/eswin/vdec/hantrodec.h b/drivers/staging/media/eswin/vdec/hantrodec.h
index 9991f4e2ed8e..4f597b740eb2 100644
--- a/drivers/staging/media/eswin/vdec/hantrodec.h
+++ b/drivers/staging/media/eswin/vdec/hantrodec.h
@@ -164,7 +164,6 @@ struct filp_priv {
struct heap_root root_d1;
#endif
void *dev;
- spinlock_t vcmdlock;
atomic_t core_tasks[DEC_CORE_NUM]; /** for task count of 4 cores*/
};
#endif
--
2.47.0