Skip to content

Commit

Permalink
Switch jitc_vcall_prepare() allocation method to avoid deadlocks
Browse files Browse the repository at this point in the history
The LLVM version of ``jitc_vcall_prepare()`` frees memory asynchronously
by calling ``jit_free(0)`` from a nanothread task. The trouble is that
we sometimes wait for tasks to finish while holding the Dr.Jit mutex,
and this then leads to a deadlock when ``jitc_free()`` tries to acquire
the lock.

This commit circumvents the issue by switching the allocations over to
``malloc()``. This is not expected to have any major performance
implications, since the allocations being done by this code path are
small.

The issue was already fixed on the ``nanothread_v2`` branch, and this
simply propagates that fix.
  • Loading branch information
wjakob committed Dec 3, 2023
1 parent 6690923 commit c13ef93
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 6 deletions.
3 changes: 1 addition & 2 deletions src/util.cpp
Expand Up @@ -1387,7 +1387,6 @@ void jitc_vcall_prepare(JitBackend backend, void *dst_, VCallDataRecord *rec_, u
size, work_units);

jitc_submit_cpu(
KernelType::Other, [rec_](uint32_t) { jit_free(rec_); }, 1, 1,
true, true);
KernelType::Other, [rec_](uint32_t) { free(rec_); }, 1, 1);
}
}
11 changes: 7 additions & 4 deletions src/vcall.cpp
Expand Up @@ -263,10 +263,13 @@ uint32_t jitc_var_vcall(const char *name, uint32_t self, uint32_t mask_,

data_v = steal(jitc_var_pointer(backend, data_d, data_buf, 0));

VCallDataRecord *rec = (VCallDataRecord *)
jitc_malloc(backend == JitBackend::CUDA ? AllocType::HostPinned
: AllocType::Host,
sizeof(VCallDataRecord) * vcall->data_map.size());
VCallDataRecord *rec;

size_t rec_size = sizeof(VCallDataRecord) * vcall->data_map.size();
if (backend == JitBackend::CUDA)
rec = (VCallDataRecord *) jitc_malloc(AllocType::HostPinned, rec_size);
else
rec = (VCallDataRecord *) malloc_check(rec_size);

VCallDataRecord *p = rec;

Expand Down

0 comments on commit c13ef93

Please sign in to comment.