drm/tegra: dc: Free syncpoint on errors
PATCH 1/4 drm/tegra: dc: Free syncpoint on errors
From: Thierry Reding <[email protected]>
If an error happens during display controller initialization, the host1x syncpoint previously requested would be leaked. Properly clean up the syncpoint along with the other resources.
--- drivers/gpu/drm/tegra/dc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/tegra/dc.c +2 -0
@@ -1925,6 +1925,8 @@ static int tegra_dc_init(struct host1x_client *client)iommu_group_put (dc->group); } +host1x_syncpt_free (dc->syncpt); +return err; }
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 2/4 drm/tegra: gr2d: Properly clean up resources
From: Thierry Reding <[email protected]>
Failure to register the Tegra DRM client would leak the resources. Move cleanup code to error unwinding gotos to fix that and share the cleanup code with the other error paths.
--- drivers/gpu/drm/tegra/gr2d.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
drivers/gpu/drm/tegra/gr2d.c +22 -6
@@ -42,8 +42,9 @@ static int gr2d_init(struct host1x_client *client) client->syncpts[0 ] =host1x_syncpt_request (client, flags);if (!client->syncpts[0 ]) { -host1x_channel_put (gr2d->channel); -return -ENOMEM ; + err = -ENOMEM ; +dev_err (client->dev,"failed to request syncpoint: %d\n" , err); + goto put; }if (tegra->domain) {
@@ -55,15 +56,30 @@ static int gr2d_init(struct host1x_client *client)dev_err (client->dev,"failed to attach to domain: %d\n" , err); -host1x_syncpt_free (client->syncpts[0 ]); -host1x_channel_put (gr2d->channel);iommu_group_put (gr2d->group); -return err; + goto free; } } } -return tegra_drm_register_client (tegra, drm); + err =tegra_drm_register_client (tegra, drm); +if (err <0 ) { +dev_err (client->dev,"failed to register client: %d\n" , err); + goto detach; + } + +return 0 ; + +detach: +if (gr2d->group) { +iommu_detach_group (tegra->domain, gr2d->group); +iommu_group_put (gr2d->group); + } +free: +host1x_syncpt_free (client->syncpts[0 ]); +put: +host1x_channel_put (gr2d->channel); +return err; }static int gr2d_exit (struct host1x_client *client)
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/4] drm/tegra: gr2d: Properly clean up resources
Quoted 53 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Failure to register the Tegra DRM client would leak the resources. Move cleanup code to error unwinding gotos to fix that and share the cleanup code with the other error paths.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/gr2d.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)drivers/gpu/drm/tegra/gr2d.c +15
-6@@ -42,8 +42,9 @@ static int gr2d_init(struct host1x_client *client) client->syncpts[0 ] =host1x_syncpt_request (client, flags);if (!client->syncpts[0 ]) { -host1x_channel_put (gr2d->channel); -return -ENOMEM ; + err = -ENOMEM ; +dev_err (client->dev,"failed to request syncpoint: %d\n" , err); + goto put; }if (tegra->domain) {@@ -55,15 +56,30 @@ static int gr2d_init(struct host1x_client *client)dev_err (client->dev,"failed to attach to domain: %d\n" , err); -host1x_syncpt_free (client->syncpts[0 ]); -host1x_channel_put (gr2d->channel);iommu_group_put (gr2d->group); -return err; + goto free; } } } -return tegra_drm_register_client (tegra, drm); + err =tegra_drm_register_client (tegra, drm); +if (err <0 ) { +dev_err (client->dev,"failed to register client: %d\n" , err); + goto detach; + } + +return 0 ; + +detach: +if (gr2d->group) { +iommu_detach_group (tegra->domain, gr2d->group);
drivers/gpu/drm/tegra/gr2d.c static int gr2d_init(struct host1x_client *client) · line 85
Quoted 10 lines
drivers/gpu/drm/tegra/gr2d.c +7
-0+iommu_group_put (gr2d->group); + } +free: +host1x_syncpt_free (client->syncpts[0 ]); +put: +host1x_channel_put (gr2d->channel); +return err; }static int gr2d_exit (struct host1x_client *client)
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/4] drm/tegra: gr2d: Properly clean up resources
In reply to Thierry RedingQuoted 16 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Failure to register the Tegra DRM client would leak the resources. Move cleanup code to error unwinding gotos to fix that and share the cleanup code with the other error paths.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/gr2d.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)drivers/gpu/drm/tegra/gr2d.c +0
-0
drivers/gpu/drm/tegra/gr2d.c static int gr2d_init(struct host1x_client *client) · line 46
Quoted 7 lines
drivers/gpu/drm/tegra/gr2d.c +2
-2@@ -42,8 +42,9 @@ static int gr2d_init(struct host1x_client *client) client->syncpts[0 ] =host1x_syncpt_request (client, flags);if (!client->syncpts[0 ]) { -host1x_channel_put (gr2d->channel); -return -ENOMEM ; + err = -ENOMEM ; +dev_err (client->dev,"failed to request syncpoint: %d\n" , err);
Nit: You could add the same error message to the gr3d patch for consistency.
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 3/4 drm/tegra: gr3d: Properly clean up resources
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
Failure to register the Tegra DRM client would leak the resources. Move cleanup code to error unwinding gotos to fix that and share the cleanup code with the other error paths.
--- drivers/gpu/drm/tegra/gr3d.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-)
drivers/gpu/drm/tegra/gr3d.c +21 -6
@@ -52,8 +52,8 @@ static int gr3d_init(struct host1x_client *client) client->syncpts[0 ] =host1x_syncpt_request (client, flags);if (!client->syncpts[0 ]) { -host1x_channel_put (gr3d->channel); -return -ENOMEM ; + err = -ENOMEM ; + goto put; }if (tegra->domain) {
@@ -65,15 +65,30 @@ static int gr3d_init(struct host1x_client *client)dev_err (client->dev,"failed to attach to domain: %d\n" , err); -host1x_syncpt_free (client->syncpts[0 ]); -host1x_channel_put (gr3d->channel);iommu_group_put (gr3d->group); -return err; + goto free; } } } -return tegra_drm_register_client (dev->dev_private, drm); + err =tegra_drm_register_client (dev->dev_private, drm); +if (err <0 ) { +dev_err (client->dev,"failed to register client: %d\n" , err); + goto detach; + } + +return 0 ; + +detach: +if (gr3d->group) { +iommu_detach_group (tegra->domain, gr3d->group); +iommu_group_put (gr3d->group); + } +free: +host1x_syncpt_free (client->syncpts[0 ]); +put: +host1x_channel_put (gr3d->channel); +return err; }static int gr3d_exit (struct host1x_client *client)
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/4] drm/tegra: gr3d: Properly clean up resources
Quoted 52 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Failure to register the Tegra DRM client would leak the resources. Move cleanup code to error unwinding gotos to fix that and share the cleanup code with the other error paths.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/gr3d.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-)drivers/gpu/drm/tegra/gr3d.c +14
-6@@ -52,8 +52,8 @@ static int gr3d_init(struct host1x_client *client) client->syncpts[0 ] =host1x_syncpt_request (client, flags);if (!client->syncpts[0 ]) { -host1x_channel_put (gr3d->channel); -return -ENOMEM ; + err = -ENOMEM ; + goto put; }if (tegra->domain) {@@ -65,15 +65,30 @@ static int gr3d_init(struct host1x_client *client)dev_err (client->dev,"failed to attach to domain: %d\n" , err); -host1x_syncpt_free (client->syncpts[0 ]); -host1x_channel_put (gr3d->channel);iommu_group_put (gr3d->group); -return err; + goto free; } } } -return tegra_drm_register_client (dev->dev_private, drm); + err =tegra_drm_register_client (dev->dev_private, drm); +if (err <0 ) { +dev_err (client->dev,"failed to register client: %d\n" , err); + goto detach; + } + +return 0 ; + +detach: +if (gr3d->group) { +iommu_detach_group (tegra->domain, gr3d->group);
drivers/gpu/drm/tegra/gr3d.c static int gr3d_init(struct host1x_client *client) · line 94
Quoted 10 lines
drivers/gpu/drm/tegra/gr3d.c +7
-0+iommu_group_put (gr3d->group); + } +free: +host1x_syncpt_free (client->syncpts[0 ]); +put: +host1x_channel_put (gr3d->channel); +return err; }static int gr3d_exit (struct host1x_client *client)
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 4/4 drm/tegra: Refactor IOMMU attach/detach
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
Attaching to and detaching from an IOMMU uses the same code sequence in every driver, so factor it out into separate helpers.
--- drivers/gpu/drm/tegra/dc.c | 42 ++++++------------------------------ drivers/gpu/drm/tegra/drm.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 4 ++++ drivers/gpu/drm/tegra/gr2d.c | 32 +++++++-------------------- drivers/gpu/drm/tegra/gr3d.c | 31 ++++++-------------------- 5 files changed, 68 insertions(+), 83 deletions(-)
drivers/gpu/drm/tegra/dc.c +7 -35
@@ -1837,21 +1837,11 @@ static int tegra_dc_init(struct host1x_client *client)if (!dc->syncpt)dev_warn (dc->dev,"failed to allocate syncpoint\n" ); -if (tegra->domain) { - dc->group =iommu_group_get (client->dev); - -if (dc->group && dc->group != tegra->group) { - err =iommu_attach_group (tegra->domain, dc->group); -if (err <0 ) { -dev_err (dc->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (dc->group); -return err; - } - - tegra->group = dc->group; - } + dc->group =host1x_client_iommu_attach (client, true); +if (IS_ERR (dc->group)) { + err =PTR_ERR (dc->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); +return err; }if (dc->soc->wgrps)
@@ -1916,15 +1906,7 @@ static int tegra_dc_init(struct host1x_client *client)if (!IS_ERR (primary))drm_plane_cleanup (primary); -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return err;
@@ -1932,9 +1914,7 @@ static int tegra_dc_init(struct host1x_client *client)static int tegra_dc_exit (struct host1x_client *client) { -struct drm_device *drm =dev_get_drvdata (client->parent);struct tegra_dc *dc =host1x_client_to_dc (client); -struct tegra_drm *tegra = drm->dev_private;int err;devm_free_irq (dc->dev, dc->irq, dc);
@@ -1945,15 +1925,7 @@ static int tegra_dc_exit(struct host1x_client *client)return err; } -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return 0 ;
drivers/gpu/drm/tegra/drm.c +42 -0
48 lines not on this page · raw message
drivers/gpu/drm/tegra/drm.h +4 -0
@@ -110,6 +110,10 @@ int tegra_drm_register_client(struct tegra_drm *tegra, struct tegra_drm_client *client);int tegra_drm_unregister_client (struct tegra_drm *tegra,struct tegra_drm_client *client); +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared); +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group);int tegra_drm_init (struct tegra_drm *tegra,struct drm_device *drm);int tegra_drm_exit (struct tegra_drm *tegra);
drivers/gpu/drm/tegra/gr2d.c +8 -24
@@ -32,7 +32,6 @@ static int gr2d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr2d *gr2d =to_gr2d (drm);int err;
@@ -47,22 +46,14 @@ static int gr2d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr2d->group =iommu_group_get (client->dev); - -if (gr2d->group) { - err =iommu_attach_group (tegra->domain, gr2d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr2d->group); - goto free; - } - } + gr2d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr2d->group)) { + err =PTR_ERR (gr2d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } - err =tegra_drm_register_client (tegra, drm); + err =tegra_drm_register_client (dev->dev_private, drm);if (err <0 ) {dev_err (client->dev,"failed to register client: %d\n" , err); goto detach;
@@ -71,10 +62,7 @@ static int gr2d_init(struct host1x_client *client)return 0 ; detach: -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } +host1x_client_iommu_detach (client, gr2d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:
@@ -94,14 +82,10 @@ static int gr2d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr2d->group);host1x_syncpt_free (client->syncpts[0 ]);host1x_channel_put (gr2d->channel); -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } -return 0 ; }
drivers/gpu/drm/tegra/gr3d.c +7 -24
@@ -42,7 +42,6 @@ static int gr3d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;
@@ -56,19 +55,11 @@ static int gr3d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr3d->group =iommu_group_get (client->dev); - -if (gr3d->group) { - err =iommu_attach_group (tegra->domain, gr3d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr3d->group); - goto free; - } - } + gr3d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr3d->group)) { + err =PTR_ERR (gr3d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } err =tegra_drm_register_client (dev->dev_private, drm);
@@ -80,10 +71,7 @@ static int gr3d_init(struct host1x_client *client)return 0 ; detach: -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } +host1x_client_iommu_detach (client, gr3d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:
@@ -95,7 +83,6 @@ static int gr3d_exit(struct host1x_client *client) {struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent); -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;
@@ -103,14 +90,10 @@ static int gr3d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr3d->group);host1x_syncpt_free (client->syncpts[0 ]);host1x_channel_put (gr3d->channel); -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } -return 0 ; }
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 4/4] drm/tegra: Refactor IOMMU attach/detach
Quoted 290 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Attaching to and detaching from an IOMMU uses the same code sequence in every driver, so factor it out into separate helpers.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 42 ++++++------------------------------ drivers/gpu/drm/tegra/drm.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 4 ++++ drivers/gpu/drm/tegra/gr2d.c | 32 +++++++-------------------- drivers/gpu/drm/tegra/gr3d.c | 31 ++++++-------------------- 5 files changed, 68 insertions(+), 83 deletions(-)drivers/gpu/drm/tegra/dc.c +7
-35@@ -1837,21 +1837,11 @@ static int tegra_dc_init(struct host1x_client *client)if (!dc->syncpt)dev_warn (dc->dev,"failed to allocate syncpoint\n" ); -if (tegra->domain) { - dc->group =iommu_group_get (client->dev); - -if (dc->group && dc->group != tegra->group) { - err =iommu_attach_group (tegra->domain, dc->group); -if (err <0 ) { -dev_err (dc->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (dc->group); -return err; - } - - tegra->group = dc->group; - } + dc->group =host1x_client_iommu_attach (client, true); +if (IS_ERR (dc->group)) { + err =PTR_ERR (dc->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); +return err; }if (dc->soc->wgrps)@@ -1916,15 +1906,7 @@ static int tegra_dc_init(struct host1x_client *client)if (!IS_ERR (primary))drm_plane_cleanup (primary); -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return err;@@ -1932,9 +1914,7 @@ static int tegra_dc_init(struct host1x_client *client)static int tegra_dc_exit (struct host1x_client *client) { -struct drm_device *drm =dev_get_drvdata (client->parent);struct tegra_dc *dc =host1x_client_to_dc (client); -struct tegra_drm *tegra = drm->dev_private;int err;devm_free_irq (dc->dev, dc->irq, dc);@@ -1945,15 +1925,7 @@ static int tegra_dc_exit(struct host1x_client *client)return err; } -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return 0 ;drivers/gpu/drm/tegra/drm.c +42
-0@@ -1114,6 +1114,48 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra,return 0 ; } +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; +struct iommu_group *group =NULL ; +int err; + +if (tegra->domain) { + group =iommu_group_get (client->dev); + +if (group && (!shared || (shared && (group != tegra->group)))) { + err =iommu_attach_group (tegra->domain, group); +if (err <0 ) { +iommu_group_put (group); +return ERR_PTR (err); + } + +if (shared && !tegra->group) + tegra->group = group; + } + } + +return group; +} + +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; + +if (group) { +if (group == tegra->group) { +iommu_detach_group (tegra->domain, group); + tegra->group =NULL ; + } + +iommu_group_put (group); + } +} +void *tegra_drm_alloc (struct tegra_drm *tegra,size_t size,dma_addr_t *dma) {struct iova *alloc;drivers/gpu/drm/tegra/drm.h +4
-0@@ -110,6 +110,10 @@ int tegra_drm_register_client(struct tegra_drm *tegra, struct tegra_drm_client *client);int tegra_drm_unregister_client (struct tegra_drm *tegra,struct tegra_drm_client *client); +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared); +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group);int tegra_drm_init (struct tegra_drm *tegra,struct drm_device *drm);int tegra_drm_exit (struct tegra_drm *tegra);drivers/gpu/drm/tegra/gr2d.c +8
-24@@ -32,7 +32,6 @@ static int gr2d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr2d *gr2d =to_gr2d (drm);int err;@@ -47,22 +46,14 @@ static int gr2d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr2d->group =iommu_group_get (client->dev); - -if (gr2d->group) { - err =iommu_attach_group (tegra->domain, gr2d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr2d->group); - goto free; - } - } + gr2d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr2d->group)) { + err =PTR_ERR (gr2d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } - err =tegra_drm_register_client (tegra, drm); + err =tegra_drm_register_client (dev->dev_private, drm);if (err <0 ) {dev_err (client->dev,"failed to register client: %d\n" , err); goto detach;@@ -71,10 +62,7 @@ static int gr2d_init(struct host1x_client *client)return 0 ; detach: -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } +host1x_client_iommu_detach (client, gr2d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -94,14 +82,10 @@ static int gr2d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr2d->group);host1x_syncpt_free (client->syncpts[0 ]);host1x_channel_put (gr2d->channel); -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } -return 0 ; }drivers/gpu/drm/tegra/gr3d.c +7
-19@@ -42,7 +42,6 @@ static int gr3d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -56,19 +55,11 @@ static int gr3d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr3d->group =iommu_group_get (client->dev); - -if (gr3d->group) { - err =iommu_attach_group (tegra->domain, gr3d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr3d->group); - goto free; - } - } + gr3d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr3d->group)) { + err =PTR_ERR (gr3d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } err =tegra_drm_register_client (dev->dev_private, drm);@@ -80,10 +71,7 @@ static int gr3d_init(struct host1x_client *client)return 0 ; detach: -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } +host1x_client_iommu_detach (client, gr3d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -95,7 +83,6 @@ static int gr3d_exit(struct host1x_client *client) {struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent); -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -103,14 +90,10 @@ static int gr3d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr3d->group);host1x_syncpt_free (client->syncpts[0 ]);
drivers/gpu/drm/tegra/gr3d.c static int gr3d_exit(struct host1x_client *client) · line 99
Quoted 10 lines
drivers/gpu/drm/tegra/gr3d.c +0
-5host1x_channel_put (gr3d->channel); -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } -return 0 ; }
Though I'd prefer to have tegra->group renamed, maybe to 'shared_dc_group'.
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 4/4] drm/tegra: Refactor IOMMU attach/detach
Quoted 304 lines · Dmitry Osipenko
Quoted 290 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Attaching to and detaching from an IOMMU uses the same code sequence in every driver, so factor it out into separate helpers.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 42 ++++++------------------------------ drivers/gpu/drm/tegra/drm.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 4 ++++ drivers/gpu/drm/tegra/gr2d.c | 32 +++++++-------------------- drivers/gpu/drm/tegra/gr3d.c | 31 ++++++-------------------- 5 files changed, 68 insertions(+), 83 deletions(-)drivers/gpu/drm/tegra/dc.c +7
-35@@ -1837,21 +1837,11 @@ static int tegra_dc_init(struct host1x_client *client)if (!dc->syncpt)dev_warn (dc->dev,"failed to allocate syncpoint\n" ); -if (tegra->domain) { - dc->group =iommu_group_get (client->dev); - -if (dc->group && dc->group != tegra->group) { - err =iommu_attach_group (tegra->domain, dc->group); -if (err <0 ) { -dev_err (dc->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (dc->group); -return err; - } - - tegra->group = dc->group; - } + dc->group =host1x_client_iommu_attach (client, true); +if (IS_ERR (dc->group)) { + err =PTR_ERR (dc->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); +return err; }if (dc->soc->wgrps)@@ -1916,15 +1906,7 @@ static int tegra_dc_init(struct host1x_client *client)if (!IS_ERR (primary))drm_plane_cleanup (primary); -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return err;@@ -1932,9 +1914,7 @@ static int tegra_dc_init(struct host1x_client *client)static int tegra_dc_exit (struct host1x_client *client) { -struct drm_device *drm =dev_get_drvdata (client->parent);struct tegra_dc *dc =host1x_client_to_dc (client); -struct tegra_drm *tegra = drm->dev_private;int err;devm_free_irq (dc->dev, dc->irq, dc);@@ -1945,15 +1925,7 @@ static int tegra_dc_exit(struct host1x_client *client)return err; } -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return 0 ;drivers/gpu/drm/tegra/drm.c +42
-0@@ -1114,6 +1114,48 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra,return 0 ; } +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; +struct iommu_group *group =NULL ; +int err; + +if (tegra->domain) { + group =iommu_group_get (client->dev); + +if (group && (!shared || (shared && (group != tegra->group)))) { + err =iommu_attach_group (tegra->domain, group); +if (err <0 ) { +iommu_group_put (group); +return ERR_PTR (err); + } + +if (shared && !tegra->group) + tegra->group = group; + } + } + +return group; +} + +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; + +if (group) { +if (group == tegra->group) { +iommu_detach_group (tegra->domain, group); + tegra->group =NULL ; + } + +iommu_group_put (group); + } +} +void *tegra_drm_alloc (struct tegra_drm *tegra,size_t size,dma_addr_t *dma) {struct iova *alloc;drivers/gpu/drm/tegra/drm.h +4
-0@@ -110,6 +110,10 @@ int tegra_drm_register_client(struct tegra_drm *tegra, struct tegra_drm_client *client);int tegra_drm_unregister_client (struct tegra_drm *tegra,struct tegra_drm_client *client); +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared); +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group);int tegra_drm_init (struct tegra_drm *tegra,struct drm_device *drm);int tegra_drm_exit (struct tegra_drm *tegra);drivers/gpu/drm/tegra/gr2d.c +8
-24@@ -32,7 +32,6 @@ static int gr2d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr2d *gr2d =to_gr2d (drm);int err;@@ -47,22 +46,14 @@ static int gr2d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr2d->group =iommu_group_get (client->dev); - -if (gr2d->group) { - err =iommu_attach_group (tegra->domain, gr2d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr2d->group); - goto free; - } - } + gr2d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr2d->group)) { + err =PTR_ERR (gr2d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } - err =tegra_drm_register_client (tegra, drm); + err =tegra_drm_register_client (dev->dev_private, drm);if (err <0 ) {dev_err (client->dev,"failed to register client: %d\n" , err); goto detach;@@ -71,10 +62,7 @@ static int gr2d_init(struct host1x_client *client)return 0 ; detach: -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } +host1x_client_iommu_detach (client, gr2d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -94,14 +82,10 @@ static int gr2d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr2d->group);host1x_syncpt_free (client->syncpts[0 ]);host1x_channel_put (gr2d->channel); -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } -return 0 ; }drivers/gpu/drm/tegra/gr3d.c +7
-19@@ -42,7 +42,6 @@ static int gr3d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -56,19 +55,11 @@ static int gr3d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr3d->group =iommu_group_get (client->dev); - -if (gr3d->group) { - err =iommu_attach_group (tegra->domain, gr3d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr3d->group); - goto free; - } - } + gr3d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr3d->group)) { + err =PTR_ERR (gr3d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } err =tegra_drm_register_client (dev->dev_private, drm);@@ -80,10 +71,7 @@ static int gr3d_init(struct host1x_client *client)return 0 ; detach: -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } +host1x_client_iommu_detach (client, gr3d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -95,7 +83,6 @@ static int gr3d_exit(struct host1x_client *client) {struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent); -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -103,14 +90,10 @@ static int gr3d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr3d->group);host1x_syncpt_free (client->syncpts[0 ]);drivers/gpu/drm/tegra/gr3d.c static int gr3d_exit(struct host1x_client *client) · line 99
Quoted 10 lines
drivers/gpu/drm/tegra/gr3d.c +0
-5host1x_channel_put (gr3d->channel); -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } -return 0 ; }Reviewed-by Dmitry Osipenko <[email protected]>
Quoted 1 line
Though I'd prefer to have
tegra->grouprenamed, maybe to 'shared_dc_group'.
tegra->group doesn't bother me at all. I think just the fact that it's in struct tegra_drm implies that it is shared. It's also declared closely to all the other "shared" variables, so I think that makes it pretty clear. If there were other IOMMU groups I'd agree that renaming it would be good to clarify the purpose. But as it is, I think there's no need for that.
Thanks for the review!
Thierry
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 4/4] drm/tegra: Refactor IOMMU attach/detach
Quoted 307 lines · Thierry Reding
Quoted 304 lines · Dmitry Osipenko
Quoted 290 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Attaching to and detaching from an IOMMU uses the same code sequence in every driver, so factor it out into separate helpers.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 42 ++++++------------------------------ drivers/gpu/drm/tegra/drm.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 4 ++++ drivers/gpu/drm/tegra/gr2d.c | 32 +++++++-------------------- drivers/gpu/drm/tegra/gr3d.c | 31 ++++++-------------------- 5 files changed, 68 insertions(+), 83 deletions(-)drivers/gpu/drm/tegra/dc.c +7
-35@@ -1837,21 +1837,11 @@ static int tegra_dc_init(struct host1x_client *client)if (!dc->syncpt)dev_warn (dc->dev,"failed to allocate syncpoint\n" ); -if (tegra->domain) { - dc->group =iommu_group_get (client->dev); - -if (dc->group && dc->group != tegra->group) { - err =iommu_attach_group (tegra->domain, dc->group); -if (err <0 ) { -dev_err (dc->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (dc->group); -return err; - } - - tegra->group = dc->group; - } + dc->group =host1x_client_iommu_attach (client, true); +if (IS_ERR (dc->group)) { + err =PTR_ERR (dc->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); +return err; }if (dc->soc->wgrps)@@ -1916,15 +1906,7 @@ static int tegra_dc_init(struct host1x_client *client)if (!IS_ERR (primary))drm_plane_cleanup (primary); -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return err;@@ -1932,9 +1914,7 @@ static int tegra_dc_init(struct host1x_client *client)static int tegra_dc_exit (struct host1x_client *client) { -struct drm_device *drm =dev_get_drvdata (client->parent);struct tegra_dc *dc =host1x_client_to_dc (client); -struct tegra_drm *tegra = drm->dev_private;int err;devm_free_irq (dc->dev, dc->irq, dc);@@ -1945,15 +1925,7 @@ static int tegra_dc_exit(struct host1x_client *client)return err; } -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return 0 ;drivers/gpu/drm/tegra/drm.c +42
-0@@ -1114,6 +1114,48 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra,return 0 ; } +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; +struct iommu_group *group =NULL ; +int err; + +if (tegra->domain) { + group =iommu_group_get (client->dev); + +if (group && (!shared || (shared && (group != tegra->group)))) { + err =iommu_attach_group (tegra->domain, group); +if (err <0 ) { +iommu_group_put (group); +return ERR_PTR (err); + } + +if (shared && !tegra->group) + tegra->group = group; + } + } + +return group; +} + +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; + +if (group) { +if (group == tegra->group) { +iommu_detach_group (tegra->domain, group); + tegra->group =NULL ; + } + +iommu_group_put (group); + } +} +void *tegra_drm_alloc (struct tegra_drm *tegra,size_t size,dma_addr_t *dma) {struct iova *alloc;drivers/gpu/drm/tegra/drm.h +4
-0@@ -110,6 +110,10 @@ int tegra_drm_register_client(struct tegra_drm *tegra, struct tegra_drm_client *client);int tegra_drm_unregister_client (struct tegra_drm *tegra,struct tegra_drm_client *client); +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared); +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group);int tegra_drm_init (struct tegra_drm *tegra,struct drm_device *drm);int tegra_drm_exit (struct tegra_drm *tegra);drivers/gpu/drm/tegra/gr2d.c +8
-24@@ -32,7 +32,6 @@ static int gr2d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr2d *gr2d =to_gr2d (drm);int err;@@ -47,22 +46,14 @@ static int gr2d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr2d->group =iommu_group_get (client->dev); - -if (gr2d->group) { - err =iommu_attach_group (tegra->domain, gr2d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr2d->group); - goto free; - } - } + gr2d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr2d->group)) { + err =PTR_ERR (gr2d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } - err =tegra_drm_register_client (tegra, drm); + err =tegra_drm_register_client (dev->dev_private, drm);if (err <0 ) {dev_err (client->dev,"failed to register client: %d\n" , err); goto detach;@@ -71,10 +62,7 @@ static int gr2d_init(struct host1x_client *client)return 0 ; detach: -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } +host1x_client_iommu_detach (client, gr2d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -94,14 +82,10 @@ static int gr2d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr2d->group);host1x_syncpt_free (client->syncpts[0 ]);host1x_channel_put (gr2d->channel); -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } -return 0 ; }drivers/gpu/drm/tegra/gr3d.c +7
-19@@ -42,7 +42,6 @@ static int gr3d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -56,19 +55,11 @@ static int gr3d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr3d->group =iommu_group_get (client->dev); - -if (gr3d->group) { - err =iommu_attach_group (tegra->domain, gr3d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr3d->group); - goto free; - } - } + gr3d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr3d->group)) { + err =PTR_ERR (gr3d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } err =tegra_drm_register_client (dev->dev_private, drm);@@ -80,10 +71,7 @@ static int gr3d_init(struct host1x_client *client)return 0 ; detach: -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } +host1x_client_iommu_detach (client, gr3d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -95,7 +83,6 @@ static int gr3d_exit(struct host1x_client *client) {struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent); -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -103,14 +90,10 @@ static int gr3d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr3d->group);host1x_syncpt_free (client->syncpts[0 ]);drivers/gpu/drm/tegra/gr3d.c static int gr3d_exit(struct host1x_client *client) · line 99
Quoted 10 lines
drivers/gpu/drm/tegra/gr3d.c +0
-5host1x_channel_put (gr3d->channel); -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } -return 0 ; }Reviewed-by Dmitry Osipenko <[email protected]>Quoted 1 line
Though I'd prefer to have
tegra->grouprenamed, maybe to 'shared_dc_group'.
Quoted 8 lines
tegra->groupdoesn't bother me at all. I think just the fact that it's in structtegra_drmimplies that it is shared. It's also declared closely to all the other "shared" variables, so I think that makes it pretty clear. If there were other IOMMU groups I'd agree that renaming it would be good to clarify the purpose. But as it is, I think there's no need for that.Thanks for the review!
Well, okay. On the other hand IOMMU API should handle re-attaching from a different device and then that shared group isn't needed at all. Does that re-attaching cause any problems right now? If yes, maybe it's worth fixing the root of the problem rather than trying to workaround it.
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 4/4] drm/tegra: Refactor IOMMU attach/detach
Quoted 315 lines · Dmitry Osipenko
Quoted 314 lines · Thierry Reding
Quoted 304 lines · Dmitry Osipenko
Quoted 290 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Attaching to and detaching from an IOMMU uses the same code sequence in every driver, so factor it out into separate helpers.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 42 ++++++------------------------------ drivers/gpu/drm/tegra/drm.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 4 ++++ drivers/gpu/drm/tegra/gr2d.c | 32 +++++++-------------------- drivers/gpu/drm/tegra/gr3d.c | 31 ++++++-------------------- 5 files changed, 68 insertions(+), 83 deletions(-)drivers/gpu/drm/tegra/dc.c +7
-35@@ -1837,21 +1837,11 @@ static int tegra_dc_init(struct host1x_client *client)if (!dc->syncpt)dev_warn (dc->dev,"failed to allocate syncpoint\n" ); -if (tegra->domain) { - dc->group =iommu_group_get (client->dev); - -if (dc->group && dc->group != tegra->group) { - err =iommu_attach_group (tegra->domain, dc->group); -if (err <0 ) { -dev_err (dc->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (dc->group); -return err; - } - - tegra->group = dc->group; - } + dc->group =host1x_client_iommu_attach (client, true); +if (IS_ERR (dc->group)) { + err =PTR_ERR (dc->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); +return err; }if (dc->soc->wgrps)@@ -1916,15 +1906,7 @@ static int tegra_dc_init(struct host1x_client *client)if (!IS_ERR (primary))drm_plane_cleanup (primary); -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return err;@@ -1932,9 +1914,7 @@ static int tegra_dc_init(struct host1x_client *client)static int tegra_dc_exit (struct host1x_client *client) { -struct drm_device *drm =dev_get_drvdata (client->parent);struct tegra_dc *dc =host1x_client_to_dc (client); -struct tegra_drm *tegra = drm->dev_private;int err;devm_free_irq (dc->dev, dc->irq, dc);@@ -1945,15 +1925,7 @@ static int tegra_dc_exit(struct host1x_client *client)return err; } -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return 0 ;drivers/gpu/drm/tegra/drm.c +42
-0@@ -1114,6 +1114,48 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra,return 0 ; } +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; +struct iommu_group *group =NULL ; +int err; + +if (tegra->domain) { + group =iommu_group_get (client->dev); + +if (group && (!shared || (shared && (group != tegra->group)))) { + err =iommu_attach_group (tegra->domain, group); +if (err <0 ) { +iommu_group_put (group); +return ERR_PTR (err); + } + +if (shared && !tegra->group) + tegra->group = group; + } + } + +return group; +} + +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; + +if (group) { +if (group == tegra->group) { +iommu_detach_group (tegra->domain, group); + tegra->group =NULL ; + } + +iommu_group_put (group); + } +} +void *tegra_drm_alloc (struct tegra_drm *tegra,size_t size,dma_addr_t *dma) {struct iova *alloc;drivers/gpu/drm/tegra/drm.h +4
-0@@ -110,6 +110,10 @@ int tegra_drm_register_client(struct tegra_drm *tegra, struct tegra_drm_client *client);int tegra_drm_unregister_client (struct tegra_drm *tegra,struct tegra_drm_client *client); +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared); +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group);int tegra_drm_init (struct tegra_drm *tegra,struct drm_device *drm);int tegra_drm_exit (struct tegra_drm *tegra);drivers/gpu/drm/tegra/gr2d.c +8
-24@@ -32,7 +32,6 @@ static int gr2d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr2d *gr2d =to_gr2d (drm);int err;@@ -47,22 +46,14 @@ static int gr2d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr2d->group =iommu_group_get (client->dev); - -if (gr2d->group) { - err =iommu_attach_group (tegra->domain, gr2d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr2d->group); - goto free; - } - } + gr2d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr2d->group)) { + err =PTR_ERR (gr2d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } - err =tegra_drm_register_client (tegra, drm); + err =tegra_drm_register_client (dev->dev_private, drm);if (err <0 ) {dev_err (client->dev,"failed to register client: %d\n" , err); goto detach;@@ -71,10 +62,7 @@ static int gr2d_init(struct host1x_client *client)return 0 ; detach: -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } +host1x_client_iommu_detach (client, gr2d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -94,14 +82,10 @@ static int gr2d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr2d->group);host1x_syncpt_free (client->syncpts[0 ]);host1x_channel_put (gr2d->channel); -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } -return 0 ; }drivers/gpu/drm/tegra/gr3d.c +7
-19@@ -42,7 +42,6 @@ static int gr3d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -56,19 +55,11 @@ static int gr3d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr3d->group =iommu_group_get (client->dev); - -if (gr3d->group) { - err =iommu_attach_group (tegra->domain, gr3d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr3d->group); - goto free; - } - } + gr3d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr3d->group)) { + err =PTR_ERR (gr3d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } err =tegra_drm_register_client (dev->dev_private, drm);@@ -80,10 +71,7 @@ static int gr3d_init(struct host1x_client *client)return 0 ; detach: -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } +host1x_client_iommu_detach (client, gr3d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -95,7 +83,6 @@ static int gr3d_exit(struct host1x_client *client) {struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent); -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -103,14 +90,10 @@ static int gr3d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr3d->group);host1x_syncpt_free (client->syncpts[0 ]);drivers/gpu/drm/tegra/gr3d.c static int gr3d_exit(struct host1x_client *client) · line 99
Quoted 10 lines
drivers/gpu/drm/tegra/gr3d.c +0
-5host1x_channel_put (gr3d->channel); -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } -return 0 ; }Reviewed-by Dmitry Osipenko <[email protected]>Quoted 1 line
Though I'd prefer to have
tegra->grouprenamed, maybe to 'shared_dc_group'.
tegra->groupdoesn't bother me at all. I think just the fact that it's in structtegra_drmimplies that it is shared. It's also declared closely to all the other "shared" variables, so I think that makes it pretty clear. If there were other IOMMU groups I'd agree that renaming it would be good to clarify the purpose. But as it is, I think there's no need for that.
Quoted 6 lines
Quoted 1 line
Thanks for the review!
Well, okay. On the other hand IOMMU API should handle re-attaching from a different device and then that shared group isn't needed at all. Does that re-attaching cause any problems right now? If yes, maybe it's worth fixing the root of the problem rather than trying to workaround it.
Agreed. I've got that on my TODO list somewhere, let me bump that up a little.
Thierry
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 4/4] drm/tegra: Refactor IOMMU attach/detach
In reply to Thierry RedingQuoted 107 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Attaching to and detaching from an IOMMU uses the same code sequence in every driver, so factor it out into separate helpers.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 42 ++++++------------------------------ drivers/gpu/drm/tegra/drm.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 4 ++++ drivers/gpu/drm/tegra/gr2d.c | 32 +++++++-------------------- drivers/gpu/drm/tegra/gr3d.c | 31 ++++++-------------------- 5 files changed, 68 insertions(+), 83 deletions(-)drivers/gpu/drm/tegra/dc.c +7
-35@@ -1837,21 +1837,11 @@ static int tegra_dc_init(struct host1x_client *client)if (!dc->syncpt)dev_warn (dc->dev,"failed to allocate syncpoint\n" ); -if (tegra->domain) { - dc->group =iommu_group_get (client->dev); - -if (dc->group && dc->group != tegra->group) { - err =iommu_attach_group (tegra->domain, dc->group); -if (err <0 ) { -dev_err (dc->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (dc->group); -return err; - } - - tegra->group = dc->group; - } + dc->group =host1x_client_iommu_attach (client, true); +if (IS_ERR (dc->group)) { + err =PTR_ERR (dc->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); +return err; }if (dc->soc->wgrps)@@ -1916,15 +1906,7 @@ static int tegra_dc_init(struct host1x_client *client)if (!IS_ERR (primary))drm_plane_cleanup (primary); -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return err;@@ -1932,9 +1914,7 @@ static int tegra_dc_init(struct host1x_client *client)static int tegra_dc_exit (struct host1x_client *client) { -struct drm_device *drm =dev_get_drvdata (client->parent);struct tegra_dc *dc =host1x_client_to_dc (client); -struct tegra_drm *tegra = drm->dev_private;int err;devm_free_irq (dc->dev, dc->irq, dc);@@ -1945,15 +1925,7 @@ static int tegra_dc_exit(struct host1x_client *client)return err; } -if (dc->group) { -if (dc->group == tegra->group) { -iommu_detach_group (tegra->domain, dc->group); - tegra->group =NULL ; - } - -iommu_group_put (dc->group); - } - +host1x_client_iommu_detach (client, dc->group);host1x_syncpt_free (dc->syncpt);return 0 ;drivers/gpu/drm/tegra/drm.c +10
-0@@ -1114,6 +1114,48 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra,return 0 ; } +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; +struct iommu_group *group =NULL ; +int err; + +if (tegra->domain) { + group =iommu_group_get (client->dev);
drivers/gpu/drm/tegra/drm.c int tegra_drm_unregister_client(struct tegra_drm *tegra, · line 1136
Quoted 10 lines
drivers/gpu/drm/tegra/drm.c +10
-0+ +if (group && (!shared || (shared && (group != tegra->group)))) { + err =iommu_attach_group (tegra->domain, group); +if (err <0 ) { +iommu_group_put (group); +return ERR_PTR (err); + } + +if (shared && !tegra->group) + tegra->group = group;
Nit: Probably it doesn't make much sense to have devices unattached to BO's AS, what about to error out here or at least display a error/warning message?
@@ -1796,7 +1796,12 @@ struct iommu_group *host1x_client_iommu_attach(struct host1x_client *client,
if (tegra->domain) {
group = iommu_group_get(client->dev);- if (group && (!shared || (shared && (group != tegra->group)))) {
+ if (!group) {
+ dev_err(client->dev, "Failed to get IOMMU group\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!shared || group != tegra->group) {
err = iommu_attach_group(tegra->domain, group);
if (err < 0) {
iommu_group_put(group);Quoted 173 lines
drivers/gpu/drm/tegra/drm.c +22
-0+ } + } + +return group; +} + +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group) +{ +struct drm_device *drm =dev_get_drvdata (client->parent); +struct tegra_drm *tegra = drm->dev_private; + +if (group) { +if (group == tegra->group) { +iommu_detach_group (tegra->domain, group); + tegra->group =NULL ; + } + +iommu_group_put (group); + } +} +void *tegra_drm_alloc (struct tegra_drm *tegra,size_t size,dma_addr_t *dma) {struct iova *alloc;drivers/gpu/drm/tegra/drm.h +4
-0@@ -110,6 +110,10 @@ int tegra_drm_register_client(struct tegra_drm *tegra, struct tegra_drm_client *client);int tegra_drm_unregister_client (struct tegra_drm *tegra,struct tegra_drm_client *client); +struct iommu_group *host1x_client_iommu_attach (struct host1x_client *client, +bool shared); +void host1x_client_iommu_detach (struct host1x_client *client, +struct iommu_group *group);int tegra_drm_init (struct tegra_drm *tegra,struct drm_device *drm);int tegra_drm_exit (struct tegra_drm *tegra);drivers/gpu/drm/tegra/gr2d.c +8
-24@@ -32,7 +32,6 @@ static int gr2d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr2d *gr2d =to_gr2d (drm);int err;@@ -47,22 +46,14 @@ static int gr2d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr2d->group =iommu_group_get (client->dev); - -if (gr2d->group) { - err =iommu_attach_group (tegra->domain, gr2d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr2d->group); - goto free; - } - } + gr2d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr2d->group)) { + err =PTR_ERR (gr2d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } - err =tegra_drm_register_client (tegra, drm); + err =tegra_drm_register_client (dev->dev_private, drm);if (err <0 ) {dev_err (client->dev,"failed to register client: %d\n" , err); goto detach;@@ -71,10 +62,7 @@ static int gr2d_init(struct host1x_client *client)return 0 ; detach: -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } +host1x_client_iommu_detach (client, gr2d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -94,14 +82,10 @@ static int gr2d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr2d->group);host1x_syncpt_free (client->syncpts[0 ]);host1x_channel_put (gr2d->channel); -if (gr2d->group) { -iommu_detach_group (tegra->domain, gr2d->group); -iommu_group_put (gr2d->group); - } -return 0 ; }drivers/gpu/drm/tegra/gr3d.c +7
-19@@ -42,7 +42,6 @@ static int gr3d_init(struct host1x_client *client)struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent);unsigned long flags =HOST1X_SYNCPT_HAS_BASE ; -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -56,19 +55,11 @@ static int gr3d_init(struct host1x_client *client) goto put; } -if (tegra->domain) { - gr3d->group =iommu_group_get (client->dev); - -if (gr3d->group) { - err =iommu_attach_group (tegra->domain, gr3d->group); -if (err <0 ) { -dev_err (client->dev, -"failed to attach to domain: %d\n" , - err); -iommu_group_put (gr3d->group); - goto free; - } - } + gr3d->group =host1x_client_iommu_attach (client, false); +if (IS_ERR (gr3d->group)) { + err =PTR_ERR (gr3d->group); +dev_err (client->dev,"failed to attach to domain: %d\n" , err); + goto free; } err =tegra_drm_register_client (dev->dev_private, drm);@@ -80,10 +71,7 @@ static int gr3d_init(struct host1x_client *client)return 0 ; detach: -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } +host1x_client_iommu_detach (client, gr3d->group); free:host1x_syncpt_free (client->syncpts[0 ]); put:@@ -95,7 +83,6 @@ static int gr3d_exit(struct host1x_client *client) {struct tegra_drm_client *drm =host1x_to_drm_client (client);struct drm_device *dev =dev_get_drvdata (client->parent); -struct tegra_drm *tegra = dev->dev_private;struct gr3d *gr3d =to_gr3d (drm);int err;@@ -103,14 +90,10 @@ static int gr3d_exit(struct host1x_client *client)if (err <0 )return err; +host1x_client_iommu_detach (client, gr3d->group);host1x_syncpt_free (client->syncpts[0 ]);
drivers/gpu/drm/tegra/gr3d.c static int gr3d_exit(struct host1x_client *client) · line 99
Quoted 10 lines
drivers/gpu/drm/tegra/gr3d.c +0
-5host1x_channel_put (gr3d->channel); -if (gr3d->group) { -iommu_detach_group (tegra->domain, gr3d->group); -iommu_group_put (gr3d->group); - } -return 0 ; }
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 16 lines · Thierry Reding
From: Thierry Reding <[email protected]>
If an error happens during display controller initialization, the host1x syncpoint previously requested would be leaked. Properly clean up the syncpoint along with the other resources.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 2 ++ 1 file changed, 2 insertions(+)drivers/gpu/drm/tegra/dc.c +0
-0
drivers/gpu/drm/tegra/dc.c static int tegra_dc_init(struct host1x_client *client) · line 1931
Quoted 7 lines
drivers/gpu/drm/tegra/dc.c +2
-0@@ -1925,6 +1925,8 @@ static int tegra_dc_init(struct host1x_client *client)iommu_group_put (dc->group); } +host1x_syncpt_free (dc->syncpt); +return err; }
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 10 lines · Thierry Reding
From: Thierry Reding <[email protected]>
If an error happens during display controller initialization, the host1x syncpoint previously requested would be leaked. Properly clean up the syncpoint along with the other resources.
Signed-off-by Thierry Reding <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 2 ++ 1 file changed, 2 insertions(+)
Patches 1-4 applied.
Thierry
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel