From patchwork Fri Jun 17 15:10:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 102156 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp331341qgy; Fri, 17 Jun 2016 08:09:23 -0700 (PDT) X-Received: by 10.98.57.220 with SMTP id u89mr2911769pfj.148.1466176163779; Fri, 17 Jun 2016 08:09:23 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r1si24329860paa.198.2016.06.17.08.09.23; Fri, 17 Jun 2016 08:09:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753487AbcFQPJV (ORCPT + 30 others); Fri, 17 Jun 2016 11:09:21 -0400 Received: from mout.kundenserver.de ([217.72.192.73]:59679 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751058AbcFQPJT (ORCPT ); Fri, 17 Jun 2016 11:09:19 -0400 Received: from wuerfel.lan. ([78.42.132.4]) by mrelayeu.kundenserver.de (mreue102) with ESMTPA (Nemesis) id 0Lm4KP-1bnXG93iOP-00ZiNi; Fri, 17 Jun 2016 17:09:08 +0200 From: Arnd Bergmann To: Jaroslav Kysela , Takashi Iwai Cc: y2038@lists.linaro.org, Arnd Bergmann , alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org Subject: [PATCH] ALSA: seq_timer: use monotonic times internally Date: Fri, 17 Jun 2016 17:10:32 +0200 Message-Id: <20160617151054.3993410-1-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 X-Provags-ID: V03:K0:SbzEbCra0Zm8+eaCQUranS9Ob+ww/d12fGcE2T0B8okQHdL3vra 7mQUmFoyUA/tzGcVsG1v9sxUBvZQM/odykg5a4216j0ZOfsZZPha7bc30b3/P145C4UgOub ZJgLe4E6jHK899yGTOsM+1e43pvwLnyYaIaHYxyV/opMjW3nlx6H7ywb5MVrzSd4S6gxvzT eyRcGFW6gaVYn/CKGnCSA== X-UI-Out-Filterresults: notjunk:1; V01:K0:MZyRvGs973c=:iLimTlCWQniXc/kqwqpG3+ 2gflUyfU9hFxMdcXHwV7GlSQwvNimWVwbUIsz9y6K2QNp3nuJ/cm6JEg2On7ok08H30R1w01i r8XNyi50v9HFCnkLsPojUEaRd5SFe6D+YJuMlBss9IwS4SkRE0RFdOqBT31JzTPQjyq/QF54l aKwYXNEbwB5XDYvpkReHXyFnOOHuz9lFh0Mu4pZnIruRehV6GmRrQiJEJNBpzcFnN2pWgIR0q USyVIhiw98OvsYcqT/m4Qxu6cfm2IusAJR85EiiLzNgNtwoFV2RW0Gb1yMofyy9eNjENCPyga iyUJwpettA7Y/Xl4tl8lFarmi3IZ/34ygnEFM9CMUTeJhFYnyanmNmT6nFLzqQ8AstvQXdM5a rQCmTCjE6nSpePrShwA8AZmKBlKd9Fani7YSiuBOwNrs/CjnxdjZFmGnc88qw7U72tL0KJDkA sxPUdDk5lYlb3WhDBsQfmcxxObDkNNI/CeYjGmaJATRr3ZolE3YsmIDK7hfCmwVPe4vStPJvS 8QeY+D2gPT/3NXxSn20NDVMHPXtiMHyi72tizhSQW5USu+GHBFpfUzMoRue2OkI2YLVp+idhS lpK6Dw9Wx47rvwj/xaXHjGPI3PhwQMQe4939eei4If/EBA4hq5KpTaHuhcW7yVj/cz3pvz+xu 655kZWaMdlNj7SiFjEHHEf0umEDe5d+V3YrZt1iUWl2qTBMFY0kDFpc8G+4Sc8PMKlx8= Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The sequencer client manager reports timestamps in units of unsigned 32-bit seconds/nanoseconds, but that does not suffer from the y2038 overflow because it stores only the delta since the 'last_update' time was recorded. However, the use of the do_gettimeofday() function is problematic and we have to replace it to avoid the overflow on on 32-bit architectures. This uses 'struct timespec64' to record 'last_update', and changes the code to use monotonic timestamps that do not suffer from leap seconds and settimeofday updates. As a side-effect, the code can now use the timespec64_sub() helper and become more readable and also avoid a multiplication to convert from microseconds to nanoseconds. Signed-off-by: Arnd Bergmann --- sound/core/seq/seq_timer.c | 23 +++++++++-------------- sound/core/seq/seq_timer.h | 2 +- 2 files changed, 10 insertions(+), 15 deletions(-) -- 2.9.0 diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index 293104926098..dcc102813aef 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c @@ -165,7 +165,7 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri, snd_seq_timer_update_tick(&tmr->tick, resolution); /* register actual time of this timer update */ - do_gettimeofday(&tmr->last_update); + ktime_get_ts64(&tmr->last_update); spin_unlock_irqrestore(&tmr->lock, flags); @@ -392,7 +392,7 @@ static int seq_timer_start(struct snd_seq_timer *tmr) return -EINVAL; snd_timer_start(tmr->timeri, tmr->ticks); tmr->running = 1; - do_gettimeofday(&tmr->last_update); + ktime_get_ts64(&tmr->last_update); return 0; } @@ -420,7 +420,7 @@ static int seq_timer_continue(struct snd_seq_timer *tmr) } snd_timer_start(tmr->timeri, tmr->ticks); tmr->running = 1; - do_gettimeofday(&tmr->last_update); + ktime_get_ts64(&tmr->last_update); return 0; } @@ -444,17 +444,12 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr) spin_lock_irqsave(&tmr->lock, flags); cur_time = tmr->cur_time; if (tmr->running) { - struct timeval tm; - int usec; - do_gettimeofday(&tm); - usec = (int)(tm.tv_usec - tmr->last_update.tv_usec); - if (usec < 0) { - cur_time.tv_nsec += (1000000 + usec) * 1000; - cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec - 1; - } else { - cur_time.tv_nsec += usec * 1000; - cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec; - } + struct timespec64 tm; + + ktime_get_ts64(&tm); + tm = timespec64_sub(tm, tmr->last_update); + cur_time.tv_nsec = tm.tv_nsec; + cur_time.tv_sec = tm.tv_sec; snd_seq_sanity_real_time(&cur_time); } spin_unlock_irqrestore(&tmr->lock, flags); diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h index 88dfb71805ae..9506b661fe5b 100644 --- a/sound/core/seq/seq_timer.h +++ b/sound/core/seq/seq_timer.h @@ -52,7 +52,7 @@ struct snd_seq_timer { unsigned int skew; unsigned int skew_base; - struct timeval last_update; /* time of last clock update, used for interpolation */ + struct timespec64 last_update; /* time of last clock update, used for interpolation */ spinlock_t lock; };