From: Cho KyongHo Date: Mon, 18 Feb 2019 03:57:02 +0000 (+0900) Subject: [RAMEN9610-12270] media: vb2: deliver alloc/map context to memops X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=632f89bc10b8d87aef2299b66ecac30b3452a22f;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [RAMEN9610-12270] media: vb2: deliver alloc/map context to memops vb2 memops never know about the context in which it is working because vb2 does not deliver information about the current working context. However, vb2 memops sometimes needs to know the current context to improve the performance or manage memory access correctly. Instead of passing such information from vb2-core, it had better generated from the client drivers because the information might be driver-specific or memops-specific. Let's deliver the information with flags. The flags should be memops- specific and the client drivers can configure the flags in a callback, memops.mem_flags(). It is called before .alloc() for mmap, .get_userptr() for userptr and .map_dmabuf() for dmabuf. The flags are defined by and specific to memops implementations. Change-Id: I0b68df4bed659fb99e94755bf9333594b68c0b3b Signed-off-by: Cho KyongHo --- diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index a5e5f000e7bb..e5f4ecdb08d6 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -195,6 +195,7 @@ static void __qbuf_work(struct work_struct *work); */ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) { + int memflags = call_vb_qop(vb, mem_flags, vb); struct vb2_queue *q = vb->vb2_queue; void *mem_priv; int plane; @@ -209,7 +210,8 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) mem_priv = call_ptr_memop(vb, alloc, q->alloc_devs[plane] ? : q->dev, - q->dma_attrs, size, q->dma_dir, q->gfp_flags); + q->dma_attrs, size, q->dma_dir, q->gfp_flags, + memflags); if (IS_ERR_OR_NULL(mem_priv)) { if (mem_priv) ret = PTR_ERR(mem_priv); @@ -895,6 +897,7 @@ EXPORT_SYMBOL_GPL(vb2_plane_cookie); static void vb2_process_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) { + int memflags = call_vb_qop(vb, mem_flags, vb); struct vb2_queue *q = vb->vb2_queue; unsigned long flags; unsigned int plane; @@ -915,7 +918,7 @@ static void vb2_process_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state /* sync buffers */ for (plane = 0; plane < vb->num_planes; ++plane) call_void_memop(vb, finish, vb->planes[plane].mem_priv, - vb->planes[plane].bytesused); + vb->planes[plane].bytesused, memflags); } spin_lock_irqsave(&q->done_lock, flags); @@ -1013,6 +1016,7 @@ static int __prepare_userptr(struct vb2_buffer *vb, const void *pb) unsigned int plane; int ret = 0; bool reacquired = vb->planes[0].mem_priv == NULL; + int memflags = call_vb_qop(vb, mem_flags, vb); memset(planes, 0, sizeof(planes[0]) * vb->num_planes); /* Copy relevant information provided by the userspace */ @@ -1062,7 +1066,7 @@ static int __prepare_userptr(struct vb2_buffer *vb, const void *pb) mem_priv = call_ptr_memop(vb, get_userptr, q->alloc_devs[plane] ? : q->dev, planes[plane].m.userptr, - planes[plane].length, q->dma_dir); + planes[plane].length, q->dma_dir, memflags); if (IS_ERR(mem_priv)) { dprintk(1, "failed acquiring userspace memory for plane %d\n", plane); @@ -1129,6 +1133,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb) unsigned int plane; int ret = 0; bool reacquired = vb->planes[0].mem_priv == NULL; + int memflags = call_vb_qop(vb, mem_flags, vb); memset(planes, 0, sizeof(planes[0]) * vb->num_planes); /* Copy relevant information provided by the userspace */ @@ -1205,7 +1210,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb) */ for (plane = 0; plane < vb->num_planes; ++plane) { ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv, - planes[plane].bytesused); + planes[plane].bytesused, memflags); if (ret) { dprintk(1, "failed to map dmabuf for plane %d\n", @@ -1278,6 +1283,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb) static int __buf_prepare(struct vb2_buffer *vb, const void *pb) { + int memflags = call_vb_qop(vb, mem_flags, vb); struct vb2_queue *q = vb->vb2_queue; unsigned int plane; int ret; @@ -1313,7 +1319,7 @@ static int __buf_prepare(struct vb2_buffer *vb, const void *pb) /* sync buffers */ for (plane = 0; plane < vb->num_planes; ++plane) call_void_memop(vb, prepare, vb->planes[plane].mem_priv, - vb->planes[plane].bytesused); + vb->planes[plane].bytesused, memflags); vb->state = VB2_BUF_STATE_PREPARED; @@ -1930,6 +1936,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q) */ for (i = 0; i < q->num_buffers; ++i) { struct vb2_buffer *vb = q->bufs[i]; + int memflags = call_vb_qop(vb, mem_flags, vb); if (vb->state == VB2_BUF_STATE_PREPARED || vb->state == VB2_BUF_STATE_QUEUED) { @@ -1938,7 +1945,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q) for (plane = 0; plane < vb->num_planes; ++plane) call_void_memop(vb, finish, vb->planes[plane].mem_priv, - 0); + 0, memflags); } if (vb->state != VB2_BUF_STATE_DEQUEUED) { diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index a78c88ed0e7c..4ad5c3ad9cc7 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -108,7 +108,7 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf, static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, unsigned long size, enum dma_data_direction dma_dir, - gfp_t gfp_flags) + gfp_t gfp_flags, int memflags) { struct vb2_dma_sg_buf *buf; struct sg_table *sgt; @@ -202,7 +202,7 @@ static void vb2_dma_sg_put(void *buf_priv) } } -static void vb2_dma_sg_prepare(void *buf_priv, size_t size) +static void vb2_dma_sg_prepare(void *buf_priv, size_t size, int memflags) { struct vb2_dma_sg_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; @@ -229,7 +229,7 @@ static void vb2_dma_sg_prepare(void *buf_priv, size_t size) } } -static void vb2_dma_sg_finish(void *buf_priv, size_t size) +static void vb2_dma_sg_finish(void *buf_priv, size_t size, int memflags) { struct vb2_dma_sg_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; @@ -258,7 +258,8 @@ static void vb2_dma_sg_finish(void *buf_priv, size_t size) static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, unsigned long size, - enum dma_data_direction dma_dir) + enum dma_data_direction dma_dir, + int memflags) { struct vb2_dma_sg_buf *buf; struct sg_table *sgt; @@ -586,7 +587,7 @@ static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags /* callbacks for DMABUF buffers */ /*********************************************/ -static int vb2_dma_sg_map_dmabuf(void *mem_priv, size_t size) +static int vb2_dma_sg_map_dmabuf(void *mem_priv, size_t size, int memflags) { struct vb2_dma_sg_buf *buf = mem_priv; struct sg_table *sgt; diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 1107ae9bf39d..0a3d4edc1900 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -117,24 +117,26 @@ struct vb2_mem_ops { void *(*alloc)(struct device *dev, unsigned long attrs, unsigned long size, enum dma_data_direction dma_dir, - gfp_t gfp_flags); + gfp_t gfp_flags, int memflags); void (*put)(void *buf_priv); struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags); void *(*get_userptr)(struct device *dev, unsigned long vaddr, unsigned long size, - enum dma_data_direction dma_dir); + enum dma_data_direction dma_dir, + int memflags); void (*put_userptr)(void *buf_priv); - void (*prepare)(void *buf_priv, size_t size); - void (*finish)(void *buf_priv, size_t size); + void (*prepare)(void *buf_priv, size_t size, int memflags); + void (*finish)(void *buf_priv, size_t size, int memflags); void *(*attach_dmabuf)(struct device *dev, struct dma_buf *dbuf, unsigned long size, enum dma_data_direction dma_dir); void (*detach_dmabuf)(void *buf_priv); - int (*map_dmabuf)(void *buf_priv, size_t size); + int (*map_dmabuf)(void *buf_priv, size_t size, + int memflags); void (*unmap_dmabuf)(void *buf_priv, size_t size); void *(*vaddr)(void *buf_priv); @@ -400,6 +402,10 @@ struct vb2_buffer { * ioctl; might be called before @start_streaming callback * if user pre-queued buffers before calling * VIDIOC_STREAMON(). + * @mem_flags: called before events of buffer manipulations including + * buffer acquisition and mappin to study extra information + * vb2 mem implementations. The return values of + * @mem_flags are implementation specific. */ struct vb2_ops { int (*queue_setup)(struct vb2_queue *q, @@ -419,6 +425,7 @@ struct vb2_ops { bool (*is_unordered)(struct vb2_queue *q); void (*buf_queue)(struct vb2_buffer *vb); + int (*mem_flags)(struct vb2_buffer *vb); }; /** @@ -595,6 +602,7 @@ struct vb2_queue { u32 cnt_start_streaming; u32 cnt_stop_streaming; u32 cnt_is_unordered; + u32 cnt_mem_flags; #endif };