aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_object.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-10-06 02:16:59 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-12-03 00:05:18 -0500
commitcff5c1332486ced8ff4180e957e04983cb72a39e (patch)
treeec1f6687156277632aef96693c1b8eca0c022b7c /drivers/gpu/drm/nouveau/nouveau_object.c
parent6a6b73f254123851f7f73ab5e57344a569d6a0ab (diff)
drm/nouveau: add more fine-grained locking to channel list + structures
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_object.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index dd572adca02a..068441c4b563 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -876,8 +876,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
876 struct nouveau_channel *chan; 876 struct nouveau_channel *chan;
877 int ret; 877 int ret;
878 878
879 NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan);
880
881 if (init->handle == ~0) 879 if (init->handle == ~0)
882 return -EINVAL; 880 return -EINVAL;
883 881
@@ -893,8 +891,14 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
893 return -EPERM; 891 return -EPERM;
894 } 892 }
895 893
896 if (nouveau_ramht_find(chan, init->handle)) 894 chan = nouveau_channel_get(dev, file_priv, init->channel);
897 return -EEXIST; 895 if (IS_ERR(chan))
896 return PTR_ERR(chan);
897
898 if (nouveau_ramht_find(chan, init->handle)) {
899 ret = -EEXIST;
900 goto out;
901 }
898 902
899 if (!grc->software) 903 if (!grc->software)
900 ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr); 904 ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr);
@@ -903,7 +907,7 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
903 if (ret) { 907 if (ret) {
904 NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", 908 NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n",
905 ret, init->channel, init->handle); 909 ret, init->channel, init->handle);
906 return ret; 910 goto out;
907 } 911 }
908 912
909 ret = nouveau_ramht_insert(chan, init->handle, gr); 913 ret = nouveau_ramht_insert(chan, init->handle, gr);
@@ -911,10 +915,11 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
911 if (ret) { 915 if (ret) {
912 NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n", 916 NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n",
913 ret, init->channel, init->handle); 917 ret, init->channel, init->handle);
914 return ret;
915 } 918 }
916 919
917 return 0; 920out:
921 nouveau_channel_put(&chan);
922 return ret;
918} 923}
919 924
920int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, 925int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
@@ -923,15 +928,20 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
923 struct drm_nouveau_gpuobj_free *objfree = data; 928 struct drm_nouveau_gpuobj_free *objfree = data;
924 struct nouveau_gpuobj *gpuobj; 929 struct nouveau_gpuobj *gpuobj;
925 struct nouveau_channel *chan; 930 struct nouveau_channel *chan;
931 int ret = -ENOENT;
926 932
927 NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan); 933 chan = nouveau_channel_get(dev, file_priv, objfree->channel);
934 if (IS_ERR(chan))
935 return PTR_ERR(chan);
928 936
929 gpuobj = nouveau_ramht_find(chan, objfree->handle); 937 gpuobj = nouveau_ramht_find(chan, objfree->handle);
930 if (!gpuobj) 938 if (gpuobj) {
931 return -ENOENT; 939 nouveau_ramht_remove(chan, objfree->handle);
940 ret = 0;
941 }
932 942
933 nouveau_ramht_remove(chan, objfree->handle); 943 nouveau_channel_put(&chan);
934 return 0; 944 return ret;
935} 945}
936 946
937u32 947u32