diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-04-06 14:39:20 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-04-06 14:39:20 +0000 |
commit | b2bf01fceec9880dbd34e96f7af56a0344712684 (patch) | |
tree | 8f5e889025bc2eb06e6856a5c67baf57b2618dfd /sys/dev/pci/drm | |
parent | ca58bbb32586ae033dfdea3b3fcb3f4357167d5d (diff) |
Another "idr" conversion.
Diffstat (limited to 'sys/dev/pci/drm')
-rw-r--r-- | sys/dev/pci/drm/drm_crtc.c | 111 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_crtc.h | 7 |
2 files changed, 37 insertions, 81 deletions
diff --git a/sys/dev/pci/drm/drm_crtc.c b/sys/dev/pci/drm/drm_crtc.c index fcfa8d638ab..98ab127db10 100644 --- a/sys/dev/pci/drm/drm_crtc.c +++ b/sys/dev/pci/drm/drm_crtc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_crtc.c,v 1.19 2015/09/27 11:09:26 jsg Exp $ */ +/* $OpenBSD: drm_crtc.c,v 1.20 2016/04/06 14:39:19 kettenis Exp $ */ /* * Copyright (c) 2006-2008 Intel Corporation * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> @@ -99,10 +99,6 @@ EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); return "(unknown)"; \ } -int drm_mode_handle_cmp(struct drm_mode_handle *, struct drm_mode_handle *); - -SPLAY_PROTOTYPE(drm_mode_tree, drm_mode_handle, entry, drm_mode_handle_cmp); - /* * Global properties */ @@ -313,27 +309,21 @@ EXPORT_SYMBOL(drm_get_format_name); static int drm_mode_object_get(struct drm_device *dev, struct drm_mode_object *obj, uint32_t obj_type) { - struct drm_mode_handle *han; - int new_id = 0; + int ret; - if ((han = drm_calloc(1, sizeof(*han))) == NULL) - return -ENOMEM; - han->obj = obj; - rw_enter_write(&dev->mode_config.idr_rwl); - -again: - new_id = han->handle = ++dev->mode_config.mode_obj_id; - /* - * Make sure we have no duplicates. this'll hurt once we wrap, 0 is - * reserved. - */ - obj->id = new_id; - obj->type = obj_type; - if (han->handle == 0 || SPLAY_INSERT(drm_mode_tree, - &dev->mode_config.mode_tree, han)) - goto again; - rw_exit_write(&dev->mode_config.idr_rwl); - return 0; + mutex_lock(&dev->mode_config.idr_mutex); + ret = idr_alloc(&dev->mode_config.crtc_idr, obj, 1, 0, GFP_KERNEL); + if (ret >= 0) { + /* + * Set up the object linking under the protection of the idr + * lock so that other users can't see inconsistent state. + */ + obj->id = ret; + obj->type = obj_type; + } + mutex_unlock(&dev->mode_config.idr_mutex); + + return ret < 0 ? ret : 0; } /** @@ -346,13 +336,9 @@ again: static void drm_mode_object_put(struct drm_device *dev, struct drm_mode_object *object) { - struct drm_mode_handle han; - han.obj = object; - han.handle = object->id; - - rw_enter_write(&dev->mode_config.idr_rwl); - SPLAY_REMOVE(drm_mode_tree, &dev->mode_config.mode_tree, &han); - rw_exit_write(&dev->mode_config.idr_rwl); + mutex_lock(&dev->mode_config.idr_mutex); + idr_remove(&dev->mode_config.crtc_idr, object->id); + mutex_unlock(&dev->mode_config.idr_mutex); } /** @@ -368,21 +354,16 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type) { struct drm_mode_object *obj = NULL; - struct drm_mode_handle *han, search; - rw_enter_write(&dev->mode_config.idr_rwl); - search.handle = id; - han = SPLAY_FIND(drm_mode_tree, &dev->mode_config.mode_tree, &search); - if (han == NULL) { - rw_exit_write(&dev->mode_config.idr_rwl); - return NULL; - } - - obj = han->obj; - if (obj->type != type) { + /* Framebuffers are reference counted and need their own lookup + * function.*/ + WARN_ON(type == DRM_MODE_OBJECT_FB); + + mutex_lock(&dev->mode_config.idr_mutex); + obj = idr_find(&dev->mode_config.crtc_idr, id); + if (!obj || (obj->type != type) || (obj->id != id)) obj = NULL; - } - rw_exit_write(&dev->mode_config.idr_rwl); + mutex_unlock(&dev->mode_config.idr_mutex); return obj; } @@ -444,23 +425,15 @@ static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev, uint32_t id) { struct drm_mode_object *obj = NULL; - struct drm_mode_handle *han, search; struct drm_framebuffer *fb; - rw_enter_write(&dev->mode_config.idr_rwl); - search.handle = id; - han = SPLAY_FIND(drm_mode_tree, &dev->mode_config.mode_tree, &search); - if (han == NULL) { - rw_exit_write(&dev->mode_config.idr_rwl); - return NULL; - } - - obj = han->obj; + mutex_lock(&dev->mode_config.idr_mutex); + obj = idr_find(&dev->mode_config.crtc_idr, id); if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id)) fb = NULL; else fb = obj_to_fb(obj); - rw_exit_write(&dev->mode_config.idr_rwl); + mutex_unlock(&dev->mode_config.idr_mutex); return fb; } @@ -528,13 +501,9 @@ static void __drm_framebuffer_unreference(struct drm_framebuffer *fb) static void __drm_framebuffer_unregister(struct drm_device *dev, struct drm_framebuffer *fb) { - struct drm_mode_handle han; - han.obj = &fb->base; - han.handle = fb->base.id; - - rw_enter_write(&dev->mode_config.idr_rwl); - SPLAY_REMOVE(drm_mode_tree, &dev->mode_config.mode_tree, &han); - rw_exit_write(&dev->mode_config.idr_rwl); + mutex_lock(&dev->mode_config.idr_mutex); + idr_remove(&dev->mode_config.crtc_idr, fb->base.id); + mutex_unlock(&dev->mode_config.idr_mutex); fb->base.id = 0; @@ -4089,7 +4058,7 @@ EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); void drm_mode_config_init(struct drm_device *dev) { rw_init(&dev->mode_config.mutex, "mcrwl"); - rw_init(&dev->mode_config.idr_rwl, "idrwl"); + rw_init(&dev->mode_config.idr_mutex, "idrwl"); rw_init(&dev->mode_config.fb_lock, "fblk"); INIT_LIST_HEAD(&dev->mode_config.fb_list); INIT_LIST_HEAD(&dev->mode_config.crtc_list); @@ -4099,7 +4068,7 @@ void drm_mode_config_init(struct drm_device *dev) INIT_LIST_HEAD(&dev->mode_config.property_list); INIT_LIST_HEAD(&dev->mode_config.property_blob_list); INIT_LIST_HEAD(&dev->mode_config.plane_list); - SPLAY_INIT(&dev->mode_config.mode_tree); + idr_init(&dev->mode_config.crtc_idr); drm_modeset_lock_all(dev); drm_mode_create_standard_connector_properties(dev); @@ -4184,18 +4153,6 @@ void drm_mode_config_cleanup(struct drm_device *dev) crtc->funcs->destroy(crtc); } -#ifdef __linux__ idr_destroy(&dev->mode_config.crtc_idr); -#else - /* XXX destroy idr/SPLAY tree */ -#endif } EXPORT_SYMBOL(drm_mode_config_cleanup); - -int -drm_mode_handle_cmp(struct drm_mode_handle *a, struct drm_mode_handle *b) -{ - return a->handle < b->handle ? -1 : a->handle > b->handle; -} - -SPLAY_GENERATE(drm_mode_tree, drm_mode_handle, entry, drm_mode_handle_cmp); diff --git a/sys/dev/pci/drm/drm_crtc.h b/sys/dev/pci/drm/drm_crtc.h index 8b69ab36325..8a6880eb25a 100644 --- a/sys/dev/pci/drm/drm_crtc.h +++ b/sys/dev/pci/drm/drm_crtc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_crtc.h,v 1.6 2015/09/27 11:09:26 jsg Exp $ */ +/* $OpenBSD: drm_crtc.h,v 1.7 2016/04/06 14:39:19 kettenis Exp $ */ /* * Copyright © 2006 Keith Packard * Copyright © 2007-2008 Dave Airlie @@ -837,9 +837,8 @@ struct drm_mode_group { */ struct drm_mode_config { struct rwlock mutex; /* protects configuration (mode lists etc.) */ - struct rwlock idr_rwl; /* for IDR management */ - SPLAY_HEAD(drm_mode_tree, drm_mode_handle) mode_tree; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ - uint32_t mode_obj_id; + struct rwlock idr_mutex; /* for IDR management */ + struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ /* this is limited to one for now */ |