mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 13:37:22 +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
@ -75,6 +75,7 @@ struct kvmfrbuf
|
|||||||
{
|
{
|
||||||
struct kvmfr_dev * kdev;
|
struct kvmfr_dev * kdev;
|
||||||
pgoff_t pagecount;
|
pgoff_t pagecount;
|
||||||
|
unsigned long offset;
|
||||||
struct page ** pages;
|
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)
|
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)
|
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (kbuf->kdev->type)
|
||||||
|
{
|
||||||
|
case KVMFR_TYPE_PCI:
|
||||||
vma->vm_ops = &kvmfr_vm_ops;
|
vma->vm_ops = &kvmfr_vm_ops;
|
||||||
vma->vm_private_data = buf->priv;
|
vma->vm_private_data = buf->priv;
|
||||||
return 0;
|
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 =
|
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->kdev = kdev;
|
||||||
kbuf->pagecount = create.size >> PAGE_SHIFT;
|
kbuf->pagecount = create.size >> PAGE_SHIFT;
|
||||||
|
kbuf->offset = create.offset;
|
||||||
kbuf->pages = kmalloc_array(kbuf->pagecount, sizeof(*kbuf->pages), GFP_KERNEL);
|
kbuf->pages = kmalloc_array(kbuf->pagecount, sizeof(*kbuf->pages), GFP_KERNEL);
|
||||||
if (!kbuf->pages)
|
if (!kbuf->pages)
|
||||||
{
|
{
|
||||||
@ -279,6 +299,7 @@ static int device_mmap(struct file * filp, struct vm_area_struct * vma)
|
|||||||
{
|
{
|
||||||
case KVMFR_TYPE_STATIC:
|
case KVMFR_TYPE_STATIC:
|
||||||
return remap_vmalloc_range(vma, kdev->addr, vma->vm_pgoff);
|
return remap_vmalloc_range(vma, kdev->addr, vma->vm_pgoff);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user