media: rockchip: isp: fix resource release if user crashes

Change-Id: I3587300198b4896f28278812651b38d08fdce2bf
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2025-06-26 10:08:01 +08:00
committed by Tao Huang
parent 835babb6ea
commit f597a314cd
12 changed files with 109 additions and 25 deletions

View File

@@ -304,7 +304,6 @@ static void rkisp_params_vb2_stop_streaming(struct vb2_queue *vq)
params_vdev->first_cfg_params = true;
return;
}
rkisp_params_disable_isp(params_vdev);
/* clean module params */
params_vdev->ops->clear_first_param(params_vdev);
params_vdev->rdbk_times = 0;
@@ -566,9 +565,12 @@ void rkisp_params_meshbuf_free(struct rkisp_isp_params_vdev *params_vdev, u64 id
void rkisp_params_stream_stop(struct rkisp_isp_params_vdev *params_vdev)
{
rkisp_params_disable_isp(params_vdev);
/* isp stop to free buf */
if (params_vdev->ops->stream_stop)
params_vdev->ops->stream_stop(params_vdev);
if (!atomic_read(&params_vdev->open_cnt) && params_vdev->ops->fop_release)
params_vdev->ops->fop_release(params_vdev);
}
bool rkisp_params_check_bigmode(struct rkisp_isp_params_vdev *params_vdev)

View File

@@ -5066,9 +5066,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
rkisp_free_buffer(params_vdev->dev, buf);
} else {
is_alloc = false;
buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
if (buf->dma_fd < 0)
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
goto err;
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
}
}
if (is_alloc) {
@@ -5079,9 +5079,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
goto err;
}
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
mesh_head->stat = MESH_BUF_INIT;
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
}
mesh_head->stat = MESH_BUF_INIT;
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
buf++;
}

View File

@@ -4055,9 +4055,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
rkisp_free_buffer(params_vdev->dev, buf);
} else {
is_alloc = false;
buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
if (buf->dma_fd < 0)
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
goto err;
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
}
}
if (is_alloc) {
@@ -4068,9 +4068,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
goto err;
}
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
mesh_head->stat = MESH_BUF_INIT;
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
}
mesh_head->stat = MESH_BUF_INIT;
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
buf++;
}

View File

@@ -4988,9 +4988,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
rkisp_free_buffer(params_vdev->dev, buf);
} else {
is_alloc = false;
buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
if (buf->dma_fd < 0)
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
goto err;
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
}
}
if (is_alloc) {
@@ -5001,11 +5001,12 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
goto err;
}
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
mesh_head->stat = MESH_BUF_INIT;
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
}
mesh_head->stat = MESH_BUF_INIT;
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
if (meshsize->module_id == ISP35_MODULE_BAY3D)
mesh_head->data1_oft = mesh_head->data_oft +
ALIGN(priv->b3dldc_hsize * 4 * priv->b3dldch_vsize, 16);
}
buf++;
}

View File

@@ -4430,9 +4430,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
rkisp_free_buffer(params_vdev->dev, buf);
} else {
is_alloc = false;
buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
if (buf->dma_fd < 0)
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
goto err;
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
}
}
if (is_alloc) {
@@ -4443,9 +4443,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
goto err;
}
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
mesh_head->stat = MESH_BUF_INIT;
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
}
mesh_head->stat = MESH_BUF_INIT;
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
buf++;
}

View File

@@ -4497,6 +4497,7 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
u32 mesh_size, buf_size;
int i, ret, id = meshsize->unite_isp_id;
int buf_cnt = meshsize->buf_cnt;
bool is_alloc;
priv_val = params_vdev->priv_val;
if (!priv_val) {
@@ -4529,14 +4530,26 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
buf->is_need_vaddr = true;
buf->is_need_dbuf = true;
buf->is_need_dmafd = true;
buf->size = buf_size;
ret = rkisp_alloc_buffer(params_vdev->dev, buf);
if (ret) {
dev_err(dev, "%s failed\n", __func__);
goto err;
is_alloc = true;
if (buf->mem_priv) {
if (buf_size > buf->size) {
rkisp_free_buffer(params_vdev->dev, buf);
} else {
is_alloc = false;
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
goto err;
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
}
}
if (is_alloc) {
buf->size = buf_size;
ret = rkisp_alloc_buffer(params_vdev->dev, buf);
if (ret) {
dev_err(dev, "%s failed\n", __func__);
goto err;
}
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
}
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
mesh_head->stat = MESH_BUF_INIT;
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
buf++;

View File

@@ -219,6 +219,8 @@ static void rkisp_stats_vb2_stop_streaming(struct vb2_queue *vq)
stats_vdev->ae_meas_done_next = false;
stats_vdev->af_meas_done_next = false;
if (stats_vdev->ops->stats_stop)
stats_vdev->ops->stats_stop(stats_vdev);
}
static int

View File

@@ -38,6 +38,7 @@ struct rkisp_isp_stats_ops {
void (*first_ddr_cfg)(struct rkisp_isp_stats_vdev *stats_vdev);
void (*next_ddr_cfg)(struct rkisp_isp_stats_vdev *stats_vdev);
int (*stats_tb)(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp_buffer *stats_buf);
void (*stats_stop)(struct rkisp_isp_stats_vdev *stats_vdev);
};
/*

View File

@@ -1146,6 +1146,21 @@ rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev)
rkisp_stats_update_buf(stats_vdev);
}
static void rkisp_stats_stop_v32(struct rkisp_isp_stats_vdev *stats_vdev)
{
struct rkisp_device *dev = stats_vdev->dev;
u32 val, addr;
/* aiq crash or exit first */
if (dev->isp_state & ISP_START &&
stats_vdev->stats_buf[0].mem_priv) {
rkisp_stats_update_buf(stats_vdev);
addr = stats_vdev->stats_buf[0].dma_addr;
readl_poll_timeout(dev->hw_dev->base_addr + ISP3X_MI_3A_WR_BASE,
val, val == addr, 5000, 50000);
}
}
static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
.isr_hdl = rkisp_stats_isr_v32,
.send_meas = rkisp_stats_send_meas_v32,
@@ -1154,6 +1169,7 @@ static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
.stats_tb = rkisp_stats_tb_v32,
.first_ddr_cfg = rkisp_stats_first_ddr_config_v32,
.next_ddr_cfg = rkisp_stats_next_ddr_config_v32,
.stats_stop = rkisp_stats_stop_v32,
};
void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev)
@@ -1167,6 +1183,7 @@ void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev)
rkisp_isp_stats_ops_tbl.stats_tb = NULL;
rkisp_isp_stats_ops_tbl.first_ddr_cfg = NULL;
rkisp_isp_stats_ops_tbl.next_ddr_cfg = NULL;
rkisp_isp_stats_ops_tbl.stats_stop = NULL;
}
stats_vdev->ops = &rkisp_isp_stats_ops_tbl;
}

