Skip to content

Commit

Permalink
[media] v4l: videobuf2: add vmalloc allocator
Browse files Browse the repository at this point in the history
Add an implementation of contiguous virtual memory allocator and handling
routines for videobuf2, implemented on top of vmalloc()/vfree() calls.

Signed-off-by: Pawel Osciak <p.osciak@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
CC: Pawel Osciak <pawel@osciak.com>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Pawel Osciak authored and Mauro Carvalho Chehab committed Mar 21, 2011
1 parent 004cc37 commit 3c18ff0
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 0 deletions.
5 changes: 5 additions & 0 deletions drivers/media/video/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ config VIDEOBUF2_CORE
config VIDEOBUF2_MEMOPS
tristate

config VIDEOBUF2_VMALLOC
select VIDEOBUF2_CORE
select VIDEOBUF2_MEMOPS
tristate

#
# Multimedia Video device configuration
#
Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o

obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o
obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o

obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o

Expand Down
132 changes: 132 additions & 0 deletions drivers/media/video/videobuf2-vmalloc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* videobuf2-vmalloc.c - vmalloc memory allocator for videobuf2
*
* Copyright (C) 2010 Samsung Electronics
*
* Author: Pawel Osciak <p.osciak@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*/

#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>

#include <media/videobuf2-core.h>
#include <media/videobuf2-memops.h>

struct vb2_vmalloc_buf {
void *vaddr;
unsigned long size;
atomic_t refcount;
struct vb2_vmarea_handler handler;
};

static void vb2_vmalloc_put(void *buf_priv);

static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size)
{
struct vb2_vmalloc_buf *buf;

buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
return NULL;

buf->size = size;
buf->vaddr = vmalloc_user(buf->size);
buf->handler.refcount = &buf->refcount;
buf->handler.put = vb2_vmalloc_put;
buf->handler.arg = buf;

if (!buf->vaddr) {
printk(KERN_ERR "vmalloc of size %ld failed\n", buf->size);
kfree(buf);
return NULL;
}

atomic_inc(&buf->refcount);
printk(KERN_DEBUG "Allocated vmalloc buffer of size %ld at vaddr=%p\n",
buf->size, buf->vaddr);

return buf;
}

static void vb2_vmalloc_put(void *buf_priv)
{
struct vb2_vmalloc_buf *buf = buf_priv;

if (atomic_dec_and_test(&buf->refcount)) {
printk(KERN_DEBUG "%s: Freeing vmalloc mem at vaddr=%p\n",
__func__, buf->vaddr);
vfree(buf->vaddr);
kfree(buf);
}
}

static void *vb2_vmalloc_vaddr(void *buf_priv)
{
struct vb2_vmalloc_buf *buf = buf_priv;

BUG_ON(!buf);

if (!buf->vaddr) {
printk(KERN_ERR "Address of an unallocated plane requested\n");
return NULL;
}

return buf->vaddr;
}

static unsigned int vb2_vmalloc_num_users(void *buf_priv)
{
struct vb2_vmalloc_buf *buf = buf_priv;
return atomic_read(&buf->refcount);
}

static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma)
{
struct vb2_vmalloc_buf *buf = buf_priv;
int ret;

if (!buf) {
printk(KERN_ERR "No memory to map\n");
return -EINVAL;
}

ret = remap_vmalloc_range(vma, buf->vaddr, 0);
if (ret) {
printk(KERN_ERR "Remapping vmalloc memory, error: %d\n", ret);
return ret;
}

/*
* Make sure that vm_areas for 2 buffers won't be merged together
*/
vma->vm_flags |= VM_DONTEXPAND;

/*
* Use common vm_area operations to track buffer refcount.
*/
vma->vm_private_data = &buf->handler;
vma->vm_ops = &vb2_common_vm_ops;

vma->vm_ops->open(vma);

return 0;
}

const struct vb2_mem_ops vb2_vmalloc_memops = {
.alloc = vb2_vmalloc_alloc,
.put = vb2_vmalloc_put,
.vaddr = vb2_vmalloc_vaddr,
.mmap = vb2_vmalloc_mmap,
.num_users = vb2_vmalloc_num_users,
};
EXPORT_SYMBOL_GPL(vb2_vmalloc_memops);

MODULE_DESCRIPTION("vmalloc memory handling routines for videobuf2");
MODULE_AUTHOR("Pawel Osciak");
MODULE_LICENSE("GPL");
20 changes: 20 additions & 0 deletions include/media/videobuf2-vmalloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* videobuf2-vmalloc.h - vmalloc memory allocator for videobuf2
*
* Copyright (C) 2010 Samsung Electronics
*
* Author: Pawel Osciak <p.osciak@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*/

#ifndef _MEDIA_VIDEOBUF2_VMALLOC_H
#define _MEDIA_VIDEOBUF2_VMALLOC_H

#include <media/videobuf2-core.h>

extern const struct vb2_mem_ops vb2_vmalloc_memops;

#endif

0 comments on commit 3c18ff0

Please sign in to comment.