mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-18 19:28:24 +02:00
intel: Add common utils for page fault reporting
Adds some data types and functions for getting the list of page faults from the KMD using the intel common library. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41318>
This commit is contained in:
parent
5074524788
commit
39a0d76f64
5 changed files with 187 additions and 1 deletions
40
src/intel/common/intel_pagefault.c
Normal file
40
src/intel/common/intel_pagefault.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/* Copyright © 2026 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "intel_pagefault.h"
|
||||
|
||||
const char *
|
||||
intel_pagefault_access_to_string(enum intel_pagefault_access access)
|
||||
{
|
||||
static const char *const lookup[] = {
|
||||
[INTEL_PAGEFAULT_ACCESS_READ] = "Read",
|
||||
[INTEL_PAGEFAULT_ACCESS_WRITE] = "Write",
|
||||
[INTEL_PAGEFAULT_ACCESS_ATOMIC] = "Atomic",
|
||||
};
|
||||
return lookup[access];
|
||||
}
|
||||
|
||||
const char *
|
||||
intel_pagefault_type_to_string(enum intel_pagefault_type type)
|
||||
{
|
||||
static const char *const lookup[] = {
|
||||
[INTEL_PAGEFAULT_TYPE_NOT_PRESENT] = "Not Present",
|
||||
[INTEL_PAGEFAULT_TYPE_WRITE_ACCESS] = "Not Writable",
|
||||
[INTEL_PAGEFAULT_TYPE_ATOMIC_ACCESS] = "Atomic",
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
const char *
|
||||
intel_pagefault_level_to_string(enum intel_pagefault_level level)
|
||||
{
|
||||
static const char *const lookup[] = {
|
||||
[INTEL_PAGEFAULT_LEVEL_PTE] = "PTE",
|
||||
[INTEL_PAGEFAULT_LEVEL_PDE] = "PDE",
|
||||
[INTEL_PAGEFAULT_LEVEL_PDP] = "PDP",
|
||||
[INTEL_PAGEFAULT_LEVEL_PML4] = "PML4",
|
||||
[INTEL_PAGEFAULT_LEVEL_PML5] = "PML5",
|
||||
};
|
||||
return lookup[level];
|
||||
}
|
||||
47
src/intel/common/intel_pagefault.h
Normal file
47
src/intel/common/intel_pagefault.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* Copyright © 2026 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum intel_pagefault_access {
|
||||
INTEL_PAGEFAULT_ACCESS_READ,
|
||||
INTEL_PAGEFAULT_ACCESS_WRITE,
|
||||
INTEL_PAGEFAULT_ACCESS_ATOMIC,
|
||||
};
|
||||
|
||||
enum intel_pagefault_type {
|
||||
INTEL_PAGEFAULT_TYPE_NOT_PRESENT,
|
||||
INTEL_PAGEFAULT_TYPE_WRITE_ACCESS,
|
||||
INTEL_PAGEFAULT_TYPE_ATOMIC_ACCESS,
|
||||
};
|
||||
|
||||
enum intel_pagefault_level {
|
||||
INTEL_PAGEFAULT_LEVEL_PTE,
|
||||
INTEL_PAGEFAULT_LEVEL_PDE,
|
||||
INTEL_PAGEFAULT_LEVEL_PDP,
|
||||
INTEL_PAGEFAULT_LEVEL_PML4,
|
||||
INTEL_PAGEFAULT_LEVEL_PML5,
|
||||
};
|
||||
|
||||
struct intel_pagefault_info {
|
||||
uint64_t address;
|
||||
uint32_t precision;
|
||||
enum intel_pagefault_access access;
|
||||
enum intel_pagefault_type type;
|
||||
enum intel_pagefault_level level;
|
||||
};
|
||||
|
||||
struct intel_pagefault_buffer {
|
||||
unsigned size;
|
||||
struct intel_pagefault_info items[];
|
||||
};
|
||||
|
||||
const char *
|
||||
intel_pagefault_access_to_string(enum intel_pagefault_access access);
|
||||
const char *
|
||||
intel_pagefault_type_to_string(enum intel_pagefault_type type);
|
||||
const char *
|
||||
intel_pagefault_level_to_string(enum intel_pagefault_level level);
|
||||
|
|
@ -42,7 +42,9 @@ files_libintel_common = files(
|
|||
'intel_uuid.h',
|
||||
'intel_measure.c',
|
||||
'intel_measure.h',
|
||||
'intel_pixel_hash.h'
|
||||
'intel_pixel_hash.h',
|
||||
'intel_pagefault.c',
|
||||
'intel_pagefault.h',
|
||||
)
|
||||
|
||||
libintel_common_links = [libisl]
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#include "util/os_time.h"
|
||||
#include "util/timespec.h"
|
||||
#include "util/compiler.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/stack_array.h"
|
||||
|
||||
bool
|
||||
xe_gem_read_render_timestamp(int fd, uint64_t *value)
|
||||
|
|
@ -123,3 +126,92 @@ xe_gem_supports_protected_exec_queue(int fd)
|
|||
*/
|
||||
return intel_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) == 0;
|
||||
}
|
||||
|
||||
bool xe_gem_supports_get_vm_faults(int fd)
|
||||
{
|
||||
struct drm_xe_vm_get_property prop = {
|
||||
.vm_id = -1,
|
||||
.property = DRM_XE_VM_GET_PROPERTY_FAULTS,
|
||||
};
|
||||
/* FIXME: Get a proper kernel api to detect this */
|
||||
int ret = intel_ioctl(fd, DRM_IOCTL_XE_VM_GET_PROPERTY, &prop);
|
||||
return ret == -1 && errno == ENOENT;
|
||||
}
|
||||
|
||||
static inline enum intel_pagefault_access
|
||||
xe_vm_fault_get_access(const struct xe_vm_fault *vm_fault)
|
||||
{
|
||||
switch (vm_fault->access_type) {
|
||||
default: UNREACHABLE("not handled"); FALLTHROUGH;
|
||||
case FAULT_ACCESS_TYPE_READ: return INTEL_PAGEFAULT_ACCESS_READ;
|
||||
case FAULT_ACCESS_TYPE_WRITE: return INTEL_PAGEFAULT_ACCESS_WRITE;
|
||||
case FAULT_ACCESS_TYPE_ATOMIC: return INTEL_PAGEFAULT_ACCESS_ATOMIC;
|
||||
}
|
||||
}
|
||||
|
||||
static inline enum intel_pagefault_type
|
||||
xe_vm_fault_get_type(const struct xe_vm_fault *vm_fault)
|
||||
{
|
||||
switch (vm_fault->fault_type) {
|
||||
default: UNREACHABLE("not handled"); FALLTHROUGH;
|
||||
case FAULT_TYPE_NOT_PRESENT: return INTEL_PAGEFAULT_TYPE_NOT_PRESENT;
|
||||
case FAULT_TYPE_WRITE_ACCESS: return INTEL_PAGEFAULT_TYPE_WRITE_ACCESS;
|
||||
case FAULT_TYPE_ATOMIC_ACCESS: return INTEL_PAGEFAULT_TYPE_ATOMIC_ACCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static inline enum intel_pagefault_level
|
||||
xe_vm_fault_get_level(const struct xe_vm_fault *vm_fault)
|
||||
{
|
||||
switch (vm_fault->fault_level) {
|
||||
default: UNREACHABLE("not handled"); FALLTHROUGH;
|
||||
case FAULT_LEVEL_PTE: return INTEL_PAGEFAULT_LEVEL_PTE;
|
||||
case FAULT_LEVEL_PDE: return INTEL_PAGEFAULT_LEVEL_PDE;
|
||||
case FAULT_LEVEL_PDP: return INTEL_PAGEFAULT_LEVEL_PDP;
|
||||
case FAULT_LEVEL_PML4: return INTEL_PAGEFAULT_LEVEL_PML4;
|
||||
case FAULT_LEVEL_PML5: return INTEL_PAGEFAULT_LEVEL_PML5;
|
||||
}
|
||||
}
|
||||
|
||||
struct intel_pagefault_buffer *
|
||||
xe_gem_alloc_get_vm_faults(int fd, int vm_id)
|
||||
{
|
||||
struct drm_xe_vm_get_property prop = {
|
||||
.vm_id = vm_id,
|
||||
.property = DRM_XE_VM_GET_PROPERTY_FAULTS,
|
||||
};
|
||||
|
||||
int ret = intel_ioctl(fd, DRM_IOCTL_XE_VM_GET_PROPERTY, &prop);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
unsigned size = (unsigned) (prop.size / sizeof(struct xe_vm_fault));
|
||||
|
||||
STACK_ARRAY(struct xe_vm_fault, kmd_faults, size);
|
||||
prop.size = size * sizeof(struct xe_vm_fault);
|
||||
prop.data = (uintptr_t) kmd_faults;
|
||||
|
||||
struct intel_pagefault_buffer *result = NULL;
|
||||
|
||||
if (size != 0)
|
||||
ret = intel_ioctl(fd, DRM_IOCTL_XE_VM_GET_PROPERTY, &prop);
|
||||
|
||||
if (ret == 0) {
|
||||
size = MIN2(size, (unsigned) (prop.size / sizeof(struct xe_vm_fault)));
|
||||
result = malloc(sizeof(*result) + sizeof(result->items[0]) * size);
|
||||
if (result) {
|
||||
result->size = size;
|
||||
for (unsigned i = 0; i < size; ++i) {
|
||||
result->items[i].address = kmd_faults[i].address;
|
||||
result->items[i].precision = kmd_faults[i].address_precision;
|
||||
result->items[i].access = xe_vm_fault_get_access(&kmd_faults[i]);
|
||||
result->items[i].type = xe_vm_fault_get_type(&kmd_faults[i]);
|
||||
result->items[i].level = xe_vm_fault_get_level(&kmd_faults[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STACK_ARRAY_FINISH(kmd_faults);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "common/intel_gem.h"
|
||||
#include "common/intel_engine.h"
|
||||
#include "common/intel_pagefault.h"
|
||||
#include "drm-uapi/xe_drm.h"
|
||||
#include "util/os_time.h"
|
||||
|
||||
|
|
@ -43,9 +44,13 @@ xe_gem_read_correlate_cpu_gpu_timestamp(int fd,
|
|||
uint64_t *cpu_delta);
|
||||
bool xe_gem_can_render_on_fd(int fd);
|
||||
bool xe_gem_supports_protected_exec_queue(int fd);
|
||||
bool xe_gem_supports_get_vm_faults(int fd);
|
||||
|
||||
void intel_xe_gem_add_ext(uint64_t *ptr, uint32_t ext_name, void *data);
|
||||
|
||||
struct intel_pagefault_buffer *
|
||||
xe_gem_alloc_get_vm_faults(int fd, int vm_id);
|
||||
|
||||
static inline int
|
||||
xe_gem_exec_ioctl(int fd, const struct intel_device_info *info,
|
||||
struct drm_xe_exec *exec)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue