drm/komeda: use devm_drm_dev_alloc

Komeda uses the component framework, which does open/close a new
devres group around all the bind callbacks. Which means we can use
devm_ functions for managing the drm_device cleanup, with leaking
stuff in case of deferred probes or other reasons to unbind
components, or the component_master.

Also note that this fixes a double-free in the probe unroll code, bot
drm_dev_put and kfree(kms) result in the kms allocation getting freed.

Aside: komeda_bind could be cleaned up a lot, devm_kfree is a bit
redundant. Plus I'm not clear on why there's suballocations for
mdrv->mdev and mdrv->kms. Plus I'm not sure the lifetimes are correct
with all that devm_kzalloc usage ... That structure layout is also the
reason why komeda still uses drm_device->dev_private and can't easily
be replaced with a proper container_of upcasting. I'm pretty sure that
there's endless amounts of hotunplug/hotremove bugs in there with all
the unprotected dereferencing of drm_device->dev_private.

Reviewed-by: James Qian Wang <james.qian.wang@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: "James (Qian) Wang" <james.qian.wang@arm.com>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Mihail Atanassov <mihail.atanassov@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200415074034.175360-33-daniel.vetter@ffwll.ch
This commit is contained in:
Daniel Vetter 2020-04-15 09:40:07 +02:00
parent b8d91c0a77
commit 843ef624a4
1 changed files with 5 additions and 11 deletions

View File

@ -261,18 +261,16 @@ static void komeda_kms_mode_config_init(struct komeda_kms_dev *kms,
struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
{
struct komeda_kms_dev *kms = kzalloc(sizeof(*kms), GFP_KERNEL);
struct komeda_kms_dev *kms;
struct drm_device *drm;
int err;
if (!kms)
return ERR_PTR(-ENOMEM);
kms = devm_drm_dev_alloc(mdev->dev, &komeda_kms_driver,
struct komeda_kms_dev, base);
if (IS_ERR(kms))
return kms;
drm = &kms->base;
err = drm_dev_init(drm, &komeda_kms_driver, mdev->dev);
if (err)
goto free_kms;
drmm_add_final_kfree(drm, kms);
drm->dev_private = mdev;
@ -329,9 +327,6 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
drm_mode_config_cleanup(drm);
komeda_kms_cleanup_private_objs(kms);
drm->dev_private = NULL;
drm_dev_put(drm);
free_kms:
kfree(kms);
return ERR_PTR(err);
}
@ -348,5 +343,4 @@ void komeda_kms_detach(struct komeda_kms_dev *kms)
drm_mode_config_cleanup(drm);
komeda_kms_cleanup_private_objs(kms);
drm->dev_private = NULL;
drm_dev_put(drm);
}