IB/core: Add umem function to read data from user-space
In some drivers there's a need to read data from a user space area that was pinned using ib_umem when running from a different process context. The ib_umem_copy_from function allows reading data from the physical pages pinned in the ib_umem struct. Signed-off-by: Haggai Eran <haggaie@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
parent
406f9e5fa9
commit
c5d76f130b
2 changed files with 36 additions and 0 deletions
|
@ -292,3 +292,37 @@ int ib_umem_page_count(struct ib_umem *umem)
|
|||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_umem_page_count);
|
||||
|
||||
/*
|
||||
* Copy from the given ib_umem's pages to the given buffer.
|
||||
*
|
||||
* umem - the umem to copy from
|
||||
* offset - offset to start copying from
|
||||
* dst - destination buffer
|
||||
* length - buffer length
|
||||
*
|
||||
* Returns 0 on success, or an error code.
|
||||
*/
|
||||
int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
|
||||
size_t length)
|
||||
{
|
||||
size_t end = offset + length;
|
||||
int ret;
|
||||
|
||||
if (offset > umem->length || length > umem->length - offset) {
|
||||
pr_err("ib_umem_copy_from not in range. offset: %zd umem length: %zd end: %zd\n",
|
||||
offset, umem->length, end);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->nmap, dst, length,
|
||||
offset + ib_umem_offset(umem));
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (ret != length)
|
||||
return -EINVAL;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_umem_copy_from);
|
||||
|
|
|
@ -84,6 +84,8 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
|
|||
size_t size, int access, int dmasync);
|
||||
void ib_umem_release(struct ib_umem *umem);
|
||||
int ib_umem_page_count(struct ib_umem *umem);
|
||||
int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
|
||||
size_t length);
|
||||
|
||||
#else /* CONFIG_INFINIBAND_USER_MEM */
|
||||
|
||||
|
|
Loading…
Reference in a new issue