Commit 3c0e234c847318304c12f9e7fffac7e1cf3db3ff
Committed by
Daniel Vetter
1 parent
1823521d2b
Exists in
master
and in
16 other branches
drm/i915; Preallocate the lazy request
It is possible for us to be forced to perform an allocation for the lazy request whilst running the shrinker. This allocation may fail, leaving us unable to reclaim any memory leading to premature OOM. A neat solution to the problem is to preallocate the request at the same time as acquiring the seqno for the ring transaction. This means that we can report ENOMEM prior to touching the rings. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Showing 3 changed files with 15 additions and 5 deletions Side-by-side Diff
drivers/gpu/drm/i915/i915_gem.c
... | ... | @@ -2041,8 +2041,8 @@ |
2041 | 2041 | if (ret) |
2042 | 2042 | return ret; |
2043 | 2043 | |
2044 | - request = kmalloc(sizeof(*request), GFP_KERNEL); | |
2045 | - if (request == NULL) | |
2044 | + request = ring->preallocated_lazy_request; | |
2045 | + if (WARN_ON(request == NULL)) | |
2046 | 2046 | return -ENOMEM; |
2047 | 2047 | |
2048 | 2048 | /* Record the position of the start of the request so that |
2049 | 2049 | |
... | ... | @@ -2053,10 +2053,8 @@ |
2053 | 2053 | request_ring_position = intel_ring_get_tail(ring); |
2054 | 2054 | |
2055 | 2055 | ret = ring->add_request(ring); |
2056 | - if (ret) { | |
2057 | - kfree(request); | |
2056 | + if (ret) | |
2058 | 2057 | return ret; |
2059 | - } | |
2060 | 2058 | |
2061 | 2059 | request->seqno = intel_ring_get_seqno(ring); |
2062 | 2060 | request->ring = ring; |
... | ... | @@ -2095,6 +2093,7 @@ |
2095 | 2093 | |
2096 | 2094 | trace_i915_gem_request_add(ring, request->seqno); |
2097 | 2095 | ring->outstanding_lazy_seqno = 0; |
2096 | + ring->preallocated_lazy_request = NULL; | |
2098 | 2097 | |
2099 | 2098 | if (!dev_priv->ums.mm_suspended) { |
2100 | 2099 | i915_queue_hangcheck(ring->dev); |
drivers/gpu/drm/i915/intel_ringbuffer.c
... | ... | @@ -1498,6 +1498,16 @@ |
1498 | 1498 | if (ring->outstanding_lazy_seqno) |
1499 | 1499 | return 0; |
1500 | 1500 | |
1501 | + if (ring->preallocated_lazy_request == NULL) { | |
1502 | + struct drm_i915_gem_request *request; | |
1503 | + | |
1504 | + request = kmalloc(sizeof(*request), GFP_KERNEL); | |
1505 | + if (request == NULL) | |
1506 | + return -ENOMEM; | |
1507 | + | |
1508 | + ring->preallocated_lazy_request = request; | |
1509 | + } | |
1510 | + | |
1501 | 1511 | return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno); |
1502 | 1512 | } |
1503 | 1513 |
drivers/gpu/drm/i915/intel_ringbuffer.h