diff options
Diffstat (limited to 'drivers/gpu/drm/xe/xe_bo.c')
| -rw-r--r-- | drivers/gpu/drm/xe/xe_bo.c | 76 |
1 files changed, 53 insertions, 23 deletions
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index dde309821237..9f3f0cb95afa 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -28,6 +28,7 @@ #include "xe_ggtt.h" #include "xe_map.h" #include "xe_migrate.h" +#include "xe_mmio_gem.h" #include "xe_pat.h" #include "xe_pm.h" #include "xe_preempt_fence.h" @@ -104,13 +105,16 @@ static bool resource_is_vram(struct ttm_resource *res) bool xe_bo_is_vram(struct xe_bo *bo) { - return resource_is_vram(bo->ttm.resource) || - resource_is_stolen_vram(xe_bo_device(bo), bo->ttm.resource); + struct ttm_resource *res = bo->ttm.resource; + + return res && (resource_is_vram(res) || resource_is_stolen_vram(xe_bo_device(bo), res)); } bool xe_bo_is_stolen(struct xe_bo *bo) { - return bo->ttm.resource->mem_type == XE_PL_STOLEN; + struct ttm_resource *res = bo->ttm.resource; + + return res && res->mem_type == XE_PL_STOLEN; } /** @@ -158,7 +162,13 @@ bool xe_bo_is_vm_bound(struct xe_bo *bo) return !list_empty(&bo->ttm.base.gpuva.list); } -static bool xe_bo_is_user(struct xe_bo *bo) +/** + * xe_bo_is_user - Check if BO is user-created + * @bo: The BO + * + * Returns: true if @bo was created by userspace + */ +bool xe_bo_is_user(struct xe_bo *bo) { return bo->flags & XE_BO_FLAG_USER; } @@ -921,7 +931,7 @@ void xe_bo_set_purgeable_state(struct xe_bo *bo, * * Return: 0 on success, negative error code on failure */ -static int xe_ttm_bo_purge(struct ttm_buffer_object *ttm_bo, struct ttm_operation_ctx *ctx) +int xe_ttm_bo_purge(struct ttm_buffer_object *ttm_bo, struct ttm_operation_ctx *ctx) { struct xe_bo *bo = ttm_to_xe_bo(ttm_bo); struct ttm_placement place = {}; @@ -929,9 +939,6 @@ static int xe_ttm_bo_purge(struct ttm_buffer_object *ttm_bo, struct ttm_operatio xe_bo_assert_held(bo); - if (!ttm_bo->ttm) - return 0; - if (!xe_bo_madv_is_dontneed(bo)) return 0; @@ -3261,6 +3268,9 @@ void xe_bo_unpin(struct xe_bo *bo) struct ttm_place *place = &bo->placements[0]; struct xe_device *xe = xe_bo_device(bo); + if (xe_bo_is_purged(bo)) + return; + xe_assert(xe, !bo->ttm.base.import_attach); xe_assert(xe, xe_bo_is_pinned(bo)); @@ -3655,6 +3665,39 @@ out_vm: return err; } +static int xe_gem_pci_barrier_mmap_offset(struct xe_device *xe, struct drm_file *file, + struct drm_xe_gem_mmap_offset *args) +{ + struct xe_file *xef = file->driver_priv; + struct xe_mmio_gem **barrier = &xef->mmio_gem.pci_barrier; + + if (XE_IOCTL_DBG(xe, !IS_DGFX(xe))) + return -EINVAL; + + if (XE_IOCTL_DBG(xe, args->handle)) + return -EINVAL; + + scoped_guard(mutex, &xef->mmio_gem.lock) { + if (!*barrier) { + phys_addr_t phys_addr; + +#define LAST_DB_PAGE_OFFSET 0x7ff000 + phys_addr = pci_resource_start(to_pci_dev(xe->drm.dev), 0) + + LAST_DB_PAGE_OFFSET; + *barrier = xe_mmio_gem_create(xe, file, phys_addr, SZ_4K); + if (IS_ERR(*barrier)) { + int err = PTR_ERR(*barrier); + + *barrier = NULL; + return err; + } + } + + args->offset = xe_mmio_gem_mmap_offset(*barrier); + } + return 0; +} + int xe_gem_mmap_offset_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { @@ -3670,21 +3713,8 @@ int xe_gem_mmap_offset_ioctl(struct drm_device *dev, void *data, ~DRM_XE_MMAP_OFFSET_FLAG_PCI_BARRIER)) return -EINVAL; - if (args->flags & DRM_XE_MMAP_OFFSET_FLAG_PCI_BARRIER) { - if (XE_IOCTL_DBG(xe, !IS_DGFX(xe))) - return -EINVAL; - - if (XE_IOCTL_DBG(xe, args->handle)) - return -EINVAL; - - if (XE_IOCTL_DBG(xe, PAGE_SIZE > SZ_4K)) - return -EINVAL; - - BUILD_BUG_ON(((XE_PCI_BARRIER_MMAP_OFFSET >> XE_PTE_SHIFT) + - SZ_4K) >= DRM_FILE_PAGE_OFFSET_START); - args->offset = XE_PCI_BARRIER_MMAP_OFFSET; - return 0; - } + if (args->flags & DRM_XE_MMAP_OFFSET_FLAG_PCI_BARRIER) + return xe_gem_pci_barrier_mmap_offset(xe, file, args); gem_obj = drm_gem_object_lookup(file, args->handle); if (XE_IOCTL_DBG(xe, !gem_obj)) |
