Skip to content

Commit

Permalink
XenGnttabBuffer: handle data offset for dmabufs
Browse files Browse the repository at this point in the history
Handle additional data offset parameter while exporting and
importing dmabufs: dmabuf is backed by a scatter-gather table
and has offset parameter which tells where the actual data starts:
  - when dmabuf is created (exported) from grant references then
    data_ofs is used to set the offset field in the scatter list
    of the new dma-buf
  - when dma-buf is imported and then grant references provided
    to the user space then data_ofs is used to report that offset
    to user-space

Note! There is a dependency on libgnttab if it supports importing/
exporting dmabufs with data offset, so conditional compilation is
employed: new definition GNTTAB_HAS_DMABUF_OFFSET is set if the
library supports the offset. If it doesn't and a non-zero offset is
requested/provided, then a run-time exception is raised.

Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Reviewed-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
  • Loading branch information
Oleksandr Andrushchenko authored and andr2000 committed Apr 30, 2020
1 parent 04e11ec commit 2e55e2a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 5 deletions.
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@ message(STATUS "XEN_INCLUDE_PATH = ${XEN_INCLUDE_PATH}")
message(STATUS "XEN_LIB_PATH = ${XEN_LIB_PATH}")
message(STATUS)

################################################################################
# Autodetected options
################################################################################

include(CheckSymbolExists)

# Test if version 2 of the xengnttab_dmabuf_imp_to_refs and
# xengnttab_dmabuf_exp_from_refs functions are supported:
# these functions have an additional data_ofs parameter
# to set/get the offset of the data in the dma-buf's scatter-gather
# table
set(CMAKE_REQUIRED_LIBRARIES xengnttab)
check_symbol_exists("xengnttab_dmabuf_imp_to_refs_v2" "xengnttab.h" GNTTAB_HAS_DMABUF_OFFSET)

if(GNTTAB_HAS_DMABUF_OFFSET)
add_definitions(-DGNTTAB_HAS_DMABUF_OFFSET)
endif()

################################################################################
# Compiler flags
################################################################################
Expand Down
11 changes: 9 additions & 2 deletions include/xen/be/XenGnttab.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ class XenGnttabDmaBufferExporter
* will be produced
* @param[in] refs vector of grant reference ids
*/
XenGnttabDmaBufferExporter(domid_t domId, const GrantRefs &refs);
XenGnttabDmaBufferExporter(domid_t domId, const GrantRefs &refs,
size_t offset = 0);

int getFd() const { return mDmaBufFd; }

Expand All @@ -178,7 +179,7 @@ class XenGnttabDmaBufferExporter
xengnttab_handle* mHandle;
Log mLog;

void init(domid_t domId, const GrantRefs &refs);
void init(domid_t domId, const GrantRefs &refs, size_t offset);
void release();
};

Expand Down Expand Up @@ -213,10 +214,16 @@ class XenGnttabDmaBufferImporter
delete;
~XenGnttabDmaBufferImporter();

/**
* Returns offset of the data of the buffer.
*/
size_t offset() const { return mOffset; }

private:
GrantRefs mRefs;
int mDmaBufFd;
xengnttab_handle* mHandle;
size_t mOffset;
Log mLog;

void init(domid_t domId, int fd, GrantRefs &refs);
Expand Down
30 changes: 27 additions & 3 deletions src/XenGnttab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,14 @@ void XenGnttabBuffer::release()
******************************************************************************/

XenGnttabDmaBufferExporter::XenGnttabDmaBufferExporter(domid_t domId,
const GrantRefs &refs):
const GrantRefs &refs,
size_t offset) :
mDmaBufFd(-1),
mLog("XenGnttabDmaBufferExporter")
{
try
{
init(domId, refs);
init(domId, refs, offset);
}
catch(const std::exception& e)
{
Expand All @@ -144,7 +145,8 @@ XenGnttabDmaBufferExporter::~XenGnttabDmaBufferExporter()
* Private
******************************************************************************/

void XenGnttabDmaBufferExporter::init(domid_t domId, const GrantRefs &refs)
void XenGnttabDmaBufferExporter::init(domid_t domId, const GrantRefs &refs,
size_t offset)
{
uint32_t fd;
int ret;
Expand All @@ -155,8 +157,21 @@ void XenGnttabDmaBufferExporter::init(domid_t domId, const GrantRefs &refs)
<< domId << ", count: " << refs.size();

/* Always allocate the buffer to be DMA capable. */
#ifdef GNTTAB_HAS_DMABUF_OFFSET
DLOG(mLog, DEBUG) << "DMA buffer offset: " << offset;

ret = xengnttab_dmabuf_exp_from_refs_v2(mHandle, domId, GNTDEV_DMA_FLAG_WC,
refs.size(), refs.data(), &fd,
offset);
#else
if (offset)
{
throw XenGnttabException("Can't produce DMA buffer from grant references with non-zero offset",
ENOTSUP);
}
ret = xengnttab_dmabuf_exp_from_refs(mHandle, domId, GNTDEV_DMA_FLAG_WC,
refs.size(), refs.data(), &fd);
#endif

if (ret)
{
Expand Down Expand Up @@ -228,15 +243,23 @@ XenGnttabDmaBufferImporter::~XenGnttabDmaBufferImporter()

void XenGnttabDmaBufferImporter::init(domid_t domId, int fd, GrantRefs &refs)
{
uint32_t offset;
int ret;

mHandle = XenGnttab::getHandle();

DLOG(mLog, DEBUG) << "Produce grant references from DMA buffer, dom: "
<< domId << ", fd: " << fd << ", count: " << refs.size();

#ifdef GNTTAB_HAS_DMABUF_OFFSET
ret = xengnttab_dmabuf_imp_to_refs_v2(mHandle, domId, fd,
refs.size(), refs.data(),
&offset);
#else
ret = xengnttab_dmabuf_imp_to_refs(mHandle, domId, fd,
refs.size(), refs.data());
offset = 0;
#endif

if (ret)
{
Expand All @@ -245,6 +268,7 @@ void XenGnttabDmaBufferImporter::init(domid_t domId, int fd, GrantRefs &refs)
}

mDmaBufFd = fd;
mOffset = static_cast<size_t>(offset);
}

void XenGnttabDmaBufferImporter::release()
Expand Down

0 comments on commit 2e55e2a

Please sign in to comment.