[RAMEN9610-12270] media: vb2: deliver alloc/map context to memops
authorCho KyongHo <pullip.cho@samsung.com>
Mon, 18 Feb 2019 03:57:02 +0000 (12:57 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:17 +0000 (20:23 +0300)
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 <pullip.cho@samsung.com>
drivers/media/v4l2-core/videobuf2-core.c
drivers/media/v4l2-core/videobuf2-dma-sg.c
include/media/videobuf2-core.h

index a5e5f000e7bbf075fce48703bcec48bf14f6e0a4..e5f4ecdb08d6feeb5816b194bf2f2c14875fd919 100644 (file)
@@ -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) {
index a78c88ed0e7c1f149de4bf62b93873ef00d0a73e..4ad5c3ad9cc77d70b549955803046140a109b1d2 100644 (file)
@@ -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;
index 1107ae9bf39d57780e71c1a3c3308b2b3909c2ae..0a3d4edc19002e68dfdc530f14e1052e2c530985 100644 (file)
@@ -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
 };