Message ID | 1375929288-3522-1-git-send-email-imirkin@alum.mit.edu (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Aug 07, 2013 at 10:34:48PM -0400, Ilia Mirkin wrote: > This makes it so that reloading a module does not cause all the > connector ids to change, which are user-visible and sometimes used > for configuration. > > Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> > --- > > v2 -> v3: > - rename ida struct name to... ida. (i'm ready to accept my "creative name > of the year" award.) Seems fine to me. We already have the foo_idr and whatever. > - fix object id leak when allocation fails. > - use ida_simple_get, since it's OK to allocate memory inside kms lock Looks fine to me. Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > drivers/gpu/drm/drm_crtc.c | 62 ++++++++++++++++++++++++++++++++-------------- > drivers/gpu/drm/drm_drv.c | 2 ++ > include/drm/drm_crtc.h | 2 ++ > 3 files changed, 48 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index fc83bb9..a691764 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -186,29 +186,29 @@ static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = { > struct drm_conn_prop_enum_list { > int type; > const char *name; > - int count; > + struct ida ida; > }; > > /* > * Connector and encoder types. > */ > static struct drm_conn_prop_enum_list drm_connector_enum_list[] = > -{ { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 }, > - { DRM_MODE_CONNECTOR_VGA, "VGA", 0 }, > - { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 }, > - { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 }, > - { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 }, > - { DRM_MODE_CONNECTOR_Composite, "Composite", 0 }, > - { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, > - { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, > - { DRM_MODE_CONNECTOR_Component, "Component", 0 }, > - { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 }, > - { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 }, > - { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 }, > - { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, > - { DRM_MODE_CONNECTOR_TV, "TV", 0 }, > - { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, > - { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0}, > +{ { DRM_MODE_CONNECTOR_Unknown, "Unknown" }, > + { DRM_MODE_CONNECTOR_VGA, "VGA" }, > + { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, > + { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, > + { DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, > + { DRM_MODE_CONNECTOR_Composite, "Composite" }, > + { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" }, > + { DRM_MODE_CONNECTOR_LVDS, "LVDS" }, > + { DRM_MODE_CONNECTOR_Component, "Component" }, > + { DRM_MODE_CONNECTOR_9PinDIN, "DIN" }, > + { DRM_MODE_CONNECTOR_DisplayPort, "DP" }, > + { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, > + { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, > + { DRM_MODE_CONNECTOR_TV, "TV" }, > + { DRM_MODE_CONNECTOR_eDP, "eDP" }, > + { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" }, > }; > > static const struct drm_prop_enum_list drm_encoder_enum_list[] = > @@ -220,6 +220,22 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] = > { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, > }; > > +void drm_connector_ida_init(void) > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) > + ida_init(&drm_connector_enum_list[i].ida); > +} > + > +void drm_connector_ida_destroy(void) > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) > + ida_destroy(&drm_connector_enum_list[i].ida); > +} > + > const char *drm_get_encoder_name(const struct drm_encoder *encoder) > { > static char buf[32]; > @@ -711,6 +727,8 @@ int drm_connector_init(struct drm_device *dev, > int connector_type) > { > int ret; > + struct ida *connector_ida = > + &drm_connector_enum_list[connector_type].ida; > > drm_modeset_lock_all(dev); > > @@ -723,7 +741,12 @@ int drm_connector_init(struct drm_device *dev, > connector->funcs = funcs; > connector->connector_type = connector_type; > connector->connector_type_id = > - ++drm_connector_enum_list[connector_type].count; /* TODO */ > + ida_simple_get(connector_ida, 1, 0, GFP_KERNEL); > + if (connector->connector_type_id < 0) { > + ret = connector->connector_type_id; > + drm_mode_object_put(dev, &connector->base); > + goto out; > + } > INIT_LIST_HEAD(&connector->probed_modes); > INIT_LIST_HEAD(&connector->modes); > connector->edid_blob_ptr = NULL; > @@ -764,6 +787,9 @@ void drm_connector_cleanup(struct drm_connector *connector) > list_for_each_entry_safe(mode, t, &connector->modes, head) > drm_mode_remove(connector, mode); > > + ida_remove(&drm_connector_enum_list[connector->connector_type].ida, > + connector->connector_type_id); > + > drm_mode_object_put(dev, &connector->base); > list_del(&connector->head); > dev->mode_config.num_connector--; > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index 99fcd7c..00597a1 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -251,6 +251,7 @@ static int __init drm_core_init(void) > int ret = -ENOMEM; > > drm_global_init(); > + drm_connector_ida_init(); > idr_init(&drm_minors_idr); > > if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) > @@ -298,6 +299,7 @@ static void __exit drm_core_exit(void) > > unregister_chrdev(DRM_MAJOR, "drm"); > > + drm_connector_ida_destroy(); > idr_destroy(&drm_minors_idr); > } > > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index fa12a2f..effee9d 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -869,6 +869,8 @@ extern int drm_crtc_init(struct drm_device *dev, > const struct drm_crtc_funcs *funcs); > extern void drm_crtc_cleanup(struct drm_crtc *crtc); > > +extern void drm_connector_ida_init(void); > +extern void drm_connector_ida_destroy(void); > extern int drm_connector_init(struct drm_device *dev, > struct drm_connector *connector, > const struct drm_connector_funcs *funcs, > -- > 1.8.1.5
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fc83bb9..a691764 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -186,29 +186,29 @@ static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = { struct drm_conn_prop_enum_list { int type; const char *name; - int count; + struct ida ida; }; /* * Connector and encoder types. */ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = -{ { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 }, - { DRM_MODE_CONNECTOR_VGA, "VGA", 0 }, - { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 }, - { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 }, - { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 }, - { DRM_MODE_CONNECTOR_Composite, "Composite", 0 }, - { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, - { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, - { DRM_MODE_CONNECTOR_Component, "Component", 0 }, - { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 }, - { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 }, - { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 }, - { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, - { DRM_MODE_CONNECTOR_TV, "TV", 0 }, - { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, - { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0}, +{ { DRM_MODE_CONNECTOR_Unknown, "Unknown" }, + { DRM_MODE_CONNECTOR_VGA, "VGA" }, + { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, + { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, + { DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, + { DRM_MODE_CONNECTOR_Composite, "Composite" }, + { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" }, + { DRM_MODE_CONNECTOR_LVDS, "LVDS" }, + { DRM_MODE_CONNECTOR_Component, "Component" }, + { DRM_MODE_CONNECTOR_9PinDIN, "DIN" }, + { DRM_MODE_CONNECTOR_DisplayPort, "DP" }, + { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, + { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, + { DRM_MODE_CONNECTOR_TV, "TV" }, + { DRM_MODE_CONNECTOR_eDP, "eDP" }, + { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" }, }; static const struct drm_prop_enum_list drm_encoder_enum_list[] = @@ -220,6 +220,22 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] = { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, }; +void drm_connector_ida_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) + ida_init(&drm_connector_enum_list[i].ida); +} + +void drm_connector_ida_destroy(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) + ida_destroy(&drm_connector_enum_list[i].ida); +} + const char *drm_get_encoder_name(const struct drm_encoder *encoder) { static char buf[32]; @@ -711,6 +727,8 @@ int drm_connector_init(struct drm_device *dev, int connector_type) { int ret; + struct ida *connector_ida = + &drm_connector_enum_list[connector_type].ida; drm_modeset_lock_all(dev); @@ -723,7 +741,12 @@ int drm_connector_init(struct drm_device *dev, connector->funcs = funcs; connector->connector_type = connector_type; connector->connector_type_id = - ++drm_connector_enum_list[connector_type].count; /* TODO */ + ida_simple_get(connector_ida, 1, 0, GFP_KERNEL); + if (connector->connector_type_id < 0) { + ret = connector->connector_type_id; + drm_mode_object_put(dev, &connector->base); + goto out; + } INIT_LIST_HEAD(&connector->probed_modes); INIT_LIST_HEAD(&connector->modes); connector->edid_blob_ptr = NULL; @@ -764,6 +787,9 @@ void drm_connector_cleanup(struct drm_connector *connector) list_for_each_entry_safe(mode, t, &connector->modes, head) drm_mode_remove(connector, mode); + ida_remove(&drm_connector_enum_list[connector->connector_type].ida, + connector->connector_type_id); + drm_mode_object_put(dev, &connector->base); list_del(&connector->head); dev->mode_config.num_connector--; diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 99fcd7c..00597a1 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -251,6 +251,7 @@ static int __init drm_core_init(void) int ret = -ENOMEM; drm_global_init(); + drm_connector_ida_init(); idr_init(&drm_minors_idr); if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) @@ -298,6 +299,7 @@ static void __exit drm_core_exit(void) unregister_chrdev(DRM_MAJOR, "drm"); + drm_connector_ida_destroy(); idr_destroy(&drm_minors_idr); } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index fa12a2f..effee9d 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -869,6 +869,8 @@ extern int drm_crtc_init(struct drm_device *dev, const struct drm_crtc_funcs *funcs); extern void drm_crtc_cleanup(struct drm_crtc *crtc); +extern void drm_connector_ida_init(void); +extern void drm_connector_ida_destroy(void); extern int drm_connector_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs,
This makes it so that reloading a module does not cause all the connector ids to change, which are user-visible and sometimes used for configuration. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> --- v2 -> v3: - rename ida struct name to... ida. (i'm ready to accept my "creative name of the year" award.) - fix object id leak when allocation fails. - use ida_simple_get, since it's OK to allocate memory inside kms lock drivers/gpu/drm/drm_crtc.c | 62 ++++++++++++++++++++++++++++++++-------------- drivers/gpu/drm/drm_drv.c | 2 ++ include/drm/drm_crtc.h | 2 ++ 3 files changed, 48 insertions(+), 18 deletions(-)