From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757579AbcAJU56 (ORCPT ); Sun, 10 Jan 2016 15:57:58 -0500 Received: from mout.gmx.net ([212.227.15.18]:61924 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757341AbcAJU5z (ORCPT ); Sun, 10 Jan 2016 15:57:55 -0500 Date: Sun, 10 Jan 2016 21:57:39 +0100 From: Helge Deller To: linux-parisc@vger.kernel.org, Thomas Gleixner , linux-m68k@vger.kernel.org, dhowells@redhat.com, linux-kernel@vger.kernel.org Subject: [PATCH parisc,frv,m68k] timerfd: Fix timeout values with CONFIG_TIME_LOW_RES=y Message-ID: <20160110205739.GA21713@p100.box> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160104222757.GA969@p100.box> User-Agent: Mutt/1.5.23 (2014-03-12) X-Provags-ID: V03:K0:qt3nkpzg4PMOlWXyD9KAiUcc12QBG406VseotkulQWThT3StCoX PJYTHfEIP23XBQcBeUNYJ/+T7AQeB0j32/CIpZswMH71q3OE+PcQSUxK5k0dPxvXgXbH9mB 8Nyr0MMhL74b9gH2bqAElCq1OKPCCzfqgC3mDazpz6yd3bFDoxB37lq9n87kkdhphDR4UYa vpAl4jhKpQTUobLclSsYw== X-UI-Out-Filterresults: notjunk:1;V01:K0:HOpuX6vRHmU=:cewJdA4m0ztpGKZMtUXBsP gHy/UQJABFygtFzGnQemUS8ZNvfSRjw9w3iaIRO5PAt5YMi4AcJ8oJJLs+8zBIgpNnuLRO42r GIkF/zQckD6K57czuBr9P+QsiqNzRpGvcseh5uEjdN0CxrP4srwJC1yahG2LCjihhfNMGLiuf /oBidfO/geA7opc+M3cLiLGdq6mR2r1EP1qfmtw75rT58VXuPRNFcpMFahEFPSyziF2OzHtQb T/L+fi7Gfpvtya1CDEgnOql7looGgVOoCjppOp9ZG6Rj7bQo/OPRumcWbHfdwVJqsfi+dJLfM MPwS26en7Sfy73Tv/r8WZb8KYdSTPZUeAl0WSZrniA8M/DyaFSEw2N0t8VokfChGSBhfnrShZ BU1BYOsQtLHw1hUWnl8darKvyh8ktzR30NW5zH8tvtf9IdA21XxUv1w85XIw1D0xnFCPsTvaR qjyD1xkdTmxvLTOgUhGCq8/nk9KjNUlvo4iHAmMnnnifNKxzFrjeLn4ECqHWN9zh3GzCO6tqt Glx01+xkiTfb6nHF1eqJgDrb13IsgBunhnBj11Wn3ZWENtoAZr7J+Hl1x2MeIK/bRtASRBzDE gobygEkwVnkLkPH5uBtDGHfTlBGR3CuT7ptQFHkeAOqEx91iAO6T74g9m3m2Ws/4wIpuBji11 kPBrlJlwXcf2iPrlx05jyi+f81A7BGD13v0N/4/cpGeBgrylfzl4t2kzs0DCku8vMrnasTLuQ UacVpaoDP9si4lc2H7iWGMqv3lsxsM8WxGJUPNYi0xiiFvK8On2S5ydwyIU= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On architectures where CONFIG_TIME_LOW_RES is set (currently parisc, m68k, frv) calling timerfd_settime() to set a timeout and directly afterwards calling timerfd_gettime() to get the remaining time shows a behaviour that the remaining time can be higher than the originally set timeout. Here is an example showing the problem, that the nsec value of it_value is higher than the set nsec value: timerfd_settime: interval (sec=0, nsec=100000000) it_value (sec=0, nsec=100000000) timerfd_gettime: interval (sec=0, nsec=100000000) it_value (sec=0, nsec=103029949) This happens because in hrtimer_start_range_ns() the expiry time is rounded to the next jiffies period to avoid short timeouts. When running with HZ=250 this is 4ms which can be seen in the example above. This behaviour confuses userspace programs. For example, the debian liblinux-fd-perl and libnanomsg-raw-perl packges fail to build because the timeout is higher than expected. Fix this problem by subtracting the value added by hrtimer_start_range_ns() before returning the timeout back to userspace. Signed-off-by: Helge Deller diff --git a/fs/timerfd.c b/fs/timerfd.c index b94fa6c..098ac0a 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -152,8 +152,17 @@ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) if (isalarm(ctx)) remaining = alarm_expires_remaining(&ctx->t.alarm); - else + else { remaining = hrtimer_expires_remaining(&ctx->t.tmr); +#ifdef CONFIG_TIME_LOW_RES + /* Expiry time was rounded up in hrtimer_start_range_ns() + * to the next jiffies period to avoid short timeouts. + * Subtract it here again to avoid userspace seeing higher + * values than originally programmed. */ + if (!(ctx->settime_flags & TFD_TIMER_ABSTIME)) + remaining.tv64 -= hrtimer_resolution; +#endif + } return remaining.tv64 < 0 ? ktime_set(0, 0): remaining; }