From patchwork Fri Jan 4 09:12:01 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Perches X-Patchwork-Id: 209407 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 6AC832C0089 for ; Fri, 4 Jan 2013 20:12:32 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754256Ab3ADJMH (ORCPT ); Fri, 4 Jan 2013 04:12:07 -0500 Received: from perches-mx.perches.com ([206.117.179.246]:37500 "EHLO labridge.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754090Ab3ADJMC (ORCPT ); Fri, 4 Jan 2013 04:12:02 -0500 Received: from [173.51.221.202] (account joe@perches.com HELO [192.168.1.167]) by labridge.com (CommuniGate Pro SMTP 5.0.14) with ESMTPA id 20464399; Fri, 04 Jan 2013 01:12:01 -0800 Message-ID: <1357290721.5452.55.camel@joe-AO722> Subject: Re: [PATCH v2 net-next] softirq: reduce latencies From: Joe Perches To: Eric Dumazet Cc: Ben Hutchings , David Miller , Andrew Morton , netdev , "linux-kernel@vger.kernel.org" , Tom Herbert Date: Fri, 04 Jan 2013 01:12:01 -0800 In-Reply-To: <1357287786.1678.87.camel@edumazet-glaptop> References: <1357216132.21409.24107.camel@edumazet-glaptop> <1357250880.2685.29.camel@bwh-desktop.uk.solarflarecom.com> <1357252816.21409.26384.camel@edumazet-glaptop> <1357285780.21409.28416.camel@edumazet-glaptop> <1357287351.5452.44.camel@joe-AO722> <1357287786.1678.87.camel@edumazet-glaptop> X-Mailer: Evolution 3.6.0-0ubuntu3 Mime-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On Fri, 2013-01-04 at 00:23 -0800, Eric Dumazet wrote: > On Fri, 2013-01-04 at 00:15 -0800, Joe Perches wrote: > > Perhaps MAX_SOFTIRQ_TIME should be > > #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) > > though it would be nicer if it were a compile time constant. > > If you send a patch to convert msecs_to_jiffies() to an inline function > when HZ = 1000, I will gladly use it instead of (2*HZ/1000) > > Right now, max(1, msecs_to_jiffies(2)) uses way too many instructions, > while it should be the constant 2, known at compile time. Something like this might work. This is incomplete, it just does msecs_to_jiffies, and it should convert usecs_to_jiffies and the jiffies_to_ types too. Maybe it's worthwhile. It does reduce object size by 16 bytes per call site (x86-32) when the argument is a constant. There are about 800 of these jiffies conversions in kernel sources. What do you think? include/linux/jiffies.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- kernel/time.c | 42 +++--------------------------------------- 2 files changed, 51 insertions(+), 40 deletions(-) --- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index 82ed068..c67ddcf 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -291,7 +291,54 @@ extern unsigned long preset_lpj; */ extern unsigned int jiffies_to_msecs(const unsigned long j); extern unsigned int jiffies_to_usecs(const unsigned long j); -extern unsigned long msecs_to_jiffies(const unsigned int m); +extern unsigned long __msecs_to_jiffies(const unsigned int m); + +static inline unsigned long __inline_msecs_to_jiffies(const unsigned int m) +{ + /* + * Negative value, means infinite timeout: + */ + if ((int)m < 0) + return MAX_JIFFY_OFFSET; + +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + /* + * HZ is equal to or smaller than 1000, and 1000 is a nice + * round multiple of HZ, divide with the factor between them, + * but round upwards: + */ + return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) + /* + * HZ is larger than 1000, and HZ is a nice round multiple of + * 1000 - simply multiply with the factor between them. + * + * But first make sure the multiplication result cannot + * overflow: + */ + if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) + return MAX_JIFFY_OFFSET; + + return m * (HZ / MSEC_PER_SEC); +#else + /* + * Generic case - multiply, round and divide. But first + * check that if we are doing a net multiplication, that + * we wouldn't overflow: + */ + if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) + return MAX_JIFFY_OFFSET; + + return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32) + >> MSEC_TO_HZ_SHR32; +#endif +} + +#define msecs_to_jiffies(x) \ + (__builtin_constant_p(x) ? \ + __inline_msecs_to_jiffies(x) : \ + __msecs_to_jiffies(x)) + extern unsigned long usecs_to_jiffies(const unsigned int u); extern unsigned long timespec_to_jiffies(const struct timespec *value); extern void jiffies_to_timespec(const unsigned long jiffies, diff --git a/kernel/time.c b/kernel/time.c index d226c6a..231f2ac 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -425,47 +425,11 @@ EXPORT_SYMBOL(ns_to_timeval); * * We must also be careful about 32-bit overflows. */ -unsigned long msecs_to_jiffies(const unsigned int m) +unsigned long __msecs_to_jiffies(const unsigned int m) { - /* - * Negative value, means infinite timeout: - */ - if ((int)m < 0) - return MAX_JIFFY_OFFSET; - -#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) - /* - * HZ is equal to or smaller than 1000, and 1000 is a nice - * round multiple of HZ, divide with the factor between them, - * but round upwards: - */ - return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); -#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) - /* - * HZ is larger than 1000, and HZ is a nice round multiple of - * 1000 - simply multiply with the factor between them. - * - * But first make sure the multiplication result cannot - * overflow: - */ - if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) - return MAX_JIFFY_OFFSET; - - return m * (HZ / MSEC_PER_SEC); -#else - /* - * Generic case - multiply, round and divide. But first - * check that if we are doing a net multiplication, that - * we wouldn't overflow: - */ - if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) - return MAX_JIFFY_OFFSET; - - return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32) - >> MSEC_TO_HZ_SHR32; -#endif + return __inline_msecs_to_jiffies(m); } -EXPORT_SYMBOL(msecs_to_jiffies); +EXPORT_SYMBOL(__msecs_to_jiffies); unsigned long usecs_to_jiffies(const unsigned int u) {