Skip to content

Commit bf8744e

Browse files
Lekensteynkraxel
authored andcommitted
qxl: refactor to use drm_fb_helper_fbdev_setup
Lots of code can be removed by relying on fb-helper: - "struct drm_framebuffer" moves to fb_helper.fb. - "struct drm_gem_object" moves to fb_helper.obj[0]. - "struct qxl_device" can be inferred as drm_fb_helper is embedded. - qxl_user_framebuffer_create -> drm_gem_fb_create. - qxl_user_framebuffer_destroy -> drm_gem_fb_destroy. - qxl_fbdev_destroy -> drm_fb_helper_fbdev_teardown + vfree(shadow). Remove unused code: - qxl_fbdev_qobj_is_fb, qxl_fbdev_set_suspend. - Unused fields of qxl_fbdev: delayed_ops, delayed_ops_lock, size. Misc notes: - The dirty callback is preserved as it is necessary to trigger update commands in the hw (the screen stays black otherwise). - No idea when .create_handle in drm_framebuffer_funcs is used, but use the same drm_gem_fb_create_handle to match drm_gem_fb_funcs. - I don't know why qxl_fb_find_or_create_single used to check for an existing framebuffer and removed that check to match other drivers. - Use of drm_fb_helper_fbdev_teardown also requires "info->fbdefio" to be dynamically allocated. Replace the existing defio config by drm_fb_helper_defio_init to accomodate this. Testing results: startx with fbdev, modesetting and qxl all seems to work. Tested also with CONFIG_DRM_FBDEV_EMULATION=n, fbdev obviously fails but others are fine. QEMU -spice and QEMU -spice with vdagent and multiple (resized) displays (via remote-viewer) also works. unbind vtconsole and rmmod has *not* regressed (i.e. it still trips on a use-after-free in qxl_check_idle via qxl_ttm_fini). Ideally setup/teardown is replaced by drm_fbdev_generic_setup as that would result in further code reduction, improve error handling (like not leaking shadow memory), but unfortunately QXL has no implementation for qxl_gem_prime_vmap. Signed-off-by: Peter Wu <peter@lekensteyn.nl> Link: http://patchwork.freedesktop.org/patch/msgid/20180910132156.23201-1-peter@lekensteyn.nl Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
1 parent 33f3542 commit bf8744e

File tree

4 files changed

+60
-276
lines changed

4 files changed

+60
-276
lines changed

drivers/gpu/drm/qxl/qxl_display.c

Lines changed: 20 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <drm/drm_plane_helper.h>
2929
#include <drm/drm_atomic_helper.h>
3030
#include <drm/drm_atomic.h>
31+
#include <drm/drm_gem_framebuffer_helper.h>
3132

3233
#include "qxl_drv.h"
3334
#include "qxl_object.h"
@@ -388,33 +389,21 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = {
388389
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
389390
};
390391

391-
void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb)
392-
{
393-
struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb);
394-
struct qxl_bo *bo = gem_to_qxl_bo(qxl_fb->obj);
395-
396-
WARN_ON(bo->shadow);
397-
drm_gem_object_put_unlocked(qxl_fb->obj);
398-
drm_framebuffer_cleanup(fb);
399-
kfree(qxl_fb);
400-
}
401-
402392
static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb,
403393
struct drm_file *file_priv,
404394
unsigned flags, unsigned color,
405395
struct drm_clip_rect *clips,
406396
unsigned num_clips)
407397
{
408398
/* TODO: vmwgfx where this was cribbed from had locking. Why? */
409-
struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb);
410-
struct qxl_device *qdev = qxl_fb->base.dev->dev_private;
399+
struct qxl_device *qdev = fb->dev->dev_private;
411400
struct drm_clip_rect norect;
412401
struct qxl_bo *qobj;
413402
int inc = 1;
414403

415404
drm_modeset_lock_all(fb->dev);
416405

417-
qobj = gem_to_qxl_bo(qxl_fb->obj);
406+
qobj = gem_to_qxl_bo(fb->obj[0]);
418407
/* if we aren't primary surface ignore this */
419408
if (!qobj->is_primary) {
420409
drm_modeset_unlock_all(fb->dev);
@@ -432,7 +421,7 @@ static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb,
432421
inc = 2; /* skip source rects */
433422
}
434423

435-
qxl_draw_dirty_fb(qdev, qxl_fb, qobj, flags, color,
424+
qxl_draw_dirty_fb(qdev, fb, qobj, flags, color,
436425
clips, num_clips, inc);
437426

438427
drm_modeset_unlock_all(fb->dev);
@@ -441,31 +430,11 @@ static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb,
441430
}
442431

443432
static const struct drm_framebuffer_funcs qxl_fb_funcs = {
444-
.destroy = qxl_user_framebuffer_destroy,
433+
.destroy = drm_gem_fb_destroy,
445434
.dirty = qxl_framebuffer_surface_dirty,
446-
/* TODO?
447-
* .create_handle = qxl_user_framebuffer_create_handle, */
435+
.create_handle = drm_gem_fb_create_handle,
448436
};
449437

450-
int
451-
qxl_framebuffer_init(struct drm_device *dev,
452-
struct qxl_framebuffer *qfb,
453-
const struct drm_mode_fb_cmd2 *mode_cmd,
454-
struct drm_gem_object *obj,
455-
const struct drm_framebuffer_funcs *funcs)
456-
{
457-
int ret;
458-
459-
qfb->obj = obj;
460-
drm_helper_mode_fill_fb_struct(dev, &qfb->base, mode_cmd);
461-
ret = drm_framebuffer_init(dev, &qfb->base, funcs);
462-
if (ret) {
463-
qfb->obj = NULL;
464-
return ret;
465-
}
466-
return 0;
467-
}
468-
469438
static void qxl_crtc_atomic_enable(struct drm_crtc *crtc,
470439
struct drm_crtc_state *old_state)
471440
{
@@ -488,14 +457,12 @@ static int qxl_primary_atomic_check(struct drm_plane *plane,
488457
struct drm_plane_state *state)
489458
{
490459
struct qxl_device *qdev = plane->dev->dev_private;
491-
struct qxl_framebuffer *qfb;
492460
struct qxl_bo *bo;
493461

494462
if (!state->crtc || !state->fb)
495463
return 0;
496464

497-
qfb = to_qxl_framebuffer(state->fb);
498-
bo = gem_to_qxl_bo(qfb->obj);
465+
bo = gem_to_qxl_bo(state->fb->obj[0]);
499466

500467
if (bo->surf.stride * bo->surf.height > qdev->vram_size) {
501468
DRM_ERROR("Mode doesn't fit in vram size (vgamem)");
@@ -556,23 +523,19 @@ static void qxl_primary_atomic_update(struct drm_plane *plane,
556523
struct drm_plane_state *old_state)
557524
{
558525
struct qxl_device *qdev = plane->dev->dev_private;
559-
struct qxl_framebuffer *qfb =
560-
to_qxl_framebuffer(plane->state->fb);
561-
struct qxl_framebuffer *qfb_old;
562-
struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj);
526+
struct qxl_bo *bo = gem_to_qxl_bo(plane->state->fb->obj[0]);
563527
struct qxl_bo *bo_old;
564528
struct drm_clip_rect norect = {
565529
.x1 = 0,
566530
.y1 = 0,
567-
.x2 = qfb->base.width,
568-
.y2 = qfb->base.height
531+
.x2 = plane->state->fb->width,
532+
.y2 = plane->state->fb->height
569533
};
570534
int ret;
571535
bool same_shadow = false;
572536

573537
if (old_state->fb) {
574-
qfb_old = to_qxl_framebuffer(old_state->fb);
575-
bo_old = gem_to_qxl_bo(qfb_old->obj);
538+
bo_old = gem_to_qxl_bo(old_state->fb->obj[0]);
576539
} else {
577540
bo_old = NULL;
578541
}
@@ -602,7 +565,7 @@ static void qxl_primary_atomic_update(struct drm_plane *plane,
602565
bo->is_primary = true;
603566
}
604567

605-
qxl_draw_dirty_fb(qdev, qfb, bo, 0, 0, &norect, 1, 1);
568+
qxl_draw_dirty_fb(qdev, plane->state->fb, bo, 0, 0, &norect, 1, 1);
606569
}
607570

608571
static void qxl_primary_atomic_disable(struct drm_plane *plane,
@@ -611,9 +574,7 @@ static void qxl_primary_atomic_disable(struct drm_plane *plane,
611574
struct qxl_device *qdev = plane->dev->dev_private;
612575

613576
if (old_state->fb) {
614-
struct qxl_framebuffer *qfb =
615-
to_qxl_framebuffer(old_state->fb);
616-
struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj);
577+
struct qxl_bo *bo = gem_to_qxl_bo(old_state->fb->obj[0]);
617578

618579
if (bo->is_primary) {
619580
qxl_io_destroy_primary(qdev);
@@ -645,7 +606,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane,
645606
return;
646607

647608
if (fb != old_state->fb) {
648-
obj = to_qxl_framebuffer(fb)->obj;
609+
obj = fb->obj[0];
649610
user_bo = gem_to_qxl_bo(obj);
650611

651612
/* pinning is done in the prepare/cleanup framevbuffer */
@@ -765,13 +726,13 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane,
765726
if (!new_state->fb)
766727
return 0;
767728

768-
obj = to_qxl_framebuffer(new_state->fb)->obj;
729+
obj = new_state->fb->obj[0];
769730
user_bo = gem_to_qxl_bo(obj);
770731

771732
if (plane->type == DRM_PLANE_TYPE_PRIMARY &&
772733
user_bo->is_dumb && !user_bo->shadow) {
773734
if (plane->state->fb) {
774-
obj = to_qxl_framebuffer(plane->state->fb)->obj;
735+
obj = plane->state->fb->obj[0];
775736
old_bo = gem_to_qxl_bo(obj);
776737
}
777738
if (old_bo && old_bo->shadow &&
@@ -815,7 +776,7 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane,
815776
return;
816777
}
817778

818-
obj = to_qxl_framebuffer(old_state->fb)->obj;
779+
obj = old_state->fb->obj[0];
819780
user_bo = gem_to_qxl_bo(obj);
820781
qxl_bo_unpin(user_bo);
821782

@@ -1115,26 +1076,8 @@ qxl_user_framebuffer_create(struct drm_device *dev,
11151076
struct drm_file *file_priv,
11161077
const struct drm_mode_fb_cmd2 *mode_cmd)
11171078
{
1118-
struct drm_gem_object *obj;
1119-
struct qxl_framebuffer *qxl_fb;
1120-
int ret;
1121-
1122-
obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]);
1123-
if (!obj)
1124-
return NULL;
1125-
1126-
qxl_fb = kzalloc(sizeof(*qxl_fb), GFP_KERNEL);
1127-
if (qxl_fb == NULL)
1128-
return NULL;
1129-
1130-
ret = qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj, &qxl_fb_funcs);
1131-
if (ret) {
1132-
kfree(qxl_fb);
1133-
drm_gem_object_put_unlocked(obj);
1134-
return NULL;
1135-
}
1136-
1137-
return &qxl_fb->base;
1079+
return drm_gem_fb_create_with_funcs(dev, file_priv, mode_cmd,
1080+
&qxl_fb_funcs);
11381081
}
11391082

11401083
static const struct drm_mode_config_funcs qxl_mode_funcs = {
@@ -1221,7 +1164,6 @@ int qxl_modeset_init(struct qxl_device *qdev)
12211164
}
12221165

12231166
qxl_display_read_client_monitors_config(qdev);
1224-
qdev->mode_info.mode_config_initialized = true;
12251167

12261168
drm_mode_config_reset(&qdev->ddev);
12271169

@@ -1237,8 +1179,5 @@ void qxl_modeset_fini(struct qxl_device *qdev)
12371179
qxl_fbdev_fini(qdev);
12381180

12391181
qxl_destroy_monitors_object(qdev);
1240-
if (qdev->mode_info.mode_config_initialized) {
1241-
drm_mode_config_cleanup(&qdev->ddev);
1242-
qdev->mode_info.mode_config_initialized = false;
1243-
}
1182+
drm_mode_config_cleanup(&qdev->ddev);
12441183
}

drivers/gpu/drm/qxl/qxl_draw.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ void qxl_draw_opaque_fb(const struct qxl_fb_image *qxl_fb_image,
262262
* by treating them differently in the server.
263263
*/
264264
void qxl_draw_dirty_fb(struct qxl_device *qdev,
265-
struct qxl_framebuffer *qxl_fb,
265+
struct drm_framebuffer *fb,
266266
struct qxl_bo *bo,
267267
unsigned flags, unsigned color,
268268
struct drm_clip_rect *clips,
@@ -281,9 +281,9 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
281281
struct qxl_drawable *drawable;
282282
struct qxl_rect drawable_rect;
283283
struct qxl_rect *rects;
284-
int stride = qxl_fb->base.pitches[0];
284+
int stride = fb->pitches[0];
285285
/* depth is not actually interesting, we don't mask with it */
286-
int depth = qxl_fb->base.format->cpp[0] * 8;
286+
int depth = fb->format->cpp[0] * 8;
287287
uint8_t *surface_base;
288288
struct qxl_release *release;
289289
struct qxl_bo *clips_bo;

drivers/gpu/drm/qxl/qxl_drv.h

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include <drm/drm_crtc.h>
4040
#include <drm/drm_encoder.h>
41+
#include <drm/drm_fb_helper.h>
4142
#include <drm/drm_gem.h>
4243
#include <drm/drmP.h>
4344
#include <drm/ttm/ttm_bo_api.h>
@@ -121,15 +122,9 @@ struct qxl_output {
121122
struct drm_encoder enc;
122123
};
123124

124-
struct qxl_framebuffer {
125-
struct drm_framebuffer base;
126-
struct drm_gem_object *obj;
127-
};
128-
129125
#define to_qxl_crtc(x) container_of(x, struct qxl_crtc, base)
130126
#define drm_connector_to_qxl_output(x) container_of(x, struct qxl_output, base)
131127
#define drm_encoder_to_qxl_output(x) container_of(x, struct qxl_output, enc)
132-
#define to_qxl_framebuffer(x) container_of(x, struct qxl_framebuffer, base)
133128

134129
struct qxl_mman {
135130
struct ttm_bo_global_ref bo_global_ref;
@@ -138,13 +133,6 @@ struct qxl_mman {
138133
struct ttm_bo_device bdev;
139134
};
140135

141-
struct qxl_mode_info {
142-
bool mode_config_initialized;
143-
144-
/* pointer to fbdev info structure */
145-
struct qxl_fbdev *qfbdev;
146-
};
147-
148136

149137
struct qxl_memslot {
150138
uint8_t generation;
@@ -232,10 +220,9 @@ struct qxl_device {
232220
void *ram;
233221
struct qxl_mman mman;
234222
struct qxl_gem gem;
235-
struct qxl_mode_info mode_info;
236223

237-
struct fb_info *fbdev_info;
238-
struct qxl_framebuffer *fbdev_qfb;
224+
struct drm_fb_helper fb_helper;
225+
239226
void *ram_physical;
240227

241228
struct qxl_ring *release_ring;
@@ -349,19 +336,8 @@ qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo,
349336

350337
int qxl_fbdev_init(struct qxl_device *qdev);
351338
void qxl_fbdev_fini(struct qxl_device *qdev);
352-
int qxl_get_handle_for_primary_fb(struct qxl_device *qdev,
353-
struct drm_file *file_priv,
354-
uint32_t *handle);
355-
void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state);
356339

357340
/* qxl_display.c */
358-
void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb);
359-
int
360-
qxl_framebuffer_init(struct drm_device *dev,
361-
struct qxl_framebuffer *rfb,
362-
const struct drm_mode_fb_cmd2 *mode_cmd,
363-
struct drm_gem_object *obj,
364-
const struct drm_framebuffer_funcs *funcs);
365341
void qxl_display_read_client_monitors_config(struct qxl_device *qdev);
366342
int qxl_create_monitors_object(struct qxl_device *qdev);
367343
int qxl_destroy_monitors_object(struct qxl_device *qdev);
@@ -471,7 +447,7 @@ void qxl_draw_opaque_fb(const struct qxl_fb_image *qxl_fb_image,
471447
int stride /* filled in if 0 */);
472448

473449
void qxl_draw_dirty_fb(struct qxl_device *qdev,
474-
struct qxl_framebuffer *qxl_fb,
450+
struct drm_framebuffer *fb,
475451
struct qxl_bo *bo,
476452
unsigned flags, unsigned color,
477453
struct drm_clip_rect *clips,

0 commit comments

Comments
 (0)