diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-04-05 23:28:35 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-04-19 18:50:14 -0400 |
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 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 | ||