2020-04-08 06:06:34

by Gabriela Bittencourt

[permalink] [raw]
Subject: [PATCH 0/2] drm/vkms: Add Virtual hardware module option

Hi,

I'm trying to implement the virtual hardware (virtual_hw) module option on
VKMS module.

The virtual hardware module option is implemented as an option to skip the
timing and vblank subtests. The main idea of virtual_hw is shorten the time
used on each period of operation. For this, the timer for counting the
period is eliminated and the KMS configurations are implemented along with
the standard atomic operations.

During the 'atomic_enable' and 'atomic_disable' the vblank is initialized
only if the virtual_hw is disabled (and therefore, the vblank is enabled).
A kick of crc/vblank is decoupled from vblank_simulate. Case the vblank
is disabled (that is, the vblank_simulate will never execute) a
vkms_composer_work routine is added to the end of the atomic_flush.

The IGT tests used to check the patch were the kms-flip, which kept the
same results, with and without my alterations, with the exceptions of the
tests that required vblank. The warning message and the related tests are
presented below:

Test requirement not met in function run_test_on_crtc_set, file ../tests/kms_flip.c:1285:
Test requirement: vblank
There is no VBlank
Last errno: 95, Operation not supported
- wf_vblank-ts-check
- blocking-wf_vblank
- absolute-wf_vblank
- blocking-absolute-wf_vblank
- busy-flip
- plain-flip-ts-check
- plain-flip-fb-recreate
- flip-vs-expired-vblank
- flip-vs-absolute-wf_vblank
- basic-flip-vs-wf_vblank
- flip-vs-blocking-wf-vblank
- dpms-vs-vblank-race
- modeset-vs-vblank-race
- wf_vblank-ts-check-interruptible
- absolute-wf_vblank-interruptible
- blocking-absolute-wf_vblank-interruptible
- plain-flip-ts-check-interruptible
- plain-flip-fb-recreate-interruptible
- flip-vs-expired-vblank-interruptible
- flip-vs-absolute-wf_vblank-interruptible
- flip-vs-wf_vblank-interruptible
- dpms-vs-vblank-race-interruptible
- modeset-vs-vblank-race-interruptible

Any suggestions are very welcome :)

Gabriela Bittencourt (2):
drm/vkms: Rework vkms_vblank_simulate
drm/vkms: Add 'virtual_hw' module option

drivers/gpu/drm/vkms/vkms_crtc.c | 42 +++++++++++++++++++++++++++-----
drivers/gpu/drm/vkms/vkms_drv.c | 13 ++++++++--
drivers/gpu/drm/vkms/vkms_drv.h | 2 ++
3 files changed, 49 insertions(+), 8 deletions(-)

--
2.25.1


2020-04-08 06:08:16

by Gabriela Bittencourt

[permalink] [raw]
Subject: [PATCH 1/2] drm/vkms: Rework vkms_vblank_simulate

Add support for Virtual Vblank on VKMS. Rework part of
'vkms_vblank_simulate' for schedule a compose worker outside.

Signed-off-by: Gabriela Bittencourt <[email protected]>
---
drivers/gpu/drm/vkms/vkms_crtc.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index ac85e17428f8..a72769b81efe 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -7,6 +7,12 @@

#include "vkms_drv.h"

+static bool vkms_queue_compose_worker(struct vkms_output *output,
+ struct vkms_crtc_state *state)
+{
+ return queue_work(output->composer_workq, &state->composer_work);
+}
+
static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
{
struct vkms_output *output = container_of(timer, struct vkms_output,
@@ -22,12 +28,12 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)

spin_lock(&output->lock);
ret = drm_crtc_handle_vblank(crtc);
- if (!ret)
- DRM_ERROR("vkms failure on handling vblank");
-
state = output->composer_state;
spin_unlock(&output->lock);

+ if (!ret)
+ DRM_ERROR("vkms failure on handling vblank");
+
if (state && output->composer_enabled) {
u64 frame = drm_crtc_accurate_vblank_count(crtc);

@@ -44,7 +50,7 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
state->crc_pending = true;
spin_unlock(&output->composer_lock);

- ret = queue_work(output->composer_workq, &state->composer_work);
+ ret = vkms_queue_compose_worker(output, state);
if (!ret)
DRM_DEBUG_DRIVER("Composer worker already queued\n");
}
--
2.25.1

2020-04-08 06:08:42

by Gabriela Bittencourt

[permalink] [raw]
Subject: [PATCH 2/2] drm/vkms: Add 'virtual_hw' module option

Add Virtual Vblank, virtual hardware module option ('virtual_hw')
allows to skip the timing of vblank routine.

Signed-off-by: Gabriela Bittencourt <[email protected]>
---
drivers/gpu/drm/vkms/vkms_crtc.c | 28 ++++++++++++++++++++++++++--
drivers/gpu/drm/vkms/vkms_drv.c | 13 +++++++++++--
drivers/gpu/drm/vkms/vkms_drv.h | 2 ++
3 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index a72769b81efe..d4aa1ed93bf2 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -58,6 +58,18 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
return HRTIMER_RESTART;
}

