drm: create mode_config idr lock

Create a separate mode_config IDR lock for simplicity.  The core DRM
config structures (connector, mode, etc. lists) are still protected by
the mode_config mutex, but the CRTC IDR (used for the various identifier
IDs) is now protected by the mode_config idr_mutex.  Simplifies the
locking a bit and removes a warning.

All objects are protected by the config mutex, we may in the future,
split the object further to have reference counts.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Jesse Barnes 2009-01-19 17:21:45 +10:00 committed by Dave Airlie
parent c1ff85d977
commit ad2563c2e4
2 changed files with 11 additions and 6 deletions

View file

@ -194,7 +194,6 @@ char *drm_get_connector_status_name(enum drm_connector_status status)
* @type: object type * @type: object type
* *
* LOCKING: * LOCKING:
* Caller must hold DRM mode_config lock.
* *
* Create a unique identifier based on @ptr in @dev's identifier space. Used * Create a unique identifier based on @ptr in @dev's identifier space. Used
* for tracking modes, CRTCs and connectors. * for tracking modes, CRTCs and connectors.
@ -209,15 +208,15 @@ static int drm_mode_object_get(struct drm_device *dev,
int new_id = 0; int new_id = 0;
int ret; int ret;
WARN(!mutex_is_locked(&dev->mode_config.mutex),
"%s called w/o mode_config lock\n", __func__);
again: again:
if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) { if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
DRM_ERROR("Ran out memory getting a mode number\n"); DRM_ERROR("Ran out memory getting a mode number\n");
return -EINVAL; return -EINVAL;
} }
mutex_lock(&dev->mode_config.idr_mutex);
ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id); ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
mutex_unlock(&dev->mode_config.idr_mutex);
if (ret == -EAGAIN) if (ret == -EAGAIN)
goto again; goto again;
@ -239,16 +238,20 @@ static int drm_mode_object_get(struct drm_device *dev,
static void drm_mode_object_put(struct drm_device *dev, static void drm_mode_object_put(struct drm_device *dev,
struct drm_mode_object *object) struct drm_mode_object *object)
{ {
mutex_lock(&dev->mode_config.idr_mutex);
idr_remove(&dev->mode_config.crtc_idr, object->id); idr_remove(&dev->mode_config.crtc_idr, object->id);
mutex_unlock(&dev->mode_config.idr_mutex);
} }
void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type) void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
{ {
struct drm_mode_object *obj; struct drm_mode_object *obj = NULL;
mutex_lock(&dev->mode_config.idr_mutex);
obj = idr_find(&dev->mode_config.crtc_idr, id); obj = idr_find(&dev->mode_config.crtc_idr, id);
if (!obj || (obj->type != type) || (obj->id != id)) if (!obj || (obj->type != type) || (obj->id != id))
return NULL; obj = NULL;
mutex_unlock(&dev->mode_config.idr_mutex);
return obj; return obj;
} }
@ -786,6 +789,7 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property);
void drm_mode_config_init(struct drm_device *dev) void drm_mode_config_init(struct drm_device *dev)
{ {
mutex_init(&dev->mode_config.mutex); mutex_init(&dev->mode_config.mutex);
mutex_init(&dev->mode_config.idr_mutex);
INIT_LIST_HEAD(&dev->mode_config.fb_list); INIT_LIST_HEAD(&dev->mode_config.fb_list);
INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list); INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list);
INIT_LIST_HEAD(&dev->mode_config.crtc_list); INIT_LIST_HEAD(&dev->mode_config.crtc_list);

View file

@ -528,7 +528,8 @@ struct drm_mode_group {
* *
*/ */
struct drm_mode_config { struct drm_mode_config {
struct mutex mutex; /* protects configuration and IDR */ struct mutex mutex; /* protects configuration (mode lists etc.) */
struct mutex idr_mutex; /* for IDR management */
struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ 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 */ /* this is limited to one for now */
int num_fb; int num_fb;