All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/xe: Invalidate userptr VMA on page pin fault
@ 2024-03-08 21:37 Matthew Brost
  2024-03-08 21:42 ` ✓ CI.Patch_applied: success for " Patchwork
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Matthew Brost @ 2024-03-08 21:37 UTC (permalink / raw)
  To: intel-xe; +Cc: fei.yang, thomas.hellstrom, rodrigo.vivi, Matthew Brost

Rather than return an error to the user or ban the VM when userptr VMA
page pin fails with -EFAULT, invalidate VMA mappings. This supports the
UMD use case of freeing userptr while still having bindings.

Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
 drivers/gpu/drm/xe/xe_gt_pagefault.c |  4 ++--
 drivers/gpu/drm/xe/xe_trace.h        |  2 +-
 drivers/gpu/drm/xe/xe_vm.c           | 20 +++++++++++++-------
 drivers/gpu/drm/xe/xe_vm_types.h     |  7 ++-----
 4 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c
index 73c535193a98..241c294270d9 100644
--- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
@@ -69,7 +69,7 @@ static bool access_is_atomic(enum access_type access_type)
 static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
 {
 	return BIT(tile->id) & vma->tile_present &&
-		!(BIT(tile->id) & vma->usm.tile_invalidated);
+		!(BIT(tile->id) & vma->tile_invalidated);
 }
 
 static bool vma_matches(struct xe_vma *vma, u64 page_addr)
@@ -226,7 +226,7 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
 
 	if (xe_vma_is_userptr(vma))
 		ret = xe_vma_userptr_check_repin(to_userptr_vma(vma));
-	vma->usm.tile_invalidated &= ~BIT(tile->id);
+	vma->tile_invalidated &= ~BIT(tile->id);
 
 unlock_dma_resv:
 	drm_exec_fini(&exec);
diff --git a/drivers/gpu/drm/xe/xe_trace.h b/drivers/gpu/drm/xe/xe_trace.h
index 4ddc55527f9a..846f14507d5f 100644
--- a/drivers/gpu/drm/xe/xe_trace.h
+++ b/drivers/gpu/drm/xe/xe_trace.h
@@ -468,7 +468,7 @@ DEFINE_EVENT(xe_vma, xe_vma_userptr_invalidate,
 	     TP_ARGS(vma)
 );
 
-DEFINE_EVENT(xe_vma, xe_vma_usm_invalidate,
+DEFINE_EVENT(xe_vma, xe_vma_invalidate,
 	     TP_PROTO(struct xe_vma *vma),
 	     TP_ARGS(vma)
 );
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 643b3701a738..9a19044f7ef6 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -724,11 +724,18 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
 	list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list,
 				 userptr.repin_link) {
 		err = xe_vma_userptr_pin_pages(uvma);
-		if (err < 0)
-			return err;
-
 		list_del_init(&uvma->userptr.repin_link);
-		list_move_tail(&uvma->vma.combined_links.rebind, &vm->rebind_list);
+		if (err == -EFAULT) {
+			err = xe_vm_invalidate_vma(&uvma->vma);
+			if (err)
+				return err;
+		} else {
+			if (err < 0)
+				return err;
+
+			list_move_tail(&uvma->vma.combined_links.rebind,
+				       &vm->rebind_list);
+		}
 	}
 
 	return 0;
@@ -3214,9 +3221,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
 	u8 id;
 	int ret;
 
-	xe_assert(xe, xe_vm_in_fault_mode(xe_vma_vm(vma)));
 	xe_assert(xe, !xe_vma_is_null(vma));
-	trace_xe_vma_usm_invalidate(vma);
+	trace_xe_vma_invalidate(vma);
 
 	/* Check that we don't race with page-table updates */
 	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
@@ -3254,7 +3260,7 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
 		}
 	}
 
-	vma->usm.tile_invalidated = vma->tile_mask;
+	vma->tile_invalidated = vma->tile_mask;
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
index 79b5cab57711..ae5fb565f6bf 100644
--- a/drivers/gpu/drm/xe/xe_vm_types.h
+++ b/drivers/gpu/drm/xe/xe_vm_types.h
@@ -84,11 +84,8 @@ struct xe_vma {
 		struct work_struct destroy_work;
 	};
 
-	/** @usm: unified shared memory state */
-	struct {
-		/** @tile_invalidated: VMA has been invalidated */
-		u8 tile_invalidated;
-	} usm;
+	/** @tile_invalidated: VMA has been invalidated */
+	u8 tile_invalidated;
 
 	/** @tile_mask: Tile mask of where to create binding for this VMA */
 	u8 tile_mask;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* ✓ CI.Patch_applied: success for drm/xe: Invalidate userptr VMA on page pin fault
  2024-03-08 21:37 [PATCH] drm/xe: Invalidate userptr VMA on page pin fault Matthew Brost
@ 2024-03-08 21:42 ` Patchwork
  2024-03-08 21:42 ` ✓ CI.checkpatch: " Patchwork
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2024-03-08 21:42 UTC (permalink / raw)
  To: Matthew Brost; +Cc: intel-xe

== Series Details ==

Series: drm/xe: Invalidate userptr VMA on page pin fault
URL   : https://patchwork.freedesktop.org/series/130935/
State : success

== Summary ==

=== Applying kernel patches on branch 'drm-tip' with base: ===
Base commit: 3fde6df89bac drm-tip: 2024y-03m-08d-18h-22m-29s UTC integration manifest
=== git am output follows ===
Applying: drm/xe: Invalidate userptr VMA on page pin fault



^ permalink raw reply	[flat|nested] 10+ messages in thread

* ✓ CI.checkpatch: success for drm/xe: Invalidate userptr VMA on page pin fault
  2024-03-08 21:37 [PATCH] drm/xe: Invalidate userptr VMA on page pin fault Matthew Brost
  2024-03-08 21:42 ` ✓ CI.Patch_applied: success for " Patchwork