+static void vkms_virtual_vblank_simulate(struct vkms_output *output,
+ struct drm_crtc *crtc)
+{
+ struct vkms_crtc_state *state;
+ bool ret;
+
+ state = output->composer_state;
+ ret = vkms_queue_compose_worker(output, state);
+ if (!ret)
+ DRM_DEBUG_DRIVER("Composer worker already queued\n");
+}
+
static int vkms_enable_vblank(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -214,16 +226,25 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
return 0;
}

+static bool vkms_crtc_atomic_check_vblank_enable(struct drm_crtc *crtc)
+{
+ struct vkms_output *vkms_out = drm_crtc_to_vkms_output(crtc);
+
+ return (!vkms_out->disable_vblank);
+}
+
static void vkms_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
- drm_crtc_vblank_on(crtc);
+ if (vkms_crtc_atomic_check_vblank_enable(crtc))
+ drm_crtc_vblank_on(crtc);
}

static void vkms_crtc_atomic_disable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
- drm_crtc_vblank_off(crtc);
+ if (vkms_crtc_atomic_check_vblank_enable(crtc))
+ drm_crtc_vblank_off(crtc);
}

static void vkms_crtc_atomic_begin(struct drm_crtc *crtc,
@@ -258,6 +279,9 @@ static void vkms_crtc_atomic_flush(struct drm_crtc *crtc,
vkms_output->composer_state = to_vkms_crtc_state(crtc->state);

spin_unlock_irq(&vkms_output->lock);
+
+ if (vkms_output->disable_vblank)
+ vkms_virtual_vblank_simulate(vkms_output, crtc);
}

static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = {
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index eef85f1a0ce5..f7c25961b083 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -39,6 +39,11 @@ bool enable_cursor;
module_param_named(enable_cursor, enable_cursor, bool, 0444);
MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");

+bool virtual_hw;
+module_param_named(virtual_hw, virtual_hw, bool, 0444);
+MODULE_PARM_DESC(virtual_hw,
+ "Enable virtual hardware mode / Disable vblank");
+
static const struct file_operations vkms_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -168,9 +173,13 @@ static int __init vkms_init(void)
goto out_put;
}

- vkms_device->drm.irq_enabled = true;
+ vkms_device->output.disable_vblank = virtual_hw;
+ vkms_device->drm.irq_enabled = !virtual_hw;
+
+ if (virtual_hw)
+ DRM_INFO("Virtual hardware mode enabled");

- ret = drm_vblank_init(&vkms_device->drm, 1);
+ ret = (virtual_hw) ? 0 : drm_vblank_init(&vkms_device->drm, 1);
if (ret) {
DRM_ERROR("Failed to vblank\n");
goto out_put;
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index eda04ffba7b1..52ad8e06adc5 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -19,6 +19,7 @@
#define YRES_MAX 8192

extern bool enable_cursor;
+extern bool virtual_hw;

struct vkms_composer {
struct drm_framebuffer fb;
@@ -64,6 +65,7 @@ struct vkms_output {
struct drm_encoder encoder;
struct drm_connector connector;
struct hrtimer vblank_hrtimer;
+ bool disable_vblank;
ktime_t period_ns;
struct drm_pending_vblank_event *event;
/* ordered wq for composer_work */
--
2.25.1