diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-10-06 02:16:59 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-03 00:05:18 -0500 |
commit | cff5c1332486ced8ff4180e957e04983cb72a39e (patch) | |
tree | ec1f6687156277632aef96693c1b8eca0c022b7c /drivers/gpu/drm/nouveau/nouveau_object.c | |
parent | 6a6b73f254123851f7f73ab5e57344a569d6a0ab (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.c | 34 |
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; | 920 | out: |
921 | nouveau_channel_put(&chan); | ||
922 | return ret; | ||
918 | } | 923 | } |
919 | 924 | ||
920 | int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, | 925 | int 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 | ||
937 | u32 | 947 | u32 |