From patchwork Thu Oct 12 14:06:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 115633 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp1983476qgn; Thu, 12 Oct 2017 07:07:37 -0700 (PDT) X-Google-Smtp-Source: AOwi7QAzlMb8to3tdS7le0TKwWyyxcrYBeGCjkDUUCsNHBpa4wCIEVNM5W8fdXtndl7MlN2t1Lqz X-Received: by 10.98.31.73 with SMTP id f70mr2279974pff.183.1507817256901; Thu, 12 Oct 2017 07:07:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507817256; cv=none; d=google.com; s=arc-20160816; b=0h9Naaerc12bMprM1jrQhuD5VCoDforLRn9AMdobqybtdiimy61/JGxs9jHVjwxxjN V1Xx89eVKTWgZyuQ9XfC7iZ8RfeIoq2Xsp4mY2xkZXyaft3L9azMo2j/Xtn7l2ANlpCE fxlP5UUDfQ4ZwxTywJ2clJeaqJ7Rky98yVArJiMwTTk+M222XUNHLUqK4p2Il2mq8ias e4rnSLV0+7//UPKi//yVwGjHi0ofUNV/4WjA67F0JdCoaoeoVD9zqiSZGq3diM/GhbQF PQTXwvgpEQI84WWjfyLHGq2n6QG995nuSJJBKMXpuhrNnkFKrPsoeb5sey/CSMh6OG4J 59rw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=8oBF+40FEOItcFRNL0RePhju1dCx0TjMQ3dX8UkDw/U=; b=nK1zs8s8YjnLLf2HcFJ0xBwBWhDtSEo7Mrz2vex6OuhR955O/WS+cEVu+J4CUOg67s edI6KM9CRaSfH5cb8G+UfiiT9zR4puPgNB42D/3zh+D5fttV/pWsBDBxBAi96dMzWnft unrasj2HnVcNn4IlIXkn+B1PgZdROPYVmgy9GCIwvsT+LPVmq5qei90qg7B08POrG8Hq zYCTQm9irKZwrAhqMZttfSy+uO9ZPNXxX5dv9Ij3eVLubiCqs5/IdoEYVovs0HyGa0vU DczCgaY3CI7IvUCUt+SXuFQISmGBrQhMxxZOYfkmcnKr4j1cp+iSDacYWXg5zeq7vN3o 84HQ== ARC-Authentication-Results: i=1; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c11si4151737pfh.312.2017.10.12.07.07.36; Thu, 12 Oct 2017 07:07:36 -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 S1752173AbdJLOHe (ORCPT + 27 others); Thu, 12 Oct 2017 10:07:34 -0400 Received: from mout.kundenserver.de ([217.72.192.75]:61400 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751348AbdJLOHd (ORCPT ); Thu, 12 Oct 2017 10:07:33 -0400 Received: from wuerfel.lan ([46.223.139.202]) by mrelayeu.kundenserver.de (mreue103 [212.227.15.145]) with ESMTPA (Nemesis) id 0MJnBU-1e1Xg41IaC-001Dri; Thu, 12 Oct 2017 16:07:04 +0200 From: Arnd Bergmann To: Jason Wessel , Thomas Gleixner Cc: y2038@lists.linaro.org, John Stultz , Stephen Boyd , Arnd Bergmann , Andy Shevchenko , Deepa Dinamani , Ingo Molnar , Andrew Morton , linux-kernel@vger.kernel.org, kgdb-bugreport@lists.sourceforge.net Subject: [PATCH] kdb: use __ktime_get_real_seconds instead of __current_kernel_time Date: Thu, 12 Oct 2017 16:06:11 +0200 Message-Id: <20171012140659.2749268-1-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 X-Provags-ID: V03:K0:/2ssX7DBodGIUjMZj9Xgpym+8tx+GxPbRP7EwNS8/zcagv5w2B0 75Meu2iI7wWvj+sG88cAOayNjhDDXLYmp9YK0iHwxtHPQXCDfaFHVxLJ3t4GOq0Bno8qDfB S5B1ywul4OgEck3VJZxPiOk7p7moQxB8CoPLDJm3U+l6dwh64LehGaaUYQIYk63wGDVNQJr MBjIHy5e4NV3tnpEZnDBw== X-UI-Out-Filterresults: notjunk:1; V01:K0:OkRb2NCj+TI=:CzJIvKD/lw3PheI2tVn6o2 18deoUOH7xESxpIWrH6zejeYqt9MTGFxl30rHdTchYyw58omt0U1gO9upNA0FT55H84vpmWuu UxFJ/t6/hU09wZUNh71Sk9rXSNqMiTZxvY/B6+lch3yqD675wfuPURDfrFxjv/nDR3VkE3L6E SI9KqFR67cSpXf4Rp/Td2SveL9SEVIuAn0d21l1rtbst9IUCTpvIY4Z5rWZ6rMTHaJQK7/bp+ 6W76MJP9PZhnJR00Ac7I+KzbPn97coG2Y4w+eZ2cJI47BJ0U1pQPa1bX6P/npDzYAyrYZsIbf htC2dTyY/iqGwx2DHYxIq70CFLdz36W6g+yqFdPkGkVp04gAE5nb5DZLelO/SBYfgl5RkbZt0 OBg9W0Y92IyMVCwuBnm4E7bUTYZvJN43gZ0jBe934bNzjwP6tDw3Qb0AJSRc5b45GFduNEdz3 M9VYWkdRpubPMA1tSx4jAV5YM7k9OrQg/+1oJNS65TatfHFFL2SPTnjkwFxjJKAjUs47jowyS 4qpr2mC7uStIlEqDxoEnfPpSbpvUNertksI2x9wwCN8IutaC24OI7gkYayMzpomoprzc2/3Rf 4W+vR0DaTx0U18zdu72z6jMTi38krtVEEwhy8y9o5jtQ3ex8LaOgq/gW/oPeFVOR4SmxZz9Ov IqtX4eMXRG3XKOvY2dQwFAqFWFqVJgiPfdz0AE/C0hL1fGUXs7+VcNwrum/6/xs/Ug70N/J/8 GNUjoz/LMjTpD9ibHQSbZsAoDEs0rHazrJOoLQ== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org kdb is the only user of the __current_kernel_time() interface, which is not y2038 safe and should be removed at some point. The kdb code also goes to great lengths to print the time in a human-readable format from 'struct timespec', again using a non-y2038-safe re-implementation of the generic time_to_tm() code. Using __current_kernel_time() here is necessary since the regular accessors that require a sequence lock might hang when called during the xtime update. However, this is safe in the particular case since kdb is only interested in the tv_sec field that is updated atomically. In order to make this y2038-safe, I'm converting the code to the generic time64_to_tm helper, but that introduces the problem that we have no interface like __current_kernel_time() that provides a 64-bit timestamp in a lockless, safe and architecture-independent way. I have multiple ideas for how to solve that: - __ktime_get_real_seconds() is lockless, but can return incorrect results on 32-bit architectures in the special case that we are in the process of changing the time across the epoch, either during the timer tick that overflows the seconds in 2038, or while calling settimeofday. - ktime_get_real_fast_ns() would work in this context, but does require a call into the clocksource driver to return a high-resolution timestamp. This may have undesired side-effects in the debugger, since we want to limit the interactions with the rest of the kernel. - Adding a ktime_get_real_fast_seconds() based on tk_fast_mono plus tkr->base_real without the tk_clock_read() delta. Not sure about the value of adding yet another interface here. - Changing the existing ktime_get_real_seconds() to use tk_fast_mono on 32-bit architectures rather than xtime_sec. I think this could work, but am not entirely sure if this is an improvement. I picked the first of those for simplicity here. It's technically not correct but probably good enough as the time is only used for the debugging output and the race will likely never be hit in practice. Another downside is having to move the declaration into a public header file. Let me know if anyone has a different preference. Cc: Andy Shevchenko Link: https://patchwork.kernel.org/patch/9775309/ Signed-off-by: Arnd Bergmann --- include/linux/timekeeping.h | 1 + kernel/debug/kdb/kdb_main.c | 45 +++++--------------------------------- kernel/time/timekeeping_internal.h | 2 -- 3 files changed, 6 insertions(+), 42 deletions(-) -- 2.9.0 Acked-by: Jason Wessel diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index eb98cbdbb323..9b59473556fe 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -41,6 +41,7 @@ struct timespec64 get_monotonic_coarse64(void); extern void getrawmonotonic64(struct timespec64 *ts); extern void ktime_get_ts64(struct timespec64 *ts); extern time64_t ktime_get_seconds(void); +extern time64_t __ktime_get_real_seconds(void); extern time64_t ktime_get_real_seconds(void); extern int __getnstimeofday64(struct timespec64 *tv); diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index c8146d53ca67..69e70f4021fe 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -2479,41 +2479,6 @@ static int kdb_kill(int argc, const char **argv) return 0; } -struct kdb_tm { - int tm_sec; /* seconds */ - int tm_min; /* minutes */ - int tm_hour; /* hours */ - int tm_mday; /* day of the month */ - int tm_mon; /* month */ - int tm_year; /* year */ -}; - -static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm) -{ - /* This will work from 1970-2099, 2100 is not a leap year */ - static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31, - 31, 30, 31, 30, 31 }; - memset(tm, 0, sizeof(*tm)); - tm->tm_sec = tv->tv_sec % (24 * 60 * 60); - tm->tm_mday = tv->tv_sec / (24 * 60 * 60) + - (2 * 365 + 1); /* shift base from 1970 to 1968 */ - tm->tm_min = tm->tm_sec / 60 % 60; - tm->tm_hour = tm->tm_sec / 60 / 60; - tm->tm_sec = tm->tm_sec % 60; - tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1)); - tm->tm_mday %= (4*365+1); - mon_day[1] = 29; - while (tm->tm_mday >= mon_day[tm->tm_mon]) { - tm->tm_mday -= mon_day[tm->tm_mon]; - if (++tm->tm_mon == 12) { - tm->tm_mon = 0; - ++tm->tm_year; - mon_day[1] = 28; - } - } - ++tm->tm_mday; -} - /* * Most of this code has been lifted from kernel/timer.c::sys_sysinfo(). * I cannot call that code directly from kdb, it has an unconditional @@ -2539,8 +2504,8 @@ static void kdb_sysinfo(struct sysinfo *val) */ static int kdb_summary(int argc, const char **argv) { - struct timespec now; - struct kdb_tm tm; + time64_t now; + struct tm tm; struct sysinfo val; if (argc) @@ -2554,9 +2519,9 @@ static int kdb_summary(int argc, const char **argv) kdb_printf("domainname %s\n", init_uts_ns.name.domainname); kdb_printf("ccversion %s\n", __stringify(CCVERSION)); - now = __current_kernel_time(); - kdb_gmtime(&now, &tm); - kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d " + now = __ktime_get_real_seconds(); + time64_to_tm(now, 0, &tm); + kdb_printf("date %04ld-%02d-%02d %02d:%02d:%02d " "tz_minuteswest %d\n", 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, diff --git a/kernel/time/timekeeping_internal.h b/kernel/time/timekeeping_internal.h index 9a18f121f399..58e79485de1b 100644 --- a/kernel/time/timekeeping_internal.h +++ b/kernel/time/timekeeping_internal.h @@ -30,6 +30,4 @@ static inline u64 clocksource_delta(u64 now, u64 last, u64 mask) } #endif -extern time64_t __ktime_get_real_seconds(void); - #endif /* _TIMEKEEPING_INTERNAL_H */