diff options
author | Jason Ekstrand <[email protected]> | 2015-11-10 11:24:08 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-11-10 11:24:11 -0800 |
commit | aafc87402d1d12a00e1969be52a2c3b6d18c5652 (patch) | |
tree | 2e8bbcd90f7eecd7d1c88d068aec5e111401aeb9 /src/vulkan/anv_device.c | |
parent | 06f466a770fcb84a5a3671d27bffb456ded90739 (diff) |
anv/device: Work around the i915 kernel driver timeout bug
There is a bug in some versions of the i915 kernel driver where it will
return immediately if the timeout is negative (it's supposed to wait
indefinitely). We've worked around this in mesa for a few months but never
implemented the work-around in the Vulkan driver.
I rediscovered this bug again while working on Ivy Bridge becasuse the
drive in my Ivy Bridge currently has Fedora 21 installed which has one of
the offending kernels.
Diffstat (limited to 'src/vulkan/anv_device.c')
-rw-r--r-- | src/vulkan/anv_device.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c index c6366a1cccb..37d58816f5d 100644 --- a/src/vulkan/anv_device.c +++ b/src/vulkan/anv_device.c @@ -1286,14 +1286,22 @@ VkResult anv_WaitForFences( uint64_t timeout) { ANV_FROM_HANDLE(anv_device, device, _device); - int64_t t = timeout; - int ret; + + /* DRM_IOCTL_I915_GEM_WAIT uses a signed 64 bit timeout and is supposed + * to block indefinitely timeouts <= 0. Unfortunately, this was broken + * for a couple of kernel releases. Since there's no way to know + * whether or not the kernel we're using is one of the broken ones, the + * best we can do is to clamp the timeout to INT64_MAX. This limits the + * maximum timeout from 584 years to 292 years - likely not a big deal. + */ + if (timeout > INT64_MAX) + timeout = INT64_MAX; /* FIXME: handle !waitAll */ for (uint32_t i = 0; i < fenceCount; i++) { ANV_FROM_HANDLE(anv_fence, fence, pFences[i]); - ret = anv_gem_wait(device, fence->bo.gem_handle, &t); + int ret = anv_gem_wait(device, fence->bo.gem_handle, &timeout); if (ret == -1 && errno == ETIME) { return VK_TIMEOUT; } else if (ret == -1) { |