summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMing Qian <ming.qian@nxp.com>2020-03-24 10:18:58 +0800
committerMing Qian <ming.qian@nxp.com>2020-03-24 17:14:55 +0800
commit82a6695ed109efa89307b4b0b5a53ba12f792b29 (patch)
treeab44a9919214f4d0aca146518c0d669677e02784
parentfc7c45cf829d1ed562f04cc219b5a79419ffa0c1 (diff)
MLK-23220:mxc:vpu_malone:kfifo_alloc failure in VPU driver when memory fragment
Suggest to use vmalloc for fifo entity. Then use kfifo_init to init the fifo structure. Then we do not have to require contiguous memory from buddy, especially in a high pressure of memory resource. Signed-off-by: Ming Qian <ming.qian@nxp.com> (cherry picked from commit 0cd3c661b95ecb273da5ee76fe7353ab7abd38c9)
-rw-r--r--drivers/mxc/vpu_malone/vpu_b0.c53
-rw-r--r--drivers/mxc/vpu_malone/vpu_b0.h4
2 files changed, 43 insertions, 14 deletions
diff --git a/drivers/mxc/vpu_malone/vpu_b0.c b/drivers/mxc/vpu_malone/vpu_b0.c
index 6757f7251ec0..6482a05fca24 100644
--- a/drivers/mxc/vpu_malone/vpu_b0.c
+++ b/drivers/mxc/vpu_malone/vpu_b0.c
@@ -40,7 +40,7 @@
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
-#include <media/videobuf2-dma-sg.h>
+#include <media/videobuf2-vmalloc.h>
#include "vpu_b0.h"
#include "insert_startcode.h"
@@ -5650,8 +5650,7 @@ static int create_instance_file(struct vpu_ctx *ctx)
create_instance_buffer_file(ctx);
create_instance_flow_file(ctx);
create_instance_perf_file(ctx);
- atomic64_set(&ctx->statistic.total_dma_size, 0);
- atomic64_set(&ctx->statistic.total_alloc_size, 0);
+
return 0;
}
@@ -5816,13 +5815,22 @@ static int v4l2_open(struct file *filp)
mutex_init(&ctx->instance_mutex);
mutex_init(&ctx->cmd_lock);
mutex_init(&ctx->perf_lock);
- if (kfifo_alloc(&ctx->msg_fifo,
- sizeof(struct event_msg) * VID_API_MESSAGE_LIMIT,
- GFP_KERNEL)) {
+ atomic64_set(&ctx->statistic.total_dma_size, 0);
+ atomic64_set(&ctx->statistic.total_alloc_size, 0);
+
+ ctx->msg_buffer_size = sizeof(struct event_msg) * VID_API_MESSAGE_LIMIT;
+ ctx->msg_buffer = vzalloc(ctx->msg_buffer_size);
+ if (!ctx->msg_buffer) {
vpu_err("fail to alloc fifo when open\n");
ret = -ENOMEM;
goto err_alloc_fifo;
}
+ atomic64_add(ctx->msg_buffer_size, &ctx->statistic.total_alloc_size);
+ if (kfifo_init(&ctx->msg_fifo, ctx->msg_buffer, ctx->msg_buffer_size)) {
+ vpu_err("fail to init fifo when open\n");
+ ret = -EINVAL;
+ goto err_init_kfifo;
+ }
ctx->dev = dev;
ctx->str_index = idx;
dev->ctx[idx] = ctx;
@@ -5906,8 +5914,12 @@ err_open_crc:
ctx->tsm = NULL;
err_create_tsm:
remove_instance_file(ctx);
- kfifo_free(&ctx->msg_fifo);
dev->ctx[idx] = NULL;
+err_init_kfifo:
+ vfree(ctx->msg_buffer);
+ atomic64_sub(ctx->msg_buffer_size, &ctx->statistic.total_alloc_size);
+ ctx->msg_buffer = NULL;
+ ctx->msg_buffer_size = 0;
err_alloc_fifo:
mutex_destroy(&ctx->instance_mutex);
mutex_destroy(&ctx->cmd_lock);
@@ -5983,7 +5995,10 @@ static int v4l2_release(struct file *filp)
mutex_lock(&ctx->dev->dev_mutex);
ctx->ctx_released = true;
cancel_work_sync(&ctx->instance_work);
- kfifo_free(&ctx->msg_fifo);
+ vfree(ctx->msg_buffer);
+ atomic64_sub(ctx->msg_buffer_size, &ctx->statistic.total_alloc_size);
+ ctx->msg_buffer = NULL;
+ ctx->msg_buffer_size = 0;
if (ctx->instance_wq)
destroy_workqueue(ctx->instance_wq);
mutex_unlock(&ctx->dev->dev_mutex);
@@ -6331,13 +6346,19 @@ static int vpu_probe(struct platform_device *pdev)
if (ret)
goto err_rm_vdev;
- ret = kfifo_alloc(&dev->mu_msg_fifo,
- sizeof(u_int32) * VPU_MAX_NUM_STREAMS * VID_API_MESSAGE_LIMIT,
- GFP_KERNEL);
- if (ret) {
+ dev->mu_msg_buffer_size =
+ sizeof(u_int32) * VPU_MAX_NUM_STREAMS * VID_API_MESSAGE_LIMIT;
+ dev->mu_msg_buffer = vzalloc(dev->mu_msg_buffer_size);
+ if (!dev->mu_msg_buffer) {
vpu_err("error: fail to alloc mu msg fifo\n");
goto err_rm_vdev;
}
+ ret = kfifo_init(&dev->mu_msg_fifo,
+ dev->mu_msg_buffer, dev->mu_msg_buffer_size);
+ if (ret) {
+ vpu_err("error: fail to init mu msg fifo\n");
+ goto err_free_fifo;
+ }
dev->workqueue = alloc_workqueue("vpu", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
if (!dev->workqueue) {
@@ -6369,7 +6390,9 @@ err_poweroff:
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
err_free_fifo:
- kfifo_free(&dev->mu_msg_fifo);
+ vfree(dev->mu_msg_buffer);
+ dev->mu_msg_buffer = NULL;
+ dev->mu_msg_buffer_size = 0;
err_rm_vdev:
if (dev->pvpu_decoder_dev) {
video_unregister_device(dev->pvpu_decoder_dev);
@@ -6406,7 +6429,9 @@ static int vpu_remove(struct platform_device *pdev)
dev->debugfs_root = NULL;
dev->debugfs_dbglog = NULL;
dev->debugfs_fwlog = NULL;
- kfifo_free(&dev->mu_msg_fifo);
+ vfree(dev->mu_msg_buffer);
+ dev->mu_msg_buffer = NULL;
+ dev->mu_msg_buffer_size = 0;
destroy_workqueue(dev->workqueue);
if (dev->m0_p_fw_space_vir)
iounmap(dev->m0_p_fw_space_vir);
diff --git a/drivers/mxc/vpu_malone/vpu_b0.h b/drivers/mxc/vpu_malone/vpu_b0.h
index e1e0949e5237..3756a9ea7765 100644
--- a/drivers/mxc/vpu_malone/vpu_b0.h
+++ b/drivers/mxc/vpu_malone/vpu_b0.h
@@ -314,6 +314,8 @@ struct vpu_dev {
char precheck_content[1024];
struct kfifo mu_msg_fifo;
+ void *mu_msg_buffer;
+ unsigned int mu_msg_buffer_size;
u_int32 vpu_irq;
/* reserve for kernel version 5.4 or later */
@@ -399,6 +401,8 @@ struct vpu_ctx {
int str_index;
struct queue_data q_data[2];
struct kfifo msg_fifo;
+ void *msg_buffer;
+ unsigned int msg_buffer_size;
struct mutex instance_mutex;
struct work_struct instance_work;
struct workqueue_struct *instance_wq;