Merge branch 'master' into rawhide/user/myoung/xendom0
Conflicts: kernel.spec
This commit is contained in:
commit
8807475c83
|
@ -4,3 +4,4 @@ clog
|
|||
*.rpm
|
||||
kernel-2.6.*/
|
||||
/patch-2.6.37-rc5.bz2
|
||||
/patch-2.6.37-rc5-git2.bz2
|
||||
|
|
36
kernel.spec
36
kernel.spec
|
@ -85,7 +85,7 @@ Summary: The Linux kernel
|
|||
# The rc snapshot level
|
||||
%define rcrev 5
|
||||
# The git snapshot level
|
||||
%define gitrev 0
|
||||
%define gitrev 2
|
||||
# Set rpm version accordingly
|
||||
%define rpmversion 2.6.%{upstream_sublevel}
|
||||
%endif
|
||||
|
@ -328,6 +328,7 @@ Summary: The Linux kernel
|
|||
%define image_install_path boot
|
||||
%define make_target image
|
||||
%define kernel_image arch/s390/boot/image
|
||||
%define with_perf 0
|
||||
%endif
|
||||
|
||||
%ifarch sparc64
|
||||
|
@ -614,6 +615,8 @@ Patch204: linux-2.6-debug-always-inline-kzalloc.patch
|
|||
Patch380: linux-2.6-defaults-pci_no_msi.patch
|
||||
Patch381: linux-2.6-defaults-pci_use_crs.patch
|
||||
Patch383: linux-2.6-defaults-aspm.patch
|
||||
Patch384: pci-disable-aspm-if-bios-asks-us-to.patch
|
||||
Patch386: pci-_osc-supported-field-should-contain-supported-features-not-enabled-ones.patch
|
||||
|
||||
Patch385: ima-allow-it-to-be-completely-disabled-and-default-off.patch
|
||||
|
||||
|
@ -708,6 +711,11 @@ Patch12401: debug-tty-print-dev-name.patch
|
|||
Patch12410: mm-page-allocator-adjust-the-per-cpu-counter-threshold-when-memory-is-low.patch
|
||||
Patch12411: mm-vmstat-use-a-single-setter-function-and-callback-for-adjusting-percpu-thresholds.patch
|
||||
|
||||
# rhbz#650934
|
||||
Patch12420: sched-cure-more-NO_HZ-load-average-woes.patch
|
||||
|
||||
Patch12421: orinoco-initialise-priv_hw-before-assigning-the-interrupt.patch
|
||||
|
||||
# Xen patches
|
||||
# git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen.git branches
|
||||
Patch20000: xen.next-2.6.37.patch
|
||||
|
@ -1200,6 +1208,9 @@ ApplyPatch linux-2.6-defaults-pci_no_msi.patch
|
|||
ApplyPatch linux-2.6-defaults-pci_use_crs.patch
|
||||
# enable ASPM by default on hardware we expect to work
|
||||
ApplyPatch linux-2.6-defaults-aspm.patch
|
||||
ApplyPatch pci-disable-aspm-if-bios-asks-us-to.patch
|
||||
# rhbz#638912
|
||||
ApplyPatch pci-_osc-supported-field-should-contain-supported-features-not-enabled-ones.patch
|
||||
|
||||
#ApplyPatch ima-allow-it-to-be-completely-disabled-and-default-off.patch
|
||||
|
||||
|
@ -1313,6 +1324,12 @@ ApplyPatch debug-tty-print-dev-name.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
|
||||
|
||||
# rhbz#650934
|
||||
ApplyPatch sched-cure-more-NO_HZ-load-average-woes.patch
|
||||
|
||||
# rhbz657864
|
||||
ApplyPatch orinoco-initialise-priv_hw-before-assigning-the-interrupt.patch
|
||||
|
||||
# Xen patches
|
||||
ApplyPatch xen.next-2.6.37.patch
|
||||
#ApplyPatch xen.upstream.core.patch
|
||||
|
@ -1932,6 +1949,23 @@ fi
|
|||
# || ||
|
||||
|
||||
%changelog
|
||||
* Fri Dec 10 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Another patch from mjg59: Set _OSC supported field correctly (#638912)
|
||||
|
||||
* Fri Dec 10 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- pci-disable-aspm-if-bios-asks-us-to.patch: Patch from mjg59 to disable
|
||||
ASPM if the BIOS has disabled it, but enabled it already on some devices.
|
||||
|
||||
* Thu Dec 09 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Snarf patch from wireless-next to fix mdomsch's orinico wifi.
|
||||
(orinoco: initialise priv->hw before assigning the interrupt)
|
||||
[229bd792] (#657864)
|
||||
|
||||
* Wed Dec 08 2010 Kyle McMartin <kyle@redhat.com> 2.6.37-0.rc5.git2.1
|
||||
- Linux 2.6.37-rc5-git2
|
||||
- sched-cure-more-NO_HZ-load-average-woes.patch: fix some of the complaints
|
||||
in 2.6.35+ about load average with dynticks. (rhbz#650934)
|
||||
|
||||
* Wed Dec 08 2010 Michael Young <m.a.young@durham.ac.uk>
|
||||
- Update the xen/next-2.6.37 patch and rebuild for rc5
|
||||
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
From 17f1e34b178ffc0111d768f48a86b58fd0c88c56 Mon Sep 17 00:00:00 2001
|
||||
From: David Kilroy <kilroyd@googlemail.com>
|
||||
Date: Tue, 7 Dec 2010 18:50:42 +0000
|
||||
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>
|
||||
---
|
||||
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 71b3d68..32954c4 100644
|
||||
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
|
||||
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
|
||||
@@ -151,20 +151,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;
|
||||
+
|
||||
ret = pcmcia_enable_device(link);
|
||||
if (ret)
|
||||
goto failed;
|
||||
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
|
||||
index fb859a5..db34c28 100644
|
||||
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
|
||||
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
|
||||
@@ -214,21 +214,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;
|
||||
+
|
||||
ret = pcmcia_enable_device(link);
|
||||
if (ret)
|
||||
goto failed;
|
||||
--
|
||||
1.7.3.3
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
commit 885c252ffb059dc493200bdb981bdd21cabe4442
|
||||
Author: Matthew Garrett <mjg@redhat.com>
|
||||
Date: Thu Dec 9 18:31:59 2010 -0500
|
||||
|
||||
PCI: _OSC "supported" field should contain supported features, not enabled ones
|
||||
|
||||
From testing with Windows, the call to the PCI root _OSC method includes
|
||||
the full set of features supported by the operating system even if the
|
||||
hardware has already indicated that it doesn't support ASPM or MSI.
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=638912 is a case where making
|
||||
the _OSC call will incorrectly configure the chipset unless the supported
|
||||
field has bits 1, 2 and 4 set. Rework the functionality to ensure that
|
||||
we match this behaviour.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg@redhat.com>
|
||||
|
||||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
|
||||
index 96668ad..afb5d08 100644
|
||||
--- a/drivers/acpi/pci_root.c
|
||||
+++ b/drivers/acpi/pci_root.c
|
||||
@@ -450,7 +450,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
struct acpi_pci_root *root;
|
||||
acpi_handle handle;
|
||||
struct acpi_device *child;
|
||||
- u32 flags, base_flags;
|
||||
+ u32 flags;
|
||||
|
||||
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
|
||||
if (!root)
|
||||
@@ -498,10 +498,15 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
device->driver_data = root;
|
||||
|
||||
/*
|
||||
- * All supported architectures that use ACPI have support for
|
||||
- * PCI domains, so we indicate this in _OSC support capabilities.
|
||||
+ * Indicate support for various _OSC capabilities. These match
|
||||
+ * what the operating system supports, not what the hardware supports,
|
||||
+ * so they shouldn't be conditional on functionality that's been
|
||||
+ * blacklisted
|
||||
*/
|
||||
- flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
|
||||
+ flags = OSC_EXT_PCI_CONFIG_SUPPORT | OSC_ACTIVE_STATE_PWR_SUPPORT |
|
||||
+ OSC_CLOCK_PWR_CAPABILITY_SUPPORT |
|
||||
+ OSC_PCI_SEGMENT_GROUPS_SUPPORT | OSC_MSI_SUPPORT;
|
||||
+
|
||||
acpi_pci_osc_support(root, flags);
|
||||
|
||||
/*
|
||||
@@ -555,17 +560,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
list_for_each_entry(child, &device->children, node)
|
||||
acpi_pci_bridge_scan(child);
|
||||
|
||||
- /* Indicate support for various _OSC capabilities. */
|
||||
- if (pci_ext_cfg_avail(root->bus->self))
|
||||
- flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
|
||||
- if (pcie_aspm_enabled())
|
||||
- flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
|
||||
- OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
|
||||
- if (pci_msi_enabled())
|
||||
- flags |= OSC_MSI_SUPPORT;
|
||||
- if (flags != base_flags)
|
||||
- acpi_pci_osc_support(root, flags);
|
||||
-
|
||||
pci_acpi_add_bus_pm_notifier(device, root->bus);
|
||||
if (device->wakeup.flags.run_wake)
|
||||
device_set_run_wake(root->bus->bridge, true);
|
|
@ -0,0 +1,144 @@
|
|||
From linux-kernel-owner@vger.kernel.org Mon Dec 6 14:01:17 2010
|
||||
From: Matthew Garrett <mjg@redhat.com>
|
||||
To: linux-pci@vger.kernel.org
|
||||
Cc: linux-kernel@vger.kernel.org, jbarnes@virtuousgeek.org,
|
||||
Matthew Garrett <mjg@redhat.com>
|
||||
Subject: [PATCH v2] PCI: Disable ASPM if BIOS asks us to
|
||||
Date: Mon, 6 Dec 2010 14:00:56 -0500
|
||||
Message-Id: <1291662056-6055-1-git-send-email-mjg@redhat.com>
|
||||
|
||||
We currently refuse to touch the ASPM registers if the BIOS tells us that
|
||||
ASPM isn't supported. This can cause problems if the BIOS has (for any
|
||||
reason) enabled ASPM on some devices anyway. Change the code such that we
|
||||
explicitly clear ASPM if the FADT indicates that ASPM isn't supported,
|
||||
and make sure we tidy up appropriately on device removal in order to deal
|
||||
with the hotplug case. If ASPM is disabled because the BIOS doesn't hand
|
||||
over control then we won't touch the registers.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg@redhat.com>
|
||||
---
|
||||
|
||||
Implement Rafael's suggestion to use two separate functions, and also
|
||||
ensure that we clear the clkpm bit as well as the ASPM bits.
|
||||
|
||||
drivers/pci/pci-acpi.c | 1 +
|
||||
drivers/pci/pcie/aspm.c | 21 +++++++++++++++++----
|
||||
include/linux/pci-aspm.h | 5 ++++-
|
||||
3 files changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
|
||||
index 24e19c5..d7ea699 100644
|
||||
--- a/drivers/pci/pci-acpi.c
|
||||
+++ b/drivers/pci/pci-acpi.c
|
||||
@@ -399,6 +399,7 @@ static int __init acpi_pci_init(void)
|
||||
|
||||
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
|
||||
printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
|
||||
+ pcie_clear_aspm();
|
||||
pcie_no_aspm();
|
||||
}
|
||||
|
||||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
|
||||
index 7122281..8112415 100644
|
||||
--- a/drivers/pci/pcie/aspm.c
|
||||
+++ b/drivers/pci/pcie/aspm.c
|
||||
@@ -68,7 +68,7 @@ struct pcie_link_state {
|
||||
struct aspm_latency acceptable[8];
|
||||
};
|
||||
|
||||
-static int aspm_disabled, aspm_force;
|
||||
+static int aspm_disabled, aspm_force, aspm_clear_state;
|
||||
static DEFINE_MUTEX(aspm_lock);
|
||||
static LIST_HEAD(link_list);
|
||||
|
||||
@@ -139,7 +139,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
|
||||
{
|
||||
/* Don't enable Clock PM if the link is not Clock PM capable */
|
||||
if (!link->clkpm_capable && enable)
|
||||
- return;
|
||||
+ enable = 0;
|
||||
/* Need nothing if the specified equals to current state */
|
||||
if (link->clkpm_enabled == enable)
|
||||
return;
|
||||
@@ -498,6 +498,10 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
|
||||
struct pci_dev *child;
|
||||
int pos;
|
||||
u32 reg32;
|
||||
+
|
||||
+ if (aspm_clear_state)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
/*
|
||||
* Some functions in a slot might not all be PCIe functions,
|
||||
* very strange. Disable ASPM for the whole slot
|
||||
@@ -563,12 +567,15 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
|
||||
struct pcie_link_state *link;
|
||||
int blacklist = !!pcie_aspm_sanity_check(pdev);
|
||||
|
||||
- if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state)
|
||||
+ if (!pci_is_pcie(pdev) || pdev->link_state)
|
||||
return;
|
||||
if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
|
||||
pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
|
||||
return;
|
||||
|
||||
+ if (aspm_disabled && !aspm_clear_state)
|
||||
+ return;
|
||||
+
|
||||
/* VIA has a strange chipset, root port is under a bridge */
|
||||
if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
|
||||
pdev->bus->self)
|
||||
@@ -641,7 +648,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
|
||||
struct pci_dev *parent = pdev->bus->self;
|
||||
struct pcie_link_state *link, *root, *parent_link;
|
||||
|
||||
- if (aspm_disabled || !pci_is_pcie(pdev) ||
|
||||
+ if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||
|
||||
!parent || !parent->link_state)
|
||||
return;
|
||||
if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
|
||||
@@ -899,6 +906,12 @@ static int __init pcie_aspm_disable(char *str)
|
||||
|
||||
__setup("pcie_aspm=", pcie_aspm_disable);
|
||||
|
||||
+void pcie_clear_aspm(void)
|
||||
+{
|
||||
+ if (!aspm_force)
|
||||
+ aspm_clear_state = 1;
|
||||
+}
|
||||
+
|
||||
void pcie_no_aspm(void)
|
||||
{
|
||||
if (!aspm_force)
|
||||
diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
|
||||
index 91ba0b3..ce68105 100644
|
||||
--- a/include/linux/pci-aspm.h
|
||||
+++ b/include/linux/pci-aspm.h
|
||||
@@ -27,6 +27,7 @@ extern void pcie_aspm_init_link_state(struct pci_dev *pdev);
|
||||
extern void pcie_aspm_exit_link_state(struct pci_dev *pdev);
|
||||
extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
|
||||
extern void pci_disable_link_state(struct pci_dev *pdev, int state);
|
||||
+extern void pcie_clear_aspm(void);
|
||||
extern void pcie_no_aspm(void);
|
||||
#else
|
||||
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
|
||||
@@ -41,7 +42,9 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev)
|
||||
static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
|
||||
{
|
||||
}
|
||||
-
|
||||
+static inline void pcie_clear_aspm(void)
|
||||
+{
|
||||
+}
|
||||
static inline void pcie_no_aspm(void)
|
||||
{
|
||||
}
|
||||
--
|
||||
1.7.3.2
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
Please read the FAQ at http://www.tux.org/lkml/
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
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