Commit a588a8bb authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Inki Dae

drm/exynos: g2d: use monotonic timestamps

The exynos DRM driver uses real-time 'struct timeval' values
for exporting its timestamps to user space. This has multiple
problems:

1. signed seconds overflow in y2038
2. the 'struct timeval' definition is deprecated in the kernel
3. time may jump or go backwards after a 'settimeofday()' syscall
4. other DRM timestamps are in CLOCK_MONOTONIC domain, so they
   can't be compared
5. exporting microseconds requires a division by 1000, which may
   be slow on some architectures.

The code existed in two places before, but the IPP portion was
removed in 8ded5941 ("drm/exynos: ipp: Remove Exynos DRM
IPP subsystem"), so we no longer need to worry about it.

Ideally timestamps should just use 64-bit nanoseconds instead, but
of course we can't change that now. Instead, this tries to address
the first four points above by using monotonic 'timespec' values.

According to Tobias Jakobi, user space doesn't care about the
timestamp at the moment, so we can change the format. Even if
there is something looking at them, it will work just fine with
monotonic times as long as the application only looks at the
relative values between two events.

Link: https://patchwork.kernel.org/patch/10038593/
Cc: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Reviewed-by: default avatarTobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent bfad2d08
...@@ -926,7 +926,7 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) ...@@ -926,7 +926,7 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no)
struct drm_device *drm_dev = g2d->subdrv.drm_dev; struct drm_device *drm_dev = g2d->subdrv.drm_dev;
struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node; struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node;
struct drm_exynos_pending_g2d_event *e; struct drm_exynos_pending_g2d_event *e;
struct timeval now; struct timespec64 now;
if (list_empty(&runqueue_node->event_list)) if (list_empty(&runqueue_node->event_list))
return; return;
...@@ -934,9 +934,9 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) ...@@ -934,9 +934,9 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no)
e = list_first_entry(&runqueue_node->event_list, e = list_first_entry(&runqueue_node->event_list,
struct drm_exynos_pending_g2d_event, base.link); struct drm_exynos_pending_g2d_event, base.link);
do_gettimeofday(&now); ktime_get_ts64(&now);
e->event.tv_sec = now.tv_sec; e->event.tv_sec = now.tv_sec;
e->event.tv_usec = now.tv_usec; e->event.tv_usec = now.tv_nsec / NSEC_PER_USEC;
e->event.cmdlist_no = cmdlist_no; e->event.cmdlist_no = cmdlist_no;
drm_send_event(drm_dev, &e->base); drm_send_event(drm_dev, &e->base);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment