diff options
| author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-01-31 05:40:48 -0500 |
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2010-02-04 12:04:01 -0500 |
| commit | 93533c291a0af78ca57115fc44d2e6c4c9517cd2 (patch) | |
| tree | b3b0bf319cc00cee85cc005174b6b83f609bdaf7 | |
| parent | 67026e03244d76b8f1fa725b079d4182fe8910aa (diff) | |
drm/i915: Fix leak of relocs along do_execbuffer error path
Following a gpu hang, we would leak the relocation buffer. So simply
earrange the error path to always free the relocation buffer.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Eric Anholt <eric@anholt.net>
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1ef7ec4f38fe..be0fd1a63321 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -3584,6 +3584,9 @@ i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object2 *exec_list, | |||
| 3584 | uint32_t reloc_count = 0, i; | 3584 | uint32_t reloc_count = 0, i; |
| 3585 | int ret = 0; | 3585 | int ret = 0; |
| 3586 | 3586 | ||
| 3587 | if (relocs == NULL) | ||
| 3588 | return 0; | ||
| 3589 | |||
| 3587 | for (i = 0; i < buffer_count; i++) { | 3590 | for (i = 0; i < buffer_count; i++) { |
| 3588 | struct drm_i915_gem_relocation_entry __user *user_relocs; | 3591 | struct drm_i915_gem_relocation_entry __user *user_relocs; |
| 3589 | int unwritten; | 3592 | int unwritten; |
| @@ -3673,7 +3676,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 3673 | struct drm_gem_object *batch_obj; | 3676 | struct drm_gem_object *batch_obj; |
| 3674 | struct drm_i915_gem_object *obj_priv; | 3677 | struct drm_i915_gem_object *obj_priv; |
| 3675 | struct drm_clip_rect *cliprects = NULL; | 3678 | struct drm_clip_rect *cliprects = NULL; |
| 3676 | struct drm_i915_gem_relocation_entry *relocs; | 3679 | struct drm_i915_gem_relocation_entry *relocs = NULL; |
| 3677 | int ret = 0, ret2, i, pinned = 0; | 3680 | int ret = 0, ret2, i, pinned = 0; |
| 3678 | uint64_t exec_offset; | 3681 | uint64_t exec_offset; |
| 3679 | uint32_t seqno, flush_domains, reloc_index; | 3682 | uint32_t seqno, flush_domains, reloc_index; |
| @@ -3950,6 +3953,7 @@ err: | |||
| 3950 | 3953 | ||
| 3951 | mutex_unlock(&dev->struct_mutex); | 3954 | mutex_unlock(&dev->struct_mutex); |
| 3952 | 3955 | ||
| 3956 | pre_mutex_err: | ||
| 3953 | /* Copy the updated relocations out regardless of current error | 3957 | /* Copy the updated relocations out regardless of current error |
| 3954 | * state. Failure to update the relocs would mean that the next | 3958 | * state. Failure to update the relocs would mean that the next |
| 3955 | * time userland calls execbuf, it would do so with presumed offset | 3959 | * time userland calls execbuf, it would do so with presumed offset |
| @@ -3964,7 +3968,6 @@ err: | |||
| 3964 | ret = ret2; | 3968 | ret = ret2; |
| 3965 | } | 3969 | } |
| 3966 | 3970 | ||
| 3967 | pre_mutex_err: | ||
| 3968 | drm_free_large(object_list); | 3971 | drm_free_large(object_list); |
| 3969 | kfree(cliprects); | 3972 | kfree(cliprects); |
| 3970 | 3973 | ||