View File

@@ -568,6 +568,21 @@ rkisp_stats_next_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev)
rkisp_stats_update_buf(stats_vdev);
}
static void rkisp_stats_stop_v33(struct rkisp_isp_stats_vdev *stats_vdev)
{
struct rkisp_device *dev = stats_vdev->dev;
u32 val, addr;
/* aiq crash or exit first */
if (dev->isp_state & ISP_START &&
stats_vdev->stats_buf[0].mem_priv) {
rkisp_stats_update_buf(stats_vdev);
addr = stats_vdev->stats_buf[0].dma_addr;
readl_poll_timeout(dev->hw_dev->base_addr + ISP39_W3A_AEBIG_ADDR_SHD,
val, val == addr, 5000, 50000);
}
}
static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
.isr_hdl = rkisp_stats_isr_v33,
.send_meas = rkisp_stats_send_meas_v33,
@@ -575,6 +590,7 @@ static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
.stats_tb = rkisp_stats_tb_v33,
.first_ddr_cfg = rkisp_stats_first_ddr_config_v33,
.next_ddr_cfg = rkisp_stats_next_ddr_config_v33,
.stats_stop = rkisp_stats_stop_v33,
};
void rkisp_init_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev)

View File

@@ -862,12 +862,28 @@ rkisp_stats_next_ddr_config_v35(struct rkisp_isp_stats_vdev *stats_vdev)
}
}
static void rkisp_stats_stop_v35(struct rkisp_isp_stats_vdev *stats_vdev)
{
struct rkisp_device *dev = stats_vdev->dev;
u32 val, addr;
/* aiq crash or exit first */
if (dev->isp_state & ISP_START &&
stats_vdev->stats_buf[0].mem_priv) {
rkisp_stats_update_buf(stats_vdev);
addr = stats_vdev->stats_buf[0].dma_addr;
readl_poll_timeout(dev->hw_dev->base_addr + ISP39_W3A_AEBIG_ADDR_SHD,
val, val == addr, 5000, 50000);
}
}
static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
.isr_hdl = rkisp_stats_isr_v35,
.get_stat_size = rkisp_get_stat_size_v35,
.stats_tb = rkisp_stats_tb_v35,
.first_ddr_cfg = rkisp_stats_first_ddr_config_v35,
.next_ddr_cfg = rkisp_stats_next_ddr_config_v35,
.stats_stop = rkisp_stats_stop_v35,
};
void rkisp_init_stats_vdev_v35(struct rkisp_isp_stats_vdev *stats_vdev)

View File

@@ -536,11 +536,27 @@ rkisp_stats_next_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev)
}
}
static void rkisp_stats_stop_v39(struct rkisp_isp_stats_vdev *stats_vdev)
{
struct rkisp_device *dev = stats_vdev->dev;
u32 val, addr;
/* aiq crash or exit first */
if (dev->isp_state & ISP_START &&
stats_vdev->stats_buf[0].mem_priv) {
rkisp_stats_update_buf(stats_vdev);
addr = stats_vdev->stats_buf[0].dma_addr;
readl_poll_timeout(dev->hw_dev->base_addr + ISP39_W3A_AEBIG_ADDR_SHD,
val, val == addr, 5000, 50000);
}
}
static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
.isr_hdl = rkisp_stats_isr_v39,
.get_stat_size = rkisp_get_stat_size_v39,
.first_ddr_cfg = rkisp_stats_first_ddr_config_v39,
.next_ddr_cfg = rkisp_stats_next_ddr_config_v39,
.stats_stop = rkisp_stats_stop_v39,
};
void rkisp_init_stats_vdev_v39(struct rkisp_isp_stats_vdev *stats_vdev)