media: amphion: Use kmalloc instead of vmalloc

Replace vmalloc/vfree with kmalloc/kfree for allocating small
driver structures (vpu_inst, vdec_t, venc_t, vpu_cmd_t, and
frame objects).

vmalloc() is designed for large memory allocations and incurs
unnecessary overhead for small objects due to virtual memory
mapping. kmalloc() is more appropriate as it allocates physically
contiguous memory with lower overhead.

ftrace measurements of vpu_alloc_cmd() show significant improvement:

  Before (vmalloc):  35-72 us   (avg ~45.7 us)
  After (kmalloc):   11-26 us   (avg ~16.8 us)

This reduces allocation time by approximately 63%.

No functional changes are intended.

Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
Ming Qian 2025-12-22 16:49:10 +08:00 committed by Hans Verkuil
parent bb22847d11
commit d79c2165a4
4 changed files with 27 additions and 35 deletions

View File

@ -9,7 +9,6 @@
#include <linux/list.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
@ -17,7 +16,6 @@
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-vmalloc.h>
#include "vpu.h"
#include "vpu_defs.h"
#include "vpu_core.h"
@ -1662,9 +1660,9 @@ static void vdec_cleanup(struct vpu_inst *inst)
vdec->slots = NULL;
vdec->slot_count = 0;
}
vfree(vdec);
kfree(vdec);
inst->priv = NULL;
vfree(inst);
kfree(inst);
}
static void vdec_init_params(struct vdec_t *vdec)
@ -1929,13 +1927,13 @@ static int vdec_open(struct file *file)
struct vdec_t *vdec;
int ret;
inst = vzalloc(sizeof(*inst));
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst)
return -ENOMEM;
vdec = vzalloc(sizeof(*vdec));
vdec = kzalloc(sizeof(*vdec), GFP_KERNEL);
if (!vdec) {
vfree(inst);
kfree(inst);
return -ENOMEM;
}
@ -1943,8 +1941,8 @@ static int vdec_open(struct file *file)
sizeof(*vdec->slots),
GFP_KERNEL | __GFP_ZERO);
if (!vdec->slots) {
vfree(vdec);
vfree(inst);
kfree(vdec);
kfree(inst);
return -ENOMEM;
}
vdec->slot_count = VDEC_SLOT_CNT_DFT;

View File

@ -13,14 +13,12 @@
#include <linux/videodev2.h>
#include <linux/ktime.h>
#include <linux/rational.h>
#include <linux/vmalloc.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-vmalloc.h>
#include "vpu.h"
#include "vpu_defs.h"
#include "vpu_core.h"
@ -844,7 +842,7 @@ static int venc_get_encoded_frames(struct vpu_inst *inst)
v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))
break;
list_del_init(&frame->list);
vfree(frame);
kfree(frame);
}
return 0;
@ -860,7 +858,7 @@ static int venc_frame_encoded(struct vpu_inst *inst, void *arg)
if (!info)
return -EINVAL;
venc = inst->priv;
frame = vzalloc(sizeof(*frame));
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
if (!frame)
return -ENOMEM;
@ -912,9 +910,9 @@ static void venc_cleanup(struct vpu_inst *inst)
return;
venc = inst->priv;
vfree(venc);
kfree(venc);
inst->priv = NULL;
vfree(inst);
kfree(inst);
}
static int venc_start_session(struct vpu_inst *inst, u32 type)
@ -1067,7 +1065,7 @@ static void venc_cleanup_frames(struct venc_t *venc)
list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
list_del_init(&frame->list);
vfree(frame);
kfree(frame);
}
}
@ -1151,7 +1149,7 @@ static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
return ret;
list_del_init(&frame->list);
vfree(frame);
kfree(frame);
return 0;
}
@ -1309,13 +1307,13 @@ static int venc_open(struct file *file)
struct venc_t *venc;
int ret;
inst = vzalloc(sizeof(*inst));
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst)
return -ENOMEM;
venc = vzalloc(sizeof(*venc));
venc = kzalloc(sizeof(*venc), GFP_KERNEL);
if (!venc) {
vfree(inst);
kfree(inst);
return -ENOMEM;
}

View File

@ -13,7 +13,6 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/vmalloc.h>
#include "vpu.h"
#include "vpu_defs.h"
#include "vpu_cmds.h"
@ -84,13 +83,13 @@ static struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data
int i;
int ret;
cmd = vzalloc(sizeof(*cmd));
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd)
return NULL;
cmd->pkt = vzalloc(sizeof(*cmd->pkt));
cmd->pkt = kzalloc(sizeof(*cmd->pkt), GFP_KERNEL);
if (!cmd->pkt) {
vfree(cmd);
kfree(cmd);
return NULL;
}
@ -98,8 +97,8 @@ static struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data
ret = vpu_iface_pack_cmd(inst->core, cmd->pkt, inst->id, id, data);
if (ret) {
dev_err(inst->dev, "iface pack cmd %s fail\n", vpu_id_name(id));
vfree(cmd->pkt);
vfree(cmd);
kfree(cmd->pkt);
kfree(cmd);
return NULL;
}
for (i = 0; i < ARRAY_SIZE(vpu_cmd_requests); i++) {
@ -118,8 +117,8 @@ static void vpu_free_cmd(struct vpu_cmd_t *cmd)
return;
if (cmd->last_response_cmd)
atomic_long_set(cmd->last_response_cmd, cmd->key);
vfree(cmd->pkt);
vfree(cmd);
kfree(cmd->pkt);
kfree(cmd);
}
static int vpu_session_process_cmd(struct vpu_inst *inst, struct vpu_cmd_t *cmd)

View File

@ -17,7 +17,6 @@
#include <linux/pm_runtime.h>
#include <linux/pm_domain.h>
#include <linux/firmware.h>
#include <linux/vmalloc.h>
#include "vpu.h"
#include "vpu_defs.h"
#include "vpu_core.h"
@ -265,7 +264,7 @@ static int vpu_core_register(struct device *dev, struct vpu_core *core)
INIT_WORK(&core->msg_work, vpu_msg_run_work);
INIT_DELAYED_WORK(&core->msg_delayed_work, vpu_msg_delayed_work);
buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE);
core->msg_buffer = vzalloc(buffer_size);
core->msg_buffer = kzalloc(buffer_size, GFP_KERNEL);
if (!core->msg_buffer) {
dev_err(core->dev, "failed allocate buffer for fifo\n");
ret = -ENOMEM;
@ -282,10 +281,8 @@ static int vpu_core_register(struct device *dev, struct vpu_core *core)
return 0;
error:
if (core->msg_buffer) {
vfree(core->msg_buffer);
core->msg_buffer = NULL;
}
kfree(core->msg_buffer);
core->msg_buffer = NULL;
if (core->workqueue) {
destroy_workqueue(core->workqueue);
core->workqueue = NULL;
@ -308,7 +305,7 @@ static int vpu_core_unregister(struct device *dev, struct vpu_core *core)
vpu_core_put_vpu(core);
core->vpu = NULL;
vfree(core->msg_buffer);
kfree(core->msg_buffer);
core->msg_buffer = NULL;
if (core->workqueue) {