[patch 20/23] add /proc/sys/kernel/timeout_granularity

From: Thomas Gleixner
Date: Fri Sep 29 2006 - 20:05:14 EST


From: Ingo Molnar <mingo@xxxxxxx>

Introduce timeout granularity: process timer wheel timers every
timeout_granularity jiffies. Defaults to 1 (process timers HZ times
per second - most finegrained).

Signed-off-by: Ingo Molnar <mingo@xxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
--
Documentation/kernel-parameters.txt | 6 ++++++
include/linux/sysctl.h | 1 +
include/linux/timer.h | 1 +
kernel/sysctl.c | 10 ++++++++++
kernel/timer.c | 24 +++++++++++++++++++++---
5 files changed, 39 insertions(+), 3 deletions(-)

Index: linux-2.6.18-mm2/Documentation/kernel-parameters.txt
===================================================================
--- linux-2.6.18-mm2.orig/Documentation/kernel-parameters.txt 2006-09-30 01:41:09.000000000 +0200
+++ linux-2.6.18-mm2/Documentation/kernel-parameters.txt 2006-09-30 01:41:19.000000000 +0200
@@ -1637,6 +1637,12 @@ and is between 256 and 4096 characters.

time Show timing data prefixed to each printk message line

+ timeout_granularity=
+ [KNL]
+ Timeout granularity: process timer wheel timers every
+ timeout_granularity jiffies. Defaults to 1 (process
+ timers HZ times per second - most finegrained).
+
clocksource= [GENERIC_TIME] Override the default clocksource
Override the default clocksource and use the clocksource
with the name specified.
Index: linux-2.6.18-mm2/include/linux/sysctl.h
===================================================================
--- linux-2.6.18-mm2.orig/include/linux/sysctl.h 2006-09-30 01:41:09.000000000 +0200
+++ linux-2.6.18-mm2/include/linux/sysctl.h 2006-09-30 01:41:19.000000000 +0200
@@ -153,6 +153,7 @@ enum
KERN_MAX_LOCK_DEPTH=74,
KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
+ KERN_TIMEOUT_GRANULARITY=77, /* int: timeout granularity in jiffies */
};


Index: linux-2.6.18-mm2/include/linux/timer.h
===================================================================
--- linux-2.6.18-mm2.orig/include/linux/timer.h 2006-09-30 01:41:16.000000000 +0200
+++ linux-2.6.18-mm2/include/linux/timer.h 2006-09-30 01:41:19.000000000 +0200
@@ -18,6 +18,7 @@ struct timer_list {
};

extern struct tvec_t_base_s boot_tvec_bases;
+extern unsigned int timeout_granularity;

#define TIMER_INITIALIZER(_function, _expires, _data) { \
.function = (_function), \
Index: linux-2.6.18-mm2/kernel/sysctl.c
===================================================================
--- linux-2.6.18-mm2.orig/kernel/sysctl.c 2006-09-30 01:41:09.000000000 +0200
+++ linux-2.6.18-mm2/kernel/sysctl.c 2006-09-30 01:41:19.000000000 +0200
@@ -640,6 +640,16 @@ static ctl_table kern_table[] = {
.proc_handler = &proc_dointvec,
},
#endif
+#ifdef CONFIG_NO_HZ
+ {
+ .ctl_name = KERN_TIMEOUT_GRANULARITY,
+ .procname = "timeout_granularity",
+ .data = &timeout_granularity,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
{
.ctl_name = KERN_PIDMAX,
.procname = "pid_max",
Index: linux-2.6.18-mm2/kernel/timer.c
===================================================================
--- linux-2.6.18-mm2.orig/kernel/timer.c 2006-09-30 01:41:18.000000000 +0200
+++ linux-2.6.18-mm2/kernel/timer.c 2006-09-30 01:41:19.000000000 +0200
@@ -66,6 +66,8 @@ typedef struct tvec_root_s {
struct list_head vec[TVR_SIZE];
} tvec_root_t;

+unsigned int __read_mostly timeout_granularity = 1;
+
struct tvec_t_base_s {
spinlock_t lock;
struct timer_list *running_timer;
@@ -417,7 +419,9 @@ static inline void __run_timers(tvec_bas
struct timer_list *timer;

spin_lock_irq(&base->lock);
- while (time_after_eq(jiffies, base->timer_jiffies)) {
+
+ while (time_before_eq(base->timer_jiffies, jiffies)) {
+
struct list_head work_list;
struct list_head *head = &work_list;
int index = base->timer_jiffies & TVR_MASK;
@@ -569,7 +573,15 @@ found:
* delayed processing, so make sure we return a value that
* makes sense externally:
*/
- return expires - (now - base->timer_jiffies);
+ expires -= (now - base->timer_jiffies);
+
+ /*
+ * Round it up per timeout_granularity:
+ */
+ expires += timeout_granularity - 1;
+ expires -= expires % timeout_granularity;
+
+ return expires;
}

unsigned long get_next_timer_interrupt(unsigned long now)
@@ -1112,7 +1124,13 @@ static void run_timer_softirq(struct sof
*/
void run_local_timers(void)
{
- raise_softirq(TIMER_SOFTIRQ);
+ tvec_base_t *base = per_cpu(tvec_bases, smp_processor_id());
+ /*
+ * Only wake up the TIMER_SOFTIRQ every timeout_granularity
+ * jiffies:
+ */
+ if (time_before_eq(base->timer_jiffies + timeout_granularity, jiffies))
+ raise_softirq(TIMER_SOFTIRQ);
softlockup_tick();
}


--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/