@ 2024-03-08 21:42 ` Patchwork
  2024-03-08 21:43 ` ✗ CI.KUnit: failure " Patchwork
  2024-03-11 10:55 ` [PATCH] " Thomas Hellström
  3 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2024-03-08 21:42 UTC (permalink / raw)
  To: Matthew Brost; +Cc: intel-xe

== Series Details ==

Series: drm/xe: Invalidate userptr VMA on page pin fault
URL   : https://patchwork.freedesktop.org/series/130935/
State : success

== Summary ==

+ KERNEL=/kernel
+ git clone https://gitlab.freedesktop.org/drm/maintainer-tools mt
Cloning into 'mt'...
warning: redirecting to https://gitlab.freedesktop.org/drm/maintainer-tools.git/
+ git -C mt rev-list -n1 origin/master
a9bb2a8a17457065eb398a81e8fd9aec2b519fd6
+ cd /kernel
+ git config --global --add safe.directory /kernel
+ git log -n1
commit 51be9738e69582621c45a442ac73cfa2571920a7
Author: Matthew Brost <matthew.brost@intel.com>
Date:   Fri Mar 8 13:37:47 2024 -0800

    drm/xe: Invalidate userptr VMA on page pin fault
    
    Rather than return an error to the user or ban the VM when userptr VMA
    page pin fails with -EFAULT, invalidate VMA mappings. This supports the
    UMD use case of freeing userptr while still having bindings.
    
    Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+ /mt/dim checkpatch 3fde6df89bac97416ce1c82b14237a1a67ce3285 drm-intel
51be9738e695 drm/xe: Invalidate userptr VMA on page pin fault



^ permalink raw reply	[flat|nested] 10+ messages in thread

* ✗ CI.KUnit: failure for drm/xe: Invalidate userptr VMA on page pin fault
  2024-03-08 21:37 [PATCH] drm/xe: Invalidate userptr VMA on page pin fault Matthew Brost
  2024-03-08 21:42 ` ✓ CI.Patch_applied: success for " Patchwork
  2024-03-08 21:42 ` ✓ CI.checkpatch: " Patchwork
@ 2024-03-08 21:43 ` Patchwork
  2024-03-11 10:55 ` [PATCH] " Thomas Hellström
  3 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2024-03-08 21:43 UTC (permalink / raw)
  To: Matthew Brost; +Cc: intel-xe

== Series Details ==

Series: drm/xe: Invalidate userptr VMA on page pin fault
URL   : https://patchwork.freedesktop.org/series/130935/
State : failure

== Summary ==

+ trap cleanup EXIT
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/xe/.kunitconfig
ERROR:root:../arch/x86/um/user-offsets.c:17:6: warning: no previous prototype for ‘foo’ [-Wmissing-prototypes]
   17 | void foo(void)
      |      ^~~
In file included from ../arch/um/kernel/asm-offsets.c:1:
../arch/x86/um/shared/sysdep/kernel-offsets.h:9:6: warning: no previous prototype for ‘foo’ [-Wmissing-prototypes]
    9 | void foo(void)
      |      ^~~
../arch/x86/um/bugs_64.c:9:6: warning: no previous prototype for ‘arch_check_bugs’ [-Wmissing-prototypes]
    9 | void arch_check_bugs(void)
      |      ^~~~~~~~~~~~~~~
../arch/x86/um/bugs_64.c:13:6: warning: no previous prototype for ‘arch_examine_signal’ [-Wmissing-prototypes]
   13 | void arch_examine_signal(int sig, struct uml_pt_regs *regs)
      |      ^~~~~~~~~~~~~~~~~~~
../arch/x86/um/fault.c:18:5: warning: no previous prototype for ‘arch_fixup’ [-Wmissing-prototypes]
   18 | int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
      |     ^~~~~~~~~~
../arch/x86/um/os-Linux/registers.c:146:15: warning: no previous prototype for ‘get_thread_reg’ [-Wmissing-prototypes]
  146 | unsigned long get_thread_reg(int reg, jmp_buf *buf)
      |               ^~~~~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:16:5: warning: no previous prototype for ‘__vdso_clock_gettime’ [-Wmissing-prototypes]
   16 | int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts)
      |     ^~~~~~~~~~~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:30:5: warning: no previous prototype for ‘__vdso_gettimeofday’ [-Wmissing-prototypes]
   30 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
      |     ^~~~~~~~~~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:44:21: warning: no previous prototype for ‘__vdso_time’ [-Wmissing-prototypes]
   44 | __kernel_old_time_t __vdso_time(__kernel_old_time_t *t)
      |                     ^~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:57:1: warning: no previous prototype for ‘__vdso_getcpu’ [-Wmissing-prototypes]
   57 | __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
      | ^~~~~~~~~~~~~
../arch/x86/um/os-Linux/mcontext.c:7:6: warning: no previous prototype for ‘get_regs_from_mc’ [-Wmissing-prototypes]
    7 | void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc)
      |      ^~~~~~~~~~~~~~~~
../arch/um/os-Linux/skas/process.c:107:6: warning: no previous prototype for ‘wait_stub_done’ [-Wmissing-prototypes]
  107 | void wait_stub_done(int pid)
      |      ^~~~~~~~~~~~~~
../arch/um/os-Linux/skas/process.c:683:6: warning: no previous prototype for ‘__switch_mm’ [-Wmissing-prototypes]
  683 | void __switch_mm(struct mm_id *mm_idp)
      |      ^~~~~~~~~~~
../arch/um/kernel/skas/mmu.c:17:5: warning: no previous prototype for ‘init_new_context’ [-Wmissing-prototypes]
   17 | int init_new_context(struct task_struct *task, struct mm_struct *mm)
      |     ^~~~~~~~~~~~~~~~
../arch/um/kernel/skas/mmu.c:60:6: warning: no previous prototype for ‘destroy_context’ [-Wmissing-prototypes]
   60 | void destroy_context(struct mm_struct *mm)
      |      ^~~~~~~~~~~~~~~
../arch/x86/um/ptrace_64.c:111:5: warning: no previous prototype for ‘poke_user’ [-Wmissing-prototypes]
  111 | int poke_user(struct task_struct *child, long addr, long data)
      |     ^~~~~~~~~
../arch/x86/um/ptrace_64.c:171:5: warning: no previous prototype for ‘peek_user’ [-Wmissing-prototypes]
  171 | int peek_user(struct task_struct *child, long addr, long data)
      |     ^~~~~~~~~
../arch/um/os-Linux/main.c:187:7: warning: no previous prototype for ‘__wrap_malloc’ [-Wmissing-prototypes]
  187 | void *__wrap_malloc(int size)
      |       ^~~~~~~~~~~~~
../arch/um/os-Linux/main.c:208:7: warning: no previous prototype for ‘__wrap_calloc’ [-Wmissing-prototypes]
  208 | void *__wrap_calloc(int n, int size)
      |       ^~~~~~~~~~~~~
../arch/um/os-Linux/main.c:222:6: warning: no previous prototype for ‘__wrap_free’ [-Wmissing-prototypes]
  222 | void __wrap_free(void *ptr)
      |      ^~~~~~~~~~~
../arch/um/os-Linux/mem.c:28:6: warning: no previous prototype for ‘kasan_map_memory’ [-Wmissing-prototypes]
   28 | void kasan_map_memory(void *start, size_t len)
      |      ^~~~~~~~~~~~~~~~
../arch/um/os-Linux/mem.c:212:13: warning: no previous prototype for ‘check_tmpexec’ [-Wmissing-prototypes]
  212 | void __init check_tmpexec(void)
      |             ^~~~~~~~~~~~~
../arch/um/kernel/skas/process.c:36:12: warning: no previous prototype for ‘start_uml’ [-Wmissing-prototypes]
   36 | int __init start_uml(void)
      |            ^~~~~~~~~
../arch/um/os-Linux/signal.c:75:6: warning: no previous prototype for ‘sig_handler’ [-Wmissing-prototypes]
   75 | void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
      |      ^~~~~~~~~~~
../arch/um/os-Linux/signal.c:111:6: warning: no previous prototype for ‘timer_alarm_handler’ [-Wmissing-prototypes]
  111 | void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
      |      ^~~~~~~~~~~~~~~~~~~
../arch/um/os-Linux/start_up.c:301:12: warning: no previous prototype for ‘parse_iomem’ [-Wmissing-prototypes]
  301 | int __init parse_iomem(char *str, int *add)
      |            ^~~~~~~~~~~
../arch/x86/um/signal.c:560:6: warning: no previous prototype for ‘sys_rt_sigreturn’ [-Wmissing-prototypes]
  560 | long sys_rt_sigreturn(void)
      |      ^~~~~~~~~~~~~~~~
../arch/x86/um/syscalls_64.c:48:6: warning: no previous prototype for ‘arch_switch_to’ [-Wmissing-prototypes]
   48 | void arch_switch_to(struct task_struct *to)
      |      ^~~~~~~~~~~~~~
../arch/um/kernel/mem.c:202:8: warning: no previous prototype for ‘pgd_alloc’ [-Wmissing-prototypes]
  202 | pgd_t *pgd_alloc(struct mm_struct *mm)
      |        ^~~~~~~~~
../arch/um/kernel/mem.c:215:7: warning: no previous prototype for ‘uml_kmalloc’ [-Wmissing-prototypes]
  215 | void *uml_kmalloc(int size, int flags)
      |       ^~~~~~~~~~~
../arch/um/kernel/process.c:51:5: warning: no previous prototype for ‘pid_to_processor_id’ [-Wmissing-prototypes]
   51 | int pid_to_processor_id(int pid)
      |     ^~~~~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:87:7: warning: no previous prototype for ‘__switch_to’ [-Wmissing-prototypes]
   87 | void *__switch_to(struct task_struct *from, struct task_struct *to)
      |       ^~~~~~~~~~~
../arch/um/kernel/process.c:140:6: warning: no previous prototype for ‘fork_handler’ [-Wmissing-prototypes]
  140 | void fork_handler(void)
      |      ^~~~~~~~~~~~
../arch/um/kernel/process.c:217:6: warning: no previous prototype for ‘arch_cpu_idle’ [-Wmissing-prototypes]
  217 | void arch_cpu_idle(void)
      |      ^~~~~~~~~~~~~
../arch/um/kernel/process.c:253:5: warning: no previous prototype for ‘copy_to_user_proc’ [-Wmissing-prototypes]
  253 | int copy_to_user_proc(void __user *to, void *from, int size)
      |     ^~~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:263:5: warning: no previous prototype for ‘clear_user_proc’ [-Wmissing-prototypes]
  263 | int clear_user_proc(void __user *buf, int size)
      |     ^~~~~~~~~~~~~~~
../arch/um/kernel/process.c:271:6: warning: no previous prototype for ‘set_using_sysemu’ [-Wmissing-prototypes]
  271 | void set_using_sysemu(int value)
      |      ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:278:5: warning: no previous prototype for ‘get_using_sysemu’ [-Wmissing-prototypes]
  278 | int get_using_sysemu(void)
      |     ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:316:12: warning: no previous prototype for ‘make_proc_sysemu’ [-Wmissing-prototypes]
  316 | int __init make_proc_sysemu(void)
      |            ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:348:15: warning: no previous prototype for ‘arch_align_stack’ [-Wmissing-prototypes]
  348 | unsigned long arch_align_stack(unsigned long sp)
      |               ^~~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:45:6: warning: no previous prototype for ‘machine_restart’ [-Wmissing-prototypes]
   45 | void machine_restart(char * __unused)
      |      ^~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:51:6: warning: no previous prototype for ‘machine_power_off’ [-Wmissing-prototypes]
   51 | void machine_power_off(void)
      |      ^~~~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:57:6: warning: no previous prototype for ‘machine_halt’ [-Wmissing-prototypes]
   57 | void machine_halt(void)
      |      ^~~~~~~~~~~~
../arch/um/kernel/tlb.c:579:6: warning: no previous prototype for ‘flush_tlb_mm_range’ [-Wmissing-prototypes]
  579 | void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
      |      ^~~~~~~~~~~~~~~~~~
../arch/um/kernel/tlb.c:594:6: warning: no previous prototype for ‘force_flush_all’ [-Wmissing-prototypes]
  594 | void force_flush_all(void)
      |      ^~~~~~~~~~~~~~~
../arch/um/kernel/kmsg_dump.c:60:12: warning: no previous prototype for ‘kmsg_dumper_stdout_init’ [-Wmissing-prototypes]
   60 | int __init kmsg_dumper_stdout_init(void)
      |            ^~~~~~~~~~~~~~~~~~~~~~~
../arch/um/kernel/um_arch.c:408:19: warning: no previous prototype for ‘read_initrd’ [-Wmissing-prototypes]
  408 | int __init __weak read_initrd(void)
      |                   ^~~~~~~~~~~
../arch/um/kernel/um_arch.c:461:7: warning: no previous prototype for ‘text_poke’ [-Wmissing-prototypes]
  461 | void *text_poke(void *addr, const void *opcode, size_t len)
      |       ^~~~~~~~~
../arch/um/kernel/um_arch.c:473:6: warning: no previous prototype for ‘text_poke_sync’ [-Wmissing-prototypes]
  473 | void text_poke_sync(void)
      |      ^~~~~~~~~~~~~~
../lib/iomap.c:156:5: warning: no previous prototype for ‘ioread64_lo_hi’ [-Wmissing-prototypes]
  156 | u64 ioread64_lo_hi(const void __iomem *addr)
      |     ^~~~~~~~~~~~~~
../lib/iomap.c:163:5: warning: no previous prototype for ‘ioread64_hi_lo’ [-Wmissing-prototypes]
  163 | u64 ioread64_hi_lo(const void __iomem *addr)
      |     ^~~~~~~~~~~~~~
../lib/iomap.c:170:5: warning: no previous prototype for ‘ioread64be_lo_hi’ [-Wmissing-prototypes]
  170 | u64 ioread64be_lo_hi(const void __iomem *addr)
      |     ^~~~~~~~~~~~~~~~
../lib/iomap.c:178:5: warning: no previous prototype for ‘ioread64be_hi_lo’ [-Wmissing-prototypes]
  178 | u64 ioread64be_hi_lo(const void __iomem *addr)
      |     ^~~~~~~~~~~~~~~~
../lib/iomap.c:264:6: warning: no previous prototype for ‘iowrite64_lo_hi’ [-Wmissing-prototypes]
  264 | void iowrite64_lo_hi(u64 val, void __iomem *addr)
      |      ^~~~~~~~~~~~~~~
../lib/iomap.c:272:6: warning: no previous prototype for ‘iowrite64_hi_lo’ [-Wmissing-prototypes]
  272 | void iowrite64_hi_lo(u64 val, void __iomem *addr)
      |      ^~~~~~~~~~~~~~~
../lib/iomap.c:280:6: warning: no previous prototype for ‘iowrite64be_lo_hi’ [-Wmissing-prototypes]
  280 | void iowrite64be_lo_hi(u64 val, void __iomem *addr)
      |      ^~~~~~~~~~~~~~~~~
../lib/iomap.c:288:6: warning: no previous prototype for ‘iowrite64be_hi_lo’ [-Wmissing-prototypes]
  288 | void iowrite64be_hi_lo(u64 val, void __iomem *addr)
      |      ^~~~~~~~~~~~~~~~~
../drivers/gpu/drm/xe/xe_vm.c: In function ‘xe_vm_prefetch’:
../drivers/gpu/drm/xe/xe_vm.c:2034:49: error: ‘struct xe_vma’ has no member named ‘usm’
 2034 |  if (vma->tile_mask != (vma->tile_present & ~vma->usm.tile_invalidated)) {
      |                                                 ^~
../drivers/gpu/drm/xe/xe_vm.c:2053:1: error: control reaches end of non-void function [-Werror=return-type]
 2053 | }
      | ^
cc1: some warnings being treated as errors
make[7]: *** [../scripts/Makefile.build:243: drivers/gpu/drm/xe/xe_vm.o] Error 1
make[7]: *** Waiting for unfinished jobs....
make[6]: *** [../scripts/Makefile.build:481: drivers/gpu/drm/xe] Error 2
make[5]: *** [../scripts/Makefile.build:481: drivers/gpu/drm] Error 2
make[4]: *** [../scripts/Makefile.build:481: drivers/gpu] Error 2
make[3]: *** [../scripts/Makefile.build:481: drivers] Error 2
make[2]: *** [/kernel/Makefile:1921: .] Error 2
make[1]: *** [/kernel/Makefile:240: __sub-make] Error 2
make: *** [Makefile:240: __sub-make] Error 2

[21:42:48] Configuring KUnit Kernel ...
Generating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[21:42:52] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make ARCH=um O=.kunit --jobs=48
+ cleanup
++ stat -c %u:%g /kernel
+ chown -R 1003:1003 /kernel



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] drm/xe: Invalidate userptr VMA on page pin fault
  2024-03-08 21:37 [PATCH] drm/xe: Invalidate userptr VMA on page pin fault Matthew Brost
                   ` (2 preceding siblings ...)
  2024-03-08 21:43 ` ✗ CI.KUnit: failure " Patchwork
@ 2024-03-11 10:55 ` Thomas Hellström
  2024-03-11 13:29   ` Thomas Hellström
  3 siblings, 1 reply; 10+ messages in thread
From: Thomas Hellström @ 2024-03-11 10:55 UTC (permalink / raw)
  To: Matthew Brost, intel-xe; +Cc: fei.yang, rodrigo.vivi

Hi, Matthew

On Fri, 2024-03-08 at 13:37 -0800, Matthew Brost wrote:
> Rather than return an error to the user or ban the VM when userptr
> VMA
> page pin fails with -EFAULT, invalidate VMA mappings. This supports
> the
> UMD use case of freeing userptr while still having bindings.
> 
> Signed-off-by: Matthew Brost <matthew.brost@intel.com>
> ---
>  drivers/gpu/drm/xe/xe_gt_pagefault.c |  4 ++--
>  drivers/gpu/drm/xe/xe_trace.h        |  2 +-
>  drivers/gpu/drm/xe/xe_vm.c           | 20 +++++++++++++-------
>  drivers/gpu/drm/xe/xe_vm_types.h     |  7 ++-----
>  4 files changed, 18 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> index 73c535193a98..241c294270d9 100644
> --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> @@ -69,7 +69,7 @@ static bool access_is_atomic(enum access_type
> access_type)
>  static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
>  {
>  	return BIT(tile->id) & vma->tile_present &&
> -		!(BIT(tile->id) & vma->usm.tile_invalidated);
> +		!(BIT(tile->id) & vma->tile_invalidated);
>  }
>  
>  static bool vma_matches(struct xe_vma *vma, u64 page_addr)
> @@ -226,7 +226,7 @@ static int handle_pagefault(struct xe_gt *gt,
> struct pagefault *pf)
>  
>  	if (xe_vma_is_userptr(vma))
>  		ret =
> xe_vma_userptr_check_repin(to_userptr_vma(vma));
> -	vma->usm.tile_invalidated &= ~BIT(tile->id);
> +	vma->tile_invalidated &= ~BIT(tile->id);
>  
>  unlock_dma_resv:
>  	drm_exec_fini(&exec);
> diff --git a/drivers/gpu/drm/xe/xe_trace.h
> b/drivers/gpu/drm/xe/xe_trace.h
> index 4ddc55527f9a..846f14507d5f 100644
> --- a/drivers/gpu/drm/xe/xe_trace.h
> +++ b/drivers/gpu/drm/xe/xe_trace.h
> @@ -468,7 +468,7 @@ DEFINE_EVENT(xe_vma, xe_vma_userptr_invalidate,
>  	     TP_ARGS(vma)
>  );
>  
> -DEFINE_EVENT(xe_vma, xe_vma_usm_invalidate,
> +DEFINE_EVENT(xe_vma, xe_vma_invalidate,
>  	     TP_PROTO(struct xe_vma *vma),
>  	     TP_ARGS(vma)
>  );
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 643b3701a738..9a19044f7ef6 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -724,11 +724,18 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
>  	list_for_each_entry_safe(uvma, next, &vm-
> >userptr.repin_list,
>  				 userptr.repin_link) {
>  		err = xe_vma_userptr_pin_pages(uvma);
> -		if (err < 0)
> -			return err;
> -
>  		list_del_init(&uvma->userptr.repin_link);
> -		list_move_tail(&uvma->vma.combined_links.rebind,
> &vm->rebind_list);
> +		if (err == -EFAULT) {
> +			err = xe_vm_invalidate_vma(&uvma->vma);

I think we need to check for FAULT_MODE here. If we hit this path in
FAULT_MODE, we already have an invalid gpu access and can kill the VM.

In preempt-fence mode, we should probably be calling
xe_vm_unbind_vma(), because xe_vm_invalidate_vma() isn't safe to call
outside of the mmu_notifier, and if there are still BOOKKEEP fences
pending- see the asserts in that function.

> +			if (err)
> +				return err;
> +		} else {
> +			if (err < 0)
> +				return err;
> +
> +			list_move_tail(&uvma-
> >vma.combined_links.rebind,
> +				       &vm->rebind_list);
> +		}
>  	}
>  
>  	return 0;
> @@ -3214,9 +3221,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
>  	u8 id;
>  	int ret;
>  
> -	xe_assert(xe, xe_vm_in_fault_mode(xe_vma_vm(vma)));
>  	xe_assert(xe, !xe_vma_is_null(vma));
> -	trace_xe_vma_usm_invalidate(vma);
> +	trace_xe_vma_invalidate(vma);
>  
>  	/* Check that we don't race with page-table updates */
>  	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
> @@ -3254,7 +3260,7 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
>  		}
>  	}
>  
> -	vma->usm.tile_invalidated = vma->tile_mask;
> +	vma->tile_invalidated = vma->tile_mask;
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/xe/xe_vm_types.h
> b/drivers/gpu/drm/xe/xe_vm_types.h
> index 79b5cab57711..ae5fb565f6bf 100644
> --- a/drivers/gpu/drm/xe/xe_vm_types.h
> +++ b/drivers/gpu/drm/xe/xe_vm_types.h
> @@ -84,11 +84,8 @@ struct xe_vma {
>  		struct work_struct destroy_work;
>  	};
>  
> -	/** @usm: unified shared memory state */
> -	struct {
> -		/** @tile_invalidated: VMA has been invalidated */
> -		u8 tile_invalidated;
> -	} usm;
> +	/** @tile_invalidated: VMA has been invalidated */
> +	u8 tile_invalidated;

Add a comment in the commit message about removing the usm struct?
/Thomas


>  
>  	/** @tile_mask: Tile mask of where to create binding for
> this VMA */
>  	u8 tile_mask;


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] drm/xe: Invalidate userptr VMA on page pin fault
  2024-03-11 10:55 ` [PATCH] " Thomas Hellström
@ 2024-03-11 13:29   ` Thomas Hellström
  2024-03-11 18:49     ` Matthew Brost
  0 siblings, 1 reply; 10+ messages in thread
From: Thomas Hellström @ 2024-03-11 13:29 UTC (permalink / raw)
  To: Matthew Brost, intel-xe; +Cc: fei.yang, rodrigo.vivi

On Mon, 2024-03-11 at 11:55 +0100, Thomas Hellström wrote:
> Hi, Matthew
> 
> On Fri, 2024-03-08 at 13:37 -0800, Matthew Brost wrote:
> > Rather than return an error to the user or ban the VM when userptr
> > VMA
> > page pin fails with -EFAULT, invalidate VMA mappings. This supports
> > the
> > UMD use case of freeing userptr while still having bindings.
> > 
> > Signed-off-by: Matthew Brost <matthew.brost@intel.com>
> > ---
> >  drivers/gpu/drm/xe/xe_gt_pagefault.c |  4 ++--
> >  drivers/gpu/drm/xe/xe_trace.h        |  2 +-
> >  drivers/gpu/drm/xe/xe_vm.c           | 20 +++++++++++++-------
> >  drivers/gpu/drm/xe/xe_vm_types.h     |  7 ++-----
> >  4 files changed, 18 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > index 73c535193a98..241c294270d9 100644
> > --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > @@ -69,7 +69,7 @@ static bool access_is_atomic(enum access_type
> > access_type)
> >  static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
> >  {
> >  	return BIT(tile->id) & vma->tile_present &&
> > -		!(BIT(tile->id) & vma->usm.tile_invalidated);
> > +		!(BIT(tile->id) & vma->tile_invalidated);
> >  }
> >  
> >  static bool vma_matches(struct xe_vma *vma, u64 page_addr)
> > @@ -226,7 +226,7 @@ static int handle_pagefault(struct xe_gt *gt,
> > struct pagefault *pf)
> >  
> >  	if (xe_vma_is_userptr(vma))
> >  		ret =
> > xe_vma_userptr_check_repin(to_userptr_vma(vma));
> > -	vma->usm.tile_invalidated &= ~BIT(tile->id);
> > +	vma->tile_invalidated &= ~BIT(tile->id);
> >  
> >  unlock_dma_resv:
> >  	drm_exec_fini(&exec);
> > diff --git a/drivers/gpu/drm/xe/xe_trace.h
> > b/drivers/gpu/drm/xe/xe_trace.h
> > index 4ddc55527f9a..846f14507d5f 100644
> > --- a/drivers/gpu/drm/xe/xe_trace.h
> > +++ b/drivers/gpu/drm/xe/xe_trace.h
> > @@ -468,7 +468,7 @@ DEFINE_EVENT(xe_vma, xe_vma_userptr_invalidate,
> >  	     TP_ARGS(vma)
> >  );
> >  
> > -DEFINE_EVENT(xe_vma, xe_vma_usm_invalidate,
> > +DEFINE_EVENT(xe_vma, xe_vma_invalidate,
> >  	     TP_PROTO(struct xe_vma *vma),
> >  	     TP_ARGS(vma)
> >  );
> > diff --git a/drivers/gpu/drm/xe/xe_vm.c
> > b/drivers/gpu/drm/xe/xe_vm.c
> > index 643b3701a738..9a19044f7ef6 100644
> > --- a/drivers/gpu/drm/xe/xe_vm.c
> > +++ b/drivers/gpu/drm/xe/xe_vm.c
> > @@ -724,11 +724,18 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
> >  	list_for_each_entry_safe(uvma, next, &vm-
> > > userptr.repin_list,
> >  				 userptr.repin_link) {
> >  		err = xe_vma_userptr_pin_pages(uvma);
> > -		if (err < 0)
> > -			return err;
> > -
> >  		list_del_init(&uvma->userptr.repin_link);
> > -		list_move_tail(&uvma->vma.combined_links.rebind,
> > &vm->rebind_list);
> > +		if (err == -EFAULT) {
> > +			err = xe_vm_invalidate_vma(&uvma->vma);
> 
> I think we need to check for FAULT_MODE here. If we hit this path in
> FAULT_MODE, we already have an invalid gpu access and can kill the
> VM.
> 
> In preempt-fence mode, we should probably be calling
> xe_vm_unbind_vma(), because xe_vm_invalidate_vma() isn't safe to call
> outside of the mmu_notifier, and if there are still BOOKKEEP fences
> pending- see the asserts in that function.


Actually, xe_vm_invalidate_vma() would probably work if we grabbed the
vm resv and waited for bookkeep fences first, and updated the asserts. 

But then xe_vm_unbind_vma() might still be better since we also clean
up the page-tables.

/Thomas


> 
> > +			if (err)
> > +				return err;
> > +		} else {
> > +			if (err < 0)
> > +				return err;
> > +
> > +			list_move_tail(&uvma-
> > > vma.combined_links.rebind,
> > +				       &vm->rebind_list);
> > +		}
> >  	}
> >  
> >  	return 0;
> > @@ -3214,9 +3221,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
> >  	u8 id;
> >  	int ret;
> >  
> > -	xe_assert(xe, xe_vm_in_fault_mode(xe_vma_vm(vma)));
> >  	xe_assert(xe, !xe_vma_is_null(vma));
> > -	trace_xe_vma_usm_invalidate(vma);
> > +	trace_xe_vma_invalidate(vma);
> >  
> >  	/* Check that we don't race with page-table updates */
> >  	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
> > @@ -3254,7 +3260,7 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
> >  		}
> >  	}
> >  
> > -	vma->usm.tile_invalidated = vma->tile_mask;
> > +	vma->tile_invalidated = vma->tile_mask;
> >  
> >  	return 0;
> >  }
> > diff --git a/drivers/gpu/drm/xe/xe_vm_types.h
> > b/drivers/gpu/drm/xe/xe_vm_types.h
> > index 79b5cab57711..ae5fb565f6bf 100644
> > --- a/drivers/gpu/drm/xe/xe_vm_types.h
> > +++ b/drivers/gpu/drm/xe/xe_vm_types.h
> > @@ -84,11 +84,8 @@ struct xe_vma {
> >  		struct work_struct destroy_work;
> >  	};
> >  
> > -	/** @usm: unified shared memory state */
> > -	struct {
> > -		/** @tile_invalidated: VMA has been invalidated */
> > -		u8 tile_invalidated;
> > -	} usm;
> > +	/** @tile_invalidated: VMA has been invalidated */
> > +	u8 tile_invalidated;
> 
> Add a comment in the commit message about removing the usm struct?
> /Thomas
> 
> 
> >  
> >  	/** @tile_mask: Tile mask of where to create binding for
> > this VMA */
> >  	u8 tile_mask;
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] drm/xe: Invalidate userptr VMA on page pin fault
  2024-03-11 13:29   ` Thomas Hellström
@ 2024-03-11 18:49     ` Matthew Brost
  2024-03-11 19:23       ` Thomas Hellström
  0 siblings, 1 reply; 10+ messages in thread
From: Matthew Brost @ 2024-03-11 18:49 UTC (permalink / raw)
  To: Thomas Hellström; +Cc: intel-xe, fei.yang, rodrigo.vivi

On Mon, Mar 11, 2024 at 02:29:26PM +0100, Thomas Hellström wrote:
> On Mon, 2024-03-11 at 11:55 +0100, Thomas Hellström wrote:
> > Hi, Matthew
> > 
> > On Fri, 2024-03-08 at 13:37 -0800, Matthew Brost wrote:
> > > Rather than return an error to the user or ban the VM when userptr
> > > VMA
> > > page pin fails with -EFAULT, invalidate VMA mappings. This supports
> > > the
> > > UMD use case of freeing userptr while still having bindings.
> > > 
> > > Signed-off-by: Matthew Brost <matthew.brost@intel.com>
> > > ---
> > >  drivers/gpu/drm/xe/xe_gt_pagefault.c |  4 ++--
> > >  drivers/gpu/drm/xe/xe_trace.h        |  2 +-
> > >  drivers/gpu/drm/xe/xe_vm.c           | 20 +++++++++++++-------
> > >  drivers/gpu/drm/xe/xe_vm_types.h     |  7 ++-----
> > >  4 files changed, 18 insertions(+), 15 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > index 73c535193a98..241c294270d9 100644
> > > --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > @@ -69,7 +69,7 @@ static bool access_is_atomic(enum access_type
> > > access_type)
> > >  static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
> > >  {
> > >  	return BIT(tile->id) & vma->tile_present &&
> > > -		!(BIT(tile->id) & vma->usm.tile_invalidated);
> > > +		!(BIT(tile->id) & vma->tile_invalidated);
> > >  }
> > >  
> > >  static bool vma_matches(struct xe_vma *vma, u64 page_addr)
> > > @@ -226,7 +226,7 @@ static int handle_pagefault(struct xe_gt *gt,
> > > struct pagefault *pf)
> > >  
> > >  	if (xe_vma_is_userptr(vma))
> > >  		ret =
> > > xe_vma_userptr_check_repin(to_userptr_vma(vma));
> > > -	vma->usm.tile_invalidated &= ~BIT(tile->id);
> > > +	vma->tile_invalidated &= ~BIT(tile->id);
> > >  
> > >  unlock_dma_resv:
> > >  	drm_exec_fini(&exec);
> > > diff --git a/drivers/gpu/drm/xe/xe_trace.h
> > > b/drivers/gpu/drm/xe/xe_trace.h
> > > index 4ddc55527f9a..846f14507d5f 100644
> > > --- a/drivers/gpu/drm/xe/xe_trace.h
> > > +++ b/drivers/gpu/drm/xe/xe_trace.h
> > > @@ -468,7 +468,7 @@ DEFINE_EVENT(xe_vma, xe_vma_userptr_invalidate,
> > >  	     TP_ARGS(vma)
> > >  );
> > >  
> > > -DEFINE_EVENT(xe_vma, xe_vma_usm_invalidate,
> > > +DEFINE_EVENT(xe_vma, xe_vma_invalidate,
> > >  	     TP_PROTO(struct xe_vma *vma),
> > >  	     TP_ARGS(vma)
> > >  );
> > > diff --git a/drivers/gpu/drm/xe/xe_vm.c
> > > b/drivers/gpu/drm/xe/xe_vm.c
> > > index 643b3701a738..9a19044f7ef6 100644
> > > --- a/drivers/gpu/drm/xe/xe_vm.c
> > > +++ b/drivers/gpu/drm/xe/xe_vm.c
> > > @@ -724,11 +724,18 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
> > >  	list_for_each_entry_safe(uvma, next, &vm-
> > > > userptr.repin_list,
> > >  				 userptr.repin_link) {
> > >  		err = xe_vma_userptr_pin_pages(uvma);
> > > -		if (err < 0)
> > > -			return err;
> > > -
> > >  		list_del_init(&uvma->userptr.repin_link);
> > > -		list_move_tail(&uvma->vma.combined_links.rebind,
> > > &vm->rebind_list);
> > > +		if (err == -EFAULT) {
> > > +			err = xe_vm_invalidate_vma(&uvma->vma);
> > 
> > I think we need to check for FAULT_MODE here. If we hit this path in
> > FAULT_MODE, we already have an invalid gpu access and can kill the
> > VM.
> > 

Agree, will fix.

> > In preempt-fence mode, we should probably be calling
> > xe_vm_unbind_vma(), because xe_vm_invalidate_vma() isn't safe to call
> > outside of the mmu_notifier, and if there are still BOOKKEEP fences
> > pending- see the asserts in that function.
> 
> 
> Actually, xe_vm_invalidate_vma() would probably work if we grabbed the
> vm resv and waited for bookkeep fences first, and updated the asserts. 
>

Yes, I think that will work but is that even needed? We have vm->lock
here in write mode which should prevent any further updates to the page
tables. What are we trying prevent a race a against? An in-flight bind
job which touches the same page tables? I guess that is possible.
 
> But then xe_vm_unbind_vma() might still be better since we also clean
> up the page-tables.
> 

I think we do not want to mess with the VMA state as that should only be
changed by user IOCTLs. An invalidation seems to be the right call here.

> /Thomas
> 
> 
> > 
> > > +			if (err)
> > > +				return err;
> > > +		} else {
> > > +			if (err < 0)
> > > +				return err;
> > > +
> > > +			list_move_tail(&uvma-
> > > > vma.combined_links.rebind,
> > > +				       &vm->rebind_list);
> > > +		}
> > >  	}
> > >  
> > >  	return 0;
> > > @@ -3214,9 +3221,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
> > >  	u8 id;
> > >  	int ret;
> > >  
> > > -	xe_assert(xe, xe_vm_in_fault_mode(xe_vma_vm(vma)));
> > >  	xe_assert(xe, !xe_vma_is_null(vma));
> > > -	trace_xe_vma_usm_invalidate(vma);
> > > +	trace_xe_vma_invalidate(vma);
> > >  
> > >  	/* Check that we don't race with page-table updates */
> > >  	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
> > > @@ -3254,7 +3260,7 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
> > >  		}
> > >  	}
> > >  
> > > -	vma->usm.tile_invalidated = vma->tile_mask;
> > > +	vma->tile_invalidated = vma->tile_mask;
> > >  
> > >  	return 0;
> > >  }
> > > diff --git a/drivers/gpu/drm/xe/xe_vm_types.h
> > > b/drivers/gpu/drm/xe/xe_vm_types.h
> > > index 79b5cab57711..ae5fb565f6bf 100644
> > > --- a/drivers/gpu/drm/xe/xe_vm_types.h
> > > +++ b/drivers/gpu/drm/xe/xe_vm_types.h
> > > @@ -84,11 +84,8 @@ struct xe_vma {
> > >  		struct work_struct destroy_work;
> > >  	};
> > >  
> > > -	/** @usm: unified shared memory state */
> > > -	struct {
> > > -		/** @tile_invalidated: VMA has been invalidated */
> > > -		u8 tile_invalidated;
> > > -	} usm;
> > > +	/** @tile_invalidated: VMA has been invalidated */
> > > +	u8 tile_invalidated;
> > 
> > Add a comment in the commit message about removing the usm struct?

Will add.

Matt

> > /Thomas
> > 
> > 
> > >  
> > >  	/** @tile_mask: Tile mask of where to create binding for
> > > this VMA */
> > >  	u8 tile_mask;
> > 
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] drm/xe: Invalidate userptr VMA on page pin fault
  2024-03-11 18:49     ` Matthew Brost
@ 2024-03-11 19:23       ` Thomas Hellström
  0 siblings, 0 replies; 10+ messages in thread
From: Thomas Hellström @ 2024-03-11 19:23 UTC (permalink / raw)
  To: Matthew Brost; +Cc: intel-xe, fei.yang, rodrigo.vivi

On Mon, 2024-03-11 at 18:49 +0000, Matthew Brost wrote:
> On Mon, Mar 11, 2024 at 02:29:26PM +0100, Thomas Hellström wrote:
> > On Mon, 2024-03-11 at 11:55 +0100, Thomas Hellström wrote:
> > > Hi, Matthew
> > > 
> > > On Fri, 2024-03-08 at 13:37 -0800, Matthew Brost wrote:
> > > > Rather than return an error to the user or ban the VM when
> > > > userptr
> > > > VMA
> > > > page pin fails with -EFAULT, invalidate VMA mappings. This
> > > > supports
> > > > the
> > > > UMD use case of freeing userptr while still having bindings.
> > > > 
> > > > Signed-off-by: Matthew Brost <matthew.brost@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/xe/xe_gt_pagefault.c |  4 ++--
> > > >  drivers/gpu/drm/xe/xe_trace.h        |  2 +-
> > > >  drivers/gpu/drm/xe/xe_vm.c           | 20 +++++++++++++-------
> > > >  drivers/gpu/drm/xe/xe_vm_types.h     |  7 ++-----
> > > >  4 files changed, 18 insertions(+), 15 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > index 73c535193a98..241c294270d9 100644
> > > > --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> > > > @@ -69,7 +69,7 @@ static bool access_is_atomic(enum access_type
> > > > access_type)
> > > >  static bool vma_is_valid(struct xe_tile *tile, struct xe_vma
> > > > *vma)
> > > >  {
> > > >  	return BIT(tile->id) & vma->tile_present &&
> > > > -		!(BIT(tile->id) & vma->usm.tile_invalidated);
> > > > +		!(BIT(tile->id) & vma->tile_invalidated);
> > > >  }
> > > >  
> > > >  static bool vma_matches(struct xe_vma *vma, u64 page_addr)
> > > > @@ -226,7 +226,7 @@ static int handle_pagefault(struct xe_gt
> > > > *gt,
> > > > struct pagefault *pf)
> > > >  
> > > >  	if (xe_vma_is_userptr(vma))
> > > >  		ret =
> > > > xe_vma_userptr_check_repin(to_userptr_vma(vma));
> > > > -	vma->usm.tile_invalidated &= ~BIT(tile->id);
> > > > +	vma->tile_invalidated &= ~BIT(tile->id);
> > > >  
> > > >  unlock_dma_resv:
> > > >  	drm_exec_fini(&exec);
> > > > diff --git a/drivers/gpu/drm/xe/xe_trace.h
> > > > b/drivers/gpu/drm/xe/xe_trace.h
> > > > index 4ddc55527f9a..846f14507d5f 100644
> > > > --- a/drivers/gpu/drm/xe/xe_trace.h
> > > > +++ b/drivers/gpu/drm/xe/xe_trace.h
> > > > @@ -468,7 +468,7 @@ DEFINE_EVENT(xe_vma,
> > > > xe_vma_userptr_invalidate,
> > > >  	     TP_ARGS(vma)
> > > >  );
> > > >  
> > > > -DEFINE_EVENT(xe_vma, xe_vma_usm_invalidate,
> > > > +DEFINE_EVENT(xe_vma, xe_vma_invalidate,
> > > >  	     TP_PROTO(struct xe_vma *vma),
> > > >  	     TP_ARGS(vma)
> > > >  );
> > > > diff --git a/drivers/gpu/drm/xe/xe_vm.c
> > > > b/drivers/gpu/drm/xe/xe_vm.c
> > > > index 643b3701a738..9a19044f7ef6 100644
> > > > --- a/drivers/gpu/drm/xe/xe_vm.c
> > > > +++ b/drivers/gpu/drm/xe/xe_vm.c
> > > > @@ -724,11 +724,18 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
> > > >  	list_for_each_entry_safe(uvma, next, &vm-
> > > > > userptr.repin_list,
> > > >  				 userptr.repin_link) {
> > > >  		err = xe_vma_userptr_pin_pages(uvma);
> > > > -		if (err < 0)
> > > > -			return err;
> > > > -
> > > >  		list_del_init(&uvma->userptr.repin_link);
> > > > -		list_move_tail(&uvma-
> > > > >vma.combined_links.rebind,
> > > > &vm->rebind_list);
> > > > +		if (err == -EFAULT) {
> > > > +			err = xe_vm_invalidate_vma(&uvma-
> > > > >vma);
> > > 
> > > I think we need to check for FAULT_MODE here. If we hit this path
> > > in
> > > FAULT_MODE, we already have an invalid gpu access and can kill
> > > the
> > > VM.
> > > 
> 
> Agree, will fix.
> 
> > > In preempt-fence mode, we should probably be calling
> > > xe_vm_unbind_vma(), because xe_vm_invalidate_vma() isn't safe to
> > > call
> > > outside of the mmu_notifier, and if there are still BOOKKEEP
> > > fences
> > > pending- see the asserts in that function.
> > 
> > 
> > Actually, xe_vm_invalidate_vma() would probably work if we grabbed
> > the
> > vm resv and waited for bookkeep fences first, and updated the
> > asserts. 
> > 
> 
> Yes, I think that will work but is that even needed? We have vm->lock
> here in write mode which should prevent any further updates to the
> page
> tables. What are we trying prevent a race a against? An in-flight
> bind
> job which touches the same page tables? I guess that is possible.

Yeah, if we adhere to the locking rules for page tables we don't need
to care about keeping track of current and future potential racing code
paths.

>  
> > But then xe_vm_unbind_vma() might still be better since we also
> > clean
> > up the page-tables.
> > 
> 
> I think we do not want to mess with the VMA state as that should only
> be
> changed by user IOCTLs. An invalidation seems to be the right call
> here.

I think the tile_present is the only vma_state touched there. What I'm
after is really also freeing the now unused page-directories, but
that's not a necessity. 

/Thomas



> 
> > /Thomas
> > 
> > 
> > > 
> > > > +			if (err)
> > > > +				return err;
> > > > +		} else {
> > > > +			if (err < 0)
> > > > +				return err;
> > > > +
> > > > +			list_move_tail(&uvma-
> > > > > vma.combined_links.rebind,
> > > > +				       &vm->rebind_list);
> > > > +		}
> > > >  	}
> > > >  
> > > >  	return 0;
> > > > @@ -3214,9 +3221,8 @@ int xe_vm_invalidate_vma(struct xe_vma
> > > > *vma)
> > > >  	u8 id;
> > > >  	int ret;
> > > >  
> > > > -	xe_assert(xe, xe_vm_in_fault_mode(xe_vma_vm(vma)));
> > > >  	xe_assert(xe, !xe_vma_is_null(vma));
> > > > -	trace_xe_vma_usm_invalidate(vma);
> > > > +	trace_xe_vma_invalidate(vma);
> > > >  
> > > >  	/* Check that we don't race with page-table updates */
> > > >  	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
> > > > @@ -3254,7 +3260,7 @@ int xe_vm_invalidate_vma(struct xe_vma
> > > > *vma)
> > > >  		}
> > > >  	}
> > > >  
> > > > -	vma->usm.tile_invalidated = vma->tile_mask;
> > > > +	vma->tile_invalidated = vma->tile_mask;
> > > >  
> > > >  	return 0;
> > > >  }
> > > > diff --git a/drivers/gpu/drm/xe/xe_vm_types.h
> > > > b/drivers/gpu/drm/xe/xe_vm_types.h
> > > > index 79b5cab57711..ae5fb565f6bf 100644
> > > > --- a/drivers/gpu/drm/xe/xe_vm_types.h
> > > > +++ b/drivers/gpu/drm/xe/xe_vm_types.h
> > > > @@ -84,11 +84,8 @@ struct xe_vma {
> > > >  		struct work_struct destroy_work;
> > > >  	};
> > > >  
> > > > -	/** @usm: unified shared memory state */
> > > > -	struct {
> > > > -		/** @tile_invalidated: VMA has been
> > > > invalidated */
> > > > -		u8 tile_invalidated;
> > > > -	} usm;
> > > > +	/** @tile_invalidated: VMA has been invalidated */
> > > > +	u8 tile_invalidated;
> > > 
> > > Add a comment in the commit message about removing the usm
> > > struct?
> 
> Will add.
> 
> Matt
> 
> > > /Thomas
> > > 
> > > 
> > > >  
> > > >  	/** @tile_mask: Tile mask of where to create binding
> > > > for
> > > > this VMA */
> > > >  	u8 tile_mask;
> > > 
> > 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] drm/xe: Invalidate userptr VMA on page pin fault
  2024-03-12 18:39 Matthew Brost
@ 2024-03-13 12:18 ` Thomas Hellström
  0 siblings, 0 replies; 10+ messages in thread
From: Thomas Hellström @ 2024-03-13 12:18 UTC (permalink / raw)
  To: Matthew Brost, intel-xe

On Tue, 2024-03-12 at 11:39 -0700, Matthew Brost wrote:
> Rather than return an error to the user or ban the VM when userptr
> VMA
> page pin fails with -EFAULT, invalidate VMA mappings. This supports
> the
> UMD use case of freeing userptr while still having bindings.
> 
> Now that non-faulting VMs can invalidate VMAs, drop the usm prefix
> for
> the tile_invalidated member.
> 
> v2:
>  - Fix build error (CI)
> v3:
>  - Don't invalidate VMA if in fault mode, rather kill VM (Thomas)
>  - Update commit message with tile_invalidated name chagne (Thomas)
>  - Wait VM bookkeep slots with VM resv lock (Thomas)
> v4:
>  - Move list_del_init(&userptr.repin_link) after error check (Thomas)
>  - Assert not in fault mode (Matthew)
> 
> Signed-off-by: Matthew Brost <matthew.brost@intel.com>

Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>




> ---
>  drivers/gpu/drm/xe/xe_gt_pagefault.c |  4 ++--
>  drivers/gpu/drm/xe/xe_trace.h        |  2 +-
>  drivers/gpu/drm/xe/xe_vm.c           | 32 +++++++++++++++++++++-----
> --
>  drivers/gpu/drm/xe/xe_vm_types.h     |  7 ++----
>  4 files changed, 29 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> index 73c535193a98..241c294270d9 100644
> --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> @@ -69,7 +69,7 @@ static bool access_is_atomic(enum access_type
> access_type)
>  static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
>  {
>  	return BIT(tile->id) & vma->tile_present &&
> -		!(BIT(tile->id) & vma->usm.tile_invalidated);
> +		!(BIT(tile->id) & vma->tile_invalidated);
>  }
>  
>  static bool vma_matches(struct xe_vma *vma, u64 page_addr)
> @@ -226,7 +226,7 @@ static int handle_pagefault(struct xe_gt *gt,
> struct pagefault *pf)
>  
>  	if (xe_vma_is_userptr(vma))
>  		ret =
> xe_vma_userptr_check_repin(to_userptr_vma(vma));
> -	vma->usm.tile_invalidated &= ~BIT(tile->id);
> +	vma->tile_invalidated &= ~BIT(tile->id);
>  
>  unlock_dma_resv:
>  	drm_exec_fini(&exec);
> diff --git a/drivers/gpu/drm/xe/xe_trace.h
> b/drivers/gpu/drm/xe/xe_trace.h
> index 4ddc55527f9a..846f14507d5f 100644
> --- a/drivers/gpu/drm/xe/xe_trace.h
> +++ b/drivers/gpu/drm/xe/xe_trace.h
> @@ -468,7 +468,7 @@ DEFINE_EVENT(xe_vma, xe_vma_userptr_invalidate,
>  	     TP_ARGS(vma)
>  );
>  
> -DEFINE_EVENT(xe_vma, xe_vma_usm_invalidate,
> +DEFINE_EVENT(xe_vma, xe_vma_invalidate,
>  	     TP_PROTO(struct xe_vma *vma),
>  	     TP_ARGS(vma)
>  );
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 643b3701a738..cbb9b8935c90 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -708,6 +708,7 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
>  	int err = 0;
>  	LIST_HEAD(tmp_evict);
>  
> +	xe_assert(vm->xe, !xe_vm_in_fault_mode(vm));
>  	lockdep_assert_held_write(&vm->lock);
>  
>  	/* Collect invalidated userptrs */
> @@ -724,11 +725,27 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
>  	list_for_each_entry_safe(uvma, next, &vm-
> >userptr.repin_list,
>  				 userptr.repin_link) {
>  		err = xe_vma_userptr_pin_pages(uvma);
> -		if (err < 0)
> -			return err;
> +		if (err == -EFAULT) {
> +			list_del_init(&uvma->userptr.repin_link);
>  
> -		list_del_init(&uvma->userptr.repin_link);
> -		list_move_tail(&uvma->vma.combined_links.rebind,
> &vm->rebind_list);
> +			/* Wait for pending binds */
> +			xe_vm_lock(vm, false);
> +			dma_resv_wait_timeout(xe_vm_resv(vm),
> +					     
> DMA_RESV_USAGE_BOOKKEEP,
> +					      false,
> MAX_SCHEDULE_TIMEOUT);
> +
> +			err = xe_vm_invalidate_vma(&uvma->vma);
> +			xe_vm_unlock(vm);
> +			if (err)
> +				return err;
> +		} else {
> +			if (err < 0)
> +				return err;
> +
> +			list_del_init(&uvma->userptr.repin_link);
> +			list_move_tail(&uvma-
> >vma.combined_links.rebind,
> +				       &vm->rebind_list);
> +		}
>  	}
>  
>  	return 0;
> @@ -2024,7 +2041,7 @@ static int xe_vm_prefetch(struct xe_vm *vm,
> struct xe_vma *vma,
>  			return err;
>  	}
>  
> -	if (vma->tile_mask != (vma->tile_present & ~vma-
> >usm.tile_invalidated)) {
> +	if (vma->tile_mask != (vma->tile_present & ~vma-
> >tile_invalidated)) {
>  		return xe_vm_bind(vm, vma, q, xe_vma_bo(vma), syncs,
> num_syncs,
>  				  true, first_op, last_op);
>  	} else {
> @@ -3214,9 +3231,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
>  	u8 id;
>  	int ret;
>  
> -	xe_assert(xe, xe_vm_in_fault_mode(xe_vma_vm(vma)));
>  	xe_assert(xe, !xe_vma_is_null(vma));
> -	trace_xe_vma_usm_invalidate(vma);
> +	trace_xe_vma_invalidate(vma);
>  
>  	/* Check that we don't race with page-table updates */
>  	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
> @@ -3254,7 +3270,7 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
>  		}
>  	}
>  
> -	vma->usm.tile_invalidated = vma->tile_mask;
> +	vma->tile_invalidated = vma->tile_mask;
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/xe/xe_vm_types.h
> b/drivers/gpu/drm/xe/xe_vm_types.h
> index 79b5cab57711..ae5fb565f6bf 100644
> --- a/drivers/gpu/drm/xe/xe_vm_types.h
> +++ b/drivers/gpu/drm/xe/xe_vm_types.h
> @@ -84,11 +84,8 @@ struct xe_vma {
>  		struct work_struct destroy_work;
>  	};
>  
> -	/** @usm: unified shared memory state */
> -	struct {
> -		/** @tile_invalidated: VMA has been invalidated */
> -		u8 tile_invalidated;
> -	} usm;
> +	/** @tile_invalidated: VMA has been invalidated */
> +	u8 tile_invalidated;
>  
>  	/** @tile_mask: Tile mask of where to create binding for
> this VMA */
>  	u8 tile_mask;


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] drm/xe: Invalidate userptr VMA on page pin fault
@ 2024-03-12 18:39 Matthew Brost
  2024-03-13 12:18 ` Thomas Hellström
  0 siblings, 1 reply; 10+ messages in thread
From: Matthew Brost @ 2024-03-12 18:39 UTC (permalink / raw)
  To: intel-xe; +Cc: Matthew Brost

Rather than return an error to the user or ban the VM when userptr VMA
page pin fails with -EFAULT, invalidate VMA mappings. This supports the
UMD use case of freeing userptr while still having bindings.

Now that non-faulting VMs can invalidate VMAs, drop the usm prefix for
the tile_invalidated member.

v2:
 - Fix build error (CI)
v3:
 - Don't invalidate VMA if in fault mode, rather kill VM (Thomas)
 - Update commit message with tile_invalidated name chagne (Thomas)
 - Wait VM bookkeep slots with VM resv lock (Thomas)
v4:
 - Move list_del_init(&userptr.repin_link) after error check (Thomas)
 - Assert not in fault mode (Matthew)

Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
 drivers/gpu/drm/xe/xe_gt_pagefault.c |  4 ++--
 drivers/gpu/drm/xe/xe_trace.h        |  2 +-
 drivers/gpu/drm/xe/xe_vm.c           | 32 +++++++++++++++++++++-------
 drivers/gpu/drm/xe/xe_vm_types.h     |  7 ++----
 4 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c
index 73c535193a98..241c294270d9 100644
--- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
@@ -69,7 +69,7 @@ static bool access_is_atomic(enum access_type access_type)
 static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
 {
 	return BIT(tile->id) & vma->tile_present &&
-		!(BIT(tile->id) & vma->usm.tile_invalidated);
+		!(BIT(tile->id) & vma->tile_invalidated);
 }
 
 static bool vma_matches(struct xe_vma *vma, u64 page_addr)
@@ -226,7 +226,7 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
 
 	if (xe_vma_is_userptr(vma))
 		ret = xe_vma_userptr_check_repin(to_userptr_vma(vma));
-	vma->usm.tile_invalidated &= ~BIT(tile->id);
+	vma->tile_invalidated &= ~BIT(tile->id);
 
 unlock_dma_resv:
 	drm_exec_fini(&exec);
diff --git a/drivers/gpu/drm/xe/xe_trace.h b/drivers/gpu/drm/xe/xe_trace.h
index 4ddc55527f9a..846f14507d5f 100644
--- a/drivers/gpu/drm/xe/xe_trace.h
+++ b/drivers/gpu/drm/xe/xe_trace.h
@@ -468,7 +468,7 @@ DEFINE_EVENT(xe_vma, xe_vma_userptr_invalidate,
 	     TP_ARGS(vma)
 );
 
-DEFINE_EVENT(xe_vma, xe_vma_usm_invalidate,
+DEFINE_EVENT(xe_vma, xe_vma_invalidate,
 	     TP_PROTO(struct xe_vma *vma),
 	     TP_ARGS(vma)
 );
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 643b3701a738..cbb9b8935c90 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -708,6 +708,7 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
 	int err = 0;
 	LIST_HEAD(tmp_evict);
 
+	xe_assert(vm->xe, !xe_vm_in_fault_mode(vm));
 	lockdep_assert_held_write(&vm->lock);
 
 	/* Collect invalidated userptrs */
@@ -724,11 +725,27 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
 	list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list,
 				 userptr.repin_link) {
 		err = xe_vma_userptr_pin_pages(uvma);
-		if (err < 0)
-			return err;
+		if (err == -EFAULT) {
+			list_del_init(&uvma->userptr.repin_link);
 
-		list_del_init(&uvma->userptr.repin_link);
-		list_move_tail(&uvma->vma.combined_links.rebind, &vm->rebind_list);
+			/* Wait for pending binds */
+			xe_vm_lock(vm, false);
+			dma_resv_wait_timeout(xe_vm_resv(vm),
+					      DMA_RESV_USAGE_BOOKKEEP,
+					      false, MAX_SCHEDULE_TIMEOUT);
+
+			err = xe_vm_invalidate_vma(&uvma->vma);
+			xe_vm_unlock(vm);
+			if (err)
+				return err;
+		} else {
+			if (err < 0)
+				return err;
+
+			list_del_init(&uvma->userptr.repin_link);
+			list_move_tail(&uvma->vma.combined_links.rebind,
+				       &vm->rebind_list);
+		}
 	}
 
 	return 0;
@@ -2024,7 +2041,7 @@ static int xe_vm_prefetch(struct xe_vm *vm, struct xe_vma *vma,
 			return err;
 	}
 
-	if (vma->tile_mask != (vma->tile_present & ~vma->usm.tile_invalidated)) {
+	if (vma->tile_mask != (vma->tile_present & ~vma->tile_invalidated)) {
 		return xe_vm_bind(vm, vma, q, xe_vma_bo(vma), syncs, num_syncs,
 				  true, first_op, last_op);
 	} else {
@@ -3214,9 +3231,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
 	u8 id;
 	int ret;
 
-	xe_assert(xe, xe_vm_in_fault_mode(xe_vma_vm(vma)));
 	xe_assert(xe, !xe_vma_is_null(vma));
-	trace_xe_vma_usm_invalidate(vma);
+	trace_xe_vma_invalidate(vma);
 
 	/* Check that we don't race with page-table updates */
 	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
@@ -3254,7 +3270,7 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
 		}
 	}
 
-	vma->usm.tile_invalidated = vma->tile_mask;
+	vma->tile_invalidated = vma->tile_mask;
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
index 79b5cab57711..ae5fb565f6bf 100644
--- a/drivers/gpu/drm/xe/xe_vm_types.h
+++ b/drivers/gpu/drm/xe/xe_vm_types.h
@@ -84,11 +84,8 @@ struct xe_vma {
 		struct work_struct destroy_work;
 	};
 
-	/** @usm: unified shared memory state */
-	struct {
-		/** @tile_invalidated: VMA has been invalidated */
-		u8 tile_invalidated;
-	} usm;
+	/** @tile_invalidated: VMA has been invalidated */
+	u8 tile_invalidated;
 
 	/** @tile_mask: Tile mask of where to create binding for this VMA */
 	u8 tile_mask;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2024-03-13 12:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-08 21:37 [PATCH] drm/xe: Invalidate userptr VMA on page pin fault Matthew Brost
2024-03-08 21:42 ` ✓ CI.Patch_applied: success for " Patchwork
2024-03-08 21:42 ` ✓ CI.checkpatch: " Patchwork
2024-03-08 21:43 ` ✗ CI.KUnit: failure " Patchwork
2024-03-11 10:55 ` [PATCH] " Thomas Hellström
2024-03-11 13:29   ` Thomas Hellström
2024-03-11 18:49     ` Matthew Brost
2024-03-11 19:23       ` Thomas Hellström
2024-03-12 18:39 Matthew Brost
2024-03-13 12:18 ` Thomas Hellström

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.