Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc

Pull main powerpc updates from Ben Herrenschmidt:
 "This time around, the powerpc merges are going to be a little bit more
  complicated than usual.

  This is the main pull request with most of the work for this merge
  window.  I will describe it a bit more further down.

  There is some additional cpuidle driver work, however I haven't
  included it in this tree as it depends on some work in tip/timer-core
  which Thomas accidentally forgot to put in a topic branch.  Since I
  didn't want to carry all of that tip timer stuff in powerpc -next, I
  setup a separate branch on top of Thomas tree with just that cpuidle
  driver in it, and Stephen has been carrying that in next separately
  for a while now.  I'll send a separate pull request for it.

  Additionally, two new pieces in this tree add users for a sysfs API
  that Tejun and Greg have been deprecating in drivers-core-next.
  Thankfully Greg reverted the patch that removes the old API so this
  merge can happen cleanly, but once merged, I will send a patch
  adjusting our new code to the new API so that Greg can send you the
  removal patch.

  Now as for the content of this branch, we have a lot of perf work for
  power8 new counters including support for our new "nest" counters
  (also called 24x7) under pHyp (not natively yet).

  We have new functionality when running under the OPAL firmware
  (non-virtualized or KVM host), such as access to the firmware error
  logs and service processor dumps, system parameters and sensors, along
  with a hwmon driver for the latter.

  There's also a bunch of bug fixes accross the board, some LE fixes,
  and a nice set of selftests for validating our various types of copy
  loops.

  On the Freescale side, we see mostly new chip/board revisions, some
  clock updates, better support for machine checks and debug exceptions,
  etc..."

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (70 commits)
  powerpc/book3s: Fix CFAR clobbering issue in machine check handler.
  powerpc/compat: 32-bit little endian machine name is ppcle, not ppc
  powerpc/le: Big endian arguments for ppc_rtas()
  powerpc: Use default set of netfilter modules (CONFIG_NETFILTER_ADVANCED=n)
  powerpc/defconfigs: Enable THP in pseries defconfig
  powerpc/mm: Make sure a local_irq_disable prevent a parallel THP split
  powerpc: Rate-limit users spamming kernel log buffer
  powerpc/perf: Fix handling of L3 events with bank == 1
  powerpc/perf/hv_{gpci, 24x7}: Add documentation of device attributes
  powerpc/perf: Add kconfig option for hypervisor provided counters
  powerpc/perf: Add support for the hv 24x7 interface
  powerpc/perf: Add support for the hv gpci (get performance counter info) interface
  powerpc/perf: Add macros for defining event fields & formats
  powerpc/perf: Add a shared interface to get gpci version and capabilities
  powerpc/perf: Add 24x7 interface headers
  powerpc/perf: Add hv_gpci interface header
  powerpc: Add hvcalls for 24x7 and gpci (Get Performance Counter Info)
  sysfs: create bin_attributes under the requested group
  powerpc/perf: Enable BHRB access for EBB events
  powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB
  ...
This commit is contained in:
Linus Torvalds
2014-04-02 13:42:59 -07:00
185 ha cambiato i file con 5964 aggiunte e 938 eliminazioni

Vedi File

@@ -111,6 +111,18 @@ config CMM
will be reused for other LPARs. The interface allows firmware to
balance memory across many LPARs.
config HV_PERF_CTRS
bool "Hypervisor supplied PMU events (24x7 & GPCI)"
default y
depends on PERF_EVENTS && PPC_PSERIES
help
Enable access to hypervisor supplied counters in perf. Currently,
this enables code that uses the hcall GetPerfCounterInfo and 24x7
interfaces to retrieve counters. GPCI exists on Power 6 and later
systems. 24x7 is available on Power 8 systems.
If unsure, select Y.
config DTL
bool "Dispatch Trace Log"
depends on PPC_SPLPAR && DEBUG_FS

Vedi File

@@ -420,4 +420,4 @@ static int __init pseries_cpu_hotplug_init(void)
return 0;
}
arch_initcall(pseries_cpu_hotplug_init);
machine_arch_initcall(pseries, pseries_cpu_hotplug_init);

