Message ID | e2e4b8f3a5cab7b2dba75bf1930f86b0a4ee08c9.1548856186.git.shayenneluzmoura@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/vkms: Bugfix for igt-tests | expand |
On 01/30, Shayenne Moura wrote: > When the vblank irq happens, kernel time subsystem executes > `vkms_vblank_simulate`. In parallel or not, it prepares all stuff > necessary to the next vblank with arm, and it must flush these > stuff before the next vblank irq. However, vblank counter is ahead > when arm is executed in parallel with handle vblank. > > CPU 0: CPU 1: > | | > atomic_commit_tail is ongoing | > | | > | hrtimer: vkms_vblank_simulate() > | | > | drm_crtc_handle_vblank() > | | > drm_crtc_arm_vblank() | > | | > ->get_vblank_timestamp() | > | | > | hrtimer_forward_now() > > Then, we should guarantee that the vblank interval time is correct > (not changed) before finish the vblank handle. > > Fix the bug including the call to `hrtimer_forward_now()` in the same > lock of `drm_crtc_handle_vblank()` to ensure that the timestamp update > is correct when finish the vblank handle. > > Signed-off-by: Shayenne Moura <shayenneluzmoura@gmail.com> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> > --- > drivers/gpu/drm/vkms/vkms_crtc.c | 18 ++++++------------ > 1 file changed, 6 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c > index 23146ff2a25b..5a095610726b 100644 > --- a/drivers/gpu/drm/vkms/vkms_crtc.c > +++ b/drivers/gpu/drm/vkms/vkms_crtc.c > @@ -10,13 +10,17 @@ > #include <drm/drm_atomic_helper.h> > #include <drm/drm_probe_helper.h> > > -static void _vblank_handle(struct vkms_output *output) > +static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) > { > + struct vkms_output *output = container_of(timer, struct vkms_output, > + vblank_hrtimer); > struct drm_crtc *crtc = &output->crtc; > struct vkms_crtc_state *state = to_vkms_crtc_state(crtc->state); > + int ret_overrun; > bool ret; > > spin_lock(&output->lock); > + > ret = drm_crtc_handle_vblank(crtc); > if (!ret) > DRM_ERROR("vkms failure on handling vblank"); > @@ -37,19 +41,9 @@ static void _vblank_handle(struct vkms_output *output) > DRM_WARN("failed to queue vkms_crc_work_handle"); > } > > - spin_unlock(&output->lock); > -} > - > -static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) > -{ > - struct vkms_output *output = container_of(timer, struct vkms_output, > - vblank_hrtimer); > - int ret_overrun; > - > - _vblank_handle(output); > - > ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, > output->period_ns); > + spin_unlock(&output->lock); > > return HRTIMER_RESTART; > } > -- > 2.17.1 > Reviewed-by: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 23146ff2a25b..5a095610726b 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -10,13 +10,17 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_probe_helper.h> -static void _vblank_handle(struct vkms_output *output) +static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) { + struct vkms_output *output = container_of(timer, struct vkms_output, + vblank_hrtimer); struct drm_crtc *crtc = &output->crtc; struct vkms_crtc_state *state = to_vkms_crtc_state(crtc->state); + int ret_overrun; bool ret; spin_lock(&output->lock); + ret = drm_crtc_handle_vblank(crtc); if (!ret) DRM_ERROR("vkms failure on handling vblank"); @@ -37,19 +41,9 @@ static void _vblank_handle(struct vkms_output *output) DRM_WARN("failed to queue vkms_crc_work_handle"); } - spin_unlock(&output->lock); -} - -static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) -{ - struct vkms_output *output = container_of(timer, struct vkms_output, - vblank_hrtimer); - int ret_overrun; - - _vblank_handle(output); - ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, output->period_ns); + spin_unlock(&output->lock); return HRTIMER_RESTART; }