Linux 2.6.36.3
Drop merged patches: posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch sched-cure-more-NO_HZ-load-average-woes.patch orinoco-initialise-priv_hw-before-assigning-the-interrupt.patch
This commit is contained in:
parent
5d6f3748c3
commit
c62fd951a3
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,4 +3,3 @@ patch-*.bz2
|
|||||||
clog
|
clog
|
||||||
*.rpm
|
*.rpm
|
||||||
kernel-2.6.*/
|
kernel-2.6.*/
|
||||||
/patch-2.6.36.2.bz2
|
|
||||||
|
26
kernel.spec
26
kernel.spec
@ -51,7 +51,7 @@ Summary: The Linux kernel
|
|||||||
# For non-released -rc kernels, this will be prepended with "0.", so
|
# For non-released -rc kernels, this will be prepended with "0.", so
|
||||||
# for example a 3 here will become 0.3
|
# for example a 3 here will become 0.3
|
||||||
#
|
#
|
||||||
%global baserelease 13
|
%global baserelease 14
|
||||||
%global fedora_build %{baserelease}
|
%global fedora_build %{baserelease}
|
||||||
|
|
||||||
# base_sublevel is the kernel version we're starting with and patching
|
# base_sublevel is the kernel version we're starting with and patching
|
||||||
@ -63,7 +63,7 @@ Summary: The Linux kernel
|
|||||||
%if 0%{?released_kernel}
|
%if 0%{?released_kernel}
|
||||||
|
|
||||||
# Do we have a -stable update to apply?
|
# Do we have a -stable update to apply?
|
||||||
%define stable_update 2
|
%define stable_update 3
|
||||||
# Is it a -stable RC?
|
# Is it a -stable RC?
|
||||||
%define stable_rc 0
|
%define stable_rc 0
|
||||||
# Set rpm version accordingly
|
# Set rpm version accordingly
|
||||||
@ -730,8 +730,6 @@ Patch12308: fix-i8k-inline-asm.patch
|
|||||||
Patch12405: inet_diag-make-sure-we-run-the-same-bytecode-we-audited.patch
|
Patch12405: inet_diag-make-sure-we-run-the-same-bytecode-we-audited.patch
|
||||||
Patch12408: netlink-make-nlmsg_find_attr-take-a-const-ptr.patch
|
Patch12408: netlink-make-nlmsg_find_attr-take-a-const-ptr.patch
|
||||||
|
|
||||||
Patch12406: posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch
|
|
||||||
|
|
||||||
Patch12410: tty-make-tiocgicount-a-handler.patch
|
Patch12410: tty-make-tiocgicount-a-handler.patch
|
||||||
Patch12411: tty-icount-changeover-for-other-main-devices.patch
|
Patch12411: tty-icount-changeover-for-other-main-devices.patch
|
||||||
|
|
||||||
@ -740,10 +738,6 @@ Patch12413: tpm-autodetect-itpm-devices.patch
|
|||||||
Patch12420: mm-page-allocator-adjust-the-per-cpu-counter-threshold-when-memory-is-low.patch
|
Patch12420: mm-page-allocator-adjust-the-per-cpu-counter-threshold-when-memory-is-low.patch
|
||||||
Patch12421: mm-vmstat-use-a-single-setter-function-and-callback-for-adjusting-percpu-thresholds.patch
|
Patch12421: mm-vmstat-use-a-single-setter-function-and-callback-for-adjusting-percpu-thresholds.patch
|
||||||
|
|
||||||
Patch12430: sched-cure-more-NO_HZ-load-average-woes.patch
|
|
||||||
|
|
||||||
Patch12431: orinoco-initialise-priv_hw-before-assigning-the-interrupt.patch
|
|
||||||
|
|
||||||
Patch12435: btrfs-fix-error-handling-in-btrfs_get_sb.patch
|
Patch12435: btrfs-fix-error-handling-in-btrfs_get_sb.patch
|
||||||
Patch12436: btrfs-fix-race-between-btrfs_get_sb-and-umount.patch
|
Patch12436: btrfs-fix-race-between-btrfs_get_sb-and-umount.patch
|
||||||
Patch12437: btrfs-setup-blank-root-and-fs_info-for-mount-time.patch
|
Patch12437: btrfs-setup-blank-root-and-fs_info-for-mount-time.patch
|
||||||
@ -1383,9 +1377,6 @@ ApplyPatch fix-i8k-inline-asm.patch
|
|||||||
ApplyPatch inet_diag-make-sure-we-run-the-same-bytecode-we-audited.patch
|
ApplyPatch inet_diag-make-sure-we-run-the-same-bytecode-we-audited.patch
|
||||||
ApplyPatch netlink-make-nlmsg_find_attr-take-a-const-ptr.patch
|
ApplyPatch netlink-make-nlmsg_find_attr-take-a-const-ptr.patch
|
||||||
|
|
||||||
# rhbz#656264
|
|
||||||
ApplyPatch posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch
|
|
||||||
|
|
||||||
# CVE-2010-4077, CVE-2010-4075 (rhbz#648660, #648663)
|
# CVE-2010-4077, CVE-2010-4075 (rhbz#648660, #648663)
|
||||||
ApplyPatch tty-make-tiocgicount-a-handler.patch
|
ApplyPatch tty-make-tiocgicount-a-handler.patch
|
||||||
ApplyPatch tty-icount-changeover-for-other-main-devices.patch
|
ApplyPatch tty-icount-changeover-for-other-main-devices.patch
|
||||||
@ -1396,12 +1387,6 @@ ApplyPatch tpm-autodetect-itpm-devices.patch
|
|||||||
ApplyPatch mm-page-allocator-adjust-the-per-cpu-counter-threshold-when-memory-is-low.patch
|
ApplyPatch mm-page-allocator-adjust-the-per-cpu-counter-threshold-when-memory-is-low.patch
|
||||||
ApplyPatch mm-vmstat-use-a-single-setter-function-and-callback-for-adjusting-percpu-thresholds.patch
|
ApplyPatch mm-vmstat-use-a-single-setter-function-and-callback-for-adjusting-percpu-thresholds.patch
|
||||||
|
|
||||||
# rhbz#650934
|
|
||||||
ApplyPatch sched-cure-more-NO_HZ-load-average-woes.patch
|
|
||||||
|
|
||||||
# rhbz#657864 [229bd792]
|
|
||||||
ApplyPatch orinoco-initialise-priv_hw-before-assigning-the-interrupt.patch
|
|
||||||
|
|
||||||
# rhbz#637619
|
# rhbz#637619
|
||||||
ApplyPatch net-AF_PACKET-vmalloc.patch
|
ApplyPatch net-AF_PACKET-vmalloc.patch
|
||||||
|
|
||||||
@ -2019,6 +2004,13 @@ fi
|
|||||||
# || ||
|
# || ||
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jan 10 2011 Chuck Ebbert <cebbert@redhat.com> 2.6.36.3-14
|
||||||
|
- Linux 2.6.36.3
|
||||||
|
- Drop merged patches:
|
||||||
|
posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch
|
||||||
|
sched-cure-more-NO_HZ-load-average-woes.patch
|
||||||
|
orinoco-initialise-priv_hw-before-assigning-the-interrupt.patch
|
||||||
|
|
||||||
* Sat Dec 18 2010 Kyle McMartin <kyle@redhat.com>
|
* Sat Dec 18 2010 Kyle McMartin <kyle@redhat.com>
|
||||||
- Patch from nhorman against f13:
|
- Patch from nhorman against f13:
|
||||||
Enhance AF_PACKET to allow non-contiguous buffer alloc (#637619)
|
Enhance AF_PACKET to allow non-contiguous buffer alloc (#637619)
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
From d2e8008554faf4905ea9435f129bc6a28303e46a Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Kilroy <kilroyd@googlemail.com>
|
|
||||||
Date: Thu, 9 Dec 2010 18:56:14 -0500
|
|
||||||
Subject: [PATCH] orinoco: initialise priv->hw before assigning the interrupt
|
|
||||||
|
|
||||||
The interrupt handler takes a lock - but since commit bcad6e80f3f this
|
|
||||||
lock goes through an indirection specified in the hermes_t structure.
|
|
||||||
We must therefore initialise the structure before setting up the
|
|
||||||
interrupt handler.
|
|
||||||
|
|
||||||
Fix orinoco_cs and spectrum_cs
|
|
||||||
|
|
||||||
<https://bugzilla.kernel.org/show_bug.cgi?id=23932>
|
|
||||||
|
|
||||||
Bisected by: Matt Domsch <Matt_Domsch@dell.com>
|
|
||||||
Signed-off by: David Kilroy <kilroyd@googlemail.com>
|
|
||||||
Cc: stable@kernel.org
|
|
||||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
|
|
||||||
drivers/net/wireless/orinoco/orinoco_cs.c
|
|
||||||
drivers/net/wireless/orinoco/spectrum_cs.c
|
|
||||||
---
|
|
||||||
drivers/net/wireless/orinoco/orinoco_cs.c | 14 +++++++-------
|
|
||||||
drivers/net/wireless/orinoco/spectrum_cs.c | 14 +++++++-------
|
|
||||||
2 files changed, 14 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
|
|
||||||
index ef46a2d..083999f 100644
|
|
||||||
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
|
|
||||||
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
|
|
||||||
@@ -248,20 +248,20 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = pcmcia_request_irq(link, orinoco_interrupt);
|
|
||||||
- if (ret)
|
|
||||||
- goto failed;
|
|
||||||
-
|
|
||||||
- /* We initialize the hermes structure before completing PCMCIA
|
|
||||||
- * configuration just in case the interrupt handler gets
|
|
||||||
- * called. */
|
|
||||||
mem = ioport_map(link->resource[0]->start,
|
|
||||||
resource_size(link->resource[0]));
|
|
||||||
if (!mem)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
+ /* We initialize the hermes structure before completing PCMCIA
|
|
||||||
+ * configuration just in case the interrupt handler gets
|
|
||||||
+ * called. */
|
|
||||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
|
||||||
|
|
||||||
+ ret = pcmcia_request_irq(link, orinoco_interrupt);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto failed;
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* This actually configures the PCMCIA socket -- setting up
|
|
||||||
* the I/O windows and the interrupt mapping, and putting the
|
|
||||||
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
|
|
||||||
index 873877e..93070a3 100644
|
|
||||||
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
|
|
||||||
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
|
|
||||||
@@ -310,21 +310,21 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = pcmcia_request_irq(link, orinoco_interrupt);
|
|
||||||
- if (ret)
|
|
||||||
- goto failed;
|
|
||||||
-
|
|
||||||
- /* We initialize the hermes structure before completing PCMCIA
|
|
||||||
- * configuration just in case the interrupt handler gets
|
|
||||||
- * called. */
|
|
||||||
mem = ioport_map(link->resource[0]->start,
|
|
||||||
resource_size(link->resource[0]));
|
|
||||||
if (!mem)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
+ /* We initialize the hermes structure before completing PCMCIA
|
|
||||||
+ * configuration just in case the interrupt handler gets
|
|
||||||
+ * called. */
|
|
||||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
|
||||||
hw->eeprom_pda = true;
|
|
||||||
|
|
||||||
+ ret = pcmcia_request_irq(link, orinoco_interrupt);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto failed;
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* This actually configures the PCMCIA socket -- setting up
|
|
||||||
* the I/O windows and the interrupt mapping, and putting the
|
|
||||||
--
|
|
||||||
1.7.3.3
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
|||||||
From 78dfb59b62d1a7735cd28fc2783e58c122954fae Mon Sep 17 00:00:00 2001
|
|
||||||
From: Oleg Nesterov <oleg@redhat.com>
|
|
||||||
Date: Fri, 5 Nov 2010 16:53:42 +0100
|
|
||||||
Subject: posix-cpu-timers: workaround to suppress the problems with mt exec
|
|
||||||
|
|
||||||
posix-cpu-timers.c correctly assumes that the dying process does
|
|
||||||
posix_cpu_timers_exit_group() and removes all !CPUCLOCK_PERTHREAD
|
|
||||||
timers from signal->cpu_timers list.
|
|
||||||
|
|
||||||
But, it also assumes that timer->it.cpu.task is always the group
|
|
||||||
leader, and thus the dead ->task means the dead thread group.
|
|
||||||
|
|
||||||
This is obviously not true after de_thread() changes the leader.
|
|
||||||
After that almost every posix_cpu_timer_ method has problems.
|
|
||||||
|
|
||||||
It is not simple to fix this bug correctly. First of all, I think
|
|
||||||
that timer->it.cpu should use struct pid instead of task_struct.
|
|
||||||
Also, the locking should be reworked completely. In particular,
|
|
||||||
tasklist_lock should not be used at all. This all needs a lot of
|
|
||||||
nontrivial and hard-to-test changes.
|
|
||||||
|
|
||||||
Change __exit_signal() to do posix_cpu_timers_exit_group() when
|
|
||||||
the old leader dies during exec. This is not the fix, just the
|
|
||||||
temporary hack to hide the problem for 2.6.37 and stable. IOW,
|
|
||||||
this is obviously wrong but this is what we currently have anyway:
|
|
||||||
cpu timers do not work after mt exec.
|
|
||||||
|
|
||||||
In theory this change adds another race. The exiting leader can
|
|
||||||
detach the timers which were attached to the new leader. However,
|
|
||||||
the window between de_thread() and release_task() is small, we
|
|
||||||
can pretend that sys_timer_create() was called before de_thread().
|
|
||||||
|
|
||||||
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
|
|
||||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
||||||
---
|
|
||||||
kernel/exit.c | 8 ++++++++
|
|
||||||
1 files changed, 8 insertions(+), 0 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kernel/exit.c b/kernel/exit.c
|
|
||||||
index 0312022..1eff9e4 100644
|
|
||||||
--- a/kernel/exit.c
|
|
||||||
+++ b/kernel/exit.c
|
|
||||||
@@ -95,6 +95,14 @@ static void __exit_signal(struct task_struct *tsk)
|
|
||||||
sig->tty = NULL;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
+ * This can only happen if the caller is de_thread().
|
|
||||||
+ * FIXME: this is the temporary hack, we should teach
|
|
||||||
+ * posix-cpu-timers to handle this case correctly.
|
|
||||||
+ */
|
|
||||||
+ if (unlikely(has_group_leader_pid(tsk)))
|
|
||||||
+ posix_cpu_timers_exit_group(tsk);
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
* If there is any task waiting for the group exit
|
|
||||||
* then notify it:
|
|
||||||
*/
|
|
||||||
--
|
|
||||||
1.7.3.2
|
|
||||||
|
|
@ -1,273 +0,0 @@
|
|||||||
From bounces.tip@hpa.at.zytor.com Wed Dec 8 15:40:48 2010
|
|
||||||
From: tip-bot for Peter Zijlstra <a.p.zijlstra@chello.nl>
|
|
||||||
In-Reply-To: <1291129145.32004.874.camel@laptop>
|
|
||||||
References: <1291129145.32004.874.camel@laptop>
|
|
||||||
Subject: [tip:sched/urgent] sched: Cure more NO_HZ load average woes
|
|
||||||
Message-ID: <tip-0f004f5a696a9434b7214d0d3cbd0525ee77d428@git.kernel.org>
|
|
||||||
Git-Commit-ID: 0f004f5a696a9434b7214d0d3cbd0525ee77d428
|
|
||||||
|
|
||||||
Commit-ID: 0f004f5a696a9434b7214d0d3cbd0525ee77d428
|
|
||||||
Gitweb: http://git.kernel.org/tip/0f004f5a696a9434b7214d0d3cbd0525ee77d428
|
|
||||||
Author: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
|
||||||
AuthorDate: Tue, 30 Nov 2010 19:48:45 +0100
|
|
||||||
Committer: Ingo Molnar <mingo@elte.hu>
|
|
||||||
CommitDate: Wed, 8 Dec 2010 20:15:04 +0100
|
|
||||||
|
|
||||||
sched: Cure more NO_HZ load average woes
|
|
||||||
|
|
||||||
There's a long-running regression that proved difficult to fix and
|
|
||||||
which is hitting certain people and is rather annoying in its effects.
|
|
||||||
|
|
||||||
Damien reported that after 74f5187ac8 (sched: Cure load average vs
|
|
||||||
NO_HZ woes) his load average is unnaturally high, he also noted that
|
|
||||||
even with that patch reverted the load avgerage numbers are not
|
|
||||||
correct.
|
|
||||||
|
|
||||||
The problem is that the previous patch only solved half the NO_HZ
|
|
||||||
problem, it addressed the part of going into NO_HZ mode, not of
|
|
||||||
comming out of NO_HZ mode. This patch implements that missing half.
|
|
||||||
|
|
||||||
When comming out of NO_HZ mode there are two important things to take
|
|
||||||
care of:
|
|
||||||
|
|
||||||
- Folding the pending idle delta into the global active count.
|
|
||||||
- Correctly aging the averages for the idle-duration.
|
|
||||||
|
|
||||||
So with this patch the NO_HZ interaction should be complete and
|
|
||||||
behaviour between CONFIG_NO_HZ=[yn] should be equivalent.
|
|
||||||
|
|
||||||
Furthermore, this patch slightly changes the load average computation
|
|
||||||
by adding a rounding term to the fixed point multiplication.
|
|
||||||
|
|
||||||
Reported-by: Damien Wyart <damien.wyart@free.fr>
|
|
||||||
Reported-by: Tim McGrath <tmhikaru@gmail.com>
|
|
||||||
Tested-by: Damien Wyart <damien.wyart@free.fr>
|
|
||||||
Tested-by: Orion Poplawski <orion@cora.nwra.com>
|
|
||||||
Tested-by: Kyle McMartin <kyle@mcmartin.ca>
|
|
||||||
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
|
||||||
Cc: stable@kernel.org
|
|
||||||
Cc: Chase Douglas <chase.douglas@canonical.com>
|
|
||||||
LKML-Reference: <1291129145.32004.874.camel@laptop>
|
|
||||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
|
||||||
---
|
|
||||||
include/linux/sched.h | 2 +-
|
|
||||||
kernel/sched.c | 150 +++++++++++++++++++++++++++++++++++++++++++++----
|
|
||||||
kernel/timer.c | 2 +-
|
|
||||||
3 files changed, 141 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
|
||||||
index 2c79e92..2238745 100644
|
|
||||||
--- a/include/linux/sched.h
|
|
||||||
+++ b/include/linux/sched.h
|
|
||||||
@@ -143,7 +143,7 @@ extern unsigned long nr_iowait_cpu(int cpu);
|
|
||||||
extern unsigned long this_cpu_load(void);
|
|
||||||
|
|
||||||
|
|
||||||
-extern void calc_global_load(void);
|
|
||||||
+extern void calc_global_load(unsigned long ticks);
|
|
||||||
|
|
||||||
extern unsigned long get_parent_ip(unsigned long addr);
|
|
||||||
|
|
||||||
diff --git a/kernel/sched.c b/kernel/sched.c
|
|
||||||
index dc91a4d..6b7c26a 100644
|
|
||||||
--- a/kernel/sched.c
|
|
||||||
+++ b/kernel/sched.c
|
|
||||||
@@ -3119,6 +3119,15 @@ static long calc_load_fold_active(struct rq *this_rq)
|
|
||||||
return delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static unsigned long
|
|
||||||
+calc_load(unsigned long load, unsigned long exp, unsigned long active)
|
|
||||||
+{
|
|
||||||
+ load *= exp;
|
|
||||||
+ load += active * (FIXED_1 - exp);
|
|
||||||
+ load += 1UL << (FSHIFT - 1);
|
|
||||||
+ return load >> FSHIFT;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
#ifdef CONFIG_NO_HZ
|
|
||||||
/*
|
|
||||||
* For NO_HZ we delay the active fold to the next LOAD_FREQ update.
|
|
||||||
@@ -3148,6 +3157,128 @@ static long calc_load_fold_idle(void)
|
|
||||||
|
|
||||||
return delta;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * fixed_power_int - compute: x^n, in O(log n) time
|
|
||||||
+ *
|
|
||||||
+ * @x: base of the power
|
|
||||||
+ * @frac_bits: fractional bits of @x
|
|
||||||
+ * @n: power to raise @x to.
|
|
||||||
+ *
|
|
||||||
+ * By exploiting the relation between the definition of the natural power
|
|
||||||
+ * function: x^n := x*x*...*x (x multiplied by itself for n times), and
|
|
||||||
+ * the binary encoding of numbers used by computers: n := \Sum n_i * 2^i,
|
|
||||||
+ * (where: n_i \elem {0, 1}, the binary vector representing n),
|
|
||||||
+ * we find: x^n := x^(\Sum n_i * 2^i) := \Prod x^(n_i * 2^i), which is
|
|
||||||
+ * of course trivially computable in O(log_2 n), the length of our binary
|
|
||||||
+ * vector.
|
|
||||||
+ */
|
|
||||||
+static unsigned long
|
|
||||||
+fixed_power_int(unsigned long x, unsigned int frac_bits, unsigned int n)
|
|
||||||
+{
|
|
||||||
+ unsigned long result = 1UL << frac_bits;
|
|
||||||
+
|
|
||||||
+ if (n) for (;;) {
|
|
||||||
+ if (n & 1) {
|
|
||||||
+ result *= x;
|
|
||||||
+ result += 1UL << (frac_bits - 1);
|
|
||||||
+ result >>= frac_bits;
|
|
||||||
+ }
|
|
||||||
+ n >>= 1;
|
|
||||||
+ if (!n)
|
|
||||||
+ break;
|
|
||||||
+ x *= x;
|
|
||||||
+ x += 1UL << (frac_bits - 1);
|
|
||||||
+ x >>= frac_bits;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return result;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * a1 = a0 * e + a * (1 - e)
|
|
||||||
+ *
|
|
||||||
+ * a2 = a1 * e + a * (1 - e)
|
|
||||||
+ * = (a0 * e + a * (1 - e)) * e + a * (1 - e)
|
|
||||||
+ * = a0 * e^2 + a * (1 - e) * (1 + e)
|
|
||||||
+ *
|
|
||||||
+ * a3 = a2 * e + a * (1 - e)
|
|
||||||
+ * = (a0 * e^2 + a * (1 - e) * (1 + e)) * e + a * (1 - e)
|
|
||||||
+ * = a0 * e^3 + a * (1 - e) * (1 + e + e^2)
|
|
||||||
+ *
|
|
||||||
+ * ...
|
|
||||||
+ *
|
|
||||||
+ * an = a0 * e^n + a * (1 - e) * (1 + e + ... + e^n-1) [1]
|
|
||||||
+ * = a0 * e^n + a * (1 - e) * (1 - e^n)/(1 - e)
|
|
||||||
+ * = a0 * e^n + a * (1 - e^n)
|
|
||||||
+ *
|
|
||||||
+ * [1] application of the geometric series:
|
|
||||||
+ *
|
|
||||||
+ * n 1 - x^(n+1)
|
|
||||||
+ * S_n := \Sum x^i = -------------
|
|
||||||
+ * i=0 1 - x
|
|
||||||
+ */
|
|
||||||
+static unsigned long
|
|
||||||
+calc_load_n(unsigned long load, unsigned long exp,
|
|
||||||
+ unsigned long active, unsigned int n)
|
|
||||||
+{
|
|
||||||
+
|
|
||||||
+ return calc_load(load, fixed_power_int(exp, FSHIFT, n), active);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * NO_HZ can leave us missing all per-cpu ticks calling
|
|
||||||
+ * calc_load_account_active(), but since an idle CPU folds its delta into
|
|
||||||
+ * calc_load_tasks_idle per calc_load_account_idle(), all we need to do is fold
|
|
||||||
+ * in the pending idle delta if our idle period crossed a load cycle boundary.
|
|
||||||
+ *
|
|
||||||
+ * Once we've updated the global active value, we need to apply the exponential
|
|
||||||
+ * weights adjusted to the number of cycles missed.
|
|
||||||
+ */
|
|
||||||
+static void calc_global_nohz(unsigned long ticks)
|
|
||||||
+{
|
|
||||||
+ long delta, active, n;
|
|
||||||
+
|
|
||||||
+ if (time_before(jiffies, calc_load_update))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If we crossed a calc_load_update boundary, make sure to fold
|
|
||||||
+ * any pending idle changes, the respective CPUs might have
|
|
||||||
+ * missed the tick driven calc_load_account_active() update
|
|
||||||
+ * due to NO_HZ.
|
|
||||||
+ */
|
|
||||||
+ delta = calc_load_fold_idle();
|
|
||||||
+ if (delta)
|
|
||||||
+ atomic_long_add(delta, &calc_load_tasks);
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If we were idle for multiple load cycles, apply them.
|
|
||||||
+ */
|
|
||||||
+ if (ticks >= LOAD_FREQ) {
|
|
||||||
+ n = ticks / LOAD_FREQ;
|
|
||||||
+
|
|
||||||
+ active = atomic_long_read(&calc_load_tasks);
|
|
||||||
+ active = active > 0 ? active * FIXED_1 : 0;
|
|
||||||
+
|
|
||||||
+ avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
|
|
||||||
+ avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
|
|
||||||
+ avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);
|
|
||||||
+
|
|
||||||
+ calc_load_update += n * LOAD_FREQ;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Its possible the remainder of the above division also crosses
|
|
||||||
+ * a LOAD_FREQ period, the regular check in calc_global_load()
|
|
||||||
+ * which comes after this will take care of that.
|
|
||||||
+ *
|
|
||||||
+ * Consider us being 11 ticks before a cycle completion, and us
|
|
||||||
+ * sleeping for 4*LOAD_FREQ + 22 ticks, then the above code will
|
|
||||||
+ * age us 4 cycles, and the test in calc_global_load() will
|
|
||||||
+ * pick up the final one.
|
|
||||||
+ */
|
|
||||||
+}
|
|
||||||
#else
|
|
||||||
static void calc_load_account_idle(struct rq *this_rq)
|
|
||||||
{
|
|
||||||
@@ -3157,6 +3288,10 @@ static inline long calc_load_fold_idle(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+static void calc_global_nohz(unsigned long ticks)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
@@ -3174,24 +3309,17 @@ void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
|
|
||||||
loads[2] = (avenrun[2] + offset) << shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static unsigned long
|
|
||||||
-calc_load(unsigned long load, unsigned long exp, unsigned long active)
|
|
||||||
-{
|
|
||||||
- load *= exp;
|
|
||||||
- load += active * (FIXED_1 - exp);
|
|
||||||
- return load >> FSHIFT;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* calc_load - update the avenrun load estimates 10 ticks after the
|
|
||||||
* CPUs have updated calc_load_tasks.
|
|
||||||
*/
|
|
||||||
-void calc_global_load(void)
|
|
||||||
+void calc_global_load(unsigned long ticks)
|
|
||||||
{
|
|
||||||
- unsigned long upd = calc_load_update + 10;
|
|
||||||
long active;
|
|
||||||
|
|
||||||
- if (time_before(jiffies, upd))
|
|
||||||
+ calc_global_nohz(ticks);
|
|
||||||
+
|
|
||||||
+ if (time_before(jiffies, calc_load_update + 10))
|
|
||||||
return;
|
|
||||||
|
|
||||||
active = atomic_long_read(&calc_load_tasks);
|
|
||||||
diff --git a/kernel/timer.c b/kernel/timer.c
|
|
||||||
index 68a9ae7..7bd715f 100644
|
|
||||||
--- a/kernel/timer.c
|
|
||||||
+++ b/kernel/timer.c
|
|
||||||
@@ -1319,7 +1319,7 @@ void do_timer(unsigned long ticks)
|
|
||||||
{
|
|
||||||
jiffies_64 += ticks;
|
|
||||||
update_wall_time();
|
|
||||||
- calc_global_load();
|
|
||||||
+ calc_global_load(ticks);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __ARCH_WANT_SYS_ALARM
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user