pvr: Return VkResult from winsys buffer_map operation

This allows VK_ERROR_MEMORY_MAP_FAILED to propagate correctly.

Signed-off-by: Matt Coster <matt.coster@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23023>
This commit is contained in:
Matt Coster 2023-04-28 14:57:26 +01:00 committed by Marge Bot
parent a986aea7f7
commit c05dd04898
9 changed files with 83 additions and 52 deletions

View file

@ -370,14 +370,12 @@ VkResult pvr_bo_alloc(struct pvr_device *device,
goto err_free_bo;
if (flags & PVR_BO_ALLOC_FLAG_CPU_MAPPED) {
void *map = device->ws->ops->buffer_map(pvr_bo->bo);
if (!map) {
result = VK_ERROR_MEMORY_MAP_FAILED;
result = device->ws->ops->buffer_map(pvr_bo->bo);
if (result != VK_SUCCESS)
goto err_buffer_destroy;
}
if (flags & PVR_BO_ALLOC_FLAG_ZERO_ON_ALLOC)
VG(VALGRIND_MAKE_MEM_DEFINED(map, pvr_bo->bo->size));
VG(VALGRIND_MAKE_MEM_DEFINED(pvr_bo->bo->map, pvr_bo->bo->size));
}
result = device->ws->ops->heap_alloc(heap, size, alignment, &pvr_bo->vma);
@ -423,7 +421,7 @@ err_out:
*
* \sa #pvr_bo_alloc(), #PVR_BO_ALLOC_FLAG_CPU_MAPPED
*/
void *pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *pvr_bo)
VkResult pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *pvr_bo)
{
assert(!pvr_bo->bo->map);
@ -706,10 +704,11 @@ void *pvr_bo_suballoc_get_map_addr(const struct pvr_suballoc_bo *suballoc_bo)
}
#if defined(HAVE_VALGRIND)
void *pvr_bo_cpu_map_unchanged(struct pvr_device *device, struct pvr_bo *pvr_bo)
VkResult pvr_bo_cpu_map_unchanged(struct pvr_device *device,
struct pvr_bo *pvr_bo)
{
void *map = pvr_bo_cpu_map(device, pvr_bo);
if (map) {
VkResult result = pvr_bo_cpu_map(device, pvr_bo);
if (result == VK_SUCCESS) {
unsigned ret = VALGRIND_SET_VBITS(pvr_bo->bo->map,
pvr_bo->bo->vbits,
pvr_bo->bo->size);
@ -717,6 +716,6 @@ void *pvr_bo_cpu_map_unchanged(struct pvr_device *device, struct pvr_bo *pvr_bo)
mesa_loge("Failed to set vbits; expect bad valgrind results.");
}
return map;
return result;
}
#endif /* defined(HAVE_VALGRIND) */

View file

@ -128,7 +128,7 @@ VkResult pvr_bo_alloc(struct pvr_device *device,
uint64_t alignment,
uint64_t flags,
struct pvr_bo **const bo_out);
void *pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *bo);
VkResult pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *bo);
void pvr_bo_cpu_unmap(struct pvr_device *device, struct pvr_bo *bo);
void pvr_bo_free(struct pvr_device *device, struct pvr_bo *bo);
@ -146,11 +146,11 @@ void pvr_bo_suballoc_free(struct pvr_suballoc_bo *suballoc_bo);
void *pvr_bo_suballoc_get_map_addr(const struct pvr_suballoc_bo *suballoc_bo);
#if defined(HAVE_VALGRIND)
void *pvr_bo_cpu_map_unchanged(struct pvr_device *device,
struct pvr_bo *pvr_bo);
VkResult pvr_bo_cpu_map_unchanged(struct pvr_device *device,
struct pvr_bo *pvr_bo);
#else /* defined(HAVE_VALGRIND) */
static ALWAYS_INLINE void *pvr_bo_cpu_map_unchanged(struct pvr_device *device,
struct pvr_bo *pvr_bo)
static ALWAYS_INLINE VkResult
pvr_bo_cpu_map_unchanged(struct pvr_device *device, struct pvr_bo *pvr_bo)
{
return pvr_bo_cpu_map(device, pvr_bo);
}

