video: rockchip: mpp: Reduce frequent malloc/free for dma buffer

Change-Id: I5474dad5b1ba08d05edce8d35765abc13d453a9b
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Ding Wei
2021-04-20 17:48:10 +08:00
committed by Tao Huang
parent 9867e44d38
commit e3781f86cd
3 changed files with 42 additions and 16 deletions

View File

@@ -964,8 +964,7 @@ static int mpp_process_request(struct mpp_session *session,
if (!mpp)
return -EINVAL;
session->device_type = (enum MPP_DEVICE_TYPE)client_type;
session->dma = mpp_dma_session_create(mpp->dev);
session->dma->max_buffers = mpp->session_max_buffers;
session->dma = mpp_dma_session_create(mpp->dev, mpp->session_max_buffers);
session->mpp = mpp;
session->index = atomic_fetch_inc(&mpp->session_index);
if (mpp->dev_ops->init_session) {

View File

@@ -38,7 +38,7 @@ mpp_dma_find_buffer_fd(struct mpp_dma_session *dma, int fd)
mutex_lock(&dma->list_mutex);
list_for_each_entry_safe(buffer, n,
&dma->buffer_list, link) {
&dma->used_list, link) {
/*
* fd may dup several and point the same dambuf.
* thus, here should be distinguish with the dmabuf.
@@ -61,12 +61,11 @@ static void mpp_dma_release_buffer(struct kref *ref)
container_of(ref, struct mpp_dma_buffer, ref);
buffer->dma->buffer_count--;
list_del_init(&buffer->link);
list_move_tail(&buffer->link, &buffer->dma->unused_list);
dma_buf_unmap_attachment(buffer->attach, buffer->sgt, buffer->dir);
dma_buf_detach(buffer->dmabuf, buffer->attach);
dma_buf_put(buffer->dmabuf);
kfree(buffer);
}
/* Remove the oldest buffer when count more than the setting */
@@ -80,7 +79,7 @@ mpp_dma_remove_extra_buffer(struct mpp_dma_session *dma)
if (dma->buffer_count > dma->max_buffers) {
mutex_lock(&dma->list_mutex);
list_for_each_entry_safe(buffer, n,
&dma->buffer_list,
&dma->used_list,
link) {
if (ktime_to_ns(oldest_time) == 0 ||
ktime_after(oldest_time, buffer->last_used)) {
@@ -198,11 +197,17 @@ struct mpp_dma_buffer *mpp_dma_import_fd(struct mpp_iommu_info *iommu_info,
return NULL;
}
/* A new DMA buffer */
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
mutex_lock(&dma->list_mutex);
buffer = list_first_entry_or_null(&dma->unused_list,
struct mpp_dma_buffer,
link);
if (!buffer) {
ret = -ENOMEM;
mutex_unlock(&dma->list_mutex);
goto fail;
}
list_del_init(&buffer->link);
mutex_unlock(&dma->list_mutex);
buffer->dmabuf = dmabuf;
buffer->dir = DMA_BIDIRECTIONAL;
@@ -230,11 +235,10 @@ struct mpp_dma_buffer *mpp_dma_import_fd(struct mpp_iommu_info *iommu_info,
kref_init(&buffer->ref);
/* Increase the reference for used outside the buffer pool */
kref_get(&buffer->ref);
INIT_LIST_HEAD(&buffer->link);
mutex_lock(&dma->list_mutex);
dma->buffer_count++;
list_add_tail(&buffer->link, &dma->buffer_list);
list_add_tail(&buffer->link, &dma->used_list);
mutex_unlock(&dma->list_mutex);
return buffer;
@@ -242,7 +246,9 @@ struct mpp_dma_buffer *mpp_dma_import_fd(struct mpp_iommu_info *iommu_info,
fail_map:
dma_buf_detach(buffer->dmabuf, attach);
fail_attach:
kfree(buffer);
mutex_lock(&dma->list_mutex);
list_add_tail(&buffer->link, &dma->unused_list);
mutex_unlock(&dma->list_mutex);
fail:
dma_buf_put(dmabuf);
return ERR_PTR(ret);
@@ -309,7 +315,7 @@ int mpp_dma_session_destroy(struct mpp_dma_session *dma)
mutex_lock(&dma->list_mutex);
list_for_each_entry_safe(buffer, n,
&dma->buffer_list,
&dma->used_list,
link) {
kref_put(&buffer->ref, mpp_dma_release_buffer);
}
@@ -321,17 +327,34 @@ int mpp_dma_session_destroy(struct mpp_dma_session *dma)
}
struct mpp_dma_session *
mpp_dma_session_create(struct device *dev)
mpp_dma_session_create(struct device *dev, u32 max_buffers)
{
int i;
struct mpp_dma_session *dma = NULL;
struct mpp_dma_buffer *buffer = NULL;
dma = kzalloc(sizeof(*dma), GFP_KERNEL);
if (!dma)
return dma;
return NULL;
INIT_LIST_HEAD(&dma->buffer_list);
mutex_init(&dma->list_mutex);
INIT_LIST_HEAD(&dma->unused_list);
INIT_LIST_HEAD(&dma->used_list);
if (max_buffers > MPP_SESSION_MAX_BUFFERS) {
mpp_debug(DEBUG_IOCTL, "session_max_buffer %d must less than %d\n",
max_buffers, MPP_SESSION_MAX_BUFFERS);
dma->max_buffers = MPP_SESSION_MAX_BUFFERS;
} else {
dma->max_buffers = max_buffers;
}
for (i = 0; i < ARRAY_SIZE(dma->dma_bufs); i++) {
buffer = &dma->dma_bufs[i];
buffer->dma = dma;
INIT_LIST_HEAD(&buffer->link);
list_add_tail(&buffer->link, &dma->unused_list);
}
dma->dev = dev;
return dma;

View File

@@ -37,9 +37,13 @@ struct mpp_dma_buffer {
struct device *dev;
};
#define MPP_SESSION_MAX_BUFFERS 60
struct mpp_dma_session {
/* the buffer used in session */
struct list_head buffer_list;
struct list_head unused_list;
struct list_head used_list;
struct mpp_dma_buffer dma_bufs[MPP_SESSION_MAX_BUFFERS];
/* the mutex for the above buffer list */
struct mutex list_mutex;
/* the max buffer num for the buffer list */
@@ -72,7 +76,7 @@ struct mpp_iommu_info {
};
struct mpp_dma_session *
mpp_dma_session_create(struct device *dev);
mpp_dma_session_create(struct device *dev, u32 max_buffers);
int mpp_dma_session_destroy(struct mpp_dma_session *dma);
struct mpp_dma_buffer *