mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
IB/hfi1: Use dma_mmap_coherent for matching buffers
For memory allocated with dma_alloc_coherent(), use dma_mmap_coherent() to mmap it into user space. Signed-off-by: Dean Luick <dean.luick@cornelisnetworks.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com> Link: https://lore.kernel.org/r/167329107460.1472990.9090255834533222032.stgit@awfm-02.cornelisnetworks.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
parent
892ede5a77
commit
1ec82317a1
|
|
@ -306,6 +306,17 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from)
|
||||||
return reqs;
|
return reqs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void mmap_cdbg(u16 ctxt, u8 subctxt, u8 type, u8 mapio, u8 vmf,
|
||||||
|
u64 memaddr, void *memvirt, dma_addr_t memdma,
|
||||||
|
ssize_t memlen, struct vm_area_struct *vma)
|
||||||
|
{
|
||||||
|
hfi1_cdbg(PROC,
|
||||||
|
"%u:%u type:%u io/vf/dma:%d/%d/%d, addr:0x%llx, len:%lu(%lu), flags:0x%lx",
|
||||||
|
ctxt, subctxt, type, mapio, vmf, !!memdma,
|
||||||
|
memaddr ?: (u64)memvirt, memlen,
|
||||||
|
vma->vm_end - vma->vm_start, vma->vm_flags);
|
||||||
|
}
|
||||||
|
|
||||||
static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||||
{
|
{
|
||||||
struct hfi1_filedata *fd = fp->private_data;
|
struct hfi1_filedata *fd = fp->private_data;
|
||||||
|
|
@ -315,6 +326,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||||
u64 token = vma->vm_pgoff << PAGE_SHIFT,
|
u64 token = vma->vm_pgoff << PAGE_SHIFT,
|
||||||
memaddr = 0;
|
memaddr = 0;
|
||||||
void *memvirt = NULL;
|
void *memvirt = NULL;
|
||||||
|
dma_addr_t memdma = 0;
|
||||||
u8 subctxt, mapio = 0, vmf = 0, type;
|
u8 subctxt, mapio = 0, vmf = 0, type;
|
||||||
ssize_t memlen = 0;
|
ssize_t memlen = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
@ -334,6 +346,11 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vm_pgoff is used as a buffer selector cookie. Always mmap from
|
||||||
|
* the beginning.
|
||||||
|
*/
|
||||||
|
vma->vm_pgoff = 0;
|
||||||
flags = vma->vm_flags;
|
flags = vma->vm_flags;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
@ -355,7 +372,8 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||||
mapio = 1;
|
mapio = 1;
|
||||||
break;
|
break;
|
||||||
case PIO_CRED:
|
case PIO_CRED: {
|
||||||
|
u64 cr_page_offset;
|
||||||
if (flags & VM_WRITE) {
|
if (flags & VM_WRITE) {
|
||||||
ret = -EPERM;
|
ret = -EPERM;
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -365,10 +383,11 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||||
* second or third page allocated for credit returns (if number
|
* second or third page allocated for credit returns (if number
|
||||||
* of enabled contexts > 64 and 128 respectively).
|
* of enabled contexts > 64 and 128 respectively).
|
||||||
*/
|
*/
|
||||||
memvirt = dd->cr_base[uctxt->numa_id].va;
|
cr_page_offset = ((u64)uctxt->sc->hw_free -
|
||||||
memaddr = virt_to_phys(memvirt) +
|
(u64)dd->cr_base[uctxt->numa_id].va) &
|
||||||
(((u64)uctxt->sc->hw_free -
|
PAGE_MASK;
|
||||||
(u64)dd->cr_base[uctxt->numa_id].va) & PAGE_MASK);
|
memvirt = dd->cr_base[uctxt->numa_id].va + cr_page_offset;
|
||||||
|
memdma = dd->cr_base[uctxt->numa_id].dma + cr_page_offset;
|
||||||
memlen = PAGE_SIZE;
|
memlen = PAGE_SIZE;
|
||||||
flags &= ~VM_MAYWRITE;
|
flags &= ~VM_MAYWRITE;
|
||||||
flags |= VM_DONTCOPY | VM_DONTEXPAND;
|
flags |= VM_DONTCOPY | VM_DONTEXPAND;
|
||||||
|
|
@ -378,14 +397,16 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||||
* memory been flagged as non-cached?
|
* memory been flagged as non-cached?
|
||||||
*/
|
*/
|
||||||
/* vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); */
|
/* vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); */
|
||||||
mapio = 1;
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case RCV_HDRQ:
|
case RCV_HDRQ:
|
||||||
memlen = rcvhdrq_size(uctxt);
|
memlen = rcvhdrq_size(uctxt);
|
||||||
memvirt = uctxt->rcvhdrq;
|
memvirt = uctxt->rcvhdrq;
|
||||||
|
memdma = uctxt->rcvhdrq_dma;
|
||||||
break;
|
break;
|
||||||
case RCV_EGRBUF: {
|
case RCV_EGRBUF: {
|
||||||
unsigned long addr;
|
unsigned long vm_start_save;
|
||||||
|
unsigned long vm_end_save;
|
||||||
int i;
|
int i;
|
||||||
/*
|
/*
|
||||||
* The RcvEgr buffer need to be handled differently
|
* The RcvEgr buffer need to be handled differently
|
||||||
|
|
@ -404,24 +425,34 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
vma->vm_flags &= ~VM_MAYWRITE;
|
vma->vm_flags &= ~VM_MAYWRITE;
|
||||||
addr = vma->vm_start;
|
/*
|
||||||
|
* Mmap multiple separate allocations into a single vma. From
|
||||||
|
* here, dma_mmap_coherent() calls dma_direct_mmap(), which
|
||||||
|
* requires the mmap to exactly fill the vma starting at
|
||||||
|
* vma_start. Adjust the vma start and end for each eager
|
||||||
|
* buffer segment mapped. Restore the originals when done.
|
||||||
|
*/
|
||||||
|
vm_start_save = vma->vm_start;
|
||||||
|
vm_end_save = vma->vm_end;
|
||||||
|
vma->vm_end = vma->vm_start;
|
||||||
for (i = 0 ; i < uctxt->egrbufs.numbufs; i++) {
|
for (i = 0 ; i < uctxt->egrbufs.numbufs; i++) {
|
||||||
memlen = uctxt->egrbufs.buffers[i].len;
|
memlen = uctxt->egrbufs.buffers[i].len;
|
||||||
memvirt = uctxt->egrbufs.buffers[i].addr;
|
memvirt = uctxt->egrbufs.buffers[i].addr;
|
||||||
ret = remap_pfn_range(
|
memdma = uctxt->egrbufs.buffers[i].dma;
|
||||||
vma, addr,
|
vma->vm_end += memlen;
|
||||||
/*
|
mmap_cdbg(ctxt, subctxt, type, mapio, vmf, memaddr,
|
||||||
* virt_to_pfn() does the same, but
|
memvirt, memdma, memlen, vma);
|
||||||
* it's not available on x86_64
|
ret = dma_mmap_coherent(&dd->pcidev->dev, vma,
|
||||||
* when CONFIG_MMU is enabled.
|
memvirt, memdma, memlen);
|
||||||
*/
|
if (ret < 0) {
|
||||||
PFN_DOWN(__pa(memvirt)),
|
vma->vm_start = vm_start_save;
|
||||||
memlen,
|
vma->vm_end = vm_end_save;
|
||||||
vma->vm_page_prot);
|
|
||||||
if (ret < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
addr += memlen;
|
}
|
||||||
|
vma->vm_start += memlen;
|
||||||
}
|
}
|
||||||
|
vma->vm_start = vm_start_save;
|
||||||
|
vma->vm_end = vm_end_save;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -481,6 +512,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||||
}
|
}
|
||||||
memlen = PAGE_SIZE;
|
memlen = PAGE_SIZE;
|
||||||
memvirt = (void *)hfi1_rcvhdrtail_kvaddr(uctxt);
|
memvirt = (void *)hfi1_rcvhdrtail_kvaddr(uctxt);
|
||||||
|
memdma = uctxt->rcvhdrqtailaddr_dma;
|
||||||
flags &= ~VM_MAYWRITE;
|
flags &= ~VM_MAYWRITE;
|
||||||
break;
|
break;
|
||||||
case SUBCTXT_UREGS:
|
case SUBCTXT_UREGS:
|
||||||
|
|
@ -529,14 +561,15 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||||
}
|
}
|
||||||
|
|
||||||
vma->vm_flags = flags;
|
vma->vm_flags = flags;
|
||||||
hfi1_cdbg(PROC,
|
mmap_cdbg(ctxt, subctxt, type, mapio, vmf, memaddr, memvirt, memdma,
|
||||||
"%u:%u type:%u io/vf:%d/%d, addr:0x%llx, len:%lu(%lu), flags:0x%lx\n",
|
memlen, vma);
|
||||||
ctxt, subctxt, type, mapio, vmf, memaddr, memlen,
|
|
||||||
vma->vm_end - vma->vm_start, vma->vm_flags);
|
|
||||||
if (vmf) {
|
if (vmf) {
|
||||||
vma->vm_pgoff = PFN_DOWN(memaddr);
|
vma->vm_pgoff = PFN_DOWN(memaddr);
|
||||||
vma->vm_ops = &vm_ops;
|
vma->vm_ops = &vm_ops;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
} else if (memdma) {
|
||||||
|
ret = dma_mmap_coherent(&dd->pcidev->dev, vma,
|
||||||
|
memvirt, memdma, memlen);
|
||||||
} else if (mapio) {
|
} else if (mapio) {
|
||||||
ret = io_remap_pfn_range(vma, vma->vm_start,
|
ret = io_remap_pfn_range(vma, vma->vm_start,
|
||||||
PFN_DOWN(memaddr),
|
PFN_DOWN(memaddr),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user