aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_object.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-04-05 23:28:35 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-04-19 18:50:14 -0400
commit04eb34a43ce5168e05e2748bd46a62a09289cdde (patch)
tree4a5bfe56c631889075416d18b6b513d1eaeb37ed /drivers/gpu/drm/nouveau/nouveau_object.c
parent12dfc843f43efe14d0cfc7a52753d971a0cc759d (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.c10
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 4f00c87ed86e..67a16e01ffa6 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)
1039{ 1039{
1040 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; 1040 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
1041 struct drm_device *dev = gpuobj->dev; 1041 struct drm_device *dev = gpuobj->dev;
1042 unsigned long flags;
1042 1043
1043 if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { 1044 if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
1044 u64 ptr = gpuobj->vinst + offset; 1045 u64 ptr = gpuobj->vinst + offset;
1045 u32 base = ptr >> 16; 1046 u32 base = ptr >> 16;
1046 u32 val; 1047 u32 val;
1047 1048
1048 spin_lock(&dev_priv->ramin_lock); 1049 spin_lock_irqsave(&dev_priv->vm_lock, flags);
1049 if (dev_priv->ramin_base != base) { 1050 if (dev_priv->ramin_base != base) {
1050 dev_priv->ramin_base = base; 1051 dev_priv->ramin_base = base;
1051 nv_wr32(dev, 0x001700, dev_priv->ramin_base); 1052 nv_wr32(dev, 0x001700, dev_priv->ramin_base);
1052 } 1053 }
1053 val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); 1054 val = nv_rd32(dev, 0x700000 + (ptr & 0xffff));
1054 spin_unlock(&dev_priv->ramin_lock); 1055 spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
1055 return val; 1056 return val;
1056 } 1057 }
1057 1058
@@ -1063,18 +1064,19 @@ nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val)
1063{ 1064{
1064 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; 1065 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
1065 struct drm_device *dev = gpuobj->dev; 1066 struct drm_device *dev = gpuobj->dev;
1067 unsigned long flags;
1066 1068
1067 if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { 1069 if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
1068 u64 ptr = gpuobj->vinst + offset; 1070 u64 ptr = gpuobj->vinst + offset;
1069 u32 base = ptr >> 16; 1071 u32 base = ptr >> 16;
1070 1072
1071 spin_lock(&dev_priv->ramin_lock); 1073 spin_lock_irqsave(&dev_priv->vm_lock, flags);
1072 if (dev_priv->ramin_base != base) { 1074 if (dev_priv->ramin_base != base) {
1073 dev_priv->ramin_base = base; 1075 dev_priv->ramin_base = base;
1074 nv_wr32(dev, 0x001700, dev_priv->ramin_base); 1076 nv_wr32(dev, 0x001700, dev_priv->ramin_base);
1075 } 1077 }
1076 nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); 1078 nv_wr32(dev, 0x700000 + (ptr & 0xffff), val);
1077 spin_unlock(&dev_priv->ramin_lock); 1079 spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
1078 return; 1080 return;
1079 } 1081 }
1080 1082