diff options
| author | Dave Airlie <airlied@redhat.com> | 2010-03-01 00:40:12 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2010-03-01 00:40:12 -0500 |
| commit | 79fa9eb7396238233c327668185d28bb47fb0796 (patch) | |
| tree | df91899c274005adb02a7a8ca5d9e5609bc2d05b | |
| parent | 60b341b778cc2929df16c0a504c91621b3c6a4ad (diff) | |
| parent | 290e55056ec3d25c72088628245d8cae037b30db (diff) | |
Merge remote branch 'korg/drm-core-next' into drm-next-stage
* korg/drm-core-next:
drm/ttm: handle OOM in ttm_tt_swapout
drm/radeon/kms/atom: fix shr/shl ops
drm/kms: fix spelling of "CLOCK"
drm/kms: fix fb_changed = true else statement
drivers/gpu/drm/drm_fb_helper.c: don't use private implementation of atoi()
drm: switch all GEM/KMS ioctls to unlocked ioctl status.
Use drm_gem_object_[handle_]unreference_unlocked where possible
drm: introduce drm_gem_object_[handle_]unreference_unlocked
| -rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_drv.c | 44 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 26 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_gem.c | 70 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_tiling.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fbcon.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_gem.c | 26 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_notifier.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv04_crtc.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_crtc.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/atom.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_cs.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_cursor.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 36 | ||||
| -rw-r--r-- | drivers/gpu/drm/ttm/ttm_tt.c | 18 | ||||
| -rw-r--r-- | include/drm/drmP.h | 28 |
21 files changed, 156 insertions, 187 deletions
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 7d0f00a935fa..f2aaf39be398 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
| @@ -836,11 +836,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 836 | mode_changed = true; | 836 | mode_changed = true; |
| 837 | } else if (set->fb == NULL) { | 837 | } else if (set->fb == NULL) { |
| 838 | mode_changed = true; | 838 | mode_changed = true; |
| 839 | } else if ((set->fb->bits_per_pixel != | 839 | } else |
| 840 | set->crtc->fb->bits_per_pixel) || | ||
| 841 | set->fb->depth != set->crtc->fb->depth) | ||
| 842 | fb_changed = true; | ||
| 843 | else | ||
| 844 | fb_changed = true; | 840 | fb_changed = true; |
| 845 | } | 841 | } |
| 846 | 842 | ||
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 766c46875a20..f3c58e2bd75c 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
| @@ -125,28 +125,28 @@ static struct drm_ioctl_desc drm_ioctls[] = { | |||
| 125 | 125 | ||
| 126 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 126 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 127 | 127 | ||
| 128 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0), | 128 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED), |
| 129 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH), | 129 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 130 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH), | 130 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 131 | 131 | ||
| 132 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW), | 132 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 133 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW), | 133 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 134 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW), | 134 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 135 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), | 135 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 136 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER), | 136 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED), |
| 137 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER), | 137 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), |
| 138 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW), | 138 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 139 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW), | 139 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 140 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), | 140 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 141 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), | 141 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 142 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW), | 142 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 143 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), | 143 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 144 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), | 144 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 145 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW), | 145 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 146 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW), | 146 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 147 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW), | 147 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 148 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), | 148 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 149 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW) | 149 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED) |
| 150 | }; | 150 | }; |
| 151 | 151 | ||
| 152 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) | 152 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 0f9e90552dc4..50549703584f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | * Dave Airlie <airlied@linux.ie> | 27 | * Dave Airlie <airlied@linux.ie> |
| 28 | * Jesse Barnes <jesse.barnes@intel.com> | 28 | * Jesse Barnes <jesse.barnes@intel.com> |
| 29 | */ | 29 | */ |
| 30 | #include <linux/kernel.h> | ||
| 30 | #include <linux/sysrq.h> | 31 | #include <linux/sysrq.h> |
| 31 | #include <linux/fb.h> | 32 | #include <linux/fb.h> |
| 32 | #include "drmP.h" | 33 | #include "drmP.h" |
| @@ -50,21 +51,6 @@ int drm_fb_helper_add_connector(struct drm_connector *connector) | |||
| 50 | } | 51 | } |
| 51 | EXPORT_SYMBOL(drm_fb_helper_add_connector); | 52 | EXPORT_SYMBOL(drm_fb_helper_add_connector); |
| 52 | 53 | ||
| 53 | static int my_atoi(const char *name) | ||
| 54 | { | ||
| 55 | int val = 0; | ||
| 56 | |||
| 57 | for (;; name++) { | ||
| 58 | switch (*name) { | ||
| 59 | case '0' ... '9': | ||
| 60 | val = 10*val+(*name-'0'); | ||
| 61 | break; | ||
| 62 | default: | ||
| 63 | return val; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | 54 | /** |
| 69 | * drm_fb_helper_connector_parse_command_line - parse command line for connector | 55 | * drm_fb_helper_connector_parse_command_line - parse command line for connector |
| 70 | * @connector - connector to parse line for | 56 | * @connector - connector to parse line for |
| @@ -111,7 +97,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con | |||
| 111 | namelen = i; | 97 | namelen = i; |
| 112 | if (!refresh_specified && !bpp_specified && | 98 | if (!refresh_specified && !bpp_specified && |
| 113 | !yres_specified) { | 99 | !yres_specified) { |
| 114 | refresh = my_atoi(&name[i+1]); | 100 | refresh = simple_strtol(&name[i+1], NULL, 10); |
| 115 | refresh_specified = 1; | 101 | refresh_specified = 1; |
| 116 | if (cvt || rb) | 102 | if (cvt || rb) |
| 117 | cvt = 0; | 103 | cvt = 0; |
| @@ -121,7 +107,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con | |||
| 121 | case '-': | 107 | case '-': |
| 122 | namelen = i; | 108 | namelen = i; |
| 123 | if (!bpp_specified && !yres_specified) { | 109 | if (!bpp_specified && !yres_specified) { |
| 124 | bpp = my_atoi(&name[i+1]); | 110 | bpp = simple_strtol(&name[i+1], NULL, 10); |
| 125 | bpp_specified = 1; | 111 | bpp_specified = 1; |
| 126 | if (cvt || rb) | 112 | if (cvt || rb) |
| 127 | cvt = 0; | 113 | cvt = 0; |
| @@ -130,7 +116,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con | |||
| 130 | break; | 116 | break; |
| 131 | case 'x': | 117 | case 'x': |
| 132 | if (!yres_specified) { | 118 | if (!yres_specified) { |
| 133 | yres = my_atoi(&name[i+1]); | 119 | yres = simple_strtol(&name[i+1], NULL, 10); |
| 134 | yres_specified = 1; | 120 | yres_specified = 1; |
| 135 | } else | 121 | } else |
| 136 | goto done; | 122 | goto done; |
| @@ -170,7 +156,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con | |||
| 170 | } | 156 | } |
| 171 | } | 157 | } |
| 172 | if (i < 0 && yres_specified) { | 158 | if (i < 0 && yres_specified) { |
| 173 | xres = my_atoi(name); | 159 | xres = simple_strtol(name, NULL, 10); |
| 174 | res_specified = 1; | 160 | res_specified = 1; |
| 175 | } | 161 | } |
| 176 | done: | 162 | done: |
| @@ -694,7 +680,7 @@ int drm_fb_helper_set_par(struct fb_info *info) | |||
| 694 | int i; | 680 | int i; |
| 695 | 681 | ||
| 696 | if (var->pixclock != 0) { | 682 | if (var->pixclock != 0) { |
| 697 | DRM_ERROR("PIXEL CLCOK SET\n"); | 683 | DRM_ERROR("PIXEL CLOCK SET\n"); |
| 698 | return -EINVAL; | 684 | return -EINVAL; |
| 699 | } | 685 | } |
| 700 | 686 | ||
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 8bf3770f294e..aa89d4b0b4c4 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
| @@ -192,9 +192,7 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle) | |||
| 192 | idr_remove(&filp->object_idr, handle); | 192 | idr_remove(&filp->object_idr, handle); |
| 193 | spin_unlock(&filp->table_lock); | 193 | spin_unlock(&filp->table_lock); |
| 194 | 194 | ||
| 195 | mutex_lock(&dev->struct_mutex); | 195 | drm_gem_object_handle_unreference_unlocked(obj); |
| 196 | drm_gem_object_handle_unreference(obj); | ||
| 197 | mutex_unlock(&dev->struct_mutex); | ||
| 198 | 196 | ||
| 199 | return 0; | 197 | return 0; |
| 200 | } | 198 | } |
| @@ -325,9 +323,7 @@ again: | |||
| 325 | } | 323 | } |
| 326 | 324 | ||
| 327 | err: | 325 | err: |
| 328 | mutex_lock(&dev->struct_mutex); | 326 | drm_gem_object_unreference_unlocked(obj); |
| 329 | drm_gem_object_unreference(obj); | ||
| 330 | mutex_unlock(&dev->struct_mutex); | ||
| 331 | return ret; | 327 | return ret; |
| 332 | } | 328 | } |
| 333 | 329 | ||
| @@ -358,9 +354,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, | |||
| 358 | return -ENOENT; | 354 | return -ENOENT; |
| 359 | 355 | ||
| 360 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 356 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
| 361 | mutex_lock(&dev->struct_mutex); | 357 | drm_gem_object_unreference_unlocked(obj); |
| 362 | drm_gem_object_unreference(obj); | ||
| 363 | mutex_unlock(&dev->struct_mutex); | ||
| 364 | if (ret) | 358 | if (ret) |
| 365 | return ret; | 359 | return ret; |
| 366 | 360 | ||
| @@ -390,7 +384,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) | |||
| 390 | { | 384 | { |
| 391 | struct drm_gem_object *obj = ptr; | 385 | struct drm_gem_object *obj = ptr; |
| 392 | 386 | ||
| 393 | drm_gem_object_handle_unreference(obj); | 387 | drm_gem_object_handle_unreference_unlocked(obj); |
| 394 | 388 | ||
| 395 | return 0; | 389 | return 0; |
| 396 | } | 390 | } |
| @@ -403,16 +397,25 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) | |||
| 403 | void | 397 | void |
| 404 | drm_gem_release(struct drm_device *dev, struct drm_file *file_private) | 398 | drm_gem_release(struct drm_device *dev, struct drm_file *file_private) |
| 405 | { | 399 | { |
| 406 | mutex_lock(&dev->struct_mutex); | ||
| 407 | idr_for_each(&file_private->object_idr, | 400 | idr_for_each(&file_private->object_idr, |
| 408 | &drm_gem_object_release_handle, NULL); | 401 | &drm_gem_object_release_handle, NULL); |
| 409 | 402 | ||
| 410 | idr_destroy(&file_private->object_idr); | 403 | idr_destroy(&file_private->object_idr); |
| 411 | mutex_unlock(&dev->struct_mutex); | 404 | } |
| 405 | |||
| 406 | static void | ||
| 407 | drm_gem_object_free_common(struct drm_gem_object *obj) | ||
| 408 | { | ||
| 409 | struct drm_device *dev = obj->dev; | ||
| 410 | fput(obj->filp); | ||
| 411 | atomic_dec(&dev->object_count); | ||
| 412 | atomic_sub(obj->size, &dev->object_memory); | ||
| 413 | kfree(obj); | ||
| 412 | } | 414 | } |
| 413 | 415 | ||
| 414 | /** | 416 | /** |
| 415 | * Called after the last reference to the object has been lost. | 417 | * Called after the last reference to the object has been lost. |
| 418 | * Must be called holding struct_ mutex | ||
| 416 | * | 419 | * |
| 417 | * Frees the object | 420 | * Frees the object |
| 418 | */ | 421 | */ |
| @@ -427,14 +430,40 @@ drm_gem_object_free(struct kref *kref) | |||
| 427 | if (dev->driver->gem_free_object != NULL) | 430 | if (dev->driver->gem_free_object != NULL) |
| 428 | dev->driver->gem_free_object(obj); | 431 | dev->driver->gem_free_object(obj); |
| 429 | 432 | ||
| 430 | fput(obj->filp); | 433 | drm_gem_object_free_common(obj); |
| 431 | atomic_dec(&dev->object_count); | ||
| 432 | atomic_sub(obj->size, &dev->object_memory); | ||
| 433 | kfree(obj); | ||
| 434 | } | 434 | } |
| 435 | EXPORT_SYMBOL(drm_gem_object_free); | 435 | EXPORT_SYMBOL(drm_gem_object_free); |
| 436 | 436 | ||
| 437 | /** | 437 | /** |
| 438 | * Called after the last reference to the object has been lost. | ||
| 439 | * Must be called without holding struct_mutex | ||
| 440 | * | ||
| 441 | * Frees the object | ||
| 442 | */ | ||
| 443 | void | ||
| 444 | drm_gem_object_free_unlocked(struct kref *kref) | ||
| 445 | { | ||
| 446 | struct drm_gem_object *obj = (struct drm_gem_object *) kref; | ||
| 447 | struct drm_device *dev = obj->dev; | ||
| 448 | |||
| 449 | if (dev->driver->gem_free_object_unlocked != NULL) | ||
| 450 | dev->driver->gem_free_object_unlocked(obj); | ||
| 451 | else if (dev->driver->gem_free_object != NULL) { | ||
| 452 | mutex_lock(&dev->struct_mutex); | ||
| 453 | dev->driver->gem_free_object(obj); | ||
| 454 | mutex_unlock(&dev->struct_mutex); | ||
| 455 | } | ||
| 456 | |||
| 457 | drm_gem_object_free_common(obj); | ||
| 458 | } | ||
| 459 | EXPORT_SYMBOL(drm_gem_object_free_unlocked); | ||
| 460 | |||
| 461 | static void drm_gem_object_ref_bug(struct kref *list_kref) | ||
| 462 | { | ||
| 463 | BUG(); | ||
| 464 | } | ||
| 465 | |||
| 466 | /** | ||
| 438 | * Called after the last handle to the object has been closed | 467 | * Called after the last handle to the object has been closed |
| 439 | * | 468 | * |
| 440 | * Removes any name for the object. Note that this must be | 469 | * Removes any name for the object. Note that this must be |
| @@ -458,8 +487,10 @@ drm_gem_object_handle_free(struct kref *kref) | |||
| 458 | /* | 487 | /* |
| 459 | * The object name held a reference to this object, drop | 488 | * The object name held a reference to this object, drop |
| 460 | * that now. | 489 | * that now. |
| 490 | * | ||
| 491 | * This cannot be the last reference, since the handle holds one too. | ||
| 461 | */ | 492 | */ |
| 462 | drm_gem_object_unreference(obj); | 493 | kref_put(&obj->refcount, drm_gem_object_ref_bug); |
| 463 | } else | 494 | } else |
| 464 | spin_unlock(&dev->object_name_lock); | 495 | spin_unlock(&dev->object_name_lock); |
| 465 | 496 | ||
| @@ -477,11 +508,8 @@ EXPORT_SYMBOL(drm_gem_vm_open); | |||
| 477 | void drm_gem_vm_close(struct vm_area_struct *vma) | 508 | void drm_gem_vm_close(struct vm_area_struct *vma) |
| 478 | { | 509 | { |
| 479 | struct drm_gem_object *obj = vma->vm_private_data; | 510 | struct drm_gem_object *obj = vma->vm_private_data; |
| 480 | struct drm_device *dev = obj->dev; | ||
| 481 | 511 | ||
| 482 | mutex_lock(&dev->struct_mutex); | 512 | drm_gem_object_unreference_unlocked(obj); |
| 483 | drm_gem_object_unreference(obj); | ||
| 484 | mutex_unlock(&dev->struct_mutex); | ||
| 485 | } | 513 | } |
| 486 | EXPORT_SYMBOL(drm_gem_vm_close); | 514 | EXPORT_SYMBOL(drm_gem_vm_close); |
| 487 | 515 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ec8a0d7ffa39..9d87d5a41bdc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -128,9 +128,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
| 128 | return -ENOMEM; | 128 | return -ENOMEM; |
| 129 | 129 | ||
| 130 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 130 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
| 131 | mutex_lock(&dev->struct_mutex); | 131 | drm_gem_object_handle_unreference_unlocked(obj); |
| 132 | drm_gem_object_handle_unreference(obj); | ||
| 133 | mutex_unlock(&dev->struct_mutex); | ||
| 134 | 132 | ||
| 135 | if (ret) | 133 | if (ret) |
| 136 | return ret; | 134 | return ret; |
| @@ -488,7 +486,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
| 488 | */ | 486 | */ |
| 489 | if (args->offset > obj->size || args->size > obj->size || | 487 | if (args->offset > obj->size || args->size > obj->size || |
| 490 | args->offset + args->size > obj->size) { | 488 | args->offset + args->size > obj->size) { |
| 491 | drm_gem_object_unreference(obj); | 489 | drm_gem_object_unreference_unlocked(obj); |
| 492 | return -EINVAL; | 490 | return -EINVAL; |
| 493 | } | 491 | } |
| 494 | 492 | ||
| @@ -501,7 +499,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
| 501 | file_priv); | 499 | file_priv); |
| 502 | } | 500 | } |
| 503 | 501 | ||
| 504 | drm_gem_object_unreference(obj); | 502 | drm_gem_object_unreference_unlocked(obj); |
| 505 | 503 | ||
| 506 | return ret; | 504 | return ret; |
| 507 | } | 505 | } |
| @@ -961,7 +959,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
| 961 | */ | 959 | */ |
| 962 | if (args->offset > obj->size || args->size > obj->size || | 960 | if (args->offset > obj->size || args->size > obj->size || |
| 963 | args->offset + args->size > obj->size) { | 961 | args->offset + args->size > obj->size) { |
| 964 | drm_gem_object_unreference(obj); | 962 | drm_gem_object_unreference_unlocked(obj); |
| 965 | return -EINVAL; | 963 | return -EINVAL; |
| 966 | } | 964 | } |
| 967 | 965 | ||
| @@ -995,7 +993,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
| 995 | DRM_INFO("pwrite failed %d\n", ret); | 993 | DRM_INFO("pwrite failed %d\n", ret); |
| 996 | #endif | 994 | #endif |
| 997 | 995 | ||
| 998 | drm_gem_object_unreference(obj); | 996 | drm_gem_object_unreference_unlocked(obj); |
| 999 | 997 | ||
| 1000 | return ret; | 998 | return ret; |
| 1001 | } | 999 | } |
| @@ -1138,9 +1136,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
| 1138 | PROT_READ | PROT_WRITE, MAP_SHARED, | 1136 | PROT_READ | PROT_WRITE, MAP_SHARED, |
| 1139 | args->offset); | 1137 | args->offset); |
| 1140 | up_write(¤t->mm->mmap_sem); | 1138 | up_write(¤t->mm->mmap_sem); |
| 1141 | mutex_lock(&dev->struct_mutex); | 1139 | drm_gem_object_unreference_unlocked(obj); |
| 1142 | drm_gem_object_unreference(obj); | ||
| 1143 | mutex_unlock(&dev->struct_mutex); | ||
| 1144 | if (IS_ERR((void *)addr)) | 1140 | if (IS_ERR((void *)addr)) |
| 1145 | return addr; | 1141 | return addr; |
| 1146 | 1142 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index df278b2685bf..137e888427f1 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
| @@ -438,9 +438,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
| 438 | obj_priv = obj->driver_private; | 438 | obj_priv = obj->driver_private; |
| 439 | 439 | ||
| 440 | if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { | 440 | if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { |
| 441 | mutex_lock(&dev->struct_mutex); | 441 | drm_gem_object_unreference_unlocked(obj); |
| 442 | drm_gem_object_unreference(obj); | ||
| 443 | mutex_unlock(&dev->struct_mutex); | ||
| 444 | return -EINVAL; | 442 | return -EINVAL; |
| 445 | } | 443 | } |
| 446 | 444 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b27202d23ebc..c8fd15f146af 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -3553,11 +3553,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 3553 | intel_crtc->cursor_bo = bo; | 3553 | intel_crtc->cursor_bo = bo; |
| 3554 | 3554 | ||
| 3555 | return 0; | 3555 | return 0; |
| 3556 | fail: | ||
| 3557 | mutex_lock(&dev->struct_mutex); | ||
| 3558 | fail_locked: | 3556 | fail_locked: |
| 3559 | drm_gem_object_unreference(bo); | ||
| 3560 | mutex_unlock(&dev->struct_mutex); | 3557 | mutex_unlock(&dev->struct_mutex); |
| 3558 | fail: | ||
| 3559 | drm_gem_object_unreference_unlocked(bo); | ||
| 3561 | return ret; | 3560 | return ret; |
| 3562 | } | 3561 | } |
| 3563 | 3562 | ||
| @@ -4476,9 +4475,7 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
| 4476 | intelfb_remove(dev, fb); | 4475 | intelfb_remove(dev, fb); |
| 4477 | 4476 | ||
| 4478 | drm_framebuffer_cleanup(fb); | 4477 | drm_framebuffer_cleanup(fb); |
| 4479 | mutex_lock(&dev->struct_mutex); | 4478 | drm_gem_object_unreference_unlocked(intel_fb->obj); |
| 4480 | drm_gem_object_unreference(intel_fb->obj); | ||
| 4481 | mutex_unlock(&dev->struct_mutex); | ||
| 4482 | 4479 | ||
| 4483 | kfree(intel_fb); | 4480 | kfree(intel_fb); |
| 4484 | } | 4481 | } |
| @@ -4541,9 +4538,7 @@ intel_user_framebuffer_create(struct drm_device *dev, | |||
| 4541 | 4538 | ||
| 4542 | ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj); | 4539 | ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj); |
| 4543 | if (ret) { | 4540 | if (ret) { |
| 4544 | mutex_lock(&dev->struct_mutex); | 4541 | drm_gem_object_unreference_unlocked(obj); |
| 4545 | drm_gem_object_unreference(obj); | ||
| 4546 | mutex_unlock(&dev->struct_mutex); | ||
| 4547 | return NULL; | 4542 | return NULL; |
| 4548 | } | 4543 | } |
| 4549 | 4544 | ||
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 2639591c72e9..1b50d61c5aaa 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
| @@ -1179,7 +1179,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
| 1179 | out_unlock: | 1179 | out_unlock: |
| 1180 | mutex_unlock(&dev->struct_mutex); | 1180 | mutex_unlock(&dev->struct_mutex); |
| 1181 | mutex_unlock(&dev->mode_config.mutex); | 1181 | mutex_unlock(&dev->mode_config.mutex); |
| 1182 | drm_gem_object_unreference(new_bo); | 1182 | drm_gem_object_unreference_unlocked(new_bo); |
| 1183 | kfree(params); | 1183 | kfree(params); |
| 1184 | 1184 | ||
| 1185 | return ret; | 1185 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index dfc94391d71e..cf1c5c0a0abe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
| @@ -39,11 +39,8 @@ nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) | |||
| 39 | if (drm_fb->fbdev) | 39 | if (drm_fb->fbdev) |
| 40 | nouveau_fbcon_remove(dev, drm_fb); | 40 | nouveau_fbcon_remove(dev, drm_fb); |
| 41 | 41 | ||
| 42 | if (fb->nvbo) { | 42 | if (fb->nvbo) |
| 43 | mutex_lock(&dev->struct_mutex); | 43 | drm_gem_object_unreference_unlocked(fb->nvbo->gem); |
| 44 | drm_gem_object_unreference(fb->nvbo->gem); | ||
| 45 | mutex_unlock(&dev->struct_mutex); | ||
| 46 | } | ||
| 47 | 44 | ||
| 48 | drm_framebuffer_cleanup(drm_fb); | 45 | drm_framebuffer_cleanup(drm_fb); |
| 49 | kfree(fb); | 46 | kfree(fb); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index ea879a2efef3..d48c59cdefe4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
| @@ -401,10 +401,8 @@ nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb) | |||
| 401 | 401 | ||
| 402 | unregister_framebuffer(info); | 402 | unregister_framebuffer(info); |
| 403 | nouveau_bo_unmap(nouveau_fb->nvbo); | 403 | nouveau_bo_unmap(nouveau_fb->nvbo); |
| 404 | mutex_lock(&dev->struct_mutex); | 404 | drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem); |
| 405 | drm_gem_object_unreference(nouveau_fb->nvbo->gem); | ||
| 406 | nouveau_fb->nvbo = NULL; | 405 | nouveau_fb->nvbo = NULL; |
| 407 | mutex_unlock(&dev->struct_mutex); | ||
| 408 | if (par) | 406 | if (par) |
| 409 | drm_fb_helper_free(&par->helper); | 407 | drm_fb_helper_free(&par->helper); |
| 410 | framebuffer_release(info); | 408 | framebuffer_release(info); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 70cc30803e3b..34063c561899 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
| @@ -167,12 +167,10 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, | |||
| 167 | 167 | ||
| 168 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); | 168 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); |
| 169 | out: | 169 | out: |
| 170 | mutex_lock(&dev->struct_mutex); | 170 | drm_gem_object_handle_unreference_unlocked(nvbo->gem); |
| 171 | drm_gem_object_handle_unreference(nvbo->gem); | ||
| 172 | mutex_unlock(&dev->struct_mutex); | ||
| 173 | 171 | ||
| 174 | if (ret) | 172 | if (ret) |
| 175 | drm_gem_object_unreference(nvbo->gem); | 173 | drm_gem_object_unreference_unlocked(nvbo->gem); |
| 176 | return ret; | 174 | return ret; |
| 177 | } | 175 | } |
| 178 | 176 | ||
| @@ -865,9 +863,7 @@ nouveau_gem_ioctl_pin(struct drm_device *dev, void *data, | |||
| 865 | req->domain = NOUVEAU_GEM_DOMAIN_VRAM; | 863 | req->domain = NOUVEAU_GEM_DOMAIN_VRAM; |
| 866 | 864 | ||
| 867 | out: | 865 | out: |
| 868 | mutex_lock(&dev->struct_mutex); | 866 | drm_gem_object_unreference_unlocked(gem); |
| 869 | drm_gem_object_unreference(gem); | ||
| 870 | mutex_unlock(&dev->struct_mutex); | ||
| 871 | 867 | ||
| 872 | return ret; | 868 | return ret; |
| 873 | } | 869 | } |
| @@ -891,9 +887,7 @@ nouveau_gem_ioctl_unpin(struct drm_device *dev, void *data, | |||
| 891 | 887 | ||
| 892 | ret = nouveau_bo_unpin(nouveau_gem_object(gem)); | 888 | ret = nouveau_bo_unpin(nouveau_gem_object(gem)); |
| 893 | 889 | ||
| 894 | mutex_lock(&dev->struct_mutex); | 890 | drm_gem_object_unreference_unlocked(gem); |
| 895 | drm_gem_object_unreference(gem); | ||
| 896 | mutex_unlock(&dev->struct_mutex); | ||
| 897 | 891 | ||
| 898 | return ret; | 892 | return ret; |
| 899 | } | 893 | } |
| @@ -935,9 +929,7 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, | |||
| 935 | } | 929 | } |
| 936 | 930 | ||
| 937 | out: | 931 | out: |
| 938 | mutex_lock(&dev->struct_mutex); | 932 | drm_gem_object_unreference_unlocked(gem); |
| 939 | drm_gem_object_unreference(gem); | ||
| 940 | mutex_unlock(&dev->struct_mutex); | ||
| 941 | return ret; | 933 | return ret; |
| 942 | } | 934 | } |
| 943 | 935 | ||
| @@ -965,9 +957,7 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, | |||
| 965 | ret = 0; | 957 | ret = 0; |
| 966 | 958 | ||
| 967 | out: | 959 | out: |
| 968 | mutex_lock(&dev->struct_mutex); | 960 | drm_gem_object_unreference_unlocked(gem); |
| 969 | drm_gem_object_unreference(gem); | ||
| 970 | mutex_unlock(&dev->struct_mutex); | ||
| 971 | return ret; | 961 | return ret; |
| 972 | } | 962 | } |
| 973 | 963 | ||
| @@ -986,9 +976,7 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data, | |||
| 986 | return -EINVAL; | 976 | return -EINVAL; |
| 987 | 977 | ||
| 988 | ret = nouveau_gem_info(gem, req); | 978 | ret = nouveau_gem_info(gem, req); |
| 989 | mutex_lock(&dev->struct_mutex); | 979 | drm_gem_object_unreference_unlocked(gem); |
| 990 | drm_gem_object_unreference(gem); | ||
| 991 | mutex_unlock(&dev->struct_mutex); | ||
| 992 | return ret; | 980 | return ret; |
| 993 | } | 981 | } |
| 994 | 982 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index d99dc087f9b1..9537f3e30115 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
| @@ -61,11 +61,8 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) | |||
| 61 | 61 | ||
| 62 | chan->notifier_bo = ntfy; | 62 | chan->notifier_bo = ntfy; |
| 63 | out_err: | 63 | out_err: |
| 64 | if (ret) { | 64 | if (ret) |
| 65 | mutex_lock(&dev->struct_mutex); | 65 | drm_gem_object_unreference_unlocked(ntfy->gem); |
| 66 | drm_gem_object_unreference(ntfy->gem); | ||
| 67 | mutex_unlock(&dev->struct_mutex); | ||
| 68 | } | ||
| 69 | 66 | ||
| 70 | return ret; | 67 | return ret; |
| 71 | } | 68 | } |
| @@ -81,8 +78,8 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan) | |||
| 81 | nouveau_bo_unmap(chan->notifier_bo); | 78 | nouveau_bo_unmap(chan->notifier_bo); |
| 82 | mutex_lock(&dev->struct_mutex); | 79 | mutex_lock(&dev->struct_mutex); |
| 83 | nouveau_bo_unpin(chan->notifier_bo); | 80 | nouveau_bo_unpin(chan->notifier_bo); |
| 84 | drm_gem_object_unreference(chan->notifier_bo->gem); | ||
| 85 | mutex_unlock(&dev->struct_mutex); | 81 | mutex_unlock(&dev->struct_mutex); |
| 82 | drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); | ||
| 86 | nouveau_mem_takedown(&chan->notifier_heap); | 83 | nouveau_mem_takedown(&chan->notifier_heap); |
| 87 | } | 84 | } |
| 88 | 85 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index d2f143ed97c1..a1d1ebb073d9 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c | |||
| @@ -926,9 +926,7 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
| 926 | nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); | 926 | nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); |
| 927 | nv_crtc->cursor.show(nv_crtc, true); | 927 | nv_crtc->cursor.show(nv_crtc, true); |
| 928 | out: | 928 | out: |
| 929 | mutex_lock(&dev->struct_mutex); | 929 | drm_gem_object_unreference_unlocked(gem); |
| 930 | drm_gem_object_unreference(gem); | ||
| 931 | mutex_unlock(&dev->struct_mutex); | ||
| 932 | return ret; | 930 | return ret; |
| 933 | } | 931 | } |
| 934 | 932 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index d1a651e3400c..cfabeb974a56 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
| @@ -358,9 +358,7 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
| 358 | nv_crtc->cursor.show(nv_crtc, true); | 358 | nv_crtc->cursor.show(nv_crtc, true); |
| 359 | 359 | ||
| 360 | out: | 360 | out: |
| 361 | mutex_lock(&dev->struct_mutex); | 361 | drm_gem_object_unreference_unlocked(gem); |
| 362 | drm_gem_object_unreference(gem); | ||
| 363 | mutex_unlock(&dev->struct_mutex); | ||
| 364 | return ret; | 362 | return ret; |
| 365 | } | 363 | } |
| 366 | 364 | ||
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 7f152f66f196..d75788feac6c 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
| @@ -881,8 +881,6 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) | |||
| 881 | uint8_t attr = U8((*ptr)++), shift; | 881 | uint8_t attr = U8((*ptr)++), shift; |
| 882 | uint32_t saved, dst; | 882 | uint32_t saved, dst; |
| 883 | int dptr = *ptr; | 883 | int dptr = *ptr; |
| 884 | attr &= 0x38; | ||
| 885 | attr |= atom_def_dst[attr >> 3] << 6; | ||
| 886 | SDEBUG(" dst: "); | 884 | SDEBUG(" dst: "); |
| 887 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 885 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
| 888 | shift = atom_get_src(ctx, attr, ptr); | 886 | shift = atom_get_src(ctx, attr, ptr); |
| @@ -897,8 +895,6 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) | |||
| 897 | uint8_t attr = U8((*ptr)++), shift; | 895 | uint8_t attr = U8((*ptr)++), shift; |
| 898 | uint32_t saved, dst; | 896 | uint32_t saved, dst; |
| 899 | int dptr = *ptr; | 897 | int dptr = *ptr; |
| 900 | attr &= 0x38; | ||
| 901 | attr |= atom_def_dst[attr >> 3] << 6; | ||
| 902 | SDEBUG(" dst: "); | 898 | SDEBUG(" dst: "); |
| 903 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 899 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
| 904 | shift = atom_get_src(ctx, attr, ptr); | 900 | shift = atom_get_src(ctx, attr, ptr); |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index e9d085021c1f..70ba02ed7723 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -194,11 +194,8 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
| 194 | } | 194 | } |
| 195 | radeon_bo_list_unreserve(&parser->validated); | 195 | radeon_bo_list_unreserve(&parser->validated); |
| 196 | for (i = 0; i < parser->nrelocs; i++) { | 196 | for (i = 0; i < parser->nrelocs; i++) { |
| 197 | if (parser->relocs[i].gobj) { | 197 | if (parser->relocs[i].gobj) |
| 198 | mutex_lock(&parser->rdev->ddev->struct_mutex); | 198 | drm_gem_object_unreference_unlocked(parser->relocs[i].gobj); |
| 199 | drm_gem_object_unreference(parser->relocs[i].gobj); | ||
| 200 | mutex_unlock(&parser->rdev->ddev->struct_mutex); | ||
| 201 | } | ||
| 202 | } | 199 | } |
| 203 | kfree(parser->track); | 200 | kfree(parser->track); |
| 204 | kfree(parser->relocs); | 201 | kfree(parser->relocs); |
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 28772a37009c..6f4a5534a99e 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
| @@ -169,17 +169,13 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 169 | unpin: | 169 | unpin: |
| 170 | if (radeon_crtc->cursor_bo) { | 170 | if (radeon_crtc->cursor_bo) { |
| 171 | radeon_gem_object_unpin(radeon_crtc->cursor_bo); | 171 | radeon_gem_object_unpin(radeon_crtc->cursor_bo); |
| 172 | mutex_lock(&crtc->dev->struct_mutex); | 172 | drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); |
| 173 | drm_gem_object_unreference(radeon_crtc->cursor_bo); | ||
| 174 | mutex_unlock(&crtc->dev->struct_mutex); | ||
| 175 | } | 173 | } |
| 176 | 174 | ||
| 177 | radeon_crtc->cursor_bo = obj; | 175 | radeon_crtc->cursor_bo = obj; |
| 178 | return 0; | 176 | return 0; |
| 179 | fail: | 177 | fail: |
| 180 | mutex_lock(&crtc->dev->struct_mutex); | 178 | drm_gem_object_unreference_unlocked(obj); |
| 181 | drm_gem_object_unreference(obj); | ||
| 182 | mutex_unlock(&crtc->dev->struct_mutex); | ||
| 183 | 179 | ||
| 184 | return 0; | 180 | return 0; |
| 185 | } | 181 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 7e17a362b54b..3db825505626 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -679,11 +679,8 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
| 679 | if (fb->fbdev) | 679 | if (fb->fbdev) |
| 680 | radeonfb_remove(dev, fb); | 680 | radeonfb_remove(dev, fb); |
| 681 | 681 | ||
| 682 | if (radeon_fb->obj) { | 682 | if (radeon_fb->obj) |
| 683 | mutex_lock(&dev->struct_mutex); | 683 | drm_gem_object_unreference_unlocked(radeon_fb->obj); |
| 684 | drm_gem_object_unreference(radeon_fb->obj); | ||
| 685 | mutex_unlock(&dev->struct_mutex); | ||
| 686 | } | ||
| 687 | drm_framebuffer_cleanup(fb); | 684 | drm_framebuffer_cleanup(fb); |
| 688 | kfree(radeon_fb); | 685 | kfree(radeon_fb); |
| 689 | } | 686 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index db8e9a355a01..ef92d147d8f0 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -69,9 +69,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
| 69 | if (r != -ERESTARTSYS) | 69 | if (r != -ERESTARTSYS) |
| 70 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", | 70 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", |
| 71 | size, initial_domain, alignment, r); | 71 | size, initial_domain, alignment, r); |
| 72 | mutex_lock(&rdev->ddev->struct_mutex); | 72 | drm_gem_object_unreference_unlocked(gobj); |
| 73 | drm_gem_object_unreference(gobj); | ||
| 74 | mutex_unlock(&rdev->ddev->struct_mutex); | ||
| 75 | return r; | 73 | return r; |
| 76 | } | 74 | } |
| 77 | gobj->driver_private = robj; | 75 | gobj->driver_private = robj; |
| @@ -202,14 +200,10 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
| 202 | } | 200 | } |
| 203 | r = drm_gem_handle_create(filp, gobj, &handle); | 201 | r = drm_gem_handle_create(filp, gobj, &handle); |
| 204 | if (r) { | 202 | if (r) { |
| 205 | mutex_lock(&dev->struct_mutex); | 203 | drm_gem_object_unreference_unlocked(gobj); |
| 206 | drm_gem_object_unreference(gobj); | ||
| 207 | mutex_unlock(&dev->struct_mutex); | ||
| 208 | return r; | 204 | return r; |
| 209 | } | 205 | } |
| 210 | mutex_lock(&dev->struct_mutex); | 206 | drm_gem_object_handle_unreference_unlocked(gobj); |
| 211 | drm_gem_object_handle_unreference(gobj); | ||
| 212 | mutex_unlock(&dev->struct_mutex); | ||
| 213 | args->handle = handle; | 207 | args->handle = handle; |
| 214 | return 0; | 208 | return 0; |
| 215 | } | 209 | } |
| @@ -236,9 +230,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
| 236 | 230 | ||
| 237 | r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain); | 231 | r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain); |
| 238 | 232 | ||
| 239 | mutex_lock(&dev->struct_mutex); | 233 | drm_gem_object_unreference_unlocked(gobj); |
| 240 | drm_gem_object_unreference(gobj); | ||
| 241 | mutex_unlock(&dev->struct_mutex); | ||
| 242 | return r; | 234 | return r; |
| 243 | } | 235 | } |
| 244 | 236 | ||
| @@ -255,9 +247,7 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
| 255 | } | 247 | } |
| 256 | robj = gobj->driver_private; | 248 | robj = gobj->driver_private; |
| 257 | args->addr_ptr = radeon_bo_mmap_offset(robj); | 249 | args->addr_ptr = radeon_bo_mmap_offset(robj); |
| 258 | mutex_lock(&dev->struct_mutex); | 250 | drm_gem_object_unreference_unlocked(gobj); |
| 259 | drm_gem_object_unreference(gobj); | ||
| 260 | mutex_unlock(&dev->struct_mutex); | ||
| 261 | return 0; | 251 | return 0; |
| 262 | } | 252 | } |
| 263 | 253 | ||
| @@ -288,9 +278,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
| 288 | default: | 278 | default: |
| 289 | break; | 279 | break; |
| 290 | } | 280 | } |
| 291 | mutex_lock(&dev->struct_mutex); | 281 | drm_gem_object_unreference_unlocked(gobj); |
| 292 | drm_gem_object_unreference(gobj); | ||
| 293 | mutex_unlock(&dev->struct_mutex); | ||
| 294 | return r; | 282 | return r; |
| 295 | } | 283 | } |
| 296 | 284 | ||
| @@ -311,9 +299,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
| 311 | /* callback hw specific functions if any */ | 299 | /* callback hw specific functions if any */ |
| 312 | if (robj->rdev->asic->ioctl_wait_idle) | 300 | if (robj->rdev->asic->ioctl_wait_idle) |
| 313 | robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); | 301 | robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); |
| 314 | mutex_lock(&dev->struct_mutex); | 302 | drm_gem_object_unreference_unlocked(gobj); |
| 315 | drm_gem_object_unreference(gobj); | ||
| 316 | mutex_unlock(&dev->struct_mutex); | ||
| 317 | return r; | 303 | return r; |
| 318 | } | 304 | } |
| 319 | 305 | ||
| @@ -331,9 +317,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
| 331 | return -EINVAL; | 317 | return -EINVAL; |
| 332 | robj = gobj->driver_private; | 318 | robj = gobj->driver_private; |
| 333 | r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch); | 319 | r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch); |
| 334 | mutex_lock(&dev->struct_mutex); | 320 | drm_gem_object_unreference_unlocked(gobj); |
| 335 | drm_gem_object_unreference(gobj); | ||
| 336 | mutex_unlock(&dev->struct_mutex); | ||
| 337 | return r; | 321 | return r; |
| 338 | } | 322 | } |
| 339 | 323 | ||
| @@ -356,8 +340,6 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | |||
| 356 | radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch); | 340 | radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch); |
| 357 | radeon_bo_unreserve(rbo); | 341 | radeon_bo_unreserve(rbo); |
| 358 | out: | 342 | out: |
| 359 | mutex_lock(&dev->struct_mutex); | 343 | drm_gem_object_unreference_unlocked(gobj); |
| 360 | drm_gem_object_unreference(gobj); | ||
| 361 | mutex_unlock(&dev->struct_mutex); | ||
| 362 | return r; | 344 | return r; |
| 363 | } | 345 | } |
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 3d47a2c12322..a759170763bb 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
| @@ -480,7 +480,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) | |||
| 480 | void *from_virtual; | 480 | void *from_virtual; |
| 481 | void *to_virtual; | 481 | void *to_virtual; |
| 482 | int i; | 482 | int i; |
| 483 | int ret; | 483 | int ret = -ENOMEM; |
| 484 | 484 | ||
| 485 | if (ttm->page_flags & TTM_PAGE_FLAG_USER) { | 485 | if (ttm->page_flags & TTM_PAGE_FLAG_USER) { |
| 486 | ret = ttm_tt_set_user(ttm, ttm->tsk, ttm->start, | 486 | ret = ttm_tt_set_user(ttm, ttm->tsk, ttm->start, |
| @@ -499,8 +499,10 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) | |||
| 499 | 499 | ||
| 500 | for (i = 0; i < ttm->num_pages; ++i) { | 500 | for (i = 0; i < ttm->num_pages; ++i) { |
| 501 | from_page = read_mapping_page(swap_space, i, NULL); | 501 | from_page = read_mapping_page(swap_space, i, NULL); |
| 502 | if (IS_ERR(from_page)) | 502 | if (IS_ERR(from_page)) { |
| 503 | ret = PTR_ERR(from_page); | ||
| 503 | goto out_err; | 504 | goto out_err; |
| 505 | } | ||
| 504 | to_page = __ttm_tt_get_page(ttm, i); | 506 | to_page = __ttm_tt_get_page(ttm, i); |
| 505 | if (unlikely(to_page == NULL)) | 507 | if (unlikely(to_page == NULL)) |
| 506 | goto out_err; | 508 | goto out_err; |
| @@ -523,7 +525,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) | |||
| 523 | return 0; | 525 | return 0; |
| 524 | out_err: | 526 | out_err: |
| 525 | ttm_tt_free_alloced_pages(ttm); | 527 | ttm_tt_free_alloced_pages(ttm); |
| 526 | return -ENOMEM; | 528 | return ret; |
| 527 | } | 529 | } |
| 528 | 530 | ||
| 529 | int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) | 531 | int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) |
| @@ -535,6 +537,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) | |||
| 535 | void *from_virtual; | 537 | void *from_virtual; |
| 536 | void *to_virtual; | 538 | void *to_virtual; |
| 537 | int i; | 539 | int i; |
| 540 | int ret = -ENOMEM; | ||
| 538 | 541 | ||
| 539 | BUG_ON(ttm->state != tt_unbound && ttm->state != tt_unpopulated); | 542 | BUG_ON(ttm->state != tt_unbound && ttm->state != tt_unpopulated); |
| 540 | BUG_ON(ttm->caching_state != tt_cached); | 543 | BUG_ON(ttm->caching_state != tt_cached); |
| @@ -557,7 +560,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) | |||
| 557 | 0); | 560 | 0); |
| 558 | if (unlikely(IS_ERR(swap_storage))) { | 561 | if (unlikely(IS_ERR(swap_storage))) { |
| 559 | printk(KERN_ERR "Failed allocating swap storage.\n"); | 562 | printk(KERN_ERR "Failed allocating swap storage.\n"); |
| 560 | return -ENOMEM; | 563 | return PTR_ERR(swap_storage); |
| 561 | } | 564 | } |
| 562 | } else | 565 | } else |
| 563 | swap_storage = persistant_swap_storage; | 566 | swap_storage = persistant_swap_storage; |
| @@ -569,9 +572,10 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) | |||
| 569 | if (unlikely(from_page == NULL)) | 572 | if (unlikely(from_page == NULL)) |
| 570 | continue; | 573 | continue; |
| 571 | to_page = read_mapping_page(swap_space, i, NULL); | 574 | to_page = read_mapping_page(swap_space, i, NULL); |
| 572 | if (unlikely(to_page == NULL)) | 575 | if (unlikely(IS_ERR(to_page))) { |
| 576 | ret = PTR_ERR(to_page); | ||
| 573 | goto out_err; | 577 | goto out_err; |
| 574 | 578 | } | |
| 575 | preempt_disable(); | 579 | preempt_disable(); |
| 576 | from_virtual = kmap_atomic(from_page, KM_USER0); | 580 | from_virtual = kmap_atomic(from_page, KM_USER0); |
| 577 | to_virtual = kmap_atomic(to_page, KM_USER1); | 581 | to_virtual = kmap_atomic(to_page, KM_USER1); |
| @@ -595,5 +599,5 @@ out_err: | |||
| 595 | if (!persistant_swap_storage) | 599 | if (!persistant_swap_storage) |
| 596 | fput(swap_storage); | 600 | fput(swap_storage); |
| 597 | 601 | ||
| 598 | return -ENOMEM; | 602 | return ret; |
| 599 | } | 603 | } |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index ffac157fb5b2..4a3c4e441027 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
| @@ -801,6 +801,7 @@ struct drm_driver { | |||
| 801 | */ | 801 | */ |
| 802 | int (*gem_init_object) (struct drm_gem_object *obj); | 802 | int (*gem_init_object) (struct drm_gem_object *obj); |
| 803 | void (*gem_free_object) (struct drm_gem_object *obj); | 803 | void (*gem_free_object) (struct drm_gem_object *obj); |
| 804 | void (*gem_free_object_unlocked) (struct drm_gem_object *obj); | ||
| 804 | 805 | ||
| 805 | /* vga arb irq handler */ | 806 | /* vga arb irq handler */ |
| 806 | void (*vgaarb_irq)(struct drm_device *dev, bool state); | 807 | void (*vgaarb_irq)(struct drm_device *dev, bool state); |
| @@ -1427,6 +1428,7 @@ extern void drm_sysfs_connector_remove(struct drm_connector *connector); | |||
| 1427 | int drm_gem_init(struct drm_device *dev); | 1428 | int drm_gem_init(struct drm_device *dev); |
| 1428 | void drm_gem_destroy(struct drm_device *dev); | 1429 | void drm_gem_destroy(struct drm_device *dev); |
| 1429 | void drm_gem_object_free(struct kref *kref); | 1430 | void drm_gem_object_free(struct kref *kref); |
| 1431 | void drm_gem_object_free_unlocked(struct kref *kref); | ||
| 1430 | struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, | 1432 | struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, |
| 1431 | size_t size); | 1433 | size_t size); |
| 1432 | void drm_gem_object_handle_free(struct kref *kref); | 1434 | void drm_gem_object_handle_free(struct kref *kref); |
| @@ -1443,10 +1445,15 @@ drm_gem_object_reference(struct drm_gem_object *obj) | |||
| 1443 | static inline void | 1445 | static inline void |
| 1444 | drm_gem_object_unreference(struct drm_gem_object *obj) | 1446 | drm_gem_object_unreference(struct drm_gem_object *obj) |
| 1445 | { | 1447 | { |
| 1446 | if (obj == NULL) | 1448 | if (obj != NULL) |
| 1447 | return; | 1449 | kref_put(&obj->refcount, drm_gem_object_free); |
| 1450 | } | ||
| 1448 | 1451 | ||
| 1449 | kref_put(&obj->refcount, drm_gem_object_free); | 1452 | static inline void |
| 1453 | drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) | ||
| 1454 | { | ||
| 1455 | if (obj != NULL) | ||
| 1456 | kref_put(&obj->refcount, drm_gem_object_free_unlocked); | ||
| 1450 | } | 1457 | } |
| 1451 | 1458 | ||
| 1452 | int drm_gem_handle_create(struct drm_file *file_priv, | 1459 | int drm_gem_handle_create(struct drm_file *file_priv, |
| @@ -1475,6 +1482,21 @@ drm_gem_object_handle_unreference(struct drm_gem_object *obj) | |||
| 1475 | drm_gem_object_unreference(obj); | 1482 | drm_gem_object_unreference(obj); |
| 1476 | } | 1483 | } |
| 1477 | 1484 | ||
| 1485 | static inline void | ||
| 1486 | drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) | ||
| 1487 | { | ||
| 1488 | if (obj == NULL) | ||
| 1489 | return; | ||
| 1490 | |||
| 1491 | /* | ||
| 1492 | * Must bump handle count first as this may be the last | ||
| 1493 | * ref, in which case the object would disappear before we | ||
| 1494 | * checked for a name | ||
| 1495 | */ | ||
| 1496 | kref_put(&obj->handlecount, drm_gem_object_handle_free); | ||
| 1497 | drm_gem_object_unreference_unlocked(obj); | ||
| 1498 | } | ||
| 1499 | |||
| 1478 | struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev, | 1500 | struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev, |
| 1479 | struct drm_file *filp, | 1501 | struct drm_file *filp, |
| 1480 | u32 handle); | 1502 | u32 handle); |
