ANDROID: dma-buf: Return EOPNOTSUPP in dma_buf_begin_cpu_access_partial

Currently callers of dma_buf_begin_cpu_access_partial and
dma_buf_end_cpu_access_partial cannot distinguish between an exporter
not providing {begin,end}_cpu_access_partial functions, and
those functions completing successfully. For cases where an exporter
provides no begin_cpu_access_partial or end_cpu_access_partial function,
we now return EOPNOTSUPP. Callers are then free to fallback to
dma_buf_{begin,end}_cpu_access or fail entirely.

Bug: 259320043
Change-Id: I8d4db5246907362f22b6fbc30338aec7d9d1be58
Signed-off-by: T.J. Mercier <tjmercier@google.com>
This commit is contained in:
T.J. Mercier
2022-11-16 19:21:06 +00:00
parent 9bc75534b3
commit 7216484575

View File

@@ -1270,18 +1270,46 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
}
EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access);
/**
* dma_buf_begin_cpu_access_partial - An alternative to dma_buf_begin_cpu_access
* which applies to a subset of the buffer instead of the entire buffer. This
* can offer better performance than dma_buf_begin_cpu_access if implemented
* by an exporter. If an exporter does not implement partial buffer access then
* this function will return -EOPNOTSUPP and it is the responsibility of the
* caller to fallback to dma_buf_begin_cpu_access or fail entirely.
*
* @dmabuf: [in] buffer to prepare cpu access for.
* @direction: [in] direction for access.
* @offset: [in] offset in bytes from beginning of buffer for partial
range.
* @len: [in] length in bytes of partial range beginning at @offset.
*
* After the cpu access is complete the caller should call
* dma_buf_end_cpu_access_partial(). Only when cpu access is bracketed by both
* calls is it guaranteed to be coherent with other DMA access.
*
* This function will also wait for any DMA transactions tracked through
* implicit synchronization in &dma_buf.resv. For DMA transactions with explicit
* synchronization this function will only ensure cache coherency, callers must
* ensure synchronization with such DMA transactions on their own.
*
* Can return negative error values, returns 0 on success.
*/
int dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,
enum dma_data_direction direction,
unsigned int offset, unsigned int len)
{
int ret = 0;
int ret;
if (WARN_ON(!dmabuf))
return -EINVAL;
if (dmabuf->ops->begin_cpu_access_partial)
ret = dmabuf->ops->begin_cpu_access_partial(dmabuf, direction,
offset, len);
if (!dmabuf->ops->begin_cpu_access_partial)
return -EOPNOTSUPP;
ret = dmabuf->ops->begin_cpu_access_partial(dmabuf, direction,
offset, len);
/* Ensure that all fences are waited upon - but we first allow
* the native handler the chance to do so more efficiently if it
@@ -1322,19 +1350,35 @@ int dma_buf_end_cpu_access(struct dma_buf *dmabuf,
}
EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access);
/**
* dma_buf_end_cpu_access_partial - An alternative to dma_buf_end_cpu_access
* which applies to a subset of the buffer instead of the entire buffer. This
* can offer better performance than dma_buf_end_cpu_access if implemented
* by an exporter. If an exporter does not implement partial buffer access then
* this function will return -EOPNOTSUPP and it is the responsibility of the
* caller to fallback to dma_buf_end_cpu_access or fail entirely.
*
* @dmabuf: [in] buffer to complete cpu access for.
* @direction: [in] direction for access.
* @offset: [in] offset in bytes from beginning of buffer for partial
range.
* @len: [in] length in bytes of partial range beginning at @offset.
*
* This terminates CPU access started with dma_buf_begin_cpu_access_partial().
*
* Can return negative error values, returns 0 on success.
*/
int dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf,
enum dma_data_direction direction,
unsigned int offset, unsigned int len)
{
int ret = 0;
WARN_ON(!dmabuf);
if (dmabuf->ops->end_cpu_access_partial)
ret = dmabuf->ops->end_cpu_access_partial(dmabuf, direction,
offset, len);
if (!dmabuf->ops->end_cpu_access_partial)
return -EOPNOTSUPP;
return ret;
return dmabuf->ops->end_cpu_access_partial(dmabuf, direction,
offset, len);
}
EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access_partial);