From: Greg Kroah-Hartman Date: Thu, 19 Jul 2012 20:49:09 +0000 (-0700) Subject: really commit the 3.0.38 files, sorry about that. X-Git-Tag: v3.4.7~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e8cd7f5d655c1cb3a27398ddc80c216d67e07722;p=thirdparty%2Fkernel%2Fstable-queue.git really commit the 3.0.38 files, sorry about that. --- diff --git a/releases/3.0.38/arm-samsung-fix-race-in-s3c_adc_start-for-adc.patch b/releases/3.0.38/arm-samsung-fix-race-in-s3c_adc_start-for-adc.patch new file mode 100644 index 00000000000..87a22a09636 --- /dev/null +++ b/releases/3.0.38/arm-samsung-fix-race-in-s3c_adc_start-for-adc.patch @@ -0,0 +1,40 @@ +From 8265981bb439f3ecc5356fb877a6c2a6636ac88a Mon Sep 17 00:00:00 2001 +From: Todd Poynor +Date: Fri, 13 Jul 2012 15:30:48 +0900 +Subject: ARM: SAMSUNG: fix race in s3c_adc_start for ADC + +From: Todd Poynor + +commit 8265981bb439f3ecc5356fb877a6c2a6636ac88a upstream. + +Checking for adc->ts_pend already claimed should be done with the +lock held. + +Signed-off-by: Todd Poynor +Acked-by: Ben Dooks +Signed-off-by: Kukjin Kim +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/plat-samsung/adc.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/arch/arm/plat-samsung/adc.c ++++ b/arch/arm/plat-samsung/adc.c +@@ -143,11 +143,13 @@ int s3c_adc_start(struct s3c_adc_client + return -EINVAL; + } + +- if (client->is_ts && adc->ts_pend) +- return -EAGAIN; +- + spin_lock_irqsave(&adc->lock, flags); + ++ if (client->is_ts && adc->ts_pend) { ++ spin_unlock_irqrestore(&adc->lock, flags); ++ return -EAGAIN; ++ } ++ + client->channel = channel; + client->nr_samples = nr_samples; + diff --git a/releases/3.0.38/block-fix-infinite-loop-in-__getblk_slow.patch b/releases/3.0.38/block-fix-infinite-loop-in-__getblk_slow.patch new file mode 100644 index 00000000000..e1e29f06a92 --- /dev/null +++ b/releases/3.0.38/block-fix-infinite-loop-in-__getblk_slow.patch @@ -0,0 +1,112 @@ +From 91f68c89d8f35fe98ea04159b9a3b42d0149478f Mon Sep 17 00:00:00 2001 +From: Jeff Moyer +Date: Thu, 12 Jul 2012 09:43:14 -0400 +Subject: block: fix infinite loop in __getblk_slow + +From: Jeff Moyer + +commit 91f68c89d8f35fe98ea04159b9a3b42d0149478f upstream. + +Commit 080399aaaf35 ("block: don't mark buffers beyond end of disk as +mapped") exposed a bug in __getblk_slow that causes mount to hang as it +loops infinitely waiting for a buffer that lies beyond the end of the +disk to become uptodate. + +The problem was initially reported by Torsten Hilbrich here: + + https://lkml.org/lkml/2012/6/18/54 + +and also reported independently here: + + http://www.sysresccd.org/forums/viewtopic.php?f=13&t=4511 + +and then Richard W.M. Jones and Marcos Mello noted a few separate +bugzillas also associated with the same issue. This patch has been +confirmed to fix: + + https://bugzilla.redhat.com/show_bug.cgi?id=835019 + +The main problem is here, in __getblk_slow: + + for (;;) { + struct buffer_head * bh; + int ret; + + bh = __find_get_block(bdev, block, size); + if (bh) + return bh; + + ret = grow_buffers(bdev, block, size); + if (ret < 0) + return NULL; + if (ret == 0) + free_more_memory(); + } + +__find_get_block does not find the block, since it will not be marked as +mapped, and so grow_buffers is called to fill in the buffers for the +associated page. I believe the for (;;) loop is there primarily to +retry in the case of memory pressure keeping grow_buffers from +succeeding. However, we also continue to loop for other cases, like the +block lying beond the end of the disk. So, the fix I came up with is to +only loop when grow_buffers fails due to memory allocation issues +(return value of 0). + +The attached patch was tested by myself, Torsten, and Rich, and was +found to resolve the problem in call cases. + +Signed-off-by: Jeff Moyer +Reported-and-Tested-by: Torsten Hilbrich +Tested-by: Richard W.M. Jones +Reviewed-by: Josh Boyer +[ Jens is on vacation, taking this directly - Linus ] +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/buffer.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -1084,6 +1084,9 @@ grow_buffers(struct block_device *bdev, + static struct buffer_head * + __getblk_slow(struct block_device *bdev, sector_t block, int size) + { ++ int ret; ++ struct buffer_head *bh; ++ + /* Size must be multiple of hard sectorsize */ + if (unlikely(size & (bdev_logical_block_size(bdev)-1) || + (size < 512 || size > PAGE_SIZE))) { +@@ -1096,20 +1099,21 @@ __getblk_slow(struct block_device *bdev, + return NULL; + } + +- for (;;) { +- struct buffer_head * bh; +- int ret; ++retry: ++ bh = __find_get_block(bdev, block, size); ++ if (bh) ++ return bh; + ++ ret = grow_buffers(bdev, block, size); ++ if (ret == 0) { ++ free_more_memory(); ++ goto retry; ++ } else if (ret > 0) { + bh = __find_get_block(bdev, block, size); + if (bh) + return bh; +- +- ret = grow_buffers(bdev, block, size); +- if (ret < 0) +- return NULL; +- if (ret == 0) +- free_more_memory(); + } ++ return NULL; + } + + /* diff --git a/releases/3.0.38/cfg80211-check-iface-combinations-only-when-iface-is-running.patch b/releases/3.0.38/cfg80211-check-iface-combinations-only-when-iface-is-running.patch new file mode 100644 index 00000000000..c4f6aac5e7f --- /dev/null +++ b/releases/3.0.38/cfg80211-check-iface-combinations-only-when-iface-is-running.patch @@ -0,0 +1,38 @@ +From f8cdddb8d61d16a156229f0910f7ecfc7a82c003 Mon Sep 17 00:00:00 2001 +From: Michal Kazior +Date: Fri, 8 Jun 2012 10:55:44 +0200 +Subject: cfg80211: check iface combinations only when iface is running + +From: Michal Kazior + +commit f8cdddb8d61d16a156229f0910f7ecfc7a82c003 upstream. + +Don't validate interface combinations on a stopped +interface. Otherwise we might end up being able to +create a new interface with a certain type, but +won't be able to change an existing interface +into that type. + +This also skips some other functions when +interface is stopped and changing interface type. + +Signed-off-by: Michal Kazior +Signed-off-by: Johannes Berg +[Fixes regression introduced by cherry pick of 463454b5dbd8] +Signed-off-by: Paul Gortmaker + +--- + net/wireless/util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -807,7 +807,7 @@ int cfg80211_change_iface(struct cfg8021 + ntype == NL80211_IFTYPE_P2P_CLIENT)) + return -EBUSY; + +- if (ntype != otype) { ++ if (ntype != otype && netif_running(dev)) { + err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, + ntype); + if (err) diff --git a/releases/3.0.38/e1000e-correct-link-check-logic-for-82571-serdes.patch b/releases/3.0.38/e1000e-correct-link-check-logic-for-82571-serdes.patch new file mode 100644 index 00000000000..384387b4420 --- /dev/null +++ b/releases/3.0.38/e1000e-correct-link-check-logic-for-82571-serdes.patch @@ -0,0 +1,37 @@ +From d0efa8f23a644f7cb7d1f8e78dd9a223efa412a3 Mon Sep 17 00:00:00 2001 +From: Tushar Dave +Date: Thu, 12 Jul 2012 08:56:56 +0000 +Subject: e1000e: Correct link check logic for 82571 serdes + +From: Tushar Dave + +commit d0efa8f23a644f7cb7d1f8e78dd9a223efa412a3 upstream. + +SYNCH bit and IV bit of RXCW register are sticky. Before examining these bits, +RXCW should be read twice to filter out one-time false events and have correct +values for these bits. Incorrect values of these bits in link check logic can +cause weird link stability issues if auto-negotiation fails. + +Reported-by: Dean Nelson +Signed-off-by: Tushar Dave +Reviewed-by: Bruce Allan +Tested-by: Jeff Pieper +Signed-off-by: Jeff Kirsher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/e1000e/82571.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/e1000e/82571.c ++++ b/drivers/net/e1000e/82571.c +@@ -1573,6 +1573,9 @@ static s32 e1000_check_for_serdes_link_8 + ctrl = er32(CTRL); + status = er32(STATUS); + rxcw = er32(RXCW); ++ /* SYNCH bit and IV bit are sticky */ ++ udelay(10); ++ rxcw = er32(RXCW); + + if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { + diff --git a/releases/3.0.38/fifo-do-not-restart-open-if-it-already-found-a-partner.patch b/releases/3.0.38/fifo-do-not-restart-open-if-it-already-found-a-partner.patch new file mode 100644 index 00000000000..2152491d957 --- /dev/null +++ b/releases/3.0.38/fifo-do-not-restart-open-if-it-already-found-a-partner.patch @@ -0,0 +1,109 @@ +From 05d290d66be6ef77a0b962ebecf01911bd984a78 Mon Sep 17 00:00:00 2001 +From: Anders Kaseorg +Date: Sun, 15 Jul 2012 17:14:25 -0400 +Subject: fifo: Do not restart open() if it already found a partner + +From: Anders Kaseorg + +commit 05d290d66be6ef77a0b962ebecf01911bd984a78 upstream. + +If a parent and child process open the two ends of a fifo, and the +child immediately exits, the parent may receive a SIGCHLD before its +open() returns. In that case, we need to make sure that open() will +return successfully after the SIGCHLD handler returns, instead of +throwing EINTR or being restarted. Otherwise, the restarted open() +would incorrectly wait for a second partner on the other end. + +The following test demonstrates the EINTR that was wrongly thrown from +the parent’s open(). Change .sa_flags = 0 to .sa_flags = SA_RESTART +to see a deadlock instead, in which the restarted open() waits for a +second reader that will never come. (On my systems, this happens +pretty reliably within about 5 to 500 iterations. Others report that +it manages to loop ~forever sometimes; YMMV.) + + #include + #include + #include + #include + #include + #include + #include + #include + + #define CHECK(x) do if ((x) == -1) {perror(#x); abort();} while(0) + + void handler(int signum) {} + + int main() + { + struct sigaction act = {.sa_handler = handler, .sa_flags = 0}; + CHECK(sigaction(SIGCHLD, &act, NULL)); + CHECK(mknod("fifo", S_IFIFO | S_IRWXU, 0)); + for (;;) { + int fd; + pid_t pid; + putc('.', stderr); + CHECK(pid = fork()); + if (pid == 0) { + CHECK(fd = open("fifo", O_RDONLY)); + _exit(0); + } + CHECK(fd = open("fifo", O_WRONLY)); + CHECK(close(fd)); + CHECK(waitpid(pid, NULL, 0)); + } + } + +This is what I suspect was causing the Git test suite to fail in +t9010-svn-fe.sh: + + http://bugs.debian.org/678852 + +Signed-off-by: Anders Kaseorg +Reviewed-by: Jonathan Nieder +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fifo.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/fs/fifo.c ++++ b/fs/fifo.c +@@ -14,7 +14,7 @@ + #include + #include + +-static void wait_for_partner(struct inode* inode, unsigned int *cnt) ++static int wait_for_partner(struct inode* inode, unsigned int *cnt) + { + int cur = *cnt; + +@@ -23,6 +23,7 @@ static void wait_for_partner(struct inod + if (signal_pending(current)) + break; + } ++ return cur == *cnt ? -ERESTARTSYS : 0; + } + + static void wake_up_partner(struct inode* inode) +@@ -67,8 +68,7 @@ static int fifo_open(struct inode *inode + * seen a writer */ + filp->f_version = pipe->w_counter; + } else { +- wait_for_partner(inode, &pipe->w_counter); +- if(signal_pending(current)) ++ if (wait_for_partner(inode, &pipe->w_counter)) + goto err_rd; + } + } +@@ -90,8 +90,7 @@ static int fifo_open(struct inode *inode + wake_up_partner(inode); + + if (!pipe->readers) { +- wait_for_partner(inode, &pipe->r_counter); +- if (signal_pending(current)) ++ if (wait_for_partner(inode, &pipe->r_counter)) + goto err_wr; + } + break; diff --git a/releases/3.0.38/hrtimer-provide-clock_was_set_delayed.patch b/releases/3.0.38/hrtimer-provide-clock_was_set_delayed.patch new file mode 100644 index 00000000000..ff2fe796083 --- /dev/null +++ b/releases/3.0.38/hrtimer-provide-clock_was_set_delayed.patch @@ -0,0 +1,119 @@ +From johnstul@us.ibm.com Tue Jul 17 15:25:04 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:52 -0400 +Subject: hrtimer: Provide clock_was_set_delayed() +To: stable@vger.kernel.org +Cc: John Stultz , Thomas Gleixner , Prarit Bhargava , Linux Kernel +Message-ID: <1342546438-17534-6-git-send-email-johnstul@us.ibm.com> + +From: John Stultz + +This is a backport of f55a6faa384304c89cfef162768e88374d3312cb + +clock_was_set() cannot be called from hard interrupt context because +it calls on_each_cpu(). + +For fixing the widely reported leap seconds issue it is necessary to +call it from hard interrupt context, i.e. the timer tick code, which +does the timekeeping updates. + +Provide a new function which denotes it in the hrtimer cpu base +structure of the cpu on which it is called and raise the hrtimer +softirq. We then execute the clock_was_set() notificiation from +softirq context in run_hrtimer_softirq(). The hrtimer softirq is +rarely used, so polling the flag there is not a performance issue. + +[ tglx: Made it depend on CONFIG_HIGH_RES_TIMERS. We really should get + rid of all this ifdeffery ASAP ] + +Signed-off-by: John Stultz +Reported-by: Jan Engelhardt +Reviewed-by: Ingo Molnar +Acked-by: Peter Zijlstra +Acked-by: Prarit Bhargava +Link: http://lkml.kernel.org/r/1341960205-56738-2-git-send-email-johnstul@us.ibm.com +Signed-off-by: Thomas Gleixner +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/hrtimer.h | 9 ++++++++- + kernel/hrtimer.c | 20 ++++++++++++++++++++ + 2 files changed, 28 insertions(+), 1 deletion(-) + +--- a/include/linux/hrtimer.h ++++ b/include/linux/hrtimer.h +@@ -165,6 +165,7 @@ enum hrtimer_base_type { + * @lock: lock protecting the base and associated clock bases + * and timers + * @active_bases: Bitfield to mark bases with active timers ++ * @clock_was_set: Indicates that clock was set from irq context. + * @expires_next: absolute time of the next event which was scheduled + * via clock_set_next_event() + * @hres_active: State of high resolution mode +@@ -177,7 +178,8 @@ enum hrtimer_base_type { + */ + struct hrtimer_cpu_base { + raw_spinlock_t lock; +- unsigned long active_bases; ++ unsigned int active_bases; ++ unsigned int clock_was_set; + #ifdef CONFIG_HIGH_RES_TIMERS + ktime_t expires_next; + int hres_active; +@@ -286,6 +288,8 @@ extern void hrtimer_peek_ahead_timers(vo + # define MONOTONIC_RES_NSEC HIGH_RES_NSEC + # define KTIME_MONOTONIC_RES KTIME_HIGH_RES + ++extern void clock_was_set_delayed(void); ++ + #else + + # define MONOTONIC_RES_NSEC LOW_RES_NSEC +@@ -306,6 +310,9 @@ static inline int hrtimer_is_hres_active + { + return 0; + } ++ ++static inline void clock_was_set_delayed(void) { } ++ + #endif + + extern void clock_was_set(void); +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -717,6 +717,19 @@ static int hrtimer_switch_to_hres(void) + return 1; + } + ++/* ++ * Called from timekeeping code to reprogramm the hrtimer interrupt ++ * device. If called from the timer interrupt context we defer it to ++ * softirq context. ++ */ ++void clock_was_set_delayed(void) ++{ ++ struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); ++ ++ cpu_base->clock_was_set = 1; ++ __raise_softirq_irqoff(HRTIMER_SOFTIRQ); ++} ++ + #else + + static inline int hrtimer_hres_active(void) { return 0; } +@@ -1395,6 +1408,13 @@ void hrtimer_peek_ahead_timers(void) + + static void run_hrtimer_softirq(struct softirq_action *h) + { ++ struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); ++ ++ if (cpu_base->clock_was_set) { ++ cpu_base->clock_was_set = 0; ++ clock_was_set(); ++ } ++ + hrtimer_peek_ahead_timers(); + } + diff --git a/releases/3.0.38/hrtimer-update-hrtimer-base-offsets-each-hrtimer_interrupt.patch b/releases/3.0.38/hrtimer-update-hrtimer-base-offsets-each-hrtimer_interrupt.patch new file mode 100644 index 00000000000..791193715aa --- /dev/null +++ b/releases/3.0.38/hrtimer-update-hrtimer-base-offsets-each-hrtimer_interrupt.patch @@ -0,0 +1,127 @@ +From johnstul@us.ibm.com Tue Jul 17 15:26:57 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:57 -0400 +Subject: hrtimer: Update hrtimer base offsets each hrtimer_interrupt +To: stable@vger.kernel.org +Cc: John Stultz , Thomas Gleixner , Prarit Bhargava , Linux Kernel +Message-ID: <1342546438-17534-11-git-send-email-johnstul@us.ibm.com> + +From: John Stultz + +This is a backport of 5baefd6d84163443215f4a99f6a20f054ef11236 + +The update of the hrtimer base offsets on all cpus cannot be made +atomically from the timekeeper.lock held and interrupt disabled region +as smp function calls are not allowed there. + +clock_was_set(), which enforces the update on all cpus, is called +either from preemptible process context in case of do_settimeofday() +or from the softirq context when the offset modification happened in +the timer interrupt itself due to a leap second. + +In both cases there is a race window for an hrtimer interrupt between +dropping timekeeper lock, enabling interrupts and clock_was_set() +issuing the updates. Any interrupt which arrives in that window will +see the new time but operate on stale offsets. + +So we need to make sure that an hrtimer interrupt always sees a +consistent state of time and offsets. + +ktime_get_update_offsets() allows us to get the current monotonic time +and update the per cpu hrtimer base offsets from hrtimer_interrupt() +to capture a consistent state of monotonic time and the offsets. The +function replaces the existing ktime_get() calls in hrtimer_interrupt(). + +The overhead of the new function vs. ktime_get() is minimal as it just +adds two store operations. + +This ensures that any changes to realtime or boottime offsets are +noticed and stored into the per-cpu hrtimer base structures, prior to +any hrtimer expiration and guarantees that timers are not expired early. + +Signed-off-by: John Stultz +Reviewed-by: Ingo Molnar +Acked-by: Peter Zijlstra +Acked-by: Prarit Bhargava +Link: http://lkml.kernel.org/r/1341960205-56738-8-git-send-email-johnstul@us.ibm.com +Signed-off-by: Thomas Gleixner +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman +--- + kernel/hrtimer.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -657,6 +657,14 @@ static inline int hrtimer_enqueue_reprog + return 0; + } + ++static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base) ++{ ++ ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset; ++ ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset; ++ ++ return ktime_get_update_offsets(offs_real, offs_boot); ++} ++ + /* + * Retrigger next event is called after clock was set + * +@@ -665,22 +673,12 @@ static inline int hrtimer_enqueue_reprog + static void retrigger_next_event(void *arg) + { + struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases); +- struct timespec realtime_offset, xtim, wtm, sleep; + + if (!hrtimer_hres_active()) + return; + +- /* Optimized out for !HIGH_RES */ +- get_xtime_and_monotonic_and_sleep_offset(&xtim, &wtm, &sleep); +- set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); +- +- /* Adjust CLOCK_REALTIME offset */ + raw_spin_lock(&base->lock); +- base->clock_base[HRTIMER_BASE_REALTIME].offset = +- timespec_to_ktime(realtime_offset); +- base->clock_base[HRTIMER_BASE_BOOTTIME].offset = +- timespec_to_ktime(sleep); +- ++ hrtimer_update_base(base); + hrtimer_force_reprogram(base, 0); + raw_spin_unlock(&base->lock); + } +@@ -710,7 +708,6 @@ static int hrtimer_switch_to_hres(void) + base->clock_base[i].resolution = KTIME_HIGH_RES; + + tick_setup_sched_timer(); +- + /* "Retrigger" the interrupt to get things going */ + retrigger_next_event(NULL); + local_irq_restore(flags); +@@ -1264,7 +1261,7 @@ void hrtimer_interrupt(struct clock_even + dev->next_event.tv64 = KTIME_MAX; + + raw_spin_lock(&cpu_base->lock); +- entry_time = now = ktime_get(); ++ entry_time = now = hrtimer_update_base(cpu_base); + retry: + expires_next.tv64 = KTIME_MAX; + /* +@@ -1342,9 +1339,12 @@ retry: + * We need to prevent that we loop forever in the hrtimer + * interrupt routine. We give it 3 attempts to avoid + * overreacting on some spurious event. ++ * ++ * Acquire base lock for updating the offsets and retrieving ++ * the current time. + */ + raw_spin_lock(&cpu_base->lock); +- now = ktime_get(); ++ now = hrtimer_update_base(cpu_base); + cpu_base->nr_retries++; + if (++retries < 3) + goto retry; diff --git a/releases/3.0.38/hrtimers-move-lock-held-region-in-hrtimer_interrupt.patch b/releases/3.0.38/hrtimers-move-lock-held-region-in-hrtimer_interrupt.patch new file mode 100644 index 00000000000..bf36ed5d1ea --- /dev/null +++ b/releases/3.0.38/hrtimers-move-lock-held-region-in-hrtimer_interrupt.patch @@ -0,0 +1,64 @@ +From johnstul@us.ibm.com Tue Jul 17 15:26:26 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:55 -0400 +Subject: hrtimers: Move lock held region in hrtimer_interrupt() +To: stable@vger.kernel.org +Cc: Thomas Gleixner , John Stultz , Prarit Bhargava , Linux Kernel +Message-ID: <1342546438-17534-9-git-send-email-johnstul@us.ibm.com> + + +From: Thomas Gleixner + +This is a backport of 196951e91262fccda81147d2bcf7fdab08668b40 + +We need to update the base offsets from this code and we need to do +that under base->lock. Move the lock held region around the +ktime_get() calls. The ktime_get() calls are going to be replaced with +a function which gets the time and the offsets atomically. + +Signed-off-by: Thomas Gleixner +Reviewed-by: Ingo Molnar +Acked-by: Peter Zijlstra +Acked-by: Prarit Bhargava +Signed-off-by: John Stultz +Link: http://lkml.kernel.org/r/1341960205-56738-6-git-send-email-johnstul@us.ibm.com +Signed-off-by: Thomas Gleixner +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman +--- + kernel/hrtimer.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -1263,11 +1263,10 @@ void hrtimer_interrupt(struct clock_even + cpu_base->nr_events++; + dev->next_event.tv64 = KTIME_MAX; + ++ raw_spin_lock(&cpu_base->lock); + entry_time = now = ktime_get(); + retry: + expires_next.tv64 = KTIME_MAX; +- +- raw_spin_lock(&cpu_base->lock); + /* + * We set expires_next to KTIME_MAX here with cpu_base->lock + * held to prevent that a timer is enqueued in our queue via +@@ -1344,6 +1343,7 @@ retry: + * interrupt routine. We give it 3 attempts to avoid + * overreacting on some spurious event. + */ ++ raw_spin_lock(&cpu_base->lock); + now = ktime_get(); + cpu_base->nr_retries++; + if (++retries < 3) +@@ -1356,6 +1356,7 @@ retry: + */ + cpu_base->nr_hangs++; + cpu_base->hang_detected = 1; ++ raw_spin_unlock(&cpu_base->lock); + delta = ktime_sub(now, entry_time); + if (delta.tv64 > cpu_base->max_hang_time.tv64) + cpu_base->max_hang_time = delta; diff --git a/releases/3.0.38/hwmon-it87-preserve-configuration-register-bits-on-init.patch b/releases/3.0.38/hwmon-it87-preserve-configuration-register-bits-on-init.patch new file mode 100644 index 00000000000..f2cab253958 --- /dev/null +++ b/releases/3.0.38/hwmon-it87-preserve-configuration-register-bits-on-init.patch @@ -0,0 +1,34 @@ +From 41002f8dd5938d5ad1d008ce5bfdbfe47fa7b4e8 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Thu, 12 Jul 2012 22:47:37 +0200 +Subject: hwmon: (it87) Preserve configuration register bits on init + +From: Jean Delvare + +commit 41002f8dd5938d5ad1d008ce5bfdbfe47fa7b4e8 upstream. + +We were accidentally losing one bit in the configuration register on +device initialization. It was reported to freeze one specific system +right away. Properly preserve all bits we don't explicitly want to +change in order to prevent that. + +Reported-by: Stevie Trujillo +Signed-off-by: Jean Delvare +Reviewed-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/it87.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -2057,7 +2057,7 @@ static void __devinit it87_init_device(s + + /* Start monitoring */ + it87_write_value(data, IT87_REG_CONFIG, +- (it87_read_value(data, IT87_REG_CONFIG) & 0x36) ++ (it87_read_value(data, IT87_REG_CONFIG) & 0x3e) + | (update_vbat ? 0x41 : 0x01)); + } + diff --git a/releases/3.0.38/input-xpad-add-andamiro-pump-it-up-pad.patch b/releases/3.0.38/input-xpad-add-andamiro-pump-it-up-pad.patch new file mode 100644 index 00000000000..36cf4af74c2 --- /dev/null +++ b/releases/3.0.38/input-xpad-add-andamiro-pump-it-up-pad.patch @@ -0,0 +1,31 @@ +From e76b8ee25e034ab601b525abb95cea14aa167ed3 Mon Sep 17 00:00:00 2001 +From: Yuri Khan +Date: Wed, 11 Jul 2012 22:12:31 -0700 +Subject: Input: xpad - add Andamiro Pump It Up pad + +From: Yuri Khan + +commit e76b8ee25e034ab601b525abb95cea14aa167ed3 upstream. + +I couldn't find the vendor ID in any of the online databases, but this +mat has a Pump It Up logo on the top side of the controller compartment, +and a disclaimer stating that Andamiro will not be liable on the bottom. + +Signed-off-by: Yuri Khan +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/joystick/xpad.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -142,6 +142,7 @@ static const struct xpad_device { + { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX }, + { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, + { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, ++ { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, + { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, + { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX }, diff --git a/releases/3.0.38/intel_ips-blacklist-hp-probook-laptops.patch b/releases/3.0.38/intel_ips-blacklist-hp-probook-laptops.patch new file mode 100644 index 00000000000..ed7378b83c9 --- /dev/null +++ b/releases/3.0.38/intel_ips-blacklist-hp-probook-laptops.patch @@ -0,0 +1,68 @@ +From 88ca518b0bb4161e5f20f8a1d9cc477cae294e54 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 25 Jun 2012 15:07:17 +0200 +Subject: intel_ips: blacklist HP ProBook laptops + +From: Takashi Iwai + +commit 88ca518b0bb4161e5f20f8a1d9cc477cae294e54 upstream. + +intel_ips driver spews the warning message + "ME failed to update for more than 1s, likely hung" +at each second endlessly on HP ProBook laptops with IronLake. + +As this has never worked, better to blacklist the driver for now. + +Signed-off-by: Takashi Iwai +Signed-off-by: Matthew Garrett +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/intel_ips.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/drivers/platform/x86/intel_ips.c ++++ b/drivers/platform/x86/intel_ips.c +@@ -72,6 +72,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1505,6 +1506,24 @@ static DEFINE_PCI_DEVICE_TABLE(ips_id_ta + + MODULE_DEVICE_TABLE(pci, ips_id_table); + ++static int ips_blacklist_callback(const struct dmi_system_id *id) ++{ ++ pr_info("Blacklisted intel_ips for %s\n", id->ident); ++ return 1; ++} ++ ++static const struct dmi_system_id ips_blacklist[] = { ++ { ++ .callback = ips_blacklist_callback, ++ .ident = "HP ProBook", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"), ++ }, ++ }, ++ { } /* terminating entry */ ++}; ++ + static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) + { + u64 platform_info; +@@ -1514,6 +1533,9 @@ static int ips_probe(struct pci_dev *dev + u16 htshi, trc, trc_required_mask; + u8 tse; + ++ if (dmi_check_system(ips_blacklist)) ++ return -ENODEV; ++ + ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL); + if (!ips) + return -ENOMEM; diff --git a/releases/3.0.38/media-dvb-core-release-semaphore-on-error-path-dvb_register_device.patch b/releases/3.0.38/media-dvb-core-release-semaphore-on-error-path-dvb_register_device.patch new file mode 100644 index 00000000000..c1e2f5691e3 --- /dev/null +++ b/releases/3.0.38/media-dvb-core-release-semaphore-on-error-path-dvb_register_device.patch @@ -0,0 +1,30 @@ +From 82163edcdfa4eb3d74516cc8e9f38dd3d039b67d Mon Sep 17 00:00:00 2001 +From: Santosh Nayak +Date: Sat, 23 Jun 2012 07:59:54 -0300 +Subject: media: dvb-core: Release semaphore on error path dvb_register_device() + +From: Santosh Nayak + +commit 82163edcdfa4eb3d74516cc8e9f38dd3d039b67d upstream. + +There is a missing "up_write()" here. Semaphore should be released +before returning error value. + +Signed-off-by: Santosh Nayak +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/dvb/dvb-core/dvbdev.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/media/dvb/dvb-core/dvbdev.c ++++ b/drivers/media/dvb/dvb-core/dvbdev.c +@@ -243,6 +243,7 @@ int dvb_register_device(struct dvb_adapt + if (minor == MAX_DVB_MINORS) { + kfree(dvbdevfops); + kfree(dvbdev); ++ up_write(&minor_rwsem); + mutex_unlock(&dvbdev_register_lock); + return -EINVAL; + } diff --git a/releases/3.0.38/mtd-nandsim-don-t-open-code-a-do_div-helper.patch b/releases/3.0.38/mtd-nandsim-don-t-open-code-a-do_div-helper.patch new file mode 100644 index 00000000000..1b1edb42050 --- /dev/null +++ b/releases/3.0.38/mtd-nandsim-don-t-open-code-a-do_div-helper.patch @@ -0,0 +1,92 @@ +From 596fd46268634082314b3af1ded4612e1b7f3f03 Mon Sep 17 00:00:00 2001 +From: Herton Ronaldo Krzesinski +Date: Wed, 16 May 2012 16:21:52 -0300 +Subject: mtd: nandsim: don't open code a do_div helper + +From: Herton Ronaldo Krzesinski + +commit 596fd46268634082314b3af1ded4612e1b7f3f03 upstream. + +We don't need to open code the divide function, just use div_u64 that +already exists and do the same job. While this is a straightforward +clean up, there is more to that, the real motivation for this. + +While building on a cross compiling environment in armel, using gcc +4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5), I was getting the following build +error: + +ERROR: "__aeabi_uldivmod" [drivers/mtd/nand/nandsim.ko] undefined! + +After investigating with objdump and hand built assembly version +generated with the compiler, I narrowed __aeabi_uldivmod as being +generated from the divide function. When nandsim.c is built with +-fno-inline-functions-called-once, that happens when +CONFIG_DEBUG_SECTION_MISMATCH is enabled, the do_div optimization in +arch/arm/include/asm/div64.h doesn't work as expected with the open +coded divide function: even if the do_div we are using doesn't have a +constant divisor, the compiler still includes the else parts of the +optimized do_div macro, and translates the divisions there to use +__aeabi_uldivmod, instead of only calling __do_div_asm -> __do_div64 and +optimizing/removing everything else out. + +So to reproduce, gcc 4.6 plus CONFIG_DEBUG_SECTION_MISMATCH=y and +CONFIG_MTD_NAND_NANDSIM=m should do it, building on armel. + +After this change, the compiler does the intended thing even with +-fno-inline-functions-called-once, and optimizes out as expected the +constant handling in the optimized do_div on arm. As this also avoids a +build issue, I'm marking for Stable, as I think is applicable for this +case. + +Signed-off-by: Herton Ronaldo Krzesinski +Acked-by: Nicolas Pitre +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/nand/nandsim.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +--- a/drivers/mtd/nand/nandsim.c ++++ b/drivers/mtd/nand/nandsim.c +@@ -28,7 +28,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -547,12 +547,6 @@ static char *get_partition_name(int i) + return kstrdup(buf, GFP_KERNEL); + } + +-static uint64_t divide(uint64_t n, uint32_t d) +-{ +- do_div(n, d); +- return n; +-} +- + /* + * Initialize the nandsim structure. + * +@@ -581,7 +575,7 @@ static int init_nandsim(struct mtd_info + ns->geom.oobsz = mtd->oobsize; + ns->geom.secsz = mtd->erasesize; + ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; +- ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz); ++ ns->geom.pgnum = div_u64(ns->geom.totsz, ns->geom.pgsz); + ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; + ns->geom.secshift = ffs(ns->geom.secsz) - 1; + ns->geom.pgshift = chip->page_shift; +@@ -924,7 +918,7 @@ static int setup_wear_reporting(struct m + + if (!rptwear) + return 0; +- wear_eb_count = divide(mtd->size, mtd->erasesize); ++ wear_eb_count = div_u64(mtd->size, mtd->erasesize); + mem = wear_eb_count * sizeof(unsigned long); + if (mem / sizeof(unsigned long) != wear_eb_count) { + NS_ERR("Too many erase blocks for wear reporting\n"); diff --git a/releases/3.0.38/ntp-correct-tai-offset-during-leap-second.patch b/releases/3.0.38/ntp-correct-tai-offset-during-leap-second.patch new file mode 100644 index 00000000000..def9f55364e --- /dev/null +++ b/releases/3.0.38/ntp-correct-tai-offset-during-leap-second.patch @@ -0,0 +1,45 @@ +From johnstul@us.ibm.com Tue Jul 17 15:24:12 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:49 -0400 +Subject: ntp: Correct TAI offset during leap second +To: stable@vger.kernel.org +Cc: Richard Cochran , Prarit Bhargava , Thomas Gleixner , Linux Kernel , John Stultz +Message-ID: <1342546438-17534-3-git-send-email-johnstul@us.ibm.com> + + +From: Richard Cochran + +This is a backport of dd48d708ff3e917f6d6b6c2b696c3f18c019feed + +When repeating a UTC time value during a leap second (when the UTC +time should be 23:59:60), the TAI timescale should not stop. The kernel +NTP code increments the TAI offset one second too late. This patch fixes +the issue by incrementing the offset during the leap second itself. + +Signed-off-by: Richard Cochran +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/ntp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/time/ntp.c ++++ b/kernel/time/ntp.c +@@ -378,6 +378,7 @@ int second_overflow(unsigned long secs) + if (secs % 86400 == 0) { + leap = -1; + time_state = TIME_OOP; ++ time_tai++; + printk(KERN_NOTICE + "Clock: inserting leap second 23:59:60 UTC\n"); + } +@@ -392,7 +393,6 @@ int second_overflow(unsigned long secs) + } + break; + case TIME_OOP: +- time_tai++; + time_state = TIME_WAIT; + break; + diff --git a/releases/3.0.38/ntp-fix-leap-second-hrtimer-livelock.patch b/releases/3.0.38/ntp-fix-leap-second-hrtimer-livelock.patch new file mode 100644 index 00000000000..ccddbc8e295 --- /dev/null +++ b/releases/3.0.38/ntp-fix-leap-second-hrtimer-livelock.patch @@ -0,0 +1,346 @@ +From johnstul@us.ibm.com Tue Jul 17 15:23:32 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:48 -0400 +Subject: ntp: Fix leap-second hrtimer livelock +To: stable@vger.kernel.org +Cc: John Stultz , Sasha Levin , Thomas Gleixner , Prarit Bhargava , Linux Kernel +Message-ID: <1342546438-17534-2-git-send-email-johnstul@us.ibm.com> + + +From: John Stultz + +This is a backport of 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d + +This should have been backported when it was commited, but I +mistook the problem as requiring the ntp_lock changes +that landed in 3.4 in order for it to occur. + +Unfortunately the same issue can happen (with only one cpu) +as follows: +do_adjtimex() + write_seqlock_irq(&xtime_lock); + process_adjtimex_modes() + process_adj_status() + ntp_start_leap_timer() + hrtimer_start() + hrtimer_reprogram() + tick_program_event() + clockevents_program_event() + ktime_get() + seq = req_seqbegin(xtime_lock); [DEADLOCK] + +This deadlock will no always occur, as it requires the +leap_timer to force a hrtimer_reprogram which only happens +if its set and there's no sooner timer to expire. + +NOTE: This patch, being faithful to the original commit, +introduces a bug (we don't update wall_to_monotonic), +which will be resovled by backporting a following fix. + +Original commit message below: + +Since commit 7dffa3c673fbcf835cd7be80bb4aec8ad3f51168 the ntp +subsystem has used an hrtimer for triggering the leapsecond +adjustment. However, this can cause a potential livelock. + +Thomas diagnosed this as the following pattern: +CPU 0 CPU 1 +do_adjtimex() + spin_lock_irq(&ntp_lock); + process_adjtimex_modes(); timer_interrupt() + process_adj_status(); do_timer() + ntp_start_leap_timer(); write_lock(&xtime_lock); + hrtimer_start(); update_wall_time(); + hrtimer_reprogram(); ntp_tick_length() + tick_program_event() spin_lock(&ntp_lock); + clockevents_program_event() + ktime_get() + seq = req_seqbegin(xtime_lock); + +This patch tries to avoid the problem by reverting back to not using +an hrtimer to inject leapseconds, and instead we handle the leapsecond +processing in the second_overflow() function. + +The downside to this change is that on systems that support highres +timers, the leap second processing will occur on a HZ tick boundary, +(ie: ~1-10ms, depending on HZ) after the leap second instead of +possibly sooner (~34us in my tests w/ x86_64 lapic). + +This patch applies on top of tip/timers/core. + +CC: Sasha Levin +CC: Thomas Gleixner +Reported-by: Sasha Levin +Diagnoised-by: Thomas Gleixner +Tested-by: Sasha Levin +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/timex.h | 2 + kernel/time/ntp.c | 122 +++++++++++++++------------------------------- + kernel/time/timekeeping.c | 18 ++---- + 3 files changed, 48 insertions(+), 94 deletions(-) + +--- a/include/linux/timex.h ++++ b/include/linux/timex.h +@@ -266,7 +266,7 @@ static inline int ntp_synced(void) + /* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */ + extern u64 tick_length; + +-extern void second_overflow(void); ++extern int second_overflow(unsigned long secs); + extern void update_ntp_one_tick(void); + extern int do_adjtimex(struct timex *); + extern void hardpps(const struct timespec *, const struct timespec *); +--- a/kernel/time/ntp.c ++++ b/kernel/time/ntp.c +@@ -31,8 +31,6 @@ unsigned long tick_nsec; + u64 tick_length; + static u64 tick_length_base; + +-static struct hrtimer leap_timer; +- + #define MAX_TICKADJ 500LL /* usecs */ + #define MAX_TICKADJ_SCALED \ + (((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ) +@@ -350,60 +348,60 @@ void ntp_clear(void) + } + + /* +- * Leap second processing. If in leap-insert state at the end of the +- * day, the system clock is set back one second; if in leap-delete +- * state, the system clock is set ahead one second. ++ * this routine handles the overflow of the microsecond field ++ * ++ * The tricky bits of code to handle the accurate clock support ++ * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame. ++ * They were originally developed for SUN and DEC kernels. ++ * All the kudos should go to Dave for this stuff. ++ * ++ * Also handles leap second processing, and returns leap offset + */ +-static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer) ++int second_overflow(unsigned long secs) + { +- enum hrtimer_restart res = HRTIMER_NORESTART; +- +- write_seqlock(&xtime_lock); ++ int leap = 0; ++ s64 delta; + ++ /* ++ * Leap second processing. If in leap-insert state at the end of the ++ * day, the system clock is set back one second; if in leap-delete ++ * state, the system clock is set ahead one second. ++ */ + switch (time_state) { + case TIME_OK: ++ if (time_status & STA_INS) ++ time_state = TIME_INS; ++ else if (time_status & STA_DEL) ++ time_state = TIME_DEL; + break; + case TIME_INS: +- timekeeping_leap_insert(-1); +- time_state = TIME_OOP; +- printk(KERN_NOTICE +- "Clock: inserting leap second 23:59:60 UTC\n"); +- hrtimer_add_expires_ns(&leap_timer, NSEC_PER_SEC); +- res = HRTIMER_RESTART; ++ if (secs % 86400 == 0) { ++ leap = -1; ++ time_state = TIME_OOP; ++ printk(KERN_NOTICE ++ "Clock: inserting leap second 23:59:60 UTC\n"); ++ } + break; + case TIME_DEL: +- timekeeping_leap_insert(1); +- time_tai--; +- time_state = TIME_WAIT; +- printk(KERN_NOTICE +- "Clock: deleting leap second 23:59:59 UTC\n"); ++ if ((secs + 1) % 86400 == 0) { ++ leap = 1; ++ time_tai--; ++ time_state = TIME_WAIT; ++ printk(KERN_NOTICE ++ "Clock: deleting leap second 23:59:59 UTC\n"); ++ } + break; + case TIME_OOP: + time_tai++; + time_state = TIME_WAIT; +- /* fall through */ ++ break; ++ + case TIME_WAIT: + if (!(time_status & (STA_INS | STA_DEL))) + time_state = TIME_OK; + break; + } + +- write_sequnlock(&xtime_lock); +- +- return res; +-} +- +-/* +- * this routine handles the overflow of the microsecond field +- * +- * The tricky bits of code to handle the accurate clock support +- * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame. +- * They were originally developed for SUN and DEC kernels. +- * All the kudos should go to Dave for this stuff. +- */ +-void second_overflow(void) +-{ +- s64 delta; + + /* Bump the maxerror field */ + time_maxerror += MAXFREQ / NSEC_PER_USEC; +@@ -423,23 +421,25 @@ void second_overflow(void) + pps_dec_valid(); + + if (!time_adjust) +- return; ++ goto out; + + if (time_adjust > MAX_TICKADJ) { + time_adjust -= MAX_TICKADJ; + tick_length += MAX_TICKADJ_SCALED; +- return; ++ goto out; + } + + if (time_adjust < -MAX_TICKADJ) { + time_adjust += MAX_TICKADJ; + tick_length -= MAX_TICKADJ_SCALED; +- return; ++ goto out; + } + + tick_length += (s64)(time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ) + << NTP_SCALE_SHIFT; + time_adjust = 0; ++out: ++ return leap; + } + + #ifdef CONFIG_GENERIC_CMOS_UPDATE +@@ -501,27 +501,6 @@ static void notify_cmos_timer(void) + static inline void notify_cmos_timer(void) { } + #endif + +-/* +- * Start the leap seconds timer: +- */ +-static inline void ntp_start_leap_timer(struct timespec *ts) +-{ +- long now = ts->tv_sec; +- +- if (time_status & STA_INS) { +- time_state = TIME_INS; +- now += 86400 - now % 86400; +- hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); +- +- return; +- } +- +- if (time_status & STA_DEL) { +- time_state = TIME_DEL; +- now += 86400 - (now + 1) % 86400; +- hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); +- } +-} + + /* + * Propagate a new txc->status value into the NTP state: +@@ -546,22 +525,6 @@ static inline void process_adj_status(st + time_status &= STA_RONLY; + time_status |= txc->status & ~STA_RONLY; + +- switch (time_state) { +- case TIME_OK: +- ntp_start_leap_timer(ts); +- break; +- case TIME_INS: +- case TIME_DEL: +- time_state = TIME_OK; +- ntp_start_leap_timer(ts); +- case TIME_WAIT: +- if (!(time_status & (STA_INS | STA_DEL))) +- time_state = TIME_OK; +- break; +- case TIME_OOP: +- hrtimer_restart(&leap_timer); +- break; +- } + } + /* + * Called with the xtime lock held, so we can access and modify +@@ -643,9 +606,6 @@ int do_adjtimex(struct timex *txc) + (txc->tick < 900000/USER_HZ || + txc->tick > 1100000/USER_HZ)) + return -EINVAL; +- +- if (txc->modes & ADJ_STATUS && time_state != TIME_OK) +- hrtimer_cancel(&leap_timer); + } + + if (txc->modes & ADJ_SETOFFSET) { +@@ -967,6 +927,4 @@ __setup("ntp_tick_adj=", ntp_tick_adj_se + void __init ntp_init(void) + { + ntp_clear(); +- hrtimer_init(&leap_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); +- leap_timer.function = ntp_leap_second; + } +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -169,15 +169,6 @@ static struct timespec raw_time; + /* flag for if timekeeping is suspended */ + int __read_mostly timekeeping_suspended; + +-/* must hold xtime_lock */ +-void timekeeping_leap_insert(int leapsecond) +-{ +- xtime.tv_sec += leapsecond; +- wall_to_monotonic.tv_sec -= leapsecond; +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); +-} +- + /** + * timekeeping_forward_now - update clock to the current time + * +@@ -828,9 +819,11 @@ static cycle_t logarithmic_accumulation( + + timekeeper.xtime_nsec += timekeeper.xtime_interval << shift; + while (timekeeper.xtime_nsec >= nsecps) { ++ int leap; + timekeeper.xtime_nsec -= nsecps; + xtime.tv_sec++; +- second_overflow(); ++ leap = second_overflow(xtime.tv_sec); ++ xtime.tv_sec += leap; + } + + /* Accumulate raw time */ +@@ -936,9 +929,12 @@ static void update_wall_time(void) + * xtime.tv_nsec isn't larger then NSEC_PER_SEC + */ + if (unlikely(xtime.tv_nsec >= NSEC_PER_SEC)) { ++ int leap; + xtime.tv_nsec -= NSEC_PER_SEC; + xtime.tv_sec++; +- second_overflow(); ++ leap = second_overflow(xtime.tv_sec); ++ xtime.tv_sec += leap; ++ + } + + /* check to see if there is a new clocksource to use */ diff --git a/releases/3.0.38/rt2x00usb-fix-indexes-ordering-on-rx-queue-kick.patch b/releases/3.0.38/rt2x00usb-fix-indexes-ordering-on-rx-queue-kick.patch new file mode 100644 index 00000000000..799cc4e913a --- /dev/null +++ b/releases/3.0.38/rt2x00usb-fix-indexes-ordering-on-rx-queue-kick.patch @@ -0,0 +1,49 @@ +From efd821182cec8c92babef6e00a95066d3252fda4 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 4 Jul 2012 13:10:02 +0200 +Subject: rt2x00usb: fix indexes ordering on RX queue kick + +From: Stanislaw Gruszka + +commit efd821182cec8c92babef6e00a95066d3252fda4 upstream. + +On rt2x00_dmastart() we increase index specified by Q_INDEX and on +rt2x00_dmadone() we increase index specified by Q_INDEX_DONE. So entries +between Q_INDEX_DONE and Q_INDEX are those we currently process in the +hardware. Entries between Q_INDEX and Q_INDEX_DONE are those we can +submit to the hardware. + +According to that fix rt2x00usb_kick_queue(), as we need to submit RX +entries that are not processed by the hardware. It worked before only +for empty queue, otherwise was broken. + +Note that for TX queues indexes ordering are ok. We need to kick entries +that have filled skb, but was not submitted to the hardware, i.e. +started from Q_INDEX_DONE and have ENTRY_DATA_PENDING bit set. + +From practical standpoint this fixes RX queue stall, usually reproducible +in AP mode, like for example reported here: +https://bugzilla.redhat.com/show_bug.cgi?id=828824 + +Reported-and-tested-by: Franco Miceli +Reported-and-tested-by: Tom Horsley +Signed-off-by: Stanislaw Gruszka +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rt2x00/rt2x00usb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/rt2x00/rt2x00usb.c +@@ -426,8 +426,8 @@ void rt2x00usb_kick_queue(struct data_qu + case QID_RX: + if (!rt2x00queue_full(queue)) + rt2x00queue_for_each_entry(queue, +- Q_INDEX_DONE, + Q_INDEX, ++ Q_INDEX_DONE, + NULL, + rt2x00usb_kick_rx_entry); + break; diff --git a/releases/3.0.38/series b/releases/3.0.38/series new file mode 100644 index 00000000000..a5cdaa6b37e --- /dev/null +++ b/releases/3.0.38/series @@ -0,0 +1,23 @@ +hwmon-it87-preserve-configuration-register-bits-on-init.patch +block-fix-infinite-loop-in-__getblk_slow.patch +media-dvb-core-release-semaphore-on-error-path-dvb_register_device.patch +mtd-nandsim-don-t-open-code-a-do_div-helper.patch +arm-samsung-fix-race-in-s3c_adc_start-for-adc.patch +intel_ips-blacklist-hp-probook-laptops.patch +fifo-do-not-restart-open-if-it-already-found-a-partner.patch +rt2x00usb-fix-indexes-ordering-on-rx-queue-kick.patch +e1000e-correct-link-check-logic-for-82571-serdes.patch +input-xpad-add-andamiro-pump-it-up-pad.patch +tcp-drop-syn-fin-messages.patch +cfg80211-check-iface-combinations-only-when-iface-is-running.patch +ntp-fix-leap-second-hrtimer-livelock.patch +ntp-correct-tai-offset-during-leap-second.patch +timekeeping-fix-clock_monotonic-inconsistency-during-leapsecond.patch +time-move-common-updates-to-a-function.patch +hrtimer-provide-clock_was_set_delayed.patch +timekeeping-fix-leapsecond-triggered-load-spike-issue.patch +timekeeping-maintain-ktime_t-based-offsets-for-hrtimers.patch +hrtimers-move-lock-held-region-in-hrtimer_interrupt.patch +timekeeping-provide-hrtimer-update-function.patch +hrtimer-update-hrtimer-base-offsets-each-hrtimer_interrupt.patch +timekeeping-add-missing-update-call-in-timekeeping_resume.patch diff --git a/releases/3.0.38/tcp-drop-syn-fin-messages.patch b/releases/3.0.38/tcp-drop-syn-fin-messages.patch new file mode 100644 index 00000000000..b5ccc21c199 --- /dev/null +++ b/releases/3.0.38/tcp-drop-syn-fin-messages.patch @@ -0,0 +1,35 @@ +From fdf5af0daf8019cec2396cdef8fb042d80fe71fa Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 2 Dec 2011 23:41:42 +0000 +Subject: tcp: drop SYN+FIN messages + +From: Eric Dumazet + +commit fdf5af0daf8019cec2396cdef8fb042d80fe71fa upstream. + +Denys Fedoryshchenko reported that SYN+FIN attacks were bringing his +linux machines to their limits. + +Dont call conn_request() if the TCP flags includes SYN flag + +Reported-by: Denys Fedoryshchenko +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/tcp_input.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5761,6 +5761,8 @@ int tcp_rcv_state_process(struct sock *s + goto discard; + + if (th->syn) { ++ if (th->fin) ++ goto discard; + if (icsk->icsk_af_ops->conn_request(sk, skb) < 0) + return 1; + diff --git a/releases/3.0.38/time-move-common-updates-to-a-function.patch b/releases/3.0.38/time-move-common-updates-to-a-function.patch new file mode 100644 index 00000000000..8031a76ebd9 --- /dev/null +++ b/releases/3.0.38/time-move-common-updates-to-a-function.patch @@ -0,0 +1,99 @@ +From johnstul@us.ibm.com Tue Jul 17 15:24:46 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:51 -0400 +Subject: time: Move common updates to a function +To: stable@vger.kernel.org +Cc: Thomas Gleixner , Eric Dumazet , Richard Cochran , Prarit Bhargava , Linux Kernel , John Stultz +Message-ID: <1342546438-17534-5-git-send-email-johnstul@us.ibm.com> + + +From: Thomas Gleixner + +This is a backport of cc06268c6a87db156af2daed6e96a936b955cc82 + +While not a bugfix itself, it allows following fixes to backport +in a more straightforward manner. + +CC: Thomas Gleixner +CC: Eric Dumazet +CC: Richard Cochran +Signed-off-by: Thomas Gleixner +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/timekeeping.c | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -166,6 +166,19 @@ static struct timespec total_sleep_time; + */ + static struct timespec raw_time; + ++/* must hold write on xtime_lock */ ++static void timekeeping_update(bool clearntp) ++{ ++ if (clearntp) { ++ timekeeper.ntp_error = 0; ++ ntp_clear(); ++ } ++ update_vsyscall(&xtime, &wall_to_monotonic, ++ timekeeper.clock, timekeeper.mult); ++} ++ ++ ++ + /* flag for if timekeeping is suspended */ + int __read_mostly timekeeping_suspended; + +@@ -366,11 +379,7 @@ int do_settimeofday(const struct timespe + + xtime = *tv; + +- timekeeper.ntp_error = 0; +- ntp_clear(); +- +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); ++ timekeeping_update(true); + + write_sequnlock_irqrestore(&xtime_lock, flags); + +@@ -403,11 +412,7 @@ int timekeeping_inject_offset(struct tim + xtime = timespec_add(xtime, *ts); + wall_to_monotonic = timespec_sub(wall_to_monotonic, *ts); + +- timekeeper.ntp_error = 0; +- ntp_clear(); +- +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); ++ timekeeping_update(true); + + write_sequnlock_irqrestore(&xtime_lock, flags); + +@@ -630,10 +635,7 @@ void timekeeping_inject_sleeptime(struct + + __timekeeping_inject_sleeptime(delta); + +- timekeeper.ntp_error = 0; +- ntp_clear(); +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); ++ timekeeping_update(true); + + write_sequnlock_irqrestore(&xtime_lock, flags); + +@@ -938,9 +940,7 @@ static void update_wall_time(void) + wall_to_monotonic.tv_sec -= leap; + } + +- /* check to see if there is a new clocksource to use */ +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); ++ timekeeping_update(false); + } + + /** diff --git a/releases/3.0.38/timekeeping-add-missing-update-call-in-timekeeping_resume.patch b/releases/3.0.38/timekeeping-add-missing-update-call-in-timekeeping_resume.patch new file mode 100644 index 00000000000..39dd05d250a --- /dev/null +++ b/releases/3.0.38/timekeeping-add-missing-update-call-in-timekeeping_resume.patch @@ -0,0 +1,54 @@ +From johnstul@us.ibm.com Tue Jul 17 15:27:16 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:58 -0400 +Subject: timekeeping: Add missing update call in timekeeping_resume() +To: stable@vger.kernel.org +Cc: Thomas Gleixner , LKML , Linux PM list , John Stultz , Ingo Molnar , Peter Zijlstra , Prarit Bhargava , Linus Torvalds +Message-ID: <1342546438-17534-12-git-send-email-johnstul@us.ibm.com> + + +From: Thomas Gleixner + +This is a backport of 3e997130bd2e8c6f5aaa49d6e3161d4d29b43ab0 + +The leap second rework unearthed another issue of inconsistent data. + +On timekeeping_resume() the timekeeper data is updated, but nothing +calls timekeeping_update(), so now the update code in the timer +interrupt sees stale values. + +This has been the case before those changes, but then the timer +interrupt was using stale data as well so this went unnoticed for quite +some time. + +Add the missing update call, so all the data is consistent everywhere. + +Reported-by: Andreas Schwab +Reported-and-tested-by: "Rafael J. Wysocki" +Reported-and-tested-by: Martin Steigerwald +Cc: John Stultz +Cc: Ingo Molnar +Cc: Peter Zijlstra , +Cc: Prarit Bhargava +Signed-off-by: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Linus Torvalds +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/timekeeping.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -693,6 +693,7 @@ static void timekeeping_resume(void) + timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); + timekeeper.ntp_error = 0; + timekeeping_suspended = 0; ++ timekeeping_update(false); + write_sequnlock_irqrestore(&xtime_lock, flags); + + touch_softlockup_watchdog(); diff --git a/releases/3.0.38/timekeeping-fix-clock_monotonic-inconsistency-during-leapsecond.patch b/releases/3.0.38/timekeeping-fix-clock_monotonic-inconsistency-during-leapsecond.patch new file mode 100644 index 00000000000..d2a1897bd73 --- /dev/null +++ b/releases/3.0.38/timekeeping-fix-clock_monotonic-inconsistency-during-leapsecond.patch @@ -0,0 +1,52 @@ +From johnstul@us.ibm.com Tue Jul 17 15:24:29 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:50 -0400 +Subject: timekeeping: Fix CLOCK_MONOTONIC inconsistency during leapsecond +To: stable@vger.kernel.org +Cc: John Stultz , Thomas Gleixner , Prarit Bhargava , Linux Kernel , John Stultz +Message-ID: <1342546438-17534-4-git-send-email-johnstul@us.ibm.com> + + +From: John Stultz + +This is a backport of fad0c66c4bb836d57a5f125ecd38bed653ca863a +which resolves a bug the previous commit. + +Commit 6b43ae8a61 (ntp: Fix leap-second hrtimer livelock) broke the +leapsecond update of CLOCK_MONOTONIC. The missing leapsecond update to +wall_to_monotonic causes discontinuities in CLOCK_MONOTONIC. + +Adjust wall_to_monotonic when NTP inserted a leapsecond. + +Reported-by: Richard Cochran +Signed-off-by: John Stultz +Tested-by: Richard Cochran +Link: http://lkml.kernel.org/r/1338400497-12420-1-git-send-email-john.stultz@linaro.org +Signed-off-by: Thomas Gleixner +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/timekeeping.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -824,6 +824,7 @@ static cycle_t logarithmic_accumulation( + xtime.tv_sec++; + leap = second_overflow(xtime.tv_sec); + xtime.tv_sec += leap; ++ wall_to_monotonic.tv_sec -= leap; + } + + /* Accumulate raw time */ +@@ -934,7 +935,7 @@ static void update_wall_time(void) + xtime.tv_sec++; + leap = second_overflow(xtime.tv_sec); + xtime.tv_sec += leap; +- ++ wall_to_monotonic.tv_sec -= leap; + } + + /* check to see if there is a new clocksource to use */ diff --git a/releases/3.0.38/timekeeping-fix-leapsecond-triggered-load-spike-issue.patch b/releases/3.0.38/timekeeping-fix-leapsecond-triggered-load-spike-issue.patch new file mode 100644 index 00000000000..8054431c12c --- /dev/null +++ b/releases/3.0.38/timekeeping-fix-leapsecond-triggered-load-spike-issue.patch @@ -0,0 +1,64 @@ +From johnstul@us.ibm.com Tue Jul 17 15:25:50 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:53 -0400 +Subject: timekeeping: Fix leapsecond triggered load spike issue +To: stable@vger.kernel.org +Cc: John Stultz , Thomas Gleixner , Prarit Bhargava , Linux Kernel +Message-ID: <1342546438-17534-7-git-send-email-johnstul@us.ibm.com> + +From: John Stultz + +This is a backport of 4873fa070ae84a4115f0b3c9dfabc224f1bc7c51 + +The timekeeping code misses an update of the hrtimer subsystem after a +leap second happened. Due to that timers based on CLOCK_REALTIME are +either expiring a second early or late depending on whether a leap +second has been inserted or deleted until an operation is initiated +which causes that update. Unless the update happens by some other +means this discrepancy between the timekeeping and the hrtimer data +stays forever and timers are expired either early or late. + +The reported immediate workaround - $ data -s "`date`" - is causing a +call to clock_was_set() which updates the hrtimer data structures. +See: http://www.sheeri.com/content/mysql-and-leap-second-high-cpu-and-fix + +Add the missing clock_was_set() call to update_wall_time() in case of +a leap second event. The actual update is deferred to softirq context +as the necessary smp function call cannot be invoked from hard +interrupt context. + +Signed-off-by: John Stultz +Reported-by: Jan Engelhardt +Reviewed-by: Ingo Molnar +Acked-by: Peter Zijlstra +Acked-by: Prarit Bhargava +Link: http://lkml.kernel.org/r/1341960205-56738-3-git-send-email-johnstul@us.ibm.com +Signed-off-by: Thomas Gleixner +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/timekeeping.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -827,6 +827,8 @@ static cycle_t logarithmic_accumulation( + leap = second_overflow(xtime.tv_sec); + xtime.tv_sec += leap; + wall_to_monotonic.tv_sec -= leap; ++ if (leap) ++ clock_was_set_delayed(); + } + + /* Accumulate raw time */ +@@ -938,6 +940,8 @@ static void update_wall_time(void) + leap = second_overflow(xtime.tv_sec); + xtime.tv_sec += leap; + wall_to_monotonic.tv_sec -= leap; ++ if (leap) ++ clock_was_set_delayed(); + } + + timekeeping_update(false); diff --git a/releases/3.0.38/timekeeping-maintain-ktime_t-based-offsets-for-hrtimers.patch b/releases/3.0.38/timekeeping-maintain-ktime_t-based-offsets-for-hrtimers.patch new file mode 100644 index 00000000000..0e769278e8f --- /dev/null +++ b/releases/3.0.38/timekeeping-maintain-ktime_t-based-offsets-for-hrtimers.patch @@ -0,0 +1,102 @@ +From johnstul@us.ibm.com Tue Jul 17 15:26:11 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:54 -0400 +Subject: timekeeping: Maintain ktime_t based offsets for hrtimers +To: stable@vger.kernel.org +Cc: Thomas Gleixner , John Stultz , Prarit Bhargava , Linux Kernel +Message-ID: <1342546438-17534-8-git-send-email-johnstul@us.ibm.com> + + +From: Thomas Gleixner + +This is a backport of 5b9fe759a678e05be4937ddf03d50e950207c1c0 + +We need to update the hrtimer clock offsets from the hrtimer interrupt +context. To avoid conversions from timespec to ktime_t maintain a +ktime_t based representation of those offsets in the timekeeper. This +puts the conversion overhead into the code which updates the +underlying offsets and provides fast accessible values in the hrtimer +interrupt. + +Signed-off-by: Thomas Gleixner +Signed-off-by: John Stultz +Reviewed-by: Ingo Molnar +Acked-by: Peter Zijlstra +Acked-by: Prarit Bhargava +Link: http://lkml.kernel.org/r/1341960205-56738-4-git-send-email-johnstul@us.ibm.com +Signed-off-by: Thomas Gleixner +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/timekeeping.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -161,18 +161,34 @@ static struct timespec xtime __attribute + static struct timespec wall_to_monotonic __attribute__ ((aligned (16))); + static struct timespec total_sleep_time; + ++/* Offset clock monotonic -> clock realtime */ ++static ktime_t offs_real; ++ ++/* Offset clock monotonic -> clock boottime */ ++static ktime_t offs_boot; ++ + /* + * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. + */ + static struct timespec raw_time; + + /* must hold write on xtime_lock */ ++static void update_rt_offset(void) ++{ ++ struct timespec tmp, *wtm = &wall_to_monotonic; ++ ++ set_normalized_timespec(&tmp, -wtm->tv_sec, -wtm->tv_nsec); ++ offs_real = timespec_to_ktime(tmp); ++} ++ ++/* must hold write on xtime_lock */ + static void timekeeping_update(bool clearntp) + { + if (clearntp) { + timekeeper.ntp_error = 0; + ntp_clear(); + } ++ update_rt_offset(); + update_vsyscall(&xtime, &wall_to_monotonic, + timekeeper.clock, timekeeper.mult); + } +@@ -587,6 +603,7 @@ void __init timekeeping_init(void) + } + set_normalized_timespec(&wall_to_monotonic, + -boot.tv_sec, -boot.tv_nsec); ++ update_rt_offset(); + total_sleep_time.tv_sec = 0; + total_sleep_time.tv_nsec = 0; + write_sequnlock_irqrestore(&xtime_lock, flags); +@@ -595,6 +612,12 @@ void __init timekeeping_init(void) + /* time in seconds when suspend began */ + static struct timespec timekeeping_suspend_time; + ++static void update_sleep_time(struct timespec t) ++{ ++ total_sleep_time = t; ++ offs_boot = timespec_to_ktime(t); ++} ++ + /** + * __timekeeping_inject_sleeptime - Internal function to add sleep interval + * @delta: pointer to a timespec delta value +@@ -606,7 +629,7 @@ static void __timekeeping_inject_sleepti + { + xtime = timespec_add(xtime, *delta); + wall_to_monotonic = timespec_sub(wall_to_monotonic, *delta); +- total_sleep_time = timespec_add(total_sleep_time, *delta); ++ update_sleep_time(timespec_add(total_sleep_time, *delta)); + } + + diff --git a/releases/3.0.38/timekeeping-provide-hrtimer-update-function.patch b/releases/3.0.38/timekeeping-provide-hrtimer-update-function.patch new file mode 100644 index 00000000000..b871229057b --- /dev/null +++ b/releases/3.0.38/timekeeping-provide-hrtimer-update-function.patch @@ -0,0 +1,91 @@ +From johnstul@us.ibm.com Tue Jul 17 15:26:41 2012 +From: John Stultz +Date: Tue, 17 Jul 2012 13:33:56 -0400 +Subject: timekeeping: Provide hrtimer update function +To: stable@vger.kernel.org +Cc: Thomas Gleixner , John Stultz , Prarit Bhargava , Linux Kernel +Message-ID: <1342546438-17534-10-git-send-email-johnstul@us.ibm.com> + + +From: Thomas Gleixner + +This is a backport of f6c06abfb3972ad4914cef57d8348fcb2932bc3b + +To finally fix the infamous leap second issue and other race windows +caused by functions which change the offsets between the various time +bases (CLOCK_MONOTONIC, CLOCK_REALTIME and CLOCK_BOOTTIME) we need a +function which atomically gets the current monotonic time and updates +the offsets of CLOCK_REALTIME and CLOCK_BOOTTIME with minimalistic +overhead. The previous patch which provides ktime_t offsets allows us +to make this function almost as cheap as ktime_get() which is going to +be replaced in hrtimer_interrupt(). + +Signed-off-by: Thomas Gleixner +Reviewed-by: Ingo Molnar +Acked-by: Peter Zijlstra +Acked-by: Prarit Bhargava +Signed-off-by: John Stultz +Link: http://lkml.kernel.org/r/1341960205-56738-7-git-send-email-johnstul@us.ibm.com +Signed-off-by: Thomas Gleixner +Cc: Prarit Bhargava +Cc: Thomas Gleixner +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/hrtimer.h | 1 + + kernel/time/timekeeping.c | 34 ++++++++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+) + +--- a/include/linux/hrtimer.h ++++ b/include/linux/hrtimer.h +@@ -327,6 +327,7 @@ extern ktime_t ktime_get(void); + extern ktime_t ktime_get_real(void); + extern ktime_t ktime_get_boottime(void); + extern ktime_t ktime_get_monotonic_offset(void); ++extern ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot); + + DECLARE_PER_CPU(struct tick_device, tick_cpu_device); + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -1126,6 +1126,40 @@ void get_xtime_and_monotonic_and_sleep_o + } while (read_seqretry(&xtime_lock, seq)); + } + ++#ifdef CONFIG_HIGH_RES_TIMERS ++/** ++ * ktime_get_update_offsets - hrtimer helper ++ * @real: pointer to storage for monotonic -> realtime offset ++ * @_boot: pointer to storage for monotonic -> boottime offset ++ * ++ * Returns current monotonic time and updates the offsets ++ * Called from hrtimer_interupt() or retrigger_next_event() ++ */ ++ktime_t ktime_get_update_offsets(ktime_t *real, ktime_t *boot) ++{ ++ ktime_t now; ++ unsigned int seq; ++ u64 secs, nsecs; ++ ++ do { ++ seq = read_seqbegin(&xtime_lock); ++ ++ secs = xtime.tv_sec; ++ nsecs = xtime.tv_nsec; ++ nsecs += timekeeping_get_ns(); ++ /* If arch requires, add in gettimeoffset() */ ++ nsecs += arch_gettimeoffset(); ++ ++ *real = offs_real; ++ *boot = offs_boot; ++ } while (read_seqretry(&xtime_lock, seq)); ++ ++ now = ktime_add_ns(ktime_set(secs, 0), nsecs); ++ now = ktime_sub(now, *real); ++ return now; ++} ++#endif ++ + /** + * ktime_get_monotonic_offset() - get wall_to_monotonic in ktime_t format + */