Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 218104
b: refs/heads/master
c: 30dbf0c
h: refs/heads/master
v: v3
  • Loading branch information
Chris Wilson committed Sep 25, 2010
1 parent 6f06603 commit 2aa07ba
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f787a5f59e1b0e320a6b0a37e9a2e306551d1e40
refs/heads/master: 30dbf0c07ff4e3e21b827e2a9d6ff7eb34458819
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ typedef struct drm_i915_private {
spinlock_t error_lock;
struct drm_i915_error_state *first_error;
struct work_struct error_work;
struct completion error_completion;
struct workqueue_struct *wq;

/* Display functions */
Expand Down Expand Up @@ -957,6 +958,7 @@ extern void i915_mem_takedown(struct mem_block **heap);
extern void i915_mem_release(struct drm_device * dev,
struct drm_file *file_priv, struct mem_block *heap);
/* i915_gem.c */
int i915_gem_check_is_wedged(struct drm_device *dev);
int i915_gem_init_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_create_ioctl(struct drm_device *dev, void *data,
Expand Down
66 changes: 59 additions & 7 deletions trunk/drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,37 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj);
static LIST_HEAD(shrink_list);
static DEFINE_SPINLOCK(shrink_list_lock);

int
i915_gem_check_is_wedged(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct completion *x = &dev_priv->error_completion;
unsigned long flags;
int ret;

if (!atomic_read(&dev_priv->mm.wedged))
return 0;

ret = wait_for_completion_interruptible(x);
if (ret)
return ret;

/* Success, we reset the GPU! */
if (!atomic_read(&dev_priv->mm.wedged))
return 0;

/* GPU is hung, bump the completion count to account for
* the token we just consumed so that we never hit zero and
* end up waiting upon a subsequent completion event that
* will never happen.
*/
spin_lock_irqsave(&x->wait.lock, flags);
x->done++;
spin_unlock_irqrestore(&x->wait.lock, flags);
return -EIO;
}


static inline bool
i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv)
{
Expand Down Expand Up @@ -1848,15 +1879,15 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno,

BUG_ON(seqno == 0);

if (atomic_read(&dev_priv->mm.wedged))
return -EAGAIN;

if (seqno == dev_priv->next_seqno) {
seqno = i915_add_request(dev, NULL, NULL, ring);
if (seqno == 0)
return -ENOMEM;
}

if (atomic_read(&dev_priv->mm.wedged))
return -EIO;

if (!i915_seqno_passed(ring->get_seqno(dev, ring), seqno)) {
if (HAS_PCH_SPLIT(dev))
ier = I915_READ(DEIER) | I915_READ(GTIER);
Expand Down Expand Up @@ -1890,7 +1921,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno,
trace_i915_gem_request_wait_end(dev, seqno);
}
if (atomic_read(&dev_priv->mm.wedged))
ret = -EIO;
ret = -EAGAIN;

if (ret && ret != -ERESTARTSYS)
DRM_ERROR("%s returns %d (awaiting %d at %d, next %d)\n",
Expand Down Expand Up @@ -3569,13 +3600,17 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
struct drm_clip_rect *cliprects = NULL;
struct drm_i915_gem_relocation_entry *relocs = NULL;
struct drm_i915_gem_request *request = NULL;
int ret = 0, ret2, i, pinned = 0;
int ret, ret2, i, pinned = 0;
uint64_t exec_offset;
uint32_t reloc_index;
int pin_tries, flips;

struct intel_ring_buffer *ring = NULL;

ret = i915_gem_check_is_wedged(dev);
if (ret)
return ret;

#if WATCH_EXEC
DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
(int) args->buffers_ptr, args->buffer_count, args->batch_len);
Expand Down Expand Up @@ -3639,7 +3674,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,

if (atomic_read(&dev_priv->mm.wedged)) {
mutex_unlock(&dev->struct_mutex);
ret = -EIO;
ret = -EAGAIN;
goto pre_mutex_err;
}

Expand Down Expand Up @@ -4126,6 +4161,10 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
struct drm_i915_gem_object *obj_priv;
int ret;

ret = i915_gem_check_is_wedged(dev);
if (ret)
return ret;

mutex_lock(&dev->struct_mutex);

obj = drm_gem_object_lookup(dev, file_priv, args->handle);
Expand Down Expand Up @@ -4215,9 +4254,15 @@ int
i915_gem_busy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_busy *args = data;
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
int ret;

ret = i915_gem_check_is_wedged(dev);
if (ret)
return ret;

obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL) {
Expand All @@ -4228,6 +4273,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,

mutex_lock(&dev->struct_mutex);

if (atomic_read(&dev_priv->mm.wedged)) {
ret = -EAGAIN;
goto unlock;
}

/* Count all active objects as busy, even if they are currently not used
* by the gpu. Users of this interface expect objects to eventually
* become non-busy without any further actions, therefore emit any
Expand Down Expand Up @@ -4256,9 +4306,10 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
args->busy = obj_priv->active;
}

unlock:
drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);
return 0;
return ret;
}

int
Expand Down Expand Up @@ -4643,6 +4694,7 @@ i915_gem_load(struct drm_device *dev)
INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
i915_gem_retire_work_handler);
init_completion(&dev_priv->error_completion);
spin_lock(&shrink_list_lock);
list_add(&dev_priv->mm.shrink_list, &shrink_list);
spin_unlock(&shrink_list_lock);
Expand Down
6 changes: 5 additions & 1 deletion trunk/drivers/gpu/drm/i915/i915_gem_tiling.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,11 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
int ret = 0;
int ret;

ret = i915_gem_check_is_wedged(dev);
if (ret)
return ret;

obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL)
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ static void i915_error_work_func(struct work_struct *work)
atomic_set(&dev_priv->mm.wedged, 0);
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event);
}
complete_all(&dev_priv->error_completion);
}
}

Expand Down Expand Up @@ -869,6 +870,7 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
i915_report_and_clear_eir(dev);

if (wedged) {
INIT_COMPLETION(dev_priv->error_completion);
atomic_set(&dev_priv->mm.wedged, 1);

/*
Expand Down

0 comments on commit 2aa07ba

Please sign in to comment.