Vedi File

@@ -14,6 +14,7 @@
#include <linux/memblock.h>
#include <linux/vmalloc.h>
#include <linux/memory.h>
#include <linux/memory_hotplug.h>
#include <asm/firmware.h>
#include <asm/machdep.h>
@@ -75,50 +76,13 @@ unsigned long memory_block_size_bytes(void)
}
#ifdef CONFIG_MEMORY_HOTREMOVE
static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
static int pseries_remove_memory(u64 start, u64 size)
{
unsigned long start, start_pfn;
struct zone *zone;
int ret;
unsigned long section;
unsigned long sections_to_remove;
start_pfn = base >> PAGE_SHIFT;
if (!pfn_valid(start_pfn)) {
memblock_remove(base, memblock_size);
return 0;
}
zone = page_zone(pfn_to_page(start_pfn));
/*
* Remove section mappings and sysfs entries for the
* section of the memory we are removing.
*
* NOTE: Ideally, this should be done in generic code like
* remove_memory(). But remove_memory() gets called by writing
* to sysfs "state" file and we can't remove sysfs entries
* while writing to it. So we have to defer it to here.
*/
sections_to_remove = (memblock_size >> PAGE_SHIFT) / PAGES_PER_SECTION;
for (section = 0; section < sections_to_remove; section++) {
unsigned long pfn = start_pfn + section * PAGES_PER_SECTION;
ret = __remove_pages(zone, pfn, PAGES_PER_SECTION);
if (ret)
return ret;
}
/*
* Update memory regions for memory remove
*/
memblock_remove(base, memblock_size);
/*
* Remove htab bolted mappings for this section of memory
*/
start = (unsigned long)__va(base);
ret = remove_section_mapping(start, start + memblock_size);
/* Remove htab bolted mappings for this section of memory */
start = (unsigned long)__va(start);
ret = remove_section_mapping(start, start + size);
/* Ensure all vmalloc mappings are flushed in case they also
* hit that section of memory
@@ -128,7 +92,34 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz
return ret;
}
static int pseries_remove_memory(struct device_node *np)
static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
{
unsigned long block_sz, start_pfn;
int sections_per_block;
int i, nid;
start_pfn = base >> PAGE_SHIFT;
if (!pfn_valid(start_pfn)) {
memblock_remove(base, memblock_size);
return 0;
}
block_sz = memory_block_size_bytes();
sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
nid = memory_add_physaddr_to_nid(base);
for (i = 0; i < sections_per_block; i++) {
remove_memory(nid, base, MIN_MEMORY_BLOCK_SIZE);
base += MIN_MEMORY_BLOCK_SIZE;
}
/* Update memory regions for memory remove */
memblock_remove(base, memblock_size);
return 0;
}
static int pseries_remove_mem_node(struct device_node *np)
{
const char *type;
const unsigned int *regs;
@@ -153,8 +144,8 @@ static int pseries_remove_memory(struct device_node *np)
base = *(unsigned long *)regs;
lmb_size = regs[3];
ret = pseries_remove_memblock(base, lmb_size);
return ret;
pseries_remove_memblock(base, lmb_size);
return 0;
}
#else
static inline int pseries_remove_memblock(unsigned long base,
@@ -162,13 +153,13 @@ static inline int pseries_remove_memblock(unsigned long base,
{
return -EOPNOTSUPP;
}
static inline int pseries_remove_memory(struct device_node *np)
static inline int pseries_remove_mem_node(struct device_node *np)
{
return -EOPNOTSUPP;
}
#endif /* CONFIG_MEMORY_HOTREMOVE */
static int pseries_add_memory(struct device_node *np)
static int pseries_add_mem_node(struct device_node *np)
{
const char *type;
const unsigned int *regs;
@@ -254,10 +245,10 @@ static int pseries_memory_notifier(struct notifier_block *nb,
switch (action) {
case OF_RECONFIG_ATTACH_NODE:
err = pseries_add_memory(node);
err = pseries_add_mem_node(node);
break;
case OF_RECONFIG_DETACH_NODE:
err = pseries_remove_memory(node);
err = pseries_remove_mem_node(node);
break;
case OF_RECONFIG_UPDATE_PROPERTY:
pr = (struct of_prop_reconfig *)node;
@@ -277,6 +268,10 @@ static int __init pseries_memory_hotplug_init(void)
if (firmware_has_feature(FW_FEATURE_LPAR))
of_reconfig_notifier_register(&pseries_mem_nb);
#ifdef CONFIG_MEMORY_HOTREMOVE
ppc_md.remove_memory = pseries_remove_memory;
#endif
return 0;
}
machine_device_initcall(pseries, pseries_memory_hotplug_init);

Vedi File

@@ -290,13 +290,6 @@ void post_mobility_fixup(void)
int rc;
int activate_fw_token;
rc = pseries_devicetree_update(MIGRATION_SCOPE);
if (rc) {
printk(KERN_ERR "Initial post-mobility device tree update "
"failed: %d\n", rc);
return;
}
activate_fw_token = rtas_token("ibm,activate-firmware");
if (activate_fw_token == RTAS_UNKNOWN_SERVICE) {
printk(KERN_ERR "Could not make post-mobility "
@@ -304,16 +297,17 @@ void post_mobility_fixup(void)
return;
}
rc = rtas_call(activate_fw_token, 0, 1, NULL);
if (!rc) {
rc = pseries_devicetree_update(MIGRATION_SCOPE);
if (rc)
printk(KERN_ERR "Secondary post-mobility device tree "
"update failed: %d\n", rc);
} else {
do {
rc = rtas_call(activate_fw_token, 0, 1, NULL);
} while (rtas_busy_delay(rc));
if (rc)
printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc);
return;
}
rc = pseries_devicetree_update(MIGRATION_SCOPE);
if (rc)
printk(KERN_ERR "Post-mobility device tree update "
"failed: %d\n", rc);
return;
}

Vedi File

@@ -26,6 +26,7 @@
#include <asm/mmu.h>
#include <asm/rtas.h>
#include <asm/topology.h>
#include "../../kernel/cacheinfo.h"
static u64 stream_id;
static struct device suspend_dev;
@@ -78,6 +79,23 @@ static int pseries_suspend_cpu(void)
return 0;
}
/**
* pseries_suspend_enable_irqs
*
* Post suspend configuration updates
*
**/
static void pseries_suspend_enable_irqs(void)
{
/*
* Update configuration which can be modified based on device tree
* changes during resume.
*/
cacheinfo_cpu_offline(smp_processor_id());
post_mobility_fixup();
cacheinfo_cpu_online(smp_processor_id());
}
/**
* pseries_suspend_enter - Final phase of hibernation
*
@@ -174,7 +192,30 @@ out:
return rc;
}
static DEVICE_ATTR(hibernate, S_IWUSR, NULL, store_hibernate);
#define USER_DT_UPDATE 0
#define KERN_DT_UPDATE 1
/**
* show_hibernate - Report device tree update responsibilty
* @dev: subsys root device
* @attr: device attribute struct
* @buf: buffer
*
* Report whether a device tree update is performed by the kernel after a
* resume, or if drmgr must coordinate the update from user space.
*
* Return value:
* 0 if drmgr is to initiate update, and 1 otherwise
**/
static ssize_t show_hibernate(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%d\n", KERN_DT_UPDATE);
}
static DEVICE_ATTR(hibernate, S_IWUSR | S_IRUGO,
show_hibernate, store_hibernate);
static struct bus_type suspend_subsys = {
.name = "power",
@@ -235,6 +276,7 @@ static int __init pseries_suspend_init(void)
return rc;
ppc_md.suspend_disable_cpu = pseries_suspend_cpu;
ppc_md.suspend_enable_irqs = pseries_suspend_enable_irqs;
suspend_set_ops(&pseries_suspend_ops);
return 0;
}