summaryrefslogtreecommitdiff
path: root/drivers/mxc
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 15:41:25 +0800
commit0cd3c661b95ecb273da5ee76fe7353ab7abd38c9 (patch)
tree49579a4eab160598c4c93cf91d4341c0fdbe215d /drivers/mxc
parentb45c81db62f95a87ce265fdaadc4a54da51f1bf0 (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>
Diffstat (limited to 'drivers/mxc')
-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 df51e63e9982..927503cadb2c 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"
@@ -5855,8 +5855,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;
}
@@ -6023,13 +6022,22 @@ static int v4l2_open(struct file *filp)
mutex_init(&ctx->cmd_lock);
mutex_init(&ctx->perf_lock);
mutex_init(&ctx->fw_flow_mutex);
- 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;
@@ -6113,8 +6121,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);
@@ -6194,7 +6206,10 @@ static int v4l2_release(struct file *filp)
cancel_delayed_work_sync(ctx->delayed_instance_work);
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);
@@ -6554,13 +6569,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) {
@@ -6594,7 +6615,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);
@@ -6631,7 +6654,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;
vpu_dec_cancel_work(dev);
destroy_workqueue(dev->workqueue);
if (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 b9bb627a21c9..fc7f9e8149b1 100644
--- a/drivers/mxc/vpu_malone/vpu_b0.h
+++ b/drivers/mxc/vpu_malone/vpu_b0.h
@@ -324,6 +324,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 */
@@ -408,6 +410,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 delayed_work *delayed_instance_work;