From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
Jon Hunter <jon-hunter@ti.com>, John Stultz <johnstul@us.ibm.com>,
Thomas Gleixner <tglx@linutronix.de>
Subject: [30/98] nohz: Prevent clocksource wrapping during idle
Date: Tue, 26 Jan 2010 15:33:56 -0800 [thread overview]
Message-ID: <20100126233924.808156660@mini.kroah.org> (raw)
In-Reply-To: <20100126233950.GA5372@kroah.com>
2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jon Hunter <jon-hunter@ti.com>
commit 98962465ed9e6ea99c38e0af63fe1dcb5a79dc25 upstream.
The dynamic tick allows the kernel to sleep for periods longer than a
single tick, but it does not limit the sleep time currently. In the
worst case the kernel could sleep longer than the wrap around time of
the time keeping clock source which would result in losing track of
time.
Prevent this by limiting it to the safe maximum sleep time of the
current time keeping clock source. The value is calculated when the
clock source is registered.
[ tglx: simplified the code a bit and massaged the commit msg ]
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Cc: John Stultz <johnstul@us.ibm.com>
LKML-Reference: <1250617512-23567-2-git-send-email-jon-hunter@ti.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
include/linux/clocksource.h | 2 +
include/linux/time.h | 1
kernel/time/clocksource.c | 44 +++++++++++++++++++++++++++++++++++++
kernel/time/tick-sched.c | 52 ++++++++++++++++++++++++++++++++------------
kernel/time/timekeeping.c | 11 +++++++++
5 files changed, 96 insertions(+), 14 deletions(-)
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -151,6 +151,7 @@ extern u64 timecounter_cyc2time(struct t
* subtraction of non 64 bit counters
* @mult: cycle to nanosecond multiplier
* @shift: cycle to nanosecond divisor (power of two)
+ * @max_idle_ns: max idle time permitted by the clocksource (nsecs)
* @flags: flags describing special properties
* @vread: vsyscall based read
* @resume: resume function for the clocksource, if necessary
@@ -168,6 +169,7 @@ struct clocksource {
cycle_t mask;
u32 mult;
u32 shift;
+ u64 max_idle_ns;
unsigned long flags;
cycle_t (*vread)(void);
void (*resume)(void);
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -148,6 +148,7 @@ extern void monotonic_to_bootbased(struc
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
extern int timekeeping_valid_for_hres(void);
+extern u64 timekeeping_max_deferment(void);
extern void update_wall_time(void);
extern void update_xtime_cache(u64 nsec);
extern void timekeeping_leap_insert(int leapsecond);
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -416,6 +416,47 @@ void clocksource_touch_watchdog(void)
#ifdef CONFIG_GENERIC_TIME
/**
+ * clocksource_max_deferment - Returns max time the clocksource can be deferred
+ * @cs: Pointer to clocksource
+ *
+ */
+static u64 clocksource_max_deferment(struct clocksource *cs)
+{
+ u64 max_nsecs, max_cycles;
+
+ /*
+ * Calculate the maximum number of cycles that we can pass to the
+ * cyc2ns function without overflowing a 64-bit signed result. The
+ * maximum number of cycles is equal to ULLONG_MAX/cs->mult which
+ * is equivalent to the below.
+ * max_cycles < (2^63)/cs->mult
+ * max_cycles < 2^(log2((2^63)/cs->mult))
+ * max_cycles < 2^(log2(2^63) - log2(cs->mult))
+ * max_cycles < 2^(63 - log2(cs->mult))
+ * max_cycles < 1 << (63 - log2(cs->mult))
+ * Please note that we add 1 to the result of the log2 to account for
+ * any rounding errors, ensure the above inequality is satisfied and
+ * no overflow will occur.
+ */
+ max_cycles = 1ULL << (63 - (ilog2(cs->mult) + 1));
+
+ /*
+ * The actual maximum number of cycles we can defer the clocksource is
+ * determined by the minimum of max_cycles and cs->mask.
+ */
+ max_cycles = min_t(u64, max_cycles, (u64) cs->mask);
+ max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult, cs->shift);
+
+ /*
+ * To ensure that the clocksource does not wrap whilst we are idle,
+ * limit the time the clocksource can be deferred by 12.5%. Please
+ * note a margin of 12.5% is used because this can be computed with
+ * a shift, versus say 10% which would require division.
+ */
+ return max_nsecs - (max_nsecs >> 5);
+}
+
+/**
* clocksource_select - Select the best clocksource available
*
* Private function. Must hold clocksource_mutex when called.
@@ -511,6 +552,9 @@ static void clocksource_enqueue(struct c
*/
int clocksource_register(struct clocksource *cs)
{
+ /* calculate max idle time permitted for this clocksource */
+ cs->max_idle_ns = clocksource_max_deferment(cs);
+
mutex_lock(&clocksource_mutex);
clocksource_enqueue(cs);
clocksource_select();
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -216,6 +216,7 @@ void tick_nohz_stop_sched_tick(int inidl
struct tick_sched *ts;
ktime_t last_update, expires, now;
struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
+ u64 time_delta;
int cpu;
local_irq_save(flags);
@@ -275,6 +276,17 @@ void tick_nohz_stop_sched_tick(int inidl
seq = read_seqbegin(&xtime_lock);
last_update = last_jiffies_update;
last_jiffies = jiffies;
+
+ /*
+ * On SMP we really should only care for the CPU which
+ * has the do_timer duty assigned. All other CPUs can
+ * sleep as long as they want.
+ */
+ if (cpu == tick_do_timer_cpu ||
+ tick_do_timer_cpu == TICK_DO_TIMER_NONE)
+ time_delta = timekeeping_max_deferment();
+ else
+ time_delta = KTIME_MAX;
} while (read_seqretry(&xtime_lock, seq));
/* Get the next timer wheel timer */
@@ -294,11 +306,26 @@ void tick_nohz_stop_sched_tick(int inidl
if ((long)delta_jiffies >= 1) {
/*
- * calculate the expiry time for the next timer wheel
- * timer
- */
- expires = ktime_add_ns(last_update, tick_period.tv64 *
- delta_jiffies);
+ * calculate the expiry time for the next timer wheel
+ * timer. delta_jiffies >= NEXT_TIMER_MAX_DELTA signals
+ * that there is no timer pending or at least extremely
+ * far into the future (12 days for HZ=1000). In this
+ * case we set the expiry to the end of time.
+ */
+ if (likely(delta_jiffies < NEXT_TIMER_MAX_DELTA)) {
+ /*
+ * Calculate the time delta for the next timer event.
+ * If the time delta exceeds the maximum time delta
+ * permitted by the current clocksource then adjust
+ * the time delta accordingly to ensure the
+ * clocksource does not wrap.
+ */
+ time_delta = min_t(u64, time_delta,
+ tick_period.tv64 * delta_jiffies);
+ expires = ktime_add_ns(last_update, time_delta);
+ } else {
+ expires.tv64 = KTIME_MAX;
+ }
/*
* If this cpu is the one which updates jiffies, then
@@ -342,22 +369,19 @@ void tick_nohz_stop_sched_tick(int inidl
ts->idle_sleeps++;
+ /* Mark expires */
+ ts->idle_expires = expires;
+
/*
- * delta_jiffies >= NEXT_TIMER_MAX_DELTA signals that
- * there is no timer pending or at least extremly far
- * into the future (12 days for HZ=1000). In this case
- * we simply stop the tick timer:
+ * If the expiration time == KTIME_MAX, then
+ * in this case we simply stop the tick timer.
*/
- if (unlikely(delta_jiffies >= NEXT_TIMER_MAX_DELTA)) {
- ts->idle_expires.tv64 = KTIME_MAX;
+ if (unlikely(expires.tv64 == KTIME_MAX)) {
if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
hrtimer_cancel(&ts->sched_timer);
goto out;
}
- /* Mark expiries */
- ts->idle_expires = expires;
-
if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
hrtimer_start(&ts->sched_timer, expires,
HRTIMER_MODE_ABS_PINNED);
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -488,6 +488,17 @@ int timekeeping_valid_for_hres(void)
}
/**
+ * timekeeping_max_deferment - Returns max time the clocksource can be deferred
+ *
+ * Caller must observe xtime_lock via read_seqbegin/read_seqretry to
+ * ensure that the clocksource does not change!
+ */
+u64 timekeeping_max_deferment(void)
+{
+ return timekeeper.clock->max_idle_ns;
+}
+
+/**
* read_persistent_clock - Return time from the persistent clock.
*
* Weak dummy function for arches that do not yet support it.
next prev parent reply other threads:[~2010-01-27 0:00 UTC|newest]
Thread overview: 110+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-26 23:39 [00/98] 2.6.32.7-stable review Greg KH
2010-01-26 23:33 ` [01/98] clockevent: Dont remove broadcast device when cpu is dead Greg KH
2010-01-26 23:33 ` [02/98] clockevents: Add missing include to pacify sparse Greg KH
2010-01-26 23:33 ` [03/98] ACPI: dont cond_resched if irq is disabled Greg KH
2010-01-26 23:33 ` [04/98] sfc: Fix DMA mapping cleanup in case of an error in TSO Greg KH
2010-01-26 23:33 ` [05/98] be2net: Add support for next generation of BladeEngine device Greg KH
2010-01-26 23:33 ` [06/98] be2net: Add the new PCI IDs to PCI_DEVICE_TABLE Greg KH
2010-01-26 23:33 ` [07/98] [SCSI] mpt2sas: New device SAS2208 support is added Greg KH
2010-01-26 23:33 ` [08/98] ar9170: Add support for D-Link DWA 160 A2 Greg KH
2010-01-26 23:33 ` [09/98] [stable] [PATCH] powerpc/fsl: Add PCI device ids for new QoirQ chips Greg KH
2010-01-26 23:33 ` [10/98] davinci: dm646x: Add support for 3.x silicon revision Greg KH
2010-01-26 23:33 ` [11/98] Input: ALPS - add interleaved protocol support (Dell E6x00 series) Greg KH
2010-01-26 23:33 ` [12/98] Driver-Core: devtmpfs - set root directory mode to 0755 Greg KH
2010-01-27 4:09 ` Kay Sievers
2010-01-27 16:35 ` Greg KH
2010-01-26 23:33 ` [13/98] driver-core: fix devtmpfs crash on s390 Greg KH
2010-01-26 23:33 ` [14/98] ALSA: hda - Add PCI IDs for Nvidia G2xx-series Greg KH
2010-01-26 23:33 ` [15/98] V4L/DVB (13569): smsusb: add autodetection support for five additional Hauppauge USB IDs Greg KH
2010-01-26 23:33 ` [16/98] USB: mos7840: add device IDs for B&B electronics devices Greg KH
2010-01-26 23:33 ` [17/98] USB: ftdi_sio: add USB device IDs for B&B Electronics line Greg KH
2010-01-26 23:33 ` [18/98] V4L/DVB (13168): Add support for Asus Europa Hybrid DVB-T card (SAA7134 SubVendor ID: 0x1043 Device ID: 0x4847) Greg KH
2010-01-26 23:33 ` [19/98] [WATCHDOG] iTCO_wdt: Add support for Intel Ibex Peak Greg KH
2010-01-26 23:33 ` [20/98] atl1c:use common_task instead of reset_task and link_chg_task Greg KH
2010-01-27 5:25 ` [Stable-review] " Willy Tarreau
2010-01-27 14:45 ` Stefan Bader
2010-01-30 18:09 ` Willy Tarreau
2010-01-26 23:33 ` [21/98] atl1e:disable NETIF_F_TSO6 for hardware limit Greg KH
2010-01-26 23:33 ` [22/98] V4L/DVB (13680a): DocBook/media: copy images after building HTML Greg KH
2010-01-26 23:33 ` [23/98] V4L/DVB (13680b): DocBook/media: create links for included sources Greg KH
2010-01-26 23:33 ` [24/98] netfilter: xtables: fix conntrack match v1 ipt-save output Greg KH
2010-01-26 23:33 ` [25/98] partitions: read whole sector with EFI GPT header Greg KH
2010-01-26 23:33 ` [26/98] partitions: use sector size for EFI GPT Greg KH
2010-01-26 23:33 ` [27/98] ALSA: ice1724 - Patch for suspend/resume for ESI Juli@ Greg KH
2010-01-26 23:33 ` [28/98] sched: Fix isolcpus boot option Greg KH
2010-01-26 23:33 ` [29/98] sched: Fix missing sched tunable recalculation on cpu add/remove Greg KH
2010-01-26 23:33 ` Greg KH [this message]
2010-01-26 23:33 ` [31/98] nfsd: Fix sort_pacl in fs/nfsd/nf4acl.c to actually sort groups Greg KH
2010-01-26 23:33 ` [32/98] timers, init: Limit the number of per cpu calibration bootup messages Greg KH
2010-01-26 23:33 ` [33/98] PCI: Always set prefetchable base/limit upper32 registers Greg KH
2010-01-26 23:34 ` [34/98] [SCSI] iscsi class: modify handling of replacement timeout Greg KH
2010-01-26 23:34 ` [35/98] NFS: Revert default r/wsize behavior Greg KH
2010-01-26 23:34 ` [36/98] HID: fixup quirk for NCR devices Greg KH
2010-01-26 23:34 ` [37/98] [SCSI] scsi_devinfo: update Hitachi entries (v2) Greg KH
2010-01-26 23:34 ` [38/98] [SCSI] scsi_dh: create sysfs file, dh_state for all SCSI disk devices Greg KH
2010-01-26 23:34 ` [39/98] [SCSI] scsi_transport_fc: remove invalid BUG_ON Greg KH
2010-01-26 23:34 ` [40/98] [SCSI] lpfc: fix hang on SGI ia64 platform Greg KH
2010-01-26 23:34 ` [41/98] [SCSI] libfc: fix typo in retry check on received PRLI Greg KH
2010-01-26 23:34 ` [42/98] [SCSI] libfc: fix ddp in fc_fcp for 0 xid Greg KH
2010-01-26 23:34 ` [43/98] [SCSI] fcoe: remove redundant checking of netdev->netdev_ops Greg KH
2010-01-26 23:34 ` [44/98] [SCSI] libfc: Fix wrong scsi return status under FC_DATA_UNDRUN Greg KH
2010-01-26 23:34 ` [45/98] [SCSI] libfc: lport: fix minor documentation errors Greg KH
2010-01-26 23:34 ` [46/98] [SCSI] libfc: dont WARN_ON in lport_timeout for RESET state Greg KH
2010-01-26 23:34 ` [47/98] [SCSI] fcoe: initialize return value in fcoe_destroy Greg KH
2010-01-26 23:34 ` [48/98] [SCSI] libfc: Fix frags in frame exceeding SKB_MAX_FRAGS in fc_fcp_send_data Greg KH
2010-01-26 23:34 ` [49/98] [SCSI] libfc: fix memory corruption caused by double frees and bad error handling Greg KH
2010-01-26 23:34 ` [50/98] [SCSI] libfc: fix free of fc_rport_priv with timer pending Greg KH
2010-01-27 0:03 ` Joe Eykholt
2010-01-27 2:03 ` Greg KH
2010-01-26 23:34 ` [51/98] [SCSI] fcoe, libfc: fix an libfc issue with queue ramp down in libfc Greg KH
2010-01-26 23:34 ` [52/98] [SCSI] fcoe: Fix checking san mac address Greg KH
2010-01-26 23:34 ` [53/98] [SCSI] fcoe: Fix getting san mac for VLAN interface Greg KH
2010-01-26 23:34 ` [54/98] qlge: Remove explicit setting of PCI Dev CTL reg Greg KH
2010-01-26 23:34 ` [55/98] qlge: Set PCIE max read request size Greg KH
2010-01-26 23:34 ` [56/98] qlge: Dont fail open when port is not initialized Greg KH
2010-01-26 23:34 ` [57/98] qlge: Add handler for DCBX firmware event Greg KH
2010-01-26 23:34 ` [58/98] qlge: Bonding fix for mode 6 Greg KH
2010-01-26 23:34 ` [59/98] PCI: AER: fix aer inject result in kernel oops Greg KH
2010-01-26 23:34 ` [60/98] DMI: allow omitting ident strings in DMI tables Greg KH
2010-01-26 23:34 ` [61/98] Input: i8042 - remove identification strings from " Greg KH
2010-01-27 0:00 ` Linus Torvalds
2010-01-27 0:11 ` Greg KH
2010-01-26 23:34 ` [62/98] Input: i8042 - add Gigabyte M1022M to the noloop list Greg KH
2010-01-26 23:34 ` [63/98] Input: i8042 - add Dritek quirk for Acer Aspire 5610 Greg KH
2010-01-26 23:34 ` [64/98] ALSA: hda - select IbexPeak handler for Calpella Greg KH
2010-01-26 23:34 ` [65/98] ALSA: hda - Fix quirk for Maxdata obook4-1 Greg KH
2010-01-26 23:34 ` [66/98] ALSA: hda - Add missing Line-Out and PCM switches as slave Greg KH
2010-01-26 23:34 ` [67/98] [WATCHDOG] iTCO_wdt.c - cleanup chipset documentation Greg KH
2010-01-26 23:34 ` [68/98] [WATCHDOG] iTCO_wdt: add PCI ID for the Intel EP80579 (Tolapai) SoC Greg KH
2010-01-26 23:34 ` [69/98] [WATCHDOG] iTCO_wdt: Add Intel Cougar Point and PCH DeviceIDs Greg KH
2010-01-26 23:34 ` [70/98] ahci: disable SNotification capability for ich8 Greg KH
2010-01-26 23:34 ` [71/98] ata_piix: fix MWDMA handling on PIIX3 Greg KH
2010-01-26 23:34 ` [72/98] ata_piix: enable 32bit PIO on SATA piix Greg KH
2010-01-26 23:56 ` Tejun Heo
2010-01-27 0:03 ` Greg KH
2010-01-26 23:34 ` [73/98] md: fix small irregularity with start_ro module parameter Greg KH
2010-01-26 23:34 ` [74/98] V4L/DVB (13826): uvcvideo: Fix controls blacklisting Greg KH
2010-01-26 23:34 ` [75/98] [S390] cio: fix double free in case of probe failure Greg KH
2010-01-26 23:34 ` [76/98] [S390] cio: dont panic in non-fatal conditions Greg KH
2010-01-26 23:34 ` [77/98] netiucv: displayed TX bytes value much too high Greg KH
2010-01-26 23:34 ` [78/98] ipc ns: fix memory leak (idr) Greg KH
2010-01-26 23:34 ` [79/98] ALSA: hda - Fix HP T5735 automute Greg KH
2010-01-26 23:34 ` [80/98] hwmon: (fschmd) Fix a memleak on multiple opens of /dev/watchdog Greg KH
2010-01-26 23:34 ` [81/98] UBI: fix memory leak in update path Greg KH
2010-01-26 23:34 ` [82/98] UBI: initialise update marker Greg KH
2010-01-26 23:34 ` [83/98] ASoC: fix a memory-leak in wm8903 Greg KH
2010-01-26 23:34 ` [84/98] mac80211: check that ieee80211_set_power_mgmt only handles STA interfaces Greg KH
2010-01-26 23:34 ` [85/98] cfg80211: fix channel setting for wext Greg KH
2010-01-26 23:34 ` [86/98] KVM: S390: fix potential array overrun in intercept handling Greg KH
2010-01-26 23:34 ` [87/98] KVM: only allow one gsi per fd Greg KH
2010-01-26 23:34 ` [88/98] KVM: Fix race between APIC TMR and IRR Greg KH
2010-01-26 23:34 ` [89/98] KVM: MMU: bail out pagewalk on kvm_read_guest error Greg KH
2010-01-26 23:34 ` [90/98] KVM: x86: Fix host_mapping_level() Greg KH
2010-01-26 23:34 ` [91/98] KVM: x86: Fix probable memory leak of vcpu->arch.mce_banks Greg KH
2010-01-26 23:34 ` [92/98] KVM: x86: Fix leak of free lapic date in kvm_arch_vcpu_init() Greg KH
2010-01-26 23:34 ` [93/98] KVM: fix lock imbalance in kvm_*_irq_source_id() Greg KH
2010-01-26 23:35 ` [94/98] KVM: only clear irq_source_id if irqchip is present Greg KH
2010-01-26 23:35 ` [95/98] IPoIB: Clear ipoib_neigh.dgid in ipoib_neigh_alloc() Greg KH
2010-01-26 23:35 ` [96/98] x86: Reenable TSC sync check at boot, even with NONSTOP_TSC Greg KH
2010-01-26 23:35 ` [97/98] ACPI: enable C2 and Turbo-mode on Nehalem notebooks on A/C Greg KH
2010-01-26 23:35 ` [98/98] iwlwifi: Fix throughput stall issue in HT mode for 5000 Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100126233924.808156660@mini.kroah.org \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=johnstul@us.ibm.com \
--cc=jon-hunter@ti.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable-review@kernel.org \
--cc=stable@kernel.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome