libhsakmt: Set CWSR SVM range MADV_DONTFORK

fork process copy-on-write MMU nitifier on CWSR range will evict user
queues, and then update GPU mapping and resume queues, use MADV_DONTFORK
to avoid COW MMU notifier callback on CWSR SVM range.

Use mmap to alloc SVM range for CWSR because posix_memalign don't alloc
new range in child process, this fails to register svm range as range is
invalid address in forked child process.

Change-Id: Ibaea56a691dd6f577ed2e1f2d43f4a3500b8316f
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
This commit is contained in:
Philip Yang
2022-08-16 09:36:11 -04:00
orang tua b2691c359d
melakukan 093cf898fb
3 mengubah file dengan 25 tambahan dan 9 penghapusan
+2 -3
Melihat File
@@ -706,9 +706,8 @@ static void *reserved_aperture_allocate_aligned(manageable_aperture_t *app,
return start;
}
static void *mmap_allocate_aligned(int prot, int flags, uint64_t size,
uint64_t align, uint64_t guard_size,
void *aper_base, void *aper_limit)
void *mmap_allocate_aligned(int prot, int flags, uint64_t size, uint64_t align,
uint64_t guard_size, void *aper_base, void *aper_limit)
{
void *addr, *aligned_addr, *aligned_end, *mapping_end;
uint64_t aligned_padded_size;
+3
Melihat File
@@ -90,4 +90,7 @@ HSAKMT_STATUS fmm_map_to_gpu_nodes(void *address, uint64_t size,
uint32_t *nodes_to_map, uint64_t num_of_nodes, uint64_t *gpuvm_address);
int open_drm_render_device(int minor);
void *mmap_allocate_aligned(int prot, int flags, uint64_t size, uint64_t align,
uint64_t guard_size, void *aper_base, void *aper_limit);
#endif /* FMM_H_ */
+20 -6
Melihat File
@@ -425,7 +425,8 @@ static void free_queue(struct queue *q)
q->eop_buffer_size,
PAGE_SIZE, q->use_ats);
if (q->unified_ctx_save_restore)
free(q->ctx_save_restore);
munmap(q->ctx_save_restore,
PAGE_ALIGN_UP(q->ctx_save_restore_size + q->debug_memory_size));
else if (q->ctx_save_restore)
free_exec_aligned_memory(q->ctx_save_restore,
q->ctx_save_restore_size + q->debug_memory_size,
@@ -500,9 +501,21 @@ static int handle_concrete_asic(struct queue *q,
void *addr;
HSAKMT_STATUS r = HSAKMT_STATUS_ERROR;
if (posix_memalign(&addr, GPU_HUGE_PAGE_SIZE, size))
pr_err("[%s] posix_memalign failed:\n", __func__);
else {
addr = mmap_allocate_aligned(PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
size, GPU_HUGE_PAGE_SIZE, 0,
0, (void *)LONG_MAX);
if (!addr) {
pr_err("mmap failed to alloc ctx area size 0x%x: %s\n",
size, strerror(errno));
} else {
/*
* To avoid fork child process COW MMU notifier
* callback evict parent process queues.
*/
if (madvise(addr, size, MADV_DONTFORK))
pr_err("madvise failed -%d\n", errno);
fill_cwsr_header(q, addr, Event, ErrPayload);
r = register_svm_range(addr, size,
@@ -511,8 +524,9 @@ static int handle_concrete_asic(struct queue *q,
if (r == HSAKMT_STATUS_SUCCESS) {
q->ctx_save_restore = addr;
q->unified_ctx_save_restore = true;
} else
free(addr);
} else {
munmap(addr, size);
}
}
}