View file

@ -2184,7 +2184,7 @@ VkResult pvr_MapMemory(VkDevice _device,
{
PVR_FROM_HANDLE(pvr_device, device, _device);
PVR_FROM_HANDLE(pvr_device_memory, mem, _memory);
void *map;
VkResult result;
if (!mem) {
*ppData = NULL;
@ -2212,11 +2212,11 @@ VkResult pvr_MapMemory(VkDevice _device,
}
/* Map it all at once */
map = device->ws->ops->buffer_map(mem->bo);
if (!map)
return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED);
result = device->ws->ops->buffer_map(mem->bo);
if (result != VK_SUCCESS)
return result;
*ppData = map + offset;
*ppData = mem->bo->map + offset;
return VK_SUCCESS;
}

View file

@ -40,7 +40,7 @@ bool pvr_dump_bo_ctx_push(struct pvr_dump_bo_ctx *const ctx,
bool did_map_bo = false;
if (!bo->bo->map) {
if (!pvr_bo_cpu_map_unchanged(device, bo))
if (pvr_bo_cpu_map_unchanged(device, bo) != VK_SUCCESS)
goto err_out;
did_map_bo = true;

View file

@ -408,7 +408,7 @@ struct pvr_winsys_ops {
VkResult (*buffer_get_fd)(struct pvr_winsys_bo *bo, int *const fd_out);
void *(*buffer_map)(struct pvr_winsys_bo *bo);
VkResult (*buffer_map)(struct pvr_winsys_bo *bo);
void (*buffer_unmap)(struct pvr_winsys_bo *bo);
VkResult (*heap_alloc)(struct pvr_winsys_heap *heap,

View file

@ -318,33 +318,26 @@ pvr_winsys_helper_fill_static_memory(struct pvr_winsys *const ws,
struct pvr_winsys_vma *const pds_vma,
struct pvr_winsys_vma *const usc_vma)
{
uint8_t *general_ptr, *pds_ptr, *usc_ptr;
VkResult result;
general_ptr = ws->ops->buffer_map(general_vma->bo);
if (!general_ptr) {
result = VK_ERROR_MEMORY_MAP_FAILED;
result = ws->ops->buffer_map(general_vma->bo);
if (result != VK_SUCCESS)
goto err_out;
}
pds_ptr = ws->ops->buffer_map(pds_vma->bo);
if (!pds_ptr) {
result = VK_ERROR_MEMORY_MAP_FAILED;
result = ws->ops->buffer_map(pds_vma->bo);
if (result != VK_SUCCESS)
goto err_pvr_srv_winsys_buffer_unmap_general;
}
usc_ptr = ws->ops->buffer_map(usc_vma->bo);
if (!usc_ptr) {
result = VK_ERROR_MEMORY_MAP_FAILED;
result = ws->ops->buffer_map(usc_vma->bo);
if (result != VK_SUCCESS)
goto err_pvr_srv_winsys_buffer_unmap_pds;
}
pvr_setup_static_vdm_sync(pds_ptr,
pvr_setup_static_vdm_sync(pds_vma->bo->map,
pds_vma->heap->static_data_offsets.vdm_sync,
usc_ptr,
usc_vma->bo->map,
usc_vma->heap->static_data_offsets.vdm_sync);
pvr_setup_static_pixel_event_program(pds_ptr,
pvr_setup_static_pixel_event_program(pds_vma->bo->map,
pds_vma->heap->static_data_offsets.eot);
ws->ops->buffer_unmap(usc_vma->bo);

View file

@ -26,8 +26,11 @@
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <xf86drm.h>
#include "pvr_types.h"
@ -79,6 +82,43 @@ pvr_winsys_helper_fill_static_memory(struct pvr_winsys *const ws,
struct pvr_winsys_vma *const pds_vma,
struct pvr_winsys_vma *const usc_vma);
static inline VkResult pvr_mmap(const size_t len,
const int prot,
const int flags,
const int fd,
const off_t offset,
void **const map_out)
{
void *const map = mmap(NULL, len, prot, flags, fd, offset);
if (map == MAP_FAILED) {
const int err = errno;
return vk_errorf(NULL,
VK_ERROR_MEMORY_MAP_FAILED,
"mmap failed (errno %d: %s)",
err,
strerror(err));
}
*map_out = map;
return VK_SUCCESS;
}
static inline VkResult pvr_munmap(void *const addr, const size_t len)
{
const int ret = munmap(addr, len);
if (ret) {
const int err = errno;
return vk_errorf(NULL,
VK_ERROR_UNKNOWN,
"munmap failed (errno %d: %s)",
err,
strerror(err));
}
return VK_SUCCESS;
}
#define pvr_ioctlf(fd, request, arg, error, fmt, args...) \
({ \
VkResult _result = VK_SUCCESS; \

View file

@ -299,28 +299,28 @@ VkResult pvr_srv_winsys_buffer_get_fd(struct pvr_winsys_bo *bo,
return VK_SUCCESS;
}
void *pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo)
VkResult pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo)
{
struct pvr_srv_winsys_bo *srv_bo = to_pvr_srv_winsys_bo(bo);
struct pvr_winsys *ws = bo->ws;
const int prot =
(srv_bo->flags & PVR_SRV_MEMALLOCFLAG_CPU_WRITEABLE ? PROT_WRITE : 0) |
(srv_bo->flags & PVR_SRV_MEMALLOCFLAG_CPU_READABLE ? PROT_READ : 0);
VkResult result;
/* assert if memory is already mapped */
assert(!bo->map);
/* Map the full PMR to CPU space */
bo->map = mmap(NULL,
bo->size,
prot,
MAP_SHARED,
ws->render_fd,
(off_t)srv_bo->pmr << ws->log2_page_size);
if (bo->map == MAP_FAILED) {
result = pvr_mmap(bo->size,
prot,
MAP_SHARED,
ws->render_fd,
(off_t)srv_bo->pmr << ws->log2_page_size,
&bo->map);
if (result != VK_SUCCESS) {
bo->map = NULL;
vk_error(NULL, VK_ERROR_MEMORY_MAP_FAILED);
return NULL;
return result;
}
VG(VALGRIND_MALLOCLIKE_BLOCK(bo->map,
@ -331,7 +331,7 @@ void *pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo)
buffer_acquire(srv_bo);
return bo->map;
return VK_SUCCESS;
}
void pvr_srv_winsys_buffer_unmap(struct pvr_winsys_bo *bo)
@ -344,8 +344,7 @@ void pvr_srv_winsys_buffer_unmap(struct pvr_winsys_bo *bo)
VG(VALGRIND_FREELIKE_BLOCK(bo->map, 0));
/* Unmap the whole PMR from CPU space */
if (munmap(bo->map, bo->size))
vk_error(NULL, VK_ERROR_UNKNOWN);
pvr_munmap(bo->map, bo->size);
bo->map = NULL;

View file

@ -156,7 +156,7 @@ void pvr_srv_winsys_buffer_destroy(struct pvr_winsys_bo *bo);
VkResult pvr_srv_winsys_buffer_get_fd(struct pvr_winsys_bo *bo,
int *const fd_out);
void *pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo);
VkResult pvr_srv_winsys_buffer_map(struct pvr_winsys_bo *bo);
void pvr_srv_winsys_buffer_unmap(struct pvr_winsys_bo *bo);
VkResult pvr_srv_heap_alloc_reserved(struct pvr_winsys_heap *heap,