2024-12-19 21:34:44 +00:00
|
|
|
From e6ab68dc8b3b40f5919b0c24086fd1be3eeab76d Mon Sep 17 00:00:00 2001
|
2024-12-15 18:29:23 +00:00
|
|
|
From: tangdaoyong <tangdaoyong@eswincomputing.com>
|
|
|
|
Date: Tue, 15 Oct 2024 14:00:44 +0800
|
|
|
|
Subject: [PATCH 190/219] fix:The wrong dev id was used for vcmd release
|
|
|
|
|
|
|
|
Changelogs:
|
|
|
|
1. The wrong dev id was used for vcmd release.
|
|
|
|
|
|
|
|
Signed-off-by: tangdaoyong <tangdaoyong@eswincomputing.com>
|
|
|
|
---
|
|
|
|
.../staging/media/eswin/vdec/hantro_vcmd.c | 98 ++++++++++++-------
|
|
|
|
1 file changed, 62 insertions(+), 36 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/drivers/staging/media/eswin/vdec/hantro_vcmd.c b/drivers/staging/media/eswin/vdec/hantro_vcmd.c
|
|
|
|
index 7fd375c41006..ee87be45c346 100644
|
|
|
|
--- a/drivers/staging/media/eswin/vdec/hantro_vcmd.c
|
|
|
|
+++ b/drivers/staging/media/eswin/vdec/hantro_vcmd.c
|
|
|
|
@@ -788,7 +788,7 @@ 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
|
|
|
|
+#define CMDBUF_LOCK_NUM 16
|
|
|
|
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)
|
|
|
|
@@ -1643,11 +1643,11 @@ static long release_cmdbuf(struct file *filp, u16 cmdbuf_id)
|
|
|
|
|
|
|
|
if (cmdbuf_obj->process_manager_obj) {
|
|
|
|
spin_lock_irqsave(&cmdbuf_obj->process_manager_obj->spinlock,
|
|
|
|
- flags);
|
|
|
|
+ flags);
|
|
|
|
cmdbuf_obj->process_manager_obj->total_exe_time -=
|
|
|
|
cmdbuf_obj->executing_time;
|
|
|
|
spin_unlock_irqrestore(&cmdbuf_obj->process_manager_obj->spinlock,
|
|
|
|
- flags);
|
|
|
|
+ flags);
|
|
|
|
wake_up_interruptible_all(&cmdbuf_obj->process_manager_obj->wait_queue);
|
|
|
|
}
|
|
|
|
free_cmdbuf_node(new_cmdbuf_node);
|
|
|
|
@@ -2413,6 +2413,7 @@ free_process_manager_obj(struct process_manager_obj *process_manager_obj)
|
|
|
|
LOG_DBG("%s\n", "free_process_manager_obj NULL");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
+ LOG_DBG("free process_manager_obj %px, filp=%px\n", process_manager_obj, process_manager_obj->filp);
|
|
|
|
//free current cmdbuf_obj
|
|
|
|
kfree(process_manager_obj);
|
|
|
|
return;
|
|
|
|
@@ -2482,6 +2483,7 @@ static void create_kernel_process_manager(void)
|
|
|
|
process_manager_obj =
|
|
|
|
(struct process_manager_obj *)process_manager_node->data;
|
|
|
|
process_manager_obj->filp = NULL;
|
|
|
|
+ LOG_DBG("create root process_manager_obj %px\n", process_manager_obj);
|
|
|
|
bi_list_insert_node_tail(&global_process_manager, process_manager_node);
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2644,7 +2646,7 @@ int hantrovcmd_open(struct inode *inode, struct file *filp)
|
|
|
|
spin_unlock_irqrestore(&vcmd_process_manager_lock, flags);
|
|
|
|
|
|
|
|
LOG_DBG("dev opened\n");
|
|
|
|
- LOG_DBG("process node %p for filp opened %p\n", (void *)process_manager_node, (void *)filp);
|
|
|
|
+ LOG_DBG("opened::process obj %px for filp %px\n", (void *)process_manager_obj, (void *)filp);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2656,11 +2658,12 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
u32 release_cmdbuf_num = 0;
|
|
|
|
bi_list_node *new_cmdbuf_node = NULL;
|
|
|
|
struct cmdbuf_obj *cmdbuf_obj_temp = NULL;
|
|
|
|
- bi_list_node *process_manager_node;
|
|
|
|
+ bi_list_node *process_manager_node = NULL;
|
|
|
|
struct process_manager_obj *process_manager_obj = NULL;
|
|
|
|
int vcmd_aborted = 0; // vcmd is aborted in this function
|
|
|
|
struct cmdbuf_obj *restart_cmdbuf = NULL;
|
|
|
|
bi_list_node *next_cmdbuf = NULL;
|
|
|
|
+ bi_list_node *removed_node = NULL;
|
|
|
|
|
|
|
|
unsigned long flags;
|
|
|
|
long retVal = 0;
|
|
|
|
@@ -2673,13 +2676,14 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
fp_priv = (struct filp_priv *)filp->private_data;
|
|
|
|
dev = (struct hantrovcmd_dev *)fp_priv->dev;
|
|
|
|
|
|
|
|
- if (down_interruptible(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]))
|
|
|
|
- return -ERESTARTSYS;
|
|
|
|
-
|
|
|
|
if (dev->hw_version_id >= HW_ID_1_2_1) {
|
|
|
|
for (core_id = 0; core_id < total_vcmd_core_num; core_id++) {
|
|
|
|
if (!(&dev[core_id]))
|
|
|
|
continue;
|
|
|
|
+
|
|
|
|
+ if (down_interruptible(&vcmd_reserve_cmdbuf_sem[dev[core_id].vcmd_core_cfg.sub_module_type]))
|
|
|
|
+ return -ERESTARTSYS;
|
|
|
|
+
|
|
|
|
spin_lock_irqsave(dev[core_id].spinlock, flags);
|
|
|
|
new_cmdbuf_node = dev[core_id].list_manager.head;
|
|
|
|
while (1) {
|
|
|
|
@@ -2696,15 +2700,17 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
if (cmdbuf_obj_temp->cmdbuf_run_done) {
|
|
|
|
cmdbuf_obj_temp->cmdbuf_need_remove = 1;
|
|
|
|
retVal = release_cmdbuf_node(&dev[core_id].list_manager, new_cmdbuf_node);
|
|
|
|
- if (retVal == 1)
|
|
|
|
+ if (retVal == 1) {
|
|
|
|
cmdbuf_obj_temp->process_manager_obj = NULL;
|
|
|
|
+ }
|
|
|
|
} else if (cmdbuf_obj_temp->cmdbuf_data_linked == 0) {
|
|
|
|
cmdbuf_obj_temp->cmdbuf_data_linked = 1;
|
|
|
|
cmdbuf_obj_temp->cmdbuf_run_done = 1;
|
|
|
|
cmdbuf_obj_temp->cmdbuf_need_remove = 1;
|
|
|
|
retVal = release_cmdbuf_node(&dev[core_id].list_manager, new_cmdbuf_node);
|
|
|
|
- if (retVal == 1)
|
|
|
|
+ if (retVal == 1) {
|
|
|
|
cmdbuf_obj_temp->process_manager_obj = NULL;
|
|
|
|
+ }
|
|
|
|
} else if (cmdbuf_obj_temp->cmdbuf_data_linked == 1 &&
|
|
|
|
dev[core_id].working_state == WORKING_STATE_IDLE) {
|
|
|
|
vcmd_delink_rm_cmdbuf(&dev[core_id], new_cmdbuf_node);
|
|
|
|
@@ -2725,7 +2731,7 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
|
|
|
|
//abort the vcmd and wait
|
|
|
|
LOG_DBG("Abort due to linked cmdbuf %d of current process.\n", cmdbuf_obj_temp->cmdbuf_id);
|
|
|
|
- printk_vcmd_register_debug((const void *)dev->hwregs, "Before trigger to 0");
|
|
|
|
+ printk_vcmd_register_debug((const void *)dev[core_id].hwregs, "Before trigger to 0");
|
|
|
|
// disable abort interrupt
|
|
|
|
//vcmd_write_register_value((const void *)dev[core_id].hwregs,
|
|
|
|
//dev[core_id].reg_mirror,HWIF_VCMD_IRQ_ABORT_EN,0);
|
|
|
|
@@ -2735,7 +2741,7 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
0);
|
|
|
|
vcmd_aborted = 1;
|
|
|
|
|
|
|
|
- printk_vcmd_register_debug((const void *)dev->hwregs, "After trigger to 0");
|
|
|
|
+ printk_vcmd_register_debug((const void *)dev[core_id].hwregs, "After trigger to 0");
|
|
|
|
// Wait vcmd core aborted and vcmd enters IDLE mode.
|
|
|
|
//while (dev[core_id].working_state != WORKING_STATE_IDLE) {
|
|
|
|
while (vcmd_get_register_value((const void *)dev[core_id].hwregs,
|
|
|
|
@@ -2744,10 +2750,10 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
loop_count++;
|
|
|
|
if (!(loop_count % 10)) {
|
|
|
|
LOG_ERR("expected idle state, but irq status = 0x%0x\n",
|
|
|
|
- vcmd_read_reg((const void *)dev->hwregs,
|
|
|
|
+ vcmd_read_reg((const void *)dev[core_id].hwregs,
|
|
|
|
VCMD_REGISTER_INT_STATUS_OFFSET));
|
|
|
|
LOG_ERR("vcmd current status is %d\n",
|
|
|
|
- vcmd_get_register_value((const void *)dev->hwregs,
|
|
|
|
+ vcmd_get_register_value((const void *)dev[core_id].hwregs,
|
|
|
|
dev[core_id].reg_mirror,
|
|
|
|
HWIF_VCMD_WORK_STATE));
|
|
|
|
}
|
|
|
|
@@ -2756,7 +2762,7 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
if (loop_count > 100) {
|
|
|
|
LOG_ERR("too long before vcmd core to IDLE state\n");
|
|
|
|
spin_unlock_irqrestore(dev[core_id].spinlock, flags);
|
|
|
|
- up(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]);
|
|
|
|
+ up(&vcmd_reserve_cmdbuf_sem[dev[core_id].vcmd_core_cfg.sub_module_type]);
|
|
|
|
return -ERESTARTSYS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -2766,11 +2772,11 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
dev[core_id].reg_mirror,
|
|
|
|
HWIF_VCMD_IRQ_ABORT)) {
|
|
|
|
LOG_DBG("Abort interrupt triggered, now clear it to avoid abort int...\n");
|
|
|
|
- vcmd_write_reg((const void *)dev->hwregs,
|
|
|
|
+ vcmd_write_reg((const void *)dev[core_id].hwregs,
|
|
|
|
VCMD_REGISTER_INT_STATUS_OFFSET,
|
|
|
|
0x1 << 4);
|
|
|
|
LOG_DBG("Now irq status = 0x%0x.\n",
|
|
|
|
- vcmd_read_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET));
|
|
|
|
+ vcmd_read_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET));
|
|
|
|
}
|
|
|
|
//printk_vcmd_register_debug((const void *)dev->hwregs, "vcmd status to IDLE");
|
|
|
|
|
|
|
|
@@ -2863,9 +2869,9 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
|
|
|
|
LOG_DBG("Restart from cmdbuf [%d] after aborting.\n", restart_cmdbuf->cmdbuf_id);
|
|
|
|
|
|
|
|
- irq_status1 = vcmd_read_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET);
|
|
|
|
- vcmd_write_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET, irq_status1);
|
|
|
|
- irq_status2 = vcmd_read_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET);
|
|
|
|
+ irq_status1 = vcmd_read_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET);
|
|
|
|
+ vcmd_write_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET, irq_status1);
|
|
|
|
+ irq_status2 = vcmd_read_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET);
|
|
|
|
LOG_DBG("Clear irq status from 0x%0x -> 0x%0x\n", irq_status1, irq_status2);
|
|
|
|
if (mmu_enable) {
|
|
|
|
vcmd_write_register_value((const void *)dev[core_id].hwregs,
|
|
|
|
@@ -2922,7 +2928,7 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
dev[core_id].reg_mirror,
|
|
|
|
HWIF_VCMD_RDY_CMDBUF_COUNT,
|
|
|
|
dev[core_id].sw_cmdbuf_rdy_num);
|
|
|
|
- printk_vcmd_register_debug((const void *)dev->hwregs, "before restart");
|
|
|
|
+ printk_vcmd_register_debug((const void *)dev[core_id].hwregs, "before restart");
|
|
|
|
vcmd_write_register_value(
|
|
|
|
(const void *)dev[core_id].hwregs,
|
|
|
|
dev[core_id].reg_mirror,
|
|
|
|
@@ -2936,7 +2942,7 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
HWIF_VCMD_START_TRIGGER));
|
|
|
|
LOG_DBG("dev state from %d -> WORKING.\n", dev[core_id].working_state);
|
|
|
|
dev[core_id].working_state = WORKING_STATE_WORKING;
|
|
|
|
- printk_vcmd_register_debug((const void *)dev->hwregs, "after restart");
|
|
|
|
+ printk_vcmd_register_debug((const void *)dev[core_id].hwregs, "after restart");
|
|
|
|
} else {
|
|
|
|
LOG_DBG("No more command buffer to be restarted!\n");
|
|
|
|
}
|
|
|
|
@@ -2944,11 +2950,17 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
// VCMD aborted but not restarted, nedd to wake up
|
|
|
|
if (vcmd_aborted && !restart_cmdbuf)
|
|
|
|
wake_up_interruptible_all(dev[core_id].wait_queue);
|
|
|
|
+
|
|
|
|
+ up(&vcmd_reserve_cmdbuf_sem[dev[core_id].vcmd_core_cfg.sub_module_type]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (core_id = 0; core_id < total_vcmd_core_num; core_id++) {
|
|
|
|
if ((&dev[core_id]) == NULL)
|
|
|
|
continue;
|
|
|
|
+
|
|
|
|
+ if (down_interruptible(&vcmd_reserve_cmdbuf_sem[dev[core_id].vcmd_core_cfg.sub_module_type]))
|
|
|
|
+ return -ERESTARTSYS;
|
|
|
|
+
|
|
|
|
spin_lock_irqsave(dev[core_id].spinlock, flags);
|
|
|
|
new_cmdbuf_node = dev[core_id].list_manager.head;
|
|
|
|
while (1) {
|
|
|
|
@@ -2960,22 +2972,25 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
if (cmdbuf_obj_temp->cmdbuf_run_done) {
|
|
|
|
cmdbuf_obj_temp->cmdbuf_need_remove = 1;
|
|
|
|
retVal = release_cmdbuf_node(&dev[core_id].list_manager, new_cmdbuf_node);
|
|
|
|
- if (retVal == 1)
|
|
|
|
+ if (retVal == 1) {
|
|
|
|
cmdbuf_obj_temp->process_manager_obj = NULL;
|
|
|
|
+ }
|
|
|
|
} else if (cmdbuf_obj_temp->cmdbuf_data_linked == 0) {
|
|
|
|
cmdbuf_obj_temp->cmdbuf_data_linked = 1;
|
|
|
|
cmdbuf_obj_temp->cmdbuf_run_done = 1;
|
|
|
|
cmdbuf_obj_temp->cmdbuf_need_remove = 1;
|
|
|
|
retVal = release_cmdbuf_node(&dev[core_id].list_manager, new_cmdbuf_node);
|
|
|
|
- if (retVal == 1)
|
|
|
|
+ if (retVal == 1) {
|
|
|
|
cmdbuf_obj_temp->process_manager_obj = NULL;
|
|
|
|
+ }
|
|
|
|
} else if (cmdbuf_obj_temp->cmdbuf_data_linked == 1 &&
|
|
|
|
dev[core_id].working_state == WORKING_STATE_IDLE) {
|
|
|
|
cmdbuf_obj_temp->cmdbuf_run_done = 1;
|
|
|
|
cmdbuf_obj_temp->cmdbuf_need_remove = 1;
|
|
|
|
retVal = release_cmdbuf_node(&dev[core_id].list_manager, new_cmdbuf_node);
|
|
|
|
- if (retVal == 1)
|
|
|
|
+ if (retVal == 1) {
|
|
|
|
cmdbuf_obj_temp->process_manager_obj = NULL;
|
|
|
|
+ }
|
|
|
|
} else if (cmdbuf_obj_temp->cmdbuf_data_linked ==1 &&
|
|
|
|
dev[core_id].working_state == WORKING_STATE_WORKING) {
|
|
|
|
bi_list_node *last_cmdbuf_node;
|
|
|
|
@@ -2987,21 +3002,22 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
0);
|
|
|
|
if (wait_event_interruptible(*dev[core_id].wait_abort_queue, wait_abort_rdy(&dev[core_id]))) {
|
|
|
|
spin_unlock_irqrestore(dev[core_id].spinlock, flags);
|
|
|
|
- up(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]);
|
|
|
|
+ up(&vcmd_reserve_cmdbuf_sem[dev[core_id].vcmd_core_cfg.sub_module_type]);
|
|
|
|
return -ERESTARTSYS;
|
|
|
|
}
|
|
|
|
cmdbuf_obj_temp->cmdbuf_run_done = 1;
|
|
|
|
cmdbuf_obj_temp->cmdbuf_need_remove = 1;
|
|
|
|
retVal = release_cmdbuf_node(&dev[core_id].list_manager, new_cmdbuf_node);
|
|
|
|
- if (retVal == 1)
|
|
|
|
+ if (retVal == 1) {
|
|
|
|
cmdbuf_obj_temp->process_manager_obj = NULL;
|
|
|
|
+ }
|
|
|
|
//link
|
|
|
|
last_cmdbuf_node = find_last_linked_cmdbuf(dev[core_id].list_manager.tail);
|
|
|
|
- record_last_cmdbuf_rdy_num = dev->sw_cmdbuf_rdy_num;
|
|
|
|
- vcmd_link_cmdbuf(dev, last_cmdbuf_node);
|
|
|
|
+ record_last_cmdbuf_rdy_num = dev[core_id].sw_cmdbuf_rdy_num;
|
|
|
|
+ vcmd_link_cmdbuf(&dev[core_id], last_cmdbuf_node);
|
|
|
|
//re-run
|
|
|
|
if (dev[core_id].sw_cmdbuf_rdy_num)
|
|
|
|
- vcmd_start(dev, last_cmdbuf_node);
|
|
|
|
+ vcmd_start(&dev[core_id], last_cmdbuf_node);
|
|
|
|
}
|
|
|
|
release_cmdbuf_num++;
|
|
|
|
LOG_DBG("release reserved cmdbuf\n");
|
|
|
|
@@ -3009,6 +3025,8 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
new_cmdbuf_node = next_cmdbuf;
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(dev[core_id].spinlock, flags);
|
|
|
|
+
|
|
|
|
+ up(&vcmd_reserve_cmdbuf_sem[dev[core_id].vcmd_core_cfg.sub_module_type]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -3021,17 +3039,25 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
|
|
|
if (!process_manager_node)
|
|
|
|
break;
|
|
|
|
process_manager_obj = (struct process_manager_obj *)process_manager_node->data;
|
|
|
|
- if (process_manager_obj->filp == filp)
|
|
|
|
+ if (process_manager_obj->filp == filp) {
|
|
|
|
+ removed_node = process_manager_node;
|
|
|
|
break;
|
|
|
|
+ }
|
|
|
|
process_manager_node = process_manager_node->next;
|
|
|
|
}
|
|
|
|
//remove node from list
|
|
|
|
- LOG_DBG("process node %p for filp to be removed: %p\n",
|
|
|
|
- (void *)process_manager_node, (void *)process_manager_obj->filp);
|
|
|
|
- bi_list_remove_node(&global_process_manager, process_manager_node);
|
|
|
|
+ if (removed_node) {
|
|
|
|
+ LOG_DBG("process node %p for filp to be removed: %px\n",
|
|
|
|
+ (void *)removed_node, (void *)process_manager_obj->filp);
|
|
|
|
+ bi_list_remove_node(&global_process_manager, removed_node);
|
|
|
|
+ }
|
|
|
|
spin_unlock_irqrestore(&vcmd_process_manager_lock, flags);
|
|
|
|
- free_process_manager_node(process_manager_node);
|
|
|
|
- up(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]);
|
|
|
|
+ if (removed_node) {
|
|
|
|
+ free_process_manager_node(removed_node);
|
|
|
|
+ } else {
|
|
|
|
+ LOG_WARN("no process node release for filp %px\n", filp);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
--
|
|
|
|
2.47.0
|
|
|
|
|