mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-10 11:17:54 +00:00
[module] improve dmabuf mmap logic for vmalloc'd memory
Instead of faulting the pages in one by one when mmaping on the dma fd, we could instead use remap_vmalloc_range to map in all the memory at once.
This commit is contained in:
parent
f65aa6e089
commit
2c909f0af7
1 changed files with 24 additions and 3 deletions
|
@ -75,6 +75,7 @@ struct kvmfrbuf
|
|||
{
|
||||
struct kvmfr_dev * kdev;
|
||||
pgoff_t pagecount;
|
||||
unsigned long offset;
|
||||
struct page ** pages;
|
||||
};
|
||||
|
||||
|
@ -139,11 +140,29 @@ static void release_kvmfrbuf(struct dma_buf * buf)
|
|||
|
||||
static int mmap_kvmfrbuf(struct dma_buf * buf, struct vm_area_struct * vma)
|
||||
{
|
||||
struct kvmfrbuf * kbuf = (struct kvmfrbuf *)buf->priv;
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
|
||||
if ((offset + size > (kbuf->pagecount << PAGE_SHIFT)) || (offset + size < offset))
|
||||
return -EINVAL;
|
||||
|
||||
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
|
||||
return -EINVAL;
|
||||
vma->vm_ops = &kvmfr_vm_ops;
|
||||
vma->vm_private_data = buf->priv;
|
||||
return 0;
|
||||
|
||||
switch (kbuf->kdev->type)
|
||||
{
|
||||
case KVMFR_TYPE_PCI:
|
||||
vma->vm_ops = &kvmfr_vm_ops;
|
||||
vma->vm_private_data = buf->priv;
|
||||
return 0;
|
||||
|
||||
case KVMFR_TYPE_STATIC:
|
||||
return remap_vmalloc_range(vma, kbuf->kdev->addr + kbuf->offset, vma->vm_pgoff);
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct dma_buf_ops kvmfrbuf_ops =
|
||||
|
@ -184,6 +203,7 @@ static long kvmfr_dmabuf_create(struct kvmfr_dev * kdev, struct file * filp, uns
|
|||
|
||||
kbuf->kdev = kdev;
|
||||
kbuf->pagecount = create.size >> PAGE_SHIFT;
|
||||
kbuf->offset = create.offset;
|
||||
kbuf->pages = kmalloc_array(kbuf->pagecount, sizeof(*kbuf->pages), GFP_KERNEL);
|
||||
if (!kbuf->pages)
|
||||
{
|
||||
|
@ -279,6 +299,7 @@ static int device_mmap(struct file * filp, struct vm_area_struct * vma)
|
|||
{
|
||||
case KVMFR_TYPE_STATIC:
|
||||
return remap_vmalloc_range(vma, kdev->addr, vma->vm_pgoff);
|
||||
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue