diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-04-06 13:28:35 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-04-20 08:50:14 +1000 |
commit | 04eb34a43ce5168e05e2748bd46a62a09289cdde (patch) | |
tree | 4a5bfe56c631889075416d18b6b513d1eaeb37ed /drivers/gpu/drm/nouveau/nouveau_object.c | |
parent | 12dfc843f43efe14d0cfc7a52753d971a0cc759d (diff) |
drm/nouveau: split ramin_lock into two locks, one hardirq safe
Fixes a possible lock ordering reversal between context_switch_lock
and ramin_lock.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_object.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 4f00c87ed86..67a16e01ffa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -1039,19 +1039,20 @@ nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) { struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; struct drm_device *dev = gpuobj->dev; + unsigned long flags; if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { u64 ptr = gpuobj->vinst + offset; u32 base = ptr >> 16; u32 val; - spin_lock(&dev_priv->ramin_lock); + spin_lock_irqsave(&dev_priv->vm_lock, flags); if (dev_priv->ramin_base != base) { dev_priv->ramin_base = base; nv_wr32(dev, 0x001700, dev_priv->ramin_base); } val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); - spin_unlock(&dev_priv->ramin_lock); + spin_unlock_irqrestore(&dev_priv->vm_lock, flags); return val; } @@ -1063,18 +1064,19 @@ nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val) { struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; struct drm_device *dev = gpuobj->dev; + unsigned long flags; if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { u64 ptr = gpuobj->vinst + offset; u32 base = ptr >> 16; - spin_lock(&dev_priv->ramin_lock); + spin_lock_irqsave(&dev_priv->vm_lock, flags); if (dev_priv->ramin_base != base) { dev_priv->ramin_base = base; nv_wr32(dev, 0x001700, dev_priv->ramin_base); } nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); - spin_unlock(&dev_priv->ramin_lock); + spin_unlock_irqrestore(&dev_priv->vm_lock, flags); return; } |