Skip to content

Commit

Permalink
drm/<drivers>: reorder framebuffer init sequence
Browse files Browse the repository at this point in the history
With more fine-grained locking we can no longer rely on the big
mode_config lock to prevent concurrent access to mode resources
like framebuffers. Instead a framebuffer becomes accessible to
other threads as soon as it is added to the relevant lookup
structures. Hence it needs to be fully set up by the time drivers
call drm_framebuffer_init.

This patch here is the drivers part of that reorg. Nothing really fancy
going on safe for three special cases.

- exynos needs to be careful to properly unref all handles.
- nouveau gets a resource leak fixed for free: one of the error
  cases didn't cleanup the framebuffer, which is now moot since
  the framebuffer is only registered once it is fully set up.
- vmwgfx requires a slight reordering of operations, I'm hoping I didn't
  break anything (but it's refcount management only, so should be safe).

v2: Split out exynos, since it's a bit more hairy than expected.

v3: Drop bogus cirrus hunk noticed by Richard Wilbur.

v4: Split out vmwgfx since there's a small change in return values.

Reviewed-by: Rob Clark <rob@ti.com> (core + omapdrm)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Daniel Vetter committed Jan 20, 2013
1 parent 065a50e commit c7d73f6
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 31 deletions.
4 changes: 2 additions & 2 deletions drivers/gpu/drm/ast/ast_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,13 +266,13 @@ int ast_framebuffer_init(struct drm_device *dev,
{
int ret;

drm_helper_mode_fill_fb_struct(&ast_fb->base, mode_cmd);
ast_fb->obj = obj;
ret = drm_framebuffer_init(dev, &ast_fb->base, &ast_fb_funcs);
if (ret) {
DRM_ERROR("framebuffer init failed %d\n", ret);
return ret;
}
drm_helper_mode_fill_fb_struct(&ast_fb->base, mode_cmd);
ast_fb->obj = obj;
return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/cirrus/cirrus_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ int cirrus_framebuffer_init(struct drm_device *dev,
{
int ret;

drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
gfb->obj = obj;
ret = drm_framebuffer_init(dev, &gfb->base, &cirrus_fb_funcs);
if (ret) {
DRM_ERROR("drm_framebuffer_init failed: %d\n", ret);
return ret;
}
drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
gfb->obj = obj;
return 0;
}

Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/drm_fb_cma_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,18 @@ static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev,
if (!fb_cma)
return ERR_PTR(-ENOMEM);

drm_helper_mode_fill_fb_struct(&fb_cma->fb, mode_cmd);

for (i = 0; i < num_planes; i++)
fb_cma->obj[i] = obj[i];

ret = drm_framebuffer_init(dev, &fb_cma->fb, &drm_fb_cma_funcs);
if (ret) {
dev_err(dev->dev, "Failed to initalize framebuffer: %d\n", ret);
kfree(fb_cma);
return ERR_PTR(ret);
}

drm_helper_mode_fill_fb_struct(&fb_cma->fb, mode_cmd);

for (i = 0; i < num_planes; i++)
fb_cma->obj[i] = obj[i];

return fb_cma;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/gma500/framebuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,13 @@ static int psb_framebuffer_init(struct drm_device *dev,
default:
return -EINVAL;
}
drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
fb->gtt = gt;
ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
if (ret) {
dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
return ret;
}
drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
fb->gtt = gt;
return 0;
}

Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -8666,14 +8666,15 @@ int intel_framebuffer_init(struct drm_device *dev,
if (mode_cmd->offsets[0] != 0)
return -EINVAL;

drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
intel_fb->obj = obj;

ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
if (ret) {
DRM_ERROR("framebuffer init failed %d\n", ret);
return ret;
}

drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
intel_fb->obj = obj;
return 0;
}

Expand Down
8 changes: 5 additions & 3 deletions drivers/gpu/drm/mgag200/mgag200_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ int mgag200_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj)
{
int ret = drm_framebuffer_init(dev, &gfb->base, &mga_fb_funcs);
int ret;

drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
gfb->obj = obj;
ret = drm_framebuffer_init(dev, &gfb->base, &mga_fb_funcs);
if (ret) {
DRM_ERROR("drm_framebuffer_init failed: %d\n", ret);
return ret;
}
drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
gfb->obj = obj;
return 0;
}

Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/nouveau/nouveau_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,6 @@ nouveau_framebuffer_init(struct drm_device *dev,
struct drm_framebuffer *fb = &nv_fb->base;
int ret;

ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
if (ret) {
return ret;
}

drm_helper_mode_fill_fb_struct(fb, mode_cmd);
nv_fb->nvbo = nvbo;

Expand Down Expand Up @@ -125,6 +120,11 @@ nouveau_framebuffer_init(struct drm_device *dev,
}
}

ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
if (ret) {
return ret;
}

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/radeon/radeon_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -1089,12 +1089,12 @@ radeon_framebuffer_init(struct drm_device *dev,
{
int ret;
rfb->obj = obj;
drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
if (ret) {
rfb->obj = NULL;
return ret;
}
drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/udl/udl_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,8 @@ udl_framebuffer_init(struct drm_device *dev,
int ret;

ufb->obj = obj;
ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs);
drm_helper_mode_fill_fb_struct(&ufb->base, mode_cmd);
ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs);
return ret;
}

Expand Down
16 changes: 8 additions & 8 deletions drivers/staging/omapdrm/omap_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,14 +424,6 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
}

fb = &omap_fb->base;
ret = drm_framebuffer_init(dev, fb, &omap_framebuffer_funcs);
if (ret) {
dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
goto fail;
}

DBG("create: FB ID: %d (%p)", fb->base.id, fb);

omap_fb->format = format;

for (i = 0; i < n; i++) {
Expand Down Expand Up @@ -462,6 +454,14 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,

drm_helper_mode_fill_fb_struct(fb, mode_cmd);

ret = drm_framebuffer_init(dev, fb, &omap_framebuffer_funcs);
if (ret) {
dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
goto fail;
}

DBG("create: FB ID: %d (%p)", fb->base.id, fb);

return fb;

fail:
Expand Down

0 comments on commit c7d73f6

Please sign in to comment.