* Re: [1/5] pseries: Define rtas hotplug event sections
From: Michael Ellerman @ 2014-09-17 7:06 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <54174C20.1000009@linux.vnet.ibm.com>
On Mon, 2014-09-15 at 15:29 -0500, Nathan Fontenot wrote:
> diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
> index b390f55..a01879e 100644
> --- a/arch/powerpc/include/asm/rtas.h
> +++ b/arch/powerpc/include/asm/rtas.h
> @@ -273,6 +273,7 @@ inline uint32_t rtas_ext_event_company_id(struct rtas_ext_event_log_v6 *ext_log)
> #define PSERIES_ELOG_SECT_ID_MANUFACT_INFO (('M' << 8) | 'I')
> #define PSERIES_ELOG_SECT_ID_CALL_HOME (('C' << 8) | 'H')
> #define PSERIES_ELOG_SECT_ID_USER_DEF (('U' << 8) | 'D')
> +#define PSERIES_ELOG_SECT_ID_HOTPLUG (('H' << 8) | 'P')
>
> /* Vendor specific Platform Event Log Format, Version 6, section header */
> struct pseries_errorlog {
> @@ -296,6 +297,31 @@ inline uint16_t pseries_errorlog_length(struct pseries_errorlog *sect)
> return be16_to_cpu(sect->length);
> }
>
> +/* RTAS pseries hotplug errorlog section */
> +struct pseries_hp_errorlog {
> + uint8_t resource;
> + uint8_t action;
> + uint8_t id_type;
> + uint8_t reserved;
These should be u8.
> + union {
> + __be32 drc_index;
> + __be32 drc_count;
> + char drc_name[1];
I don't see drc_name used?
> + } _drc_u;
> +};
cheers
^ permalink raw reply
* Re: [2/5] pseries: Export drc_[acquire|release]_drc() routines
From: Michael Ellerman @ 2014-09-17 7:07 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <54174C5F.4090604@linux.vnet.ibm.com>
On Mon, 2014-09-15 at 15:30 -0500, Nathan Fontenot wrote:
> diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
> index 361add6..b94516b 100644
> --- a/arch/powerpc/platforms/pseries/pseries.h
> +++ b/arch/powerpc/platforms/pseries/pseries.h
> @@ -59,6 +59,8 @@ extern void dlpar_free_cc_property(struct property *);
> extern struct device_node *dlpar_configure_connector(u32, struct device_node *);
> extern int dlpar_attach_node(struct device_node *);
> extern int dlpar_detach_node(struct device_node *);
> +extern int dlpar_acquire_drc(u32);
> +extern int dlpar_release_drc(u32);
Please name the parameters.
And don't bother with extern.
cheers
^ permalink raw reply
* [PATCH 1/3] powerpc: Remove -mno-sched-epilog workaround
From: Anton Blanchard @ 2014-09-17 7:07 UTC (permalink / raw)
To: benh, paulus, mpe, rostedt; +Cc: linuxppc-dev
We added -mno-sched-epilog in commit 7563dc645853 (powerpc:
Work around gcc's -fno-omit-frame-pointer bug).
We shouldn't apply -fno-omit-frame-pointer on powerpc any more (it's
protected by CONFIG_FRAME_POINTER and CONFIG_SCHED_OMIT_FRAME_POINTER).
It's also an undocumented gcc option, so lets remove it.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/Makefile | 5 -----
arch/powerpc/kernel/Makefile | 12 ++++++------
arch/powerpc/platforms/powermac/Makefile | 2 +-
3 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 132d9c6..c6f64e2 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -198,11 +198,6 @@ ifeq ($(CONFIG_6xx),y)
KBUILD_CFLAGS += -mcpu=powerpc
endif
-# Work around a gcc code-gen bug with -fno-omit-frame-pointer.
-ifeq ($(CONFIG_FUNCTION_TRACER),y)
-KBUILD_CFLAGS += -mno-sched-epilog
-endif
-
cpu-as-$(CONFIG_4xx) += -Wa,-m405
cpu-as-$(CONFIG_ALTIVEC) += -Wa,-maltivec
cpu-as-$(CONFIG_E200) += -Wa,-me200
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 502cf69..e14bda6 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -17,14 +17,14 @@ endif
ifdef CONFIG_FUNCTION_TRACER
# Do not trace early boot code
-CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog
-CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog
-CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog
-CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_cputable.o = -pg
+CFLAGS_REMOVE_prom_init.o = -pg
+CFLAGS_REMOVE_btext.o = -pg
+CFLAGS_REMOVE_prom.o = -pg
# do not trace tracer code
-CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_ftrace.o = -pg
# timers used by tracing
-CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_time.o = -pg
endif
obj-y := cputable.o ptrace.o syscalls.o \
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index 52c6ce1..e238872 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -2,7 +2,7 @@ CFLAGS_bootx_init.o += -fPIC
ifdef CONFIG_FUNCTION_TRACER
# Do not trace early boot code
-CFLAGS_REMOVE_bootx_init.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_bootx_init.o = -pg
endif
obj-y += pic.o setup.o time.o feature.o pci.o \
--
1.9.1
^ permalink raw reply related
* [PATCH 2/3] powerpc/ftrace: Remove mod_return_to_handler
From: Anton Blanchard @ 2014-09-17 7:07 UTC (permalink / raw)
To: benh, paulus, mpe, rostedt; +Cc: linuxppc-dev
In-Reply-To: <1410937624-25140-1-git-send-email-anton@samba.org>
mod_return_to_handler is the same as return_to_handler, except
it handles the change of the TOC (r2). Add this into
return_to_handler and remove mod_return_to_handler.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/entry_64.S | 24 +-----------------------
arch/powerpc/kernel/ftrace.c | 14 ++------------
arch/powerpc/kernel/process.c | 9 +--------
3 files changed, 4 insertions(+), 43 deletions(-)
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 5bbd1bc..955d509 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -1235,28 +1235,6 @@ _GLOBAL(ftrace_graph_caller)
_GLOBAL(return_to_handler)
/* need to save return values */
- std r4, -24(r1)
- std r3, -16(r1)
- std r31, -8(r1)
- mr r31, r1
- stdu r1, -112(r1)
-
- bl ftrace_return_to_handler
- nop
-
- /* return value has real return address */
- mtlr r3
-
- ld r1, 0(r1)
- ld r4, -24(r1)
- ld r3, -16(r1)
- ld r31, -8(r1)
-
- /* Jump back to real return address */
- blr
-
-_GLOBAL(mod_return_to_handler)
- /* need to save return values */
std r4, -32(r1)
std r3, -24(r1)
/* save TOC */
@@ -1266,7 +1244,7 @@ _GLOBAL(mod_return_to_handler)
stdu r1, -112(r1)
/*
- * We are in a module using the module's TOC.
+ * We might be called from a module.
* Switch to our TOC to run inside the core kernel.
*/
ld r2, PACATOC(r13)
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 390311c..abf7921 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -510,10 +510,6 @@ int ftrace_disable_ftrace_graph_caller(void)
}
#endif /* CONFIG_DYNAMIC_FTRACE */
-#ifdef CONFIG_PPC64
-extern void mod_return_to_handler(void);
-#endif
-
/*
* Hook the return address and push it in the stack of return addrs
* in current thread info.
@@ -523,7 +519,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
unsigned long old;
int faulted;
struct ftrace_graph_ent trace;
- unsigned long return_hooker = (unsigned long)&return_to_handler;
+ unsigned long return_hooker;
if (unlikely(ftrace_graph_is_dead()))
return;
@@ -531,13 +527,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
if (unlikely(atomic_read(¤t->tracing_graph_pause)))
return;
-#ifdef CONFIG_PPC64
- /* non core kernel code needs to save and restore the TOC */
- if (REGION_ID(self_addr) != KERNEL_REGION_ID)
- return_hooker = (unsigned long)&mod_return_to_handler;
-#endif
-
- return_hooker = ppc_function_entry((void *)return_hooker);
+ return_hooker = ppc_function_entry(return_to_handler);
/*
* Protect against fault, even if it shouldn't
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index aa1df89..080c0b9 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1531,13 +1531,6 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
int curr_frame = current->curr_ret_stack;
extern void return_to_handler(void);
unsigned long rth = (unsigned long)return_to_handler;
- unsigned long mrth = -1;
-#ifdef CONFIG_PPC64
- extern void mod_return_to_handler(void);
- rth = *(unsigned long *)rth;
- mrth = (unsigned long)mod_return_to_handler;
- mrth = *(unsigned long *)mrth;
-#endif
#endif
sp = (unsigned long) stack;
@@ -1562,7 +1555,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
if (!firstframe || ip != lr) {
printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- if ((ip == rth || ip == mrth) && curr_frame >= 0) {
+ if ((ip == rth) && curr_frame >= 0) {
printk(" (%pS)",
(void *)current->ret_stack[curr_frame].ret);
curr_frame--;
--
1.9.1
^ permalink raw reply related
* [PATCH 3/3] powerpc/ftrace: simplify prepare_ftrace_return
From: Anton Blanchard @ 2014-09-17 7:07 UTC (permalink / raw)
To: benh, paulus, mpe, rostedt; +Cc: linuxppc-dev
In-Reply-To: <1410937624-25140-1-git-send-email-anton@samba.org>
Instead of passing in the stack address of the link register
to be modified, just pass in the old value and return the
new value and rely on ftrace_graph_caller to do the
modification.
This removes the exception handling around the stack update -
it isn't needed and we weren't consistent about it. Later on
we would do an unprotected modification:
if (!ftrace_graph_entry(&trace)) {
*parent = old;
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/entry_32.S | 10 +++++--
arch/powerpc/kernel/entry_64.S | 11 ++++++--
arch/powerpc/kernel/ftrace.c | 59 ++++++++++--------------------------------
3 files changed, 30 insertions(+), 50 deletions(-)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 22b45a4..ad837d8 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -1424,12 +1424,18 @@ _GLOBAL(ftrace_graph_caller)
lwz r4, 44(r1)
subi r4, r4, MCOUNT_INSN_SIZE
- /* get the parent address */
- addi r3, r1, 52
+ /* Grab the LR out of the caller stack frame */
+ lwz r3,52(r1)
bl prepare_ftrace_return
nop
+ /*
+ * prepare_ftrace_return gives us the address we divert to.
+ * Change the LR in the callers stack frame to this.
+ */
+ stw r3,52(r1)
+
MCOUNT_RESTORE_FRAME
/* old link register ends up in ctr reg */
bctr
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 955d509..9caab69 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -1221,13 +1221,20 @@ _GLOBAL(ftrace_graph_caller)
ld r4, 128(r1)
subi r4, r4, MCOUNT_INSN_SIZE
- /* get the parent address */
+ /* Grab the LR out of the caller stack frame */
ld r11, 112(r1)
- addi r3, r11, 16
+ ld r3, 16(r11)
bl prepare_ftrace_return
nop
+ /*
+ * prepare_ftrace_return gives us the address we divert to.
+ * Change the LR in the callers stack frame to this.
+ */
+ ld r11, 112(r1)
+ std r3, 16(r11)
+
ld r0, 128(r1)
mtlr r0
addi r1, r1, 112
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index abf7921..d795031 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -512,67 +512,34 @@ int ftrace_disable_ftrace_graph_caller(void)
/*
* Hook the return address and push it in the stack of return addrs
- * in current thread info.
+ * in current thread info. Return the address we want to divert to.
*/
-void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)
{
- unsigned long old;
- int faulted;
struct ftrace_graph_ent trace;
unsigned long return_hooker;
if (unlikely(ftrace_graph_is_dead()))
- return;
+ goto out;
if (unlikely(atomic_read(¤t->tracing_graph_pause)))
- return;
+ goto out;
return_hooker = ppc_function_entry(return_to_handler);
- /*
- * Protect against fault, even if it shouldn't
- * happen. This tool is too much intrusive to
- * ignore such a protection.
- */
- asm volatile(
- "1: " PPC_LL "%[old], 0(%[parent])\n"
- "2: " PPC_STL "%[return_hooker], 0(%[parent])\n"
- " li %[faulted], 0\n"
- "3:\n"
-
- ".section .fixup, \"ax\"\n"
- "4: li %[faulted], 1\n"
- " b 3b\n"
- ".previous\n"
-
- ".section __ex_table,\"a\"\n"
- PPC_LONG_ALIGN "\n"
- PPC_LONG "1b,4b\n"
- PPC_LONG "2b,4b\n"
- ".previous"
-
- : [old] "=&r" (old), [faulted] "=r" (faulted)
- : [parent] "r" (parent), [return_hooker] "r" (return_hooker)
- : "memory"
- );
-
- if (unlikely(faulted)) {
- ftrace_graph_stop();
- WARN_ON(1);
- return;
- }
-
- trace.func = self_addr;
+ trace.func = ip;
trace.depth = current->curr_ret_stack + 1;
/* Only trace if the calling function expects to */
- if (!ftrace_graph_entry(&trace)) {
- *parent = old;
- return;
- }
+ if (!ftrace_graph_entry(&trace))
+ goto out;
+
+ if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY)
+ goto out;
- if (ftrace_push_return_trace(old, self_addr, &trace.depth, 0) == -EBUSY)
- *parent = old;
+ parent = return_hooker;
+out:
+ return parent;
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
--
1.9.1
^ permalink raw reply related
* Re: [3/5] pseries: Create device hotplug entry point
From: Michael Ellerman @ 2014-09-17 7:07 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <54174CB7.2080704@linux.vnet.ibm.com>
On Mon, 2014-09-15 at 15:31 -0500, Nathan Fontenot wrote:
> For pseries system the kernel will be notified of hotplug requests in
> the form of rtas hotplug events.
Can you flesh that design out a bit for me, I don't entirely get how it's going
to work.
The kernel gets the rtas hotplug events (in rtasd.c) and spits them out to
userspace, which then writes them back in ?
> This patch creates a common routine that can handle these requests in both
> the PowerVM anbd PowerKVM environments, handle_dlpar_errorlog(). This also
^
> creates the initial memory hotplug request handling stub.
>
> For PowerVM this patch also creates a new /proc file that the drmgr
> command will use to write rtas hotplug events to.
Why is this different between phyp and KVM?
> For future PowerKVM handling the rtas check-exception code can pass
> any rtas hotplug events received to handle_dlpar_errorlog().
Internally to the kernel you mean?
> diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
> index a2450b8..574ec73 100644
> --- a/arch/powerpc/platforms/pseries/dlpar.c
> +++ b/arch/powerpc/platforms/pseries/dlpar.c
> @@ -16,7 +16,9 @@
> #include <linux/cpu.h>
> #include <linux/slab.h>
> #include <linux/of.h>
> +#include <linux/proc_fs.h>
> #include "offline_states.h"
> +#include "pseries.h"
>
> #include <asm/prom.h>
> #include <asm/machdep.h>
> @@ -530,13 +532,72 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
> return count;
> }
>
> +#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
That is really confusing, but I think it's just a diff artifact?
> +static int handle_dlpar_errorlog(struct rtas_error_log *error_log)
> +{
> + struct pseries_errorlog *pseries_log;
> + struct pseries_hp_errorlog *hp_elog;
> + int rc = -EINVAL;
> +
> + pseries_log = get_pseries_errorlog(error_log,
> + PSERIES_ELOG_SECT_ID_HOTPLUG);
> + if (!pseries_log)
> + return rc;
> +
> + hp_elog = (struct pseries_hp_errorlog *)pseries_log->data;
> + if (!hp_elog)
> + return rc;
I don't see how that can happen?
struct pseries_errorlog {
__be16 id; /* 0x00 2-byte ASCII section ID */
__be16 length; /* 0x02 Section length in bytes */
uint8_t version; /* 0x04 Section version */
uint8_t subtype; /* 0x05 Section subtype */
__be16 creator_component; /* 0x06 Creator component ID */
uint8_t data[]; /* 0x08 Start of section data */
};
Should you be checking for length == 0 instead ?
Also I think the code will probably end up cleaner if you do the endian
conversions immediately when you read the hp_elog, rather than passing it
around in BE and having to remember to convert at all the usages.
> + switch (hp_elog->resource) {
> + case PSERIES_HP_ELOG_RESOURCE_MEM:
> + rc = dlpar_memory(hp_elog);
> + break;
Please add:
default:
pr_warn_ratelimited("Unknown resource ..")
Or something.
> + }
> +
> + return rc;
> +}
> +
> +static ssize_t dlpar_write(struct file *file, const char __user *buf,
> + size_t count, loff_t *offset)
> +{
> + char *event_buf;
> + int rc;
> +
> + event_buf = kmalloc(count + 1, GFP_KERNEL);
Why + 1 ? It's not null-terminated AFAICS.
> + if (!event_buf)
> + return -ENOMEM;
> +
> + rc = copy_from_user(event_buf, buf, count);
> + if (rc) {
> + kfree(event_buf);
> + return rc;
> + }
> +
> + rc = handle_dlpar_errorlog((struct rtas_error_log *)event_buf);
If you start with a struct rtas_error_log * you shouldn't need any casts.
> + kfree(event_buf);
> + return rc ? rc : count;
> +}
> +
> +static const struct file_operations dlpar_fops = {
> + .write = dlpar_write,
> + .llseek = noop_llseek,
> +};
> +
> static int __init pseries_dlpar_init(void)
> {
> + struct proc_dir_entry *proc_ent;
> +
> + proc_ent = proc_create("powerpc/dlpar", S_IWUSR, NULL, &dlpar_fops);
> + if (proc_ent)
> + proc_set_size(proc_ent, 0);
else
error message at least please
Why are we putting it in /proc, can't it go in /sys/kernel like the mobility
stuff?
> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
> index 24abc5c..0e60e15 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
> @@ -20,6 +22,9 @@
> #include <asm/machdep.h>
> #include <asm/prom.h>
> #include <asm/sparsemem.h>
> +#include <asm/rtas.h>
> +
> +DEFINE_MUTEX(dlpar_mem_mutex);
static ?
> diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
> index b94516b..28bd994 100644
> --- a/arch/powerpc/platforms/pseries/pseries.h
> +++ b/arch/powerpc/platforms/pseries/pseries.h
> @@ -62,6 +63,15 @@ extern int dlpar_detach_node(struct device_node *);
> extern int dlpar_acquire_drc(u32);
> extern int dlpar_release_drc(u32);
>
> +#ifdef CONFIG_MEMORY_HOTPLUG
> +extern int dlpar_memory(struct pseries_hp_errorlog *);
> +#else
> +static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
> +{
> + return -ENOTSUPP;
EOPNOTSUPP is a bit more standard.
cheers
^ permalink raw reply
* Re: [4/5] pseries: Implement memory hotplug add in the kernel
From: Michael Ellerman @ 2014-09-17 7:07 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <54174CF3.1010802@linux.vnet.ibm.com>
On Mon, 2014-09-15 at 15:32 -0500, Nathan Fontenot wrote:
> This patch adds the ability to do memory hotplug adding in the kernel.
>
> Currently the hotplug add/remove of memory is handled by the drmgr
> command. The drmgr command performs the add/remove by performing
> some work in user-space and making requests to the kernel to handle
> other pieces. By moving all of the work to the kernel we can do the
> add and remove faster, and provide a common place to do memory hotplug
> for both the PowerVM and PowerKVM environments.
>
> Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/hotplug-memory.c | 170 +++++++++++++++++++++++
> 1 file changed, 170 insertions(+)
>
> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
> index 0e60e15..b254773 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
> @@ -17,6 +17,7 @@
> #include <linux/vmalloc.h>
> #include <linux/memory.h>
> #include <linux/memory_hotplug.h>
> +#include <linux/slab.h>
>
> #include <asm/firmware.h>
> #include <asm/machdep.h>
> @@ -24,6 +25,8 @@
> #include <asm/sparsemem.h>
> #include <asm/rtas.h>
>
> +#include "pseries.h"
> +
> DEFINE_MUTEX(dlpar_mem_mutex);
>
> unsigned long pseries_memory_block_size(void)
> @@ -69,6 +72,53 @@ unsigned long pseries_memory_block_size(void)
> return memblock_size;
> }
>
> +static void dlpar_free_drconf_property(struct property *prop)
> +{
> + kfree(prop->name);
> + kfree(prop->value);
> + kfree(prop);
> +}
> +
> +static struct property *dlpar_clone_drconf_property(struct device_node *dn)
> +{
> + struct property *prop, *new_prop;
> +
> + prop = of_find_property(dn, "ibm,dynamic-memory", NULL);
> + if (!prop)
> + return NULL;
> +
> + new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
> + if (!new_prop)
> + return NULL;
> +
> + new_prop->name = kstrdup(prop->name, GFP_KERNEL);
> + new_prop->value = kmalloc(prop->length + 1, GFP_KERNEL);
> + if (!new_prop->name || !new_prop->value) {
> + dlpar_free_drconf_property(new_prop);
> + return NULL;
> + }
> +
> + memcpy(new_prop->value, prop->value, prop->length);
> + new_prop->length = prop->length;
> + *(((char *)new_prop->value) + new_prop->length) = 0;
It's not a string, is it?
> + return new_prop;
> +}
> +
> +static struct memory_block *lmb_to_memblock(struct of_drconf_cell *lmb)
> +{
> + unsigned long section_nr;
> + struct mem_section *mem_sect;
> + struct memory_block *mem_block;
> + u64 phys_addr = be64_to_cpu(lmb->base_addr);
> +
> + section_nr = pfn_to_section_nr(PFN_DOWN(phys_addr));
> + mem_sect = __nr_to_section(section_nr);
> +
> + mem_block = find_memory_block(mem_sect);
> + return mem_block;
> +}
> +
> #ifdef CONFIG_MEMORY_HOTREMOVE
> static int pseries_remove_memory(u64 start, u64 size)
> {
> @@ -155,13 +205,133 @@ static inline int pseries_remove_mem_node(struct device_node *np)
> }
> #endif /* CONFIG_MEMORY_HOTREMOVE */
>
> +static int dlpar_add_one_lmb(struct of_drconf_cell *lmb)
> +{
> + struct memory_block *mem_block;
> + u64 phys_addr;
> + unsigned long pages_per_block;
> + unsigned long block_sz;
> + int nid, sections_per_block;
> + int rc;
> +
> + phys_addr = be64_to_cpu(lmb->base_addr);
of_drconf_cell needs endian annotations.
> + block_sz = memory_block_size_bytes();
> + sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
> + pages_per_block = PAGES_PER_SECTION * sections_per_block;
> +
> + if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
> + return -EINVAL;
> +
> + nid = memory_add_physaddr_to_nid(phys_addr);
> + rc = add_memory(nid, phys_addr, block_sz);
> + if (rc)
> + return rc;
> +
> + rc = memblock_add(phys_addr, block_sz);
> + if (rc) {
> + remove_memory(nid, phys_addr, block_sz);
> + return rc;
> + }
> +
> + mem_block = lmb_to_memblock(lmb);
> + if (!mem_block) {
> + remove_memory(nid, phys_addr, block_sz);
> + return -EINVAL;
> + }
That could all use a lot of comments. ie. why do we have to add it twice?
> + rc = device_online(&mem_block->dev);
> + put_device(&mem_block->dev);
> + if (rc)
> + remove_memory(nid, phys_addr, block_sz);
> +
> + return rc;
> +}
> +
> +static int dlpar_memory_add(struct pseries_hp_errorlog *hp_elog)
> +{
> + struct of_drconf_cell *lmb;
> + struct device_node *dn;
> + struct property *prop;
> + uint32_t entries, *p;
*p should be __be32.
> + int i, lmbs_to_add;
> + int lmbs_added = 0;
> + int rc = -EINVAL;
Don't pre-initialise your rc variables.
> + if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT) {
> + lmbs_to_add = be32_to_cpu(hp_elog->_drc_u.drc_count);
> + pr_info("Attempting to hot-add %d LMB(s)\n", lmbs_to_add);
> + } else {
> + lmbs_to_add = 1;
> + pr_info("Attempting to hot-add LMB, drc index %x\n",
> + be32_to_cpu(hp_elog->_drc_u.drc_index));
> + }
> +
> + dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
> + if (!dn)
> + return -EINVAL;
> +
> + prop = dlpar_clone_drconf_property(dn);
> + if (!prop) {
> + of_node_put(dn);
> + return -EINVAL;
> + }
> +
> + p = prop->value;
> + entries = be32_to_cpu(*p++);
> + lmb = (struct of_drconf_cell *)p;
So if I'm reading this right the hp_elog either contains an index or a count of
LMBs to add. But it doesn't contain anything about which address ranges to add
or any of those details. That is all in the ibm,dynamic-memory property - but
how did it get in there?
> +
> + for (i = 0; i < entries; i++, lmb++) {
> + u32 drc_index = be32_to_cpu(lmb->drc_index);
> +
> + if (lmbs_to_add == lmbs_added)
> + break;
> +
> + if (be32_to_cpu(lmb->flags) & DRCONF_MEM_ASSIGNED)
> + continue;
> +
> + if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX
> + && lmb->drc_index != hp_elog->_drc_u.drc_index)
> + continue;
> +
> + rc = dlpar_acquire_drc(drc_index);
> + if (rc)
> + continue;
> +
> + rc = dlpar_add_one_lmb(lmb);
> + if (rc) {
> + dlpar_release_drc(drc_index);
> + continue;
> + }
In both the above error cases you just move along. That means we potentially
hotplugged some memory but not everything that we were asked to. That seems
like a bad idea, we should either do everything or nothing.
> +
> + lmb->flags |= cpu_to_be32(DRCONF_MEM_ASSIGNED);
> + lmbs_added++;
> + pr_info("Memory at %llx (drc index %x) has been hot-added\n",
> + be64_to_cpu(lmb->base_addr), drc_index);
> + }
> +
> + if (lmbs_added)
> + rc = of_update_property(dn, prop);
> + else
> + dlpar_free_drconf_property(prop);
The value of rc here is not clear. It could be EINVAL or it could be the result
of the last dlpar_add_one_lmb(lmb). gcc would have told you that if you hadn't
initialised it.
> +
> + of_node_put(dn);
> + return rc ? rc : lmbs_added;
This looks wrong.
Doesn't the rc eventually go back to dlpar_write(), which expects 0 for success?
That should show up as the write failing in userspace.
> int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
> {
> int rc = 0;
Don't initialise to zero, that way gcc can tell you if there's a path where you
forget to initialise it. It also means you can't accidentally return success.
> + if (hp_elog->id_type != PSERIES_HP_ELOG_ID_DRC_COUNT
> + && hp_elog->id_type != PSERIES_HP_ELOG_ID_DRC_INDEX)
> + return -EINVAL;
This would look nicer as a switch I think.
> mutex_lock(&dlpar_mem_mutex);
>
> switch (hp_elog->action) {
> + case PSERIES_HP_ELOG_ACTION_ADD:
> + rc = dlpar_memory_add(hp_elog);
> + break;
> default:
> pr_err("Invalid action (%d) specified\n", hp_elog->action);
> rc = -EINVAL;
>
cheers
^ permalink raw reply
* Re: [5/5] pseries: Implement memory hotplug remove in the kernel
From: Michael Ellerman @ 2014-09-17 7:07 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev list
In-Reply-To: <54174D36.4000002@linux.vnet.ibm.com>
On Mon, 2014-09-15 at 15:33 -0500, Nathan Fontenot wrote:
> This patch adds the ability to do memory hotplug remove in the kernel.
>
> Currently the hotplug add/remove of memory is handled by the drmgr
> command. The drmgr command performs the add/remove by performing
> some work in user-space and making requests to the kernel to handle
> other pieces. By moving all of the work to the kernel we can do the
> add and remove faster, and provide a common place to do memory hotplug
> for both the PowerVM and PowerKVM environments.
>
> Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/hotplug-memory.c | 140 +++++++++++++++++++++++
> 1 file changed, 139 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
> index b254773..160c424 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
> @@ -193,7 +193,137 @@ static int pseries_remove_mem_node(struct device_node *np)
> pseries_remove_memblock(base, lmb_size);
> return 0;
> }
> +
> +static int lmb_is_removable(struct of_drconf_cell *lmb)
> +{
Do we not already have something like this?
> + int i, scns_per_block;
> + int rc = 1;
I can see this makes the &= work below.
But what if block_sz / MIN_MEMORY_BLOCK_SIZE = 0 ?
> + unsigned long pfn, block_sz;
> + u64 phys_addr;
> +
> + phys_addr = be64_to_cpu(lmb->base_addr);
> + block_sz = memory_block_size_bytes();
> + scns_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
> +
> + for (i = 0; i < scns_per_block; i++) {
> + pfn = PFN_DOWN(phys_addr);
> + if (!pfn_present(pfn))
> + continue;
> +
> + rc &= is_mem_section_removable(pfn, PAGES_PER_SECTION);
> + phys_addr += MIN_MEMORY_BLOCK_SIZE;
> + }
> +
> + return rc;
> +}
> +static int dlpar_memory_remove(struct pseries_hp_errorlog *hp_elog)
> +{
...
> +}
Most of the same comments as for add.
cheers
^ permalink raw reply
* Re: [PATCH 3/5] powerpc: Remove superfluous bootmem includes
From: Emil Medve @ 2014-09-17 8:49 UTC (permalink / raw)
To: Anton Blanchard, benh, paulus, mpe; +Cc: linuxppc-dev
In-Reply-To: <1410933504-28564-3-git-send-email-anton@samba.org>
Hello Anton,
On 09/17/2014 12:58 AM, Anton Blanchard wrote:
> Lots of places included bootmem.h even when not using bootmem.
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
> arch/powerpc/kernel/crash_dump.c | 1 -
> arch/powerpc/kernel/irq.c | 1 -
> arch/powerpc/kernel/pci_64.c | 1 -
> arch/powerpc/kernel/rtas_pci.c | 1 -
> arch/powerpc/kernel/setup_32.c | 1 -
> arch/powerpc/kernel/vdso.c | 1 -
> arch/powerpc/kvm/book3s_hv_builtin.c | 1 -
> arch/powerpc/mm/init_32.c | 1 -
> arch/powerpc/mm/init_64.c | 1 -
> arch/powerpc/mm/pgtable_64.c | 1 -
> arch/powerpc/platforms/cell/celleb_scc_epci.c | 1 -
> arch/powerpc/platforms/cell/celleb_scc_pciex.c | 1 -
> arch/powerpc/platforms/maple/pci.c | 1 -
> arch/powerpc/platforms/powermac/pci.c | 1 -
> arch/powerpc/platforms/powernv/eeh-ioda.c | 1 -
> arch/powerpc/platforms/powernv/pci.c | 1 -
> arch/powerpc/sysdev/fsl_msi.c | 1 -
> arch/powerpc/sysdev/ipic.c | 1 -
> arch/powerpc/sysdev/mpic.c | 1 -
> arch/powerpc/sysdev/mpic_pasemi_msi.c | 1 -
> arch/powerpc/sysdev/mpic_u3msi.c | 1 -
> arch/powerpc/sysdev/ppc4xx_msi.c | 1 -
> arch/powerpc/sysdev/ppc4xx_pci.c | 1 -
> arch/powerpc/sysdev/qe_lib/qe.c | 1 -
> arch/powerpc/sysdev/qe_lib/qe_ic.c | 1 -
> arch/powerpc/sysdev/uic.c | 1 -
> 26 files changed, 26 deletions(-)
> ...
> diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
> index aa91737..feed47c 100644
> --- a/arch/powerpc/mm/pgtable_64.c
> +++ b/arch/powerpc/mm/pgtable_64.c
> @@ -33,7 +33,6 @@
> #include <linux/swap.h>
> #include <linux/stddef.h>
> #include <linux/vmalloc.h>
> -#include <linux/bootmem.h>
> #include <linux/memblock.h>
> #include <linux/slab.h>
While building corenet64_smp I get this:
> ../arch/powerpc/mm/pgtable_64.c: In function 'early_alloc_pgtable':
> ../arch/powerpc/mm/pgtable_64.c:77:95: error: 'MAX_DMA_ADDRESS' undeclared (first use in this function)
> ../arch/powerpc/mm/pgtable_64.c:77:95: note: each undeclared identifier is reported only once for each function it appears in
Adding '#include <asm/dma.h>' seems to fix it
Other than that, for the entire set:
Tested-by: Emil Medve <Emilian.Medve@Freescale.com>
Cheers,
^ permalink raw reply
* [PATCH][V2] Freescale Frame Manager Device Tree binding document
From: Igal.Liberman @ 2014-09-17 11:08 UTC (permalink / raw)
To: devicetree, linuxppc-dev, netdev; +Cc: scottwood, Igal Liberman, Emilian.Medve
From: Igal Liberman <Igal.Liberman@freescale.com>
The Frame Manager (FMan) combines the Ethernet network interfaces with packet
distribution logic to provide intelligent distribution and queuing decisions
for incoming traffic at line rate.
This binding document describes Freescale's Frame Manager hardware attributes
that are used by the Frame Manager driver for its basic initialization and
configuration.
Difference between [V1] and [V2]:
Addressed all comments recieved from Scott in [V1]
Signed-off-by: Igal Liberman <Igal.Liberman@freescale.com>
---
.../devicetree/bindings/powerpc/fsl/fman.txt | 529 ++++++++++++++++++++
1 file changed, 529 insertions(+)
create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/fman.txt
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
new file mode 100644
index 0000000..da8e5f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
@@ -0,0 +1,529 @@
+=============================================================================
+Freescale Frame Manager Device Bindings
+
+CONTENTS
+ - FMan Node
+ - FMan Port Node
+ - FMan MURAM Node
+ - FMan dTSEC/XGEC/mEMAC Node
+ - FMan IEEE 1588 Node
+ - Example
+
+=============================================================================
+FMan Node
+
+DESCRIPTION
+
+Due to the fact that the FMan is an aggregation of sub-engines (ports, MACs,
+etc.) the FMan node will have child nodes for each of them.
+
+PROPERTIES
+
+- compatible
+ Usage: required
+ Value type: <stringlist>
+ Definition: Must include "fsl,fman"
+ FMan version can be determined via FM_IP_REV_1 register in the
+ FMan block. The offset is 0xc4 from the beginning of the
+ Frame Processing Manager memory map (0xc3000 from the
+ beginning of the FMan node).
+
+- cell-index
+ Usage: required
+ Value type: <u32>
+ Definition: Specifies the index of the FMan unit.
+
+ The cell-index value may be used by the SoC, to identify the
+ FMan unit in the SoC memory map. In the table bellow,
+ there's a description of the cell-index use in each SoC:
+
+ - P1023:
+ register[bit] FMan unit cell-index
+ ============================================================
+ DEVDISR[1] 1 0
+
+ - P2041, P3041, P4080 P5020, P5040:
+ register[bit] FMan unit cell-index
+ ============================================================
+ DCFG_DEVDISR2[6] 1 0
+ DCFG_DEVDISR2[14] 2 1
+ (Second FM available only in P4080 and P5040)
+
+ - B4860, T1040, T2080, T4240:
+ register[bit] FMan unit cell-index
+ ============================================================
+ DCFG_CCSR_DEVDISR2[24] 1 0
+ DCFG_CCSR_DEVDISR2[25] 2 1
+ (Second FM available only in T4240)
+
+ DEVDISR, DCFG_DEVDISR2 and DCFG_CCSR_DEVDISR2 are located in
+ the specific SoC "Device Configuration/Pin Control" Memory
+ Map.
+
+- reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property. Specifies the offset of the
+ following configuration registers:
+ - BMI configuration registers.
+ - QMI configuration registers.
+ - DMA configuration registers.
+ - FPM configuration registers.
+ - FMan controller configuration registers.
+
+- ranges
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property.
+
+- clocks
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: phandle for fman clock.
+
+- clock-names
+ usage: optional
+ Value type: <stringlist>
+ Definition: A standard property
+
+- interrupts
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A pair of IRQs are specified in this property.
+ The first element is associated with the event interrupts and
+ the second element is associated with the error interrupts.
+
+- fsl,qman-channel-range
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Specifies the range of the available dedicated
+ channels in the FMan. The first cell specifies the beginning
+ of the range and the second cell specifies the number of
+ channels.
+ Further information available at:
+ "Work Queue (WQ) Channel Assignments in the QMan" section
+ in DPAA Reference Manual.
+
+=============================================================================
+FMan MURAM Node
+
+DESCRIPTION
+
+FMan Internal memory - shared between all the FMan modules.
+It contains data structures that are common and written to or read by
+the modules.
+FMan internal memory is split into the following parts:
+ Packet buffering (Tx/Rx FIFOs)
+ Frames internal context
+
+PROPERTIES
+
+- compatible
+ Usage: required
+ Value type: <stringlist>
+ Definition: Must include "fsl,fman-muram"
+
+- ranges
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property.
+ Specifies the multi-user memory offset and the size within
+ the FMan.
+
+EXAMPLE
+
+muram@0 {
+ compatible = "fsl,fman-muram";
+ ranges = <0 0x000000 0x28000>;
+};
+
+=============================================================================
+FMan Port Node
+
+DESCRIPTION
+
+The Frame Manager (FMan) supports several types of hardware ports:
+ Ethernet receiver (RX)
+ Ethernet transmitter (TX)
+ Offline/Host command (O/H)
+
+PROPERTIES
+
+- compatible
+ Usage: required
+ Value type: <stringlist>
+ Definition: A standard property.
+ Must include one of the following:
+ - "fsl,fman-v2-port-oh" for FManV2 OH ports
+ - "fsl,fman-v2-port-rx" for FManV2 RX ports
+ - "fsl,fman-v2-port-tx" for FManV2 TX ports
+ - "fsl,fman-v3-port-oh" for FManV3 OH ports
+ - "fsl,fman-v3-port-rx" for FManV3 RX ports
+ - "fsl,fman-v3-port-tx" for FManV3 TX ports
+
+- cell-index
+ Usage: required
+ Value type: <u32>
+ Definition: Specifies the hardware port id.
+ Each hardware port on the FMan has its own hardware PortID.
+ Super set of all hardware Port IDs available at FMan Reference
+ Manual under "FMan Hardware Ports in Freescale Devices" table.
+
+ Each hardware port is assigned a 4KB, port-specific page in
+ the FMan hardware port memory region (which is part of the
+ FMan memory map). The first 4 KB in the FMan hardware ports
+ memory region is used for what are called common registers.
+ The subsequent 63 4KB pages are allocated to the hardware
+ ports.
+ The page of a specific port is determined by the cell-index.
+
+- reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: There is one reg region describing the port
+ configuration registers.
+
+EXAMPLE
+
+port@a8000 {
+ cell-index = <0x28>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xa8000 0x1000>;
+};
+
+port@88000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x88000 0x1000>;
+};
+
+port@81000 {
+ cell-index = <0x1>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x81000 0x1000>;
+};
+
+=============================================================================
+FMan dTSEC/XGEC/mEMAC Node
+
+DESCRIPTION
+
+mEMAC/dTSEC/XGEC are the Ethernet network interfaces
+
+PROPERTIES
+
+- compatible
+ Usage: required
+ Value type: <stringlist>
+ Definition: A standard property.
+ Must include one of the following:
+ - "fsl,fman-dtsec" for dTSEC MAC
+ - "fsl,fman-xgec" for XGEC MAC
+ - "fsl,fman-memac for mEMAC MAC
+
+- cell-index
+ Usage: required
+ Value type: <u32>
+ Definition: Specifies the MAC id.
+
+ The cell-index value may be used by the FMan or the SoC, to
+ identify the MAC unit in the FMan (or SoC) memory map.
+ In the tables bellow there's a description of the cell-index
+ use, there are two tables, one describes the use of cell-index
+ by the FMan, the second describes the use by the SoC:
+
+ 1. FMan Registers
+
+ FManV2:
+ register[bit] MAC cell-index
+ ============================================================
+ FM_EPI[16] XGEC 8
+ FM_EPI[16+n] dTSECn n-1
+ FM_NPI[11+n] dTSECn n-1
+ n = 1,..,5
+
+ FManV3:
+ register[bit] MAC cell-index
+ ============================================================
+ FM_EPI[16+n] mEMACn n-1
+ FM_EPI[25] mEMAC10 9
+
+ FM_NPI[11+n] mEMACn n-1
+ FM_NPI[10] mEMAC10 9
+ FM_NPI[11] mEMAC9 8
+ n = 1,..8
+
+ FM_EPI and FM_NPI are located in the FMan memory map.
+
+ 2. SoC registers:
+
+ - P2041, P3041, P4080 P5020, P5040:
+ register[bit] FMan MAC cell
+ Unit index
+ ============================================================
+ DCFG_DEVDISR2[7] 1 XGEC 8
+ DCFG_DEVDISR2[7+n] 1 dTSECn n-1
+ DCFG_DEVDISR2[15] 2 XGEC 8
+ DCFG_DEVDISR2[15+n] 2 dTSECn n-1
+ n = 1,..5
+
+ - T1040, T2080, T4240, B4860:
+ register[bit] FMan MAC cell
+ Unit index
+ ============================================================
+ DCFG_CCSR_DEVDISR2[n-1] 1 mEMACn n-1
+ DCFG_CCSR_DEVDISR2[11+n] 2 mEMACn n-1
+ n = 1,..6,9,10
+
+ EVDISR, DCFG_DEVDISR2 and DCFG_CCSR_DEVDISR2 are located in
+ the specific SoC "Device Configuration/Pin Control" Memory
+ Map.
+
+- reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property.
+
+- fsl,fman-ports
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: An array of two phandles - the first references is
+ the FMan RX port and the second is the TX port used by this
+ MAC.
+
+- ptp-timer
+ Usage required
+ Value type: <phandle>
+ Definition: A phandle for 1EEE1588 timer.
+
+EXAMPLE
+
+fman1_tx28: port@a8000 {
+ cell-index = <0x28>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xa8000 0x1000>;
+};
+
+fman1_rx8: port@88000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x88000 0x1000>;
+};
+
+ptp-timer: ptp_timer@fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0xfe000 0x1000>;
+};
+
+ethernet@e0000 {
+ compatible = "fsl,fman-dtsec";
+ cell-index = <0>;
+ reg = <0xe0000 0x1000>;
+ fsl,fman-ports = <&fman1_rx8 &fman1_tx28>;
+ ptp-timer = <&ptp-timer>;
+};
+
+============================================================================
+FMan IEEE 1588 Node
+
+DESCRIPTION
+
+The FMan interface to support IEEE 1588
+
+
+PROPERTIES
+
+- compatible
+ Usage: required
+ Value type: <stringlist>
+ Definition: A standard property.
+ Must include "fsl,fman-ptp-timer".
+
+- reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property.
+
+EXAMPLE
+
+ptp-timer@fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0xfe000 0x1000>;
+};
+
+=============================================================================
+Example
+
+fman@400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ compatible = "fsl,fman"
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ clocks = <&fman_clk>;
+ clock-names = "fmanclk";
+ interrupts = <
+ 96 2 0 0
+ 16 2 1 1>;
+ fsl,qman-channel-range = <0x40 0xc>;
+
+ muram@0 {
+ compatible = "fsl,fman-muram";
+ reg = <0x0 0x28000>;
+ };
+
+ port@81000 {
+ cell-index = <1>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x81000 0x1000>;
+ };
+
+ port@82000 {
+ cell-index = <2>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x82000 0x1000>;
+ };
+
+ port@83000 {
+ cell-index = <3>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x83000 0x1000>;
+ };
+
+ port@84000 {
+ cell-index = <4>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x84000 0x1000>;
+ };
+
+ port@85000 {
+ cell-index = <5>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x85000 0x1000>;
+ };
+
+ port@86000 {
+ cell-index = <6>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x86000 0x1000>;
+ };
+
+ fman1_rx_0x8: port@88000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x88000 0x1000>;
+ };
+
+ fman1_rx_0x9: port@89000 {
+ cell-index = <0x9>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x89000 0x1000>;
+ };
+
+ fman1_rx_0xa: port@8a000 {
+ cell-index = <0xa>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x8a000 0x1000>;
+ };
+
+ fman1_rx_0xb: port@8b000 {
+ cell-index = <0xb>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x8b000 0x1000>;
+ };
+
+ fman1_rx_0xc: port@8c000 {
+ cell-index = <0xc>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x8c000 0x1000>;
+ };
+
+ fman1_rx_0x10: port@90000 {
+ cell-index = <0x10>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x90000 0x1000>;
+ };
+
+ fman1_tx_0x28: port@a8000 {
+ cell-index = <0x28>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xa8000 0x1000>;
+ };
+
+ fman1_tx_0x29: port@a9000 {
+ cell-index = <0x29>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xa9000 0x1000>;
+ };
+
+ fman1_tx_0x2a: port@aa000 {
+ cell-index = <0x2a>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xaa000 0x1000>;
+ };
+
+ fman1_tx_0x2b: port@ab000 {
+ cell-index = <0x2b>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xab000 0x1000>;
+ };
+
+ fman1_tx_0x2c: port@ac0000 {
+ cell-index = <0x2c>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xac000 0x1000>;
+ };
+
+ fman1_tx_0x30: port@b0000 {
+ cell-index = <0x30>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xb0000 0x1000>;
+ };
+
+ ethernet@e0000 {
+ compatible = "fsl,fman-dtsec";
+ cell-index = <0>;
+ reg = <0xe0000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x8 &fman1_tx_0x28>;
+ };
+
+ ethernet@e2000 {
+ compatible = "fsl,fman-dtsec";
+ cell-index = <1>;
+ reg = <0xe2000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x9 &fman1_tx_0x29>;
+ };
+
+ ethernet@e4000 {
+ compatible = "fsl,fman-dtsec";
+ cell-index = <2>;
+ reg = <0xe4000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0xa &fman1_tx_0x2a>;
+ };
+
+ ethernet@e6000 {
+ compatible = "fsl,fman-dtsec";
+ cell-index = <3>;
+ reg = <0xe6000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0xb &fman1_tx_0x2b>;
+ };
+
+ ethernet@e8000 {
+ compatible = "fsl,fman-dtsec";
+ cell-index = <4>;
+ reg = <0xf0000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0xc &fman1_tx_0x2c>;
+
+ ethernet@f0000 {
+ cell-index = <8>;
+ compatible = "fsl,fman-xgec";
+ reg = <0xf0000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x10 &fman1_tx_0x30>;
+ };
+
+ ptp-timer@fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0xfe000 0x1000>;
+ };
+};
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 3/5] powerpc: Remove superfluous bootmem includes
From: Anton Blanchard @ 2014-09-17 12:08 UTC (permalink / raw)
To: Emil Medve; +Cc: paulus, linuxppc-dev
In-Reply-To: <54194B21.6050105@Freescale.com>
Hi Emil,
> While building corenet64_smp I get this:
>
> > ../arch/powerpc/mm/pgtable_64.c: In function 'early_alloc_pgtable':
> > ../arch/powerpc/mm/pgtable_64.c:77:95: error: 'MAX_DMA_ADDRESS'
> > undeclared (first use in this
> > function) ../arch/powerpc/mm/pgtable_64.c:77:95: note: each
> > undeclared identifier is reported only once for each function it
> > appears in
>
> Adding '#include <asm/dma.h>' seems to fix it
>
> Other than that, for the entire set:
>
> Tested-by: Emil Medve <Emilian.Medve@Freescale.com>
Thanks for testing! I'll respin the patch with that include added.
Anton
^ permalink raw reply
* [PATCH 1/5] powerpc: Remove bootmem allocator
From: Anton Blanchard @ 2014-09-17 12:15 UTC (permalink / raw)
To: benh, paulus, mpe, Emilian.Medve; +Cc: linuxppc-dev
At the moment we transition from the memblock alloctor to the bootmem
allocator. Gitting rid of the bootmem allocator removes a bunch of
complicated code (most of which I owe the dubious honour of being
responsible for writing).
Signed-off-by: Anton Blanchard <anton@samba.org>
Tested-by: Emil Medve <Emilian.Medve@Freescale.com>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/setup.h | 3 +-
arch/powerpc/kernel/setup_32.c | 5 +-
arch/powerpc/kernel/setup_64.c | 3 +-
arch/powerpc/mm/init_32.c | 9 --
arch/powerpc/mm/mem.c | 62 +----------
arch/powerpc/mm/numa.c | 224 ++++++---------------------------------
arch/powerpc/mm/pgtable_32.c | 3 +-
arch/powerpc/mm/pgtable_64.c | 6 +-
9 files changed, 43 insertions(+), 273 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 90fe77a..3eeeb9d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -148,6 +148,7 @@ config PPC
select HAVE_ARCH_AUDITSYSCALL
select ARCH_SUPPORTS_ATOMIC_RMW
select HAVE_PERF_EVENTS_NMI if PPC64
+ select NO_BOOTMEM
config GENERIC_CSUM
def_bool CPU_LITTLE_ENDIAN
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 11ba86e..fbdf18c 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -8,7 +8,6 @@ extern void ppc_printk_progress(char *s, unsigned short hex);
extern unsigned int rtas_data;
extern int mem_init_done; /* set on boot once kmalloc can be called */
-extern int init_bootmem_done; /* set once bootmem is available */
extern unsigned long long memory_limit;
extern unsigned long klimit;
extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
@@ -24,7 +23,7 @@ extern void reloc_got2(unsigned long);
#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
void check_for_initrd(void);
-void do_init_bootmem(void);
+void initmem_init(void);
void setup_panic(void);
#define ARCH_PANIC_TIMEOUT 180
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index ea4fda6..e2bc044 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -311,9 +311,8 @@ void __init setup_arch(char **cmdline_p)
irqstack_early_init();
- /* set up the bootmem stuff with available memory */
- do_init_bootmem();
- if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
+ initmem_init();
+ if ( ppc_md.progress ) ppc_md.progress("setup_arch: initmem", 0x3eab);
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index fa17c94..9f8f472 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -681,8 +681,7 @@ void __init setup_arch(char **cmdline_p)
exc_lvl_early_init();
emergency_stack_init();
- /* set up the bootmem stuff with available memory */
- do_init_bootmem();
+ initmem_init();
sparse_init();
#ifdef CONFIG_DUMMY_CONSOLE
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index cff59f1..9d1bde2 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -195,15 +195,6 @@ void __init MMU_init(void)
memblock_set_current_limit(lowmem_end_addr);
}
-/* This is only called until mem_init is done. */
-void __init *early_get_page(void)
-{
- if (init_bootmem_done)
- return alloc_bootmem_pages(PAGE_SIZE);
- else
- return __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
-}
-
#ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
phys_addr_t first_memblock_size)
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index e0f7a18..aa067b7 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -60,7 +60,6 @@
#define CPU_FTR_NOEXECUTE 0
#endif
-int init_bootmem_done;
int mem_init_done;
unsigned long long memory_limit;
@@ -180,70 +179,22 @@ walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
}
EXPORT_SYMBOL_GPL(walk_system_ram_range);
-/*
- * Initialize the bootmem system and give it all the memory we
- * have available. If we are using highmem, we only put the
- * lowmem into the bootmem system.
- */
#ifndef CONFIG_NEED_MULTIPLE_NODES
-void __init do_init_bootmem(void)
+void __init initmem_init(void)
{
- unsigned long start, bootmap_pages;
- unsigned long total_pages;
- struct memblock_region *reg;
- int boot_mapsize;
-
max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
- total_pages = (memblock_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT;
+ min_low_pfn = MEMORY_START >> PAGE_SHIFT;
#ifdef CONFIG_HIGHMEM
- total_pages = total_lowmem >> PAGE_SHIFT;
max_low_pfn = lowmem_end_addr >> PAGE_SHIFT;
#endif
- /*
- * Find an area to use for the bootmem bitmap. Calculate the size of
- * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
- * Add 1 additional page in case the address isn't page-aligned.
- */
- bootmap_pages = bootmem_bootmap_pages(total_pages);
-
- start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
-
- min_low_pfn = MEMORY_START >> PAGE_SHIFT;
- boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
-
/* Place all memblock_regions in the same node and merge contiguous
* memblock_regions
*/
memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
- /* Add all physical memory to the bootmem map, mark each area
- * present.
- */
-#ifdef CONFIG_HIGHMEM
- free_bootmem_with_active_regions(0, lowmem_end_addr >> PAGE_SHIFT);
-
- /* reserve the sections we're already using */
- for_each_memblock(reserved, reg) {
- unsigned long top = reg->base + reg->size - 1;
- if (top < lowmem_end_addr)
- reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
- else if (reg->base < lowmem_end_addr) {
- unsigned long trunc_size = lowmem_end_addr - reg->base;
- reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
- }
- }
-#else
- free_bootmem_with_active_regions(0, max_pfn);
-
- /* reserve the sections we're already using */
- for_each_memblock(reserved, reg)
- reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
-#endif
/* XXX need to clip this if using highmem? */
sparse_memory_present_with_active_regions(0);
-
- init_bootmem_done = 1;
}
/* mark pages that don't exist as nosave */
@@ -303,14 +254,6 @@ void __init paging_init(void)
}
#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
-static void __init register_page_bootmem_info(void)
-{
- int i;
-
- for_each_online_node(i)
- register_page_bootmem_info_node(NODE_DATA(i));
-}
-
void __init mem_init(void)
{
/*
@@ -323,7 +266,6 @@ void __init mem_init(void)
swiotlb_init(0);
#endif
- register_page_bootmem_info();
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
set_max_mapnr(max_pfn);
free_all_bootmem();
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index ec32d46..4f9c18a 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -132,28 +132,6 @@ static int __init fake_numa_create_new_node(unsigned long end_pfn,
return 0;
}
-/*
- * get_node_active_region - Return active region containing pfn
- * Active range returned is empty if none found.
- * @pfn: The page to return the region for
- * @node_ar: Returned set to the active region containing @pfn
- */
-static void __init get_node_active_region(unsigned long pfn,
- struct node_active_region *node_ar)
-{
- unsigned long start_pfn, end_pfn;
- int i, nid;
-
- for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) {
- if (pfn >= start_pfn && pfn < end_pfn) {
- node_ar->nid = nid;
- node_ar->start_pfn = start_pfn;
- node_ar->end_pfn = end_pfn;
- break;
- }
- }
-}
-
static void reset_numa_cpu_lookup_table(void)
{
unsigned int cpu;
@@ -926,134 +904,48 @@ static void __init dump_numa_memory_topology(void)
}
}
-/*
- * Allocate some memory, satisfying the memblock or bootmem allocator where
- * required. nid is the preferred node and end is the physical address of
- * the highest address in the node.
- *
- * Returns the virtual address of the memory.
- */
-static void __init *careful_zallocation(int nid, unsigned long size,
- unsigned long align,
- unsigned long end_pfn)
-{
- void *ret;
- int new_nid;
- unsigned long ret_paddr;
-
- ret_paddr = __memblock_alloc_base(size, align, end_pfn << PAGE_SHIFT);
-
- /* retry over all memory */
- if (!ret_paddr)
- ret_paddr = __memblock_alloc_base(size, align, memblock_end_of_DRAM());
-
- if (!ret_paddr)
- panic("numa.c: cannot allocate %lu bytes for node %d",
- size, nid);
-
- ret = __va(ret_paddr);
-
- /*
- * We initialize the nodes in numeric order: 0, 1, 2...
- * and hand over control from the MEMBLOCK allocator to the
- * bootmem allocator. If this function is called for
- * node 5, then we know that all nodes <5 are using the
- * bootmem allocator instead of the MEMBLOCK allocator.
- *
- * So, check the nid from which this allocation came
- * and double check to see if we need to use bootmem
- * instead of the MEMBLOCK. We don't free the MEMBLOCK memory
- * since it would be useless.
- */
- new_nid = early_pfn_to_nid(ret_paddr >> PAGE_SHIFT);
- if (new_nid < nid) {
- ret = __alloc_bootmem_node(NODE_DATA(new_nid),
- size, align, 0);
-
- dbg("alloc_bootmem %p %lx\n", ret, size);
- }
-
- memset(ret, 0, size);
- return ret;
-}
-
static struct notifier_block ppc64_numa_nb = {
.notifier_call = cpu_numa_callback,
.priority = 1 /* Must run before sched domains notifier. */
};
-static void __init mark_reserved_regions_for_nid(int nid)
+/* Initialize NODE_DATA for a node on the local memory */
+static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
{
- struct pglist_data *node = NODE_DATA(nid);
- struct memblock_region *reg;
-
- for_each_memblock(reserved, reg) {
- unsigned long physbase = reg->base;
- unsigned long size = reg->size;
- unsigned long start_pfn = physbase >> PAGE_SHIFT;
- unsigned long end_pfn = PFN_UP(physbase + size);
- struct node_active_region node_ar;
- unsigned long node_end_pfn = pgdat_end_pfn(node);
-
- /*
- * Check to make sure that this memblock.reserved area is
- * within the bounds of the node that we care about.
- * Checking the nid of the start and end points is not
- * sufficient because the reserved area could span the
- * entire node.
- */
- if (end_pfn <= node->node_start_pfn ||
- start_pfn >= node_end_pfn)
- continue;
-
- get_node_active_region(start_pfn, &node_ar);
- while (start_pfn < end_pfn &&
- node_ar.start_pfn < node_ar.end_pfn) {
- unsigned long reserve_size = size;
- /*
- * if reserved region extends past active region
- * then trim size to active region
- */
- if (end_pfn > node_ar.end_pfn)
- reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
- - physbase;
- /*
- * Only worry about *this* node, others may not
- * yet have valid NODE_DATA().
- */
- if (node_ar.nid == nid) {
- dbg("reserve_bootmem %lx %lx nid=%d\n",
- physbase, reserve_size, node_ar.nid);
- reserve_bootmem_node(NODE_DATA(node_ar.nid),
- physbase, reserve_size,
- BOOTMEM_DEFAULT);
- }
- /*
- * if reserved region is contained in the active region
- * then done.
- */
- if (end_pfn <= node_ar.end_pfn)
- break;
-
- /*
- * reserved region extends past the active region
- * get next active region that contains this
- * reserved region
- */
- start_pfn = node_ar.end_pfn;
- physbase = start_pfn << PAGE_SHIFT;
- size = size - reserve_size;
- get_node_active_region(start_pfn, &node_ar);
- }
- }
+ u64 spanned_pages = end_pfn - start_pfn;
+ const size_t nd_size = roundup(sizeof(pg_data_t), SMP_CACHE_BYTES);
+ u64 nd_pa;
+ void *nd;
+ int tnid;
+
+ if (spanned_pages)
+ pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
+ nid, start_pfn << PAGE_SHIFT,
+ (end_pfn << PAGE_SHIFT) - 1);
+ else
+ pr_info("Initmem setup node %d\n", nid);
+
+ nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
+ nd = __va(nd_pa);
+
+ /* report and initialize */
+ pr_info(" NODE_DATA [mem %#010Lx-%#010Lx]\n",
+ nd_pa, nd_pa + nd_size - 1);
+ tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
+ if (tnid != nid)
+ pr_info(" NODE_DATA(%d) on node %d\n", nid, tnid);
+
+ node_data[nid] = nd;
+ memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+ NODE_DATA(nid)->node_id = nid;
+ NODE_DATA(nid)->node_start_pfn = start_pfn;
+ NODE_DATA(nid)->node_spanned_pages = spanned_pages;
}
-
-void __init do_init_bootmem(void)
+void __init initmem_init(void)
{
int nid, cpu;
- min_low_pfn = 0;
max_low_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
max_pfn = max_low_pfn;
@@ -1062,64 +954,16 @@ void __init do_init_bootmem(void)
else
dump_numa_memory_topology();
+ memblock_dump_all();
+
for_each_online_node(nid) {
unsigned long start_pfn, end_pfn;
- void *bootmem_vaddr;
- unsigned long bootmap_pages;
get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
-
- /*
- * Allocate the node structure node local if possible
- *
- * Be careful moving this around, as it relies on all
- * previous nodes' bootmem to be initialized and have
- * all reserved areas marked.
- */
- NODE_DATA(nid) = careful_zallocation(nid,
- sizeof(struct pglist_data),
- SMP_CACHE_BYTES, end_pfn);
-
- dbg("node %d\n", nid);
- dbg("NODE_DATA() = %p\n", NODE_DATA(nid));
-
- NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
- NODE_DATA(nid)->node_start_pfn = start_pfn;
- NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
-
- if (NODE_DATA(nid)->node_spanned_pages == 0)
- continue;
-
- dbg("start_paddr = %lx\n", start_pfn << PAGE_SHIFT);
- dbg("end_paddr = %lx\n", end_pfn << PAGE_SHIFT);
-
- bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
- bootmem_vaddr = careful_zallocation(nid,
- bootmap_pages << PAGE_SHIFT,
- PAGE_SIZE, end_pfn);
-
- dbg("bootmap_vaddr = %p\n", bootmem_vaddr);
-
- init_bootmem_node(NODE_DATA(nid),
- __pa(bootmem_vaddr) >> PAGE_SHIFT,
- start_pfn, end_pfn);
-
- free_bootmem_with_active_regions(nid, end_pfn);
- /*
- * Be very careful about moving this around. Future
- * calls to careful_zallocation() depend on this getting
- * done correctly.
- */
- mark_reserved_regions_for_nid(nid);
+ setup_node_data(nid, start_pfn, end_pfn);
sparse_memory_present_with_active_regions(nid);
}
- init_bootmem_done = 1;
-
- /*
- * Now bootmem is initialised we can create the node to cpumask
- * lookup tables and setup the cpu callback to populate them.
- */
setup_node_to_cpumask_map();
reset_numa_cpu_lookup_table();
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index cf11342..d545b12 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -100,12 +100,11 @@ __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long add
{
pte_t *pte;
extern int mem_init_done;
- extern void *early_get_page(void);
if (mem_init_done) {
pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
} else {
- pte = (pte_t *)early_get_page();
+ pte = __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
if (pte)
clear_page(pte);
}
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index c8d709a..cdb19ab 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -75,11 +75,7 @@ static __ref void *early_alloc_pgtable(unsigned long size)
{
void *pt;
- if (init_bootmem_done)
- pt = __alloc_bootmem(size, size, __pa(MAX_DMA_ADDRESS));
- else
- pt = __va(memblock_alloc_base(size, size,
- __pa(MAX_DMA_ADDRESS)));
+ pt = __va(memblock_alloc_base(size, size, __pa(MAX_DMA_ADDRESS)));
memset(pt, 0, size);
return pt;
--
1.9.1
^ permalink raw reply related
* [PATCH 2/5] powerpc: Remove some old bootmem related comments
From: Anton Blanchard @ 2014-09-17 12:15 UTC (permalink / raw)
To: benh, paulus, mpe, Emilian.Medve; +Cc: linuxppc-dev
In-Reply-To: <1410956137-4824-1-git-send-email-anton@samba.org>
Now bootmem is gone from powerpc we can remove comments mentioning it.
Signed-off-by: Anton Blanchard <anton@samba.org>
Tested-by: Emil Medve <Emilian.Medve@Freescale.com>
---
arch/powerpc/kernel/prom.c | 5 +----
arch/powerpc/kernel/rtas.c | 4 ++--
arch/powerpc/kvm/book3s_hv_builtin.c | 2 +-
arch/powerpc/mm/hugetlbpage.c | 4 ++--
arch/powerpc/mm/pgtable_64.c | 4 ----
5 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 5957625..02e3e4c 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -698,10 +698,7 @@ void __init early_init_devtree(void *params)
reserve_crashkernel();
early_reserve_mem();
- /*
- * Ensure that total memory size is page-aligned, because otherwise
- * mark_bootmem() gets upset.
- */
+ /* Ensure that total memory size is page-aligned. */
limit = ALIGN(memory_limit ?: memblock_phys_mem_size(), PAGE_SIZE);
memblock_enforce_memory_limit(limit);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 8b4c857..4af905e 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -1091,8 +1091,8 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
}
/*
- * Call early during boot, before mem init or bootmem, to retrieve the RTAS
- * informations from the device-tree and allocate the RMO buffer for userland
+ * Call early during boot, before mem init, to retrieve the RTAS
+ * information from the device-tree and allocate the RMO buffer for userland
* accesses.
*/
void __init rtas_initialize(void)
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index b9615ba..297dbaf 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -154,7 +154,7 @@ EXPORT_SYMBOL_GPL(kvm_release_hpt);
* kvm_cma_reserve() - reserve area for kvm hash pagetable
*
* This function reserves memory from early allocator. It should be
- * called by arch specific code once the early allocator (memblock or bootmem)
+ * called by arch specific code once the memblock allocator
* has been activated and all other subsystems have already allocated/reserved
* memory.
*/
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 7e70ae9..5215d25 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -276,7 +276,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz
#ifdef CONFIG_PPC_FSL_BOOK3E
/* Build list of addresses of gigantic pages. This function is used in early
- * boot before the buddy or bootmem allocator is setup.
+ * boot before the buddy allocator is setup.
*/
void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages)
{
@@ -399,7 +399,7 @@ void __init reserve_hugetlb_gpages(void)
#else /* !PPC_FSL_BOOK3E */
/* Build list of addresses of gigantic pages. This function is used in early
- * boot before the buddy or bootmem allocator is setup.
+ * boot before the buddy allocator is setup.
*/
void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages)
{
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index cdb19ab..aa91737 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -109,10 +109,6 @@ int map_kernel_page(unsigned long ea, unsigned long pa, int flags)
__pgprot(flags)));
} else {
#ifdef CONFIG_PPC_MMU_NOHASH
- /* Warning ! This will blow up if bootmem is not initialized
- * which our ppc64 code is keen to do that, we'll need to
- * fix it and/or be more careful
- */
pgdp = pgd_offset_k(ea);
#ifdef PUD_TABLE_SIZE
if (pgd_none(*pgdp)) {
--
1.9.1
^ permalink raw reply related
* [PATCH 3/5] powerpc: Remove superfluous bootmem includes
From: Anton Blanchard @ 2014-09-17 12:15 UTC (permalink / raw)
To: benh, paulus, mpe, Emilian.Medve; +Cc: linuxppc-dev
In-Reply-To: <1410956137-4824-1-git-send-email-anton@samba.org>
Lots of places included bootmem.h even when not using bootmem.
Signed-off-by: Anton Blanchard <anton@samba.org>
Tested-by: Emil Medve <Emilian.Medve@Freescale.com>
---
arch/powerpc/kernel/crash_dump.c | 1 -
arch/powerpc/kernel/irq.c | 1 -
arch/powerpc/kernel/pci_64.c | 1 -
arch/powerpc/kernel/rtas_pci.c | 1 -
arch/powerpc/kernel/setup_32.c | 1 -
arch/powerpc/kernel/vdso.c | 1 -
arch/powerpc/kvm/book3s_hv_builtin.c | 1 -
arch/powerpc/mm/init_32.c | 1 -
arch/powerpc/mm/init_64.c | 1 -
arch/powerpc/mm/pgtable_64.c | 2 +-
arch/powerpc/platforms/cell/celleb_scc_epci.c | 1 -
arch/powerpc/platforms/cell/celleb_scc_pciex.c | 1 -
arch/powerpc/platforms/maple/pci.c | 1 -
arch/powerpc/platforms/powermac/pci.c | 1 -
arch/powerpc/platforms/powernv/eeh-ioda.c | 1 -
arch/powerpc/platforms/powernv/pci.c | 1 -
arch/powerpc/sysdev/fsl_msi.c | 1 -
arch/powerpc/sysdev/ipic.c | 1 -
arch/powerpc/sysdev/mpic.c | 1 -
arch/powerpc/sysdev/mpic_pasemi_msi.c | 1 -
arch/powerpc/sysdev/mpic_u3msi.c | 1 -
arch/powerpc/sysdev/ppc4xx_msi.c | 1 -
arch/powerpc/sysdev/ppc4xx_pci.c | 1 -
arch/powerpc/sysdev/qe_lib/qe.c | 1 -
arch/powerpc/sysdev/qe_lib/qe_ic.c | 1 -
arch/powerpc/sysdev/uic.c | 1 -
26 files changed, 1 insertion(+), 26 deletions(-)
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 7a13f37..0bfe370 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -12,7 +12,6 @@
#undef DEBUG
#include <linux/crash_dump.h>
-#include <linux/bootmem.h>
#include <linux/memblock.h>
#include <asm/code-patching.h>
#include <asm/kdump.h>
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 4c5891d..c47a74d 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -50,7 +50,6 @@
#include <linux/list.h>
#include <linux/radix-tree.h>
#include <linux/mutex.h>
-#include <linux/bootmem.h>
#include <linux/pci.h>
#include <linux/debugfs.h>
#include <linux/of.h>
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 155013d..ba0f2d6 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -17,7 +17,6 @@
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/list.h>
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index c168337..fe39926 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -26,7 +26,6 @@
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <asm/io.h>
#include <asm/pgtable.h>
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index e2bc044..84dafdf 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -11,7 +11,6 @@
#include <linux/delay.h>
#include <linux/initrd.h>
#include <linux/tty.h>
-#include <linux/bootmem.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index f174351..305eb0d 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -20,7 +20,6 @@
#include <linux/user.h>
#include <linux/elf.h>
#include <linux/security.h>
-#include <linux/bootmem.h>
#include <linux/memblock.h>
#include <asm/pgtable.h>
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 297dbaf..6baa186 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -12,7 +12,6 @@
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
-#include <linux/bootmem.h>
#include <linux/init.h>
#include <linux/memblock.h>
#include <linux/sizes.h>
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 9d1bde2..6332368 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -26,7 +26,6 @@
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <linux/highmem.h>
#include <linux/initrd.h>
#include <linux/pagemap.h>
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 3481556..10471f9 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -34,7 +34,6 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/bootmem.h>
#include <linux/highmem.h>
#include <linux/idr.h>
#include <linux/nodemask.h>
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index aa91737..e0c7185 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -33,7 +33,6 @@
#include <linux/swap.h>
#include <linux/stddef.h>
#include <linux/vmalloc.h>
-#include <linux/bootmem.h>
#include <linux/memblock.h>
#include <linux/slab.h>
@@ -51,6 +50,7 @@
#include <asm/cputable.h>
#include <asm/sections.h>
#include <asm/firmware.h>
+#include <asm/dma.h>
#include "mmu_decl.h"
diff --git a/arch/powerpc/platforms/cell/celleb_scc_epci.c b/arch/powerpc/platforms/cell/celleb_scc_epci.c
index 844c0fa..9438bbe 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_epci.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_epci.c
@@ -25,7 +25,6 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/pci_regs.h>
-#include <linux/bootmem.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index 4278acf..f223875 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -25,7 +25,6 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index f7136aa..d3a1306 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -15,7 +15,6 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <linux/irq.h>
#include <asm/sections.h>
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 7e868cc..04702db 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -15,7 +15,6 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <linux/irq.h>
#include <linux/of_pci.h>
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index df5c2cc..3ff6fe7 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -11,7 +11,6 @@
* (at your option) any later version.
*/
-#include <linux/bootmem.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/io.h>
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index b854b57..f4e91a3 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -16,7 +16,6 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/msi.h>
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 77efbae..b9afd5f 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -13,7 +13,6 @@
*
*/
#include <linux/irq.h>
-#include <linux/bootmem.h>
#include <linux/msi.h>
#include <linux/pci.h>
#include <linux/slab.h>
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index b50f978..b287337 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -20,7 +20,6 @@
#include <linux/signal.h>
#include <linux/syscore_ops.h>
#include <linux/device.h>
-#include <linux/bootmem.h>
#include <linux/spinlock.h>
#include <linux/fsl_devices.h>
#include <asm/irq.h>
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 89cec0e..c4648ad 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -24,7 +24,6 @@
#include <linux/irq.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
-#include <linux/bootmem.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/slab.h>
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index 38e6238..71d3e85 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -16,7 +16,6 @@
#undef DEBUG
#include <linux/irq.h>
-#include <linux/bootmem.h>
#include <linux/msi.h>
#include <asm/mpic.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index 9a7aa0e..6b1dd9b 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -10,7 +10,6 @@
*/
#include <linux/irq.h>
-#include <linux/bootmem.h>
#include <linux/msi.h>
#include <asm/mpic.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c
index 43948da..ed188a1 100644
--- a/arch/powerpc/sysdev/ppc4xx_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_msi.c
@@ -22,7 +22,6 @@
*/
#include <linux/irq.h>
-#include <linux/bootmem.h>
#include <linux/pci.h>
#include <linux/msi.h>
#include <linux/of_platform.h>
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index df6e2fc..086aca6 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -22,7 +22,6 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/of.h>
-#include <linux/bootmem.h>
#include <linux/delay.h>
#include <linux/slab.h>
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 238a07b..b584deb 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -22,7 +22,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
-#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/ioport.h>
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index b2b87c3..543765e 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -23,7 +23,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/device.h>
-#include <linux/bootmem.h>
#include <linux/spinlock.h>
#include <asm/irq.h>
#include <asm/io.h>
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 9203393..7c37157 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -19,7 +19,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/device.h>
-#include <linux/bootmem.h>
#include <linux/spinlock.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
--
1.9.1
^ permalink raw reply related
* [PATCH 4/5] powerpc: Move sparse_init() into initmem_init
From: Anton Blanchard @ 2014-09-17 12:15 UTC (permalink / raw)
To: benh, paulus, mpe, Emilian.Medve; +Cc: linuxppc-dev
In-Reply-To: <1410956137-4824-1-git-send-email-anton@samba.org>
We did part of sparse initialisation in setup_arch and part in
initmem_init. Put them together.
Signed-off-by: Anton Blanchard <anton@samba.org>
Tested-by: Emil Medve <Emilian.Medve@Freescale.com>
---
arch/powerpc/kernel/setup_64.c | 1 -
arch/powerpc/mm/mem.c | 1 +
arch/powerpc/mm/numa.c | 2 ++
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 9f8f472..8bc8f77 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -682,7 +682,6 @@ void __init setup_arch(char **cmdline_p)
emergency_stack_init();
initmem_init();
- sparse_init();
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index aa067b7..abbc55d 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -195,6 +195,7 @@ void __init initmem_init(void)
/* XXX need to clip this if using highmem? */
sparse_memory_present_with_active_regions(0);
+ sparse_init();
}
/* mark pages that don't exist as nosave */
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 4f9c18a..52559ff 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -964,6 +964,8 @@ void __init initmem_init(void)
sparse_memory_present_with_active_regions(nid);
}
+ sparse_init();
+
setup_node_to_cpumask_map();
reset_numa_cpu_lookup_table();
--
1.9.1
^ permalink raw reply related
* [PATCH 5/5] powerpc: make __ffs return unsigned long
From: Anton Blanchard @ 2014-09-17 12:15 UTC (permalink / raw)
To: benh, paulus, mpe, Emilian.Medve; +Cc: linuxppc-dev
In-Reply-To: <1410956137-4824-1-git-send-email-anton@samba.org>
I'm seeing a build warning in mm/nobootmem.c after removing
bootmem:
mm/nobootmem.c: In function '__free_pages_memory':
include/linux/kernel.h:713:17: warning: comparison of distinct pointer types lacks a cast [enabled by default]
(void) (&_min1 == &_min2); \
^
mm/nobootmem.c:90:11: note: in expansion of macro 'min'
order = min(MAX_ORDER - 1UL, __ffs(start));
^
The rest of the worlds seems to define __ffs as returning unsigned long,
so lets do that.
Signed-off-by: Anton Blanchard <anton@samba.org>
Tested-by: Emil Medve <Emilian.Medve@Freescale.com>
---
arch/powerpc/include/asm/bitops.h | 2 +-
arch/powerpc/sysdev/fsl_pci.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index bd3bd57..c633f05 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -213,7 +213,7 @@ static __inline__ unsigned long ffz(unsigned long x)
return __ilog2(x & -x);
}
-static __inline__ int __ffs(unsigned long x)
+static __inline__ unsigned long __ffs(unsigned long x)
{
return __ilog2(x & -x);
}
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index c507767..dae96fb 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -152,7 +152,7 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
flags |= 0x10000000; /* enable relaxed ordering */
for (i = 0; size > 0; i++) {
- unsigned int bits = min(ilog2(size),
+ unsigned int bits = min_t(u32, ilog2(size),
__ffs(pci_addr | phys_addr));
if (index + i >= 5)
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v2 0/3] PCI/MSI: Remove arch_msi_check_device()
From: Thomas Petazzoni @ 2014-09-17 15:25 UTC (permalink / raw)
To: Alexander Gordeev
Cc: Lior Amsalem, Jason Cooper, linux-pci, linux-kernel, Nadav Haklai,
Ezequiel Garcia, Gregory Clément, Thomas Gleixner,
linuxppc-dev
In-Reply-To: <cover.1410078503.git.agordeev@redhat.com>
Dear Alexander Gordeev,
On Sun, 7 Sep 2014 20:57:52 +0200, Alexander Gordeev wrote:
> Alexander Gordeev (3):
> patch 1 - PCI/MSI/PPC: Remove arch_msi_check_device()
> patch 2 - PCI/MSI/Armada-370-xp: Remove arch_msi_check_device()
> patch 3 - PCI/MSI: Remove arch_msi_check_device()
For the entire series:
Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
I tested on the Armada XP GP platform, which is particularly affected
by PATCH 2/3, as it is using the irq-armada-370-xp irqchip driver. I
tested with an igb PCIe NIC that supports MSI and MSI-X, and I verified
that MSI-X is still rejected (since we don't support it on Armada XP,
at least for now), and that MSI is accepted and actually works.
Thanks for doing this, and sorry for the delay in getting the patches
tested!
Best regards,
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply
* Re: [RFC PATCH] dt:numa: adding numa node mapping for memory nodes.
From: Kumar Gala @ 2014-09-17 15:37 UTC (permalink / raw)
To: Ganapatrao Kulkarni
Cc: Mark Rutland, open list:OPEN FIRMWARE AND..., Pawel Moll,
Ian Campbell, Rob Herring, linuxppc-dev, linux-arm-kernel,
gpkulkarni
In-Reply-To: <1410944189-3608-1-git-send-email-ganapatrao.kulkarni@caviumnetworks.com>
On Sep 17, 2014, at 1:56 AM, Ganapatrao Kulkarni =
<ganapatrao.kulkarni@caviumnetworks.com> wrote:
> From: Ganapatrao Kulkarni <ganapatrao.kulkarni@cavium.com>
>=20
> This patch adds property "nid" to memory node to provide the memory =
range to
> numa node id mapping.
>=20
> Signed-off-by: Ganapatrao Kulkarni <ganapatrao.kulkarni@cavium.com>
>=20
> =97
Adding the PPC guys as they=92ve been doing NUMA on IBM Power Servers =
for years with OF/DT. So we should really try and follow what they=92ve =
done.
> Documentation/devicetree/bindings/numa.txt | 58 =
++++++++++++++++++++++++++++++
> 1 file changed, 58 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/numa.txt
>=20
> diff --git a/Documentation/devicetree/bindings/numa.txt =
b/Documentation/devicetree/bindings/numa.txt
> new file mode 100644
> index 0000000..c4a94f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/numa.txt
> @@ -0,0 +1,58 @@
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
> +numa id binding description
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
> +
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
> +1 - Introduction
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
> +The device node property "nid(numa node id)" can be added to memory
> +device node to map the range of memory addresses as defined in =
property "reg".
> +The property "nid" maps the memory range to the numa node id, which =
is used to
> +find the local and remory pages on numa aware systems.
> +
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
> +2 - nid property
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
> +Numa node id, "nid" is required property of memory device node for=20
> +numa enabled platforms.
> +
> +|------------------------------------------------------|
> +|Property Type | Usage | Value Type | Definition |
> +|------------------------------------------------------|
> +| nid | R | <u32> | Numa Node id |
> +| | | | for this memory |
> +|------------------------------------------------------|
> +
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D
> +4 - Example memory nodes with numa node id mapping
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D
> +
> +Example 1 (2 memory nodes, each mapped to a numa node.):
> +
> + memory@00000000 {
> + device_type =3D "memory";
> + reg =3D <0x0 0x00000000 0x0 0x80000000>;
> + nid =3D <0x0>;
> + };
> +
> + memory@10000000000 {
> + device_type =3D "memory";
> + reg =3D <0x100 0x00000000 0x0 0x80000000>;
> + nid =3D <0x1>;
> + };
> +
> +Example 2 (multiple memory ranges in each memory node and mapped to =
numa node):
> +
> + memory@00000000 {
> + device_type =3D "memory";
> + reg =3D <0x0 0x00000000 0x0 0x80000000>,
> + <0x0 0x80000000 0x0 0x80000000>;
> + nid =3D <0x0>;
> + };
> +
> + memory@10000000000 {
> + device_type =3D "memory";
> + reg =3D <0x100 0x00000000 0x0 0x80000000>,
> + <0x100 0x80000000 0x0 0x80000000>;
> + nid =3D <0x1>;
> + };
> --=20
> 1.8.1.4
>=20
--=20
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, =
hosted by The Linux Foundation
^ permalink raw reply
* [PATCH v3 01/21] powerpc/8xx: Declare SPRG2 as a SCRATCH register
From: Christophe Leroy @ 2014-09-17 16:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras
Cc: scottwood, linuxppc-dev, linux-kernel
Since coming 469d62be9263b92f2c3329540cbb1c076111f4f3, SPRG2 is used as a
scratch register just like SPRG0 and SPRG1. So Declare it as such and fix
the comment which is not valid anymore since that commit.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
Changes in v2:
- None
Changes in v3:
- None
arch/powerpc/include/asm/reg.h | 3 ++-
arch/powerpc/kernel/head_8xx.S | 10 +++++-----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index cb9c174..b6a7d62 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -888,7 +888,7 @@
* 32-bit 8xx:
* - SPRG0 scratch for exception vectors
* - SPRG1 scratch for exception vectors
- * - SPRG2 apparently unused but initialized
+ * - SPRG2 scratch for exception vectors
*
*/
#ifdef CONFIG_PPC64
@@ -994,6 +994,7 @@
#ifdef CONFIG_8xx
#define SPRN_SPRG_SCRATCH0 SPRN_SPRG0
#define SPRN_SPRG_SCRATCH1 SPRN_SPRG1
+#define SPRN_SPRG_SCRATCH2 SPRN_SPRG2
#endif
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 55d12fb..1329c5a 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -301,7 +301,7 @@ InstructionTLBMiss:
stw r11, 4(r0)
#else
mtspr SPRN_DAR, r10
- mtspr SPRN_SPRG2, r11
+ mtspr SPRN_SPRG_SCRATCH2, r11
#endif
mfspr r10, SPRN_SRR0 /* Get effective address of fault */
#ifdef CONFIG_8xx_CPU15
@@ -363,7 +363,7 @@ InstructionTLBMiss:
mfspr r10, SPRN_DAR
mtcr r10
mtspr SPRN_DAR, r11 /* Tag DAR */
- mfspr r11, SPRN_SPRG2
+ mfspr r11, SPRN_SPRG_SCRATCH2
#else
lwz r11, 0(r0)
mtcr r11
@@ -386,7 +386,7 @@ InstructionTLBMiss:
mtcr r10
li r11, 0x00f0
mtspr SPRN_DAR, r11 /* Tag DAR */
- mfspr r11, SPRN_SPRG2
+ mfspr r11, SPRN_SPRG_SCRATCH2
#else
lwz r11, 0(r0)
mtcr r11
@@ -409,7 +409,7 @@ DataStoreTLBMiss:
stw r11, 4(r0)
#else
mtspr SPRN_DAR, r10
- mtspr SPRN_SPRG2, r11
+ mtspr SPRN_SPRG_SCRATCH2, r11
#endif
mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
@@ -487,7 +487,7 @@ DataStoreTLBMiss:
mfspr r10, SPRN_DAR
mtcr r10
mtspr SPRN_DAR, r11 /* Tag DAR */
- mfspr r11, SPRN_SPRG2
+ mfspr r11, SPRN_SPRG_SCRATCH2
#else
mtspr SPRN_DAR, r11 /* Tag DAR */
lwz r11, 0(r0)
--
1.7.1
^ permalink raw reply related
* [PATCH v3 03/21] powerpc/8xx: exception InstructionAccess does not exist on MPC8xx
From: Christophe Leroy @ 2014-09-17 16:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras
Cc: scottwood, linuxppc-dev, linux-kernel
Exception InstructionAccess does not exist on MPC8xx. No need to branch there from somewhere else.
Handling can be done directly in InstructionTLBError Exception.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
Changes in v2:
- None
Changes in v3:
- arch/powerpc/mm/fault.c uses the vector number, so make sure it understand
the new ones.
arch/powerpc/kernel/head_8xx.S | 17 +++++++----------
arch/powerpc/mm/fault.c | 1 +
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 3af6db1..fbe5d10 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -234,15 +234,9 @@ DataAccess:
EXC_XFER_LITE(0x300, handle_page_fault)
/* Instruction access exception.
- * This is "never generated" by the MPC8xx. We jump to it for other
- * translation errors.
+ * This is "never generated" by the MPC8xx.
*/
- . = 0x400
-InstructionAccess:
- EXCEPTION_PROLOG
- mr r4,r12
- mr r5,r9
- EXC_XFER_LITE(0x400, handle_page_fault)
+ EXCEPTION(0x400, InstructionAccess, unknown_exception, EXC_XFER_STD)
/* External interrupt */
EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
@@ -382,7 +376,7 @@ InstructionTLBMiss:
#endif
mfspr r10, SPRN_SPRG_SCRATCH2
EXCEPTION_EPILOG_0
- b InstructionAccess
+ b InstructionTLBError
. = 0x1200
DataStoreTLBMiss:
@@ -477,7 +471,10 @@ DataStoreTLBMiss:
*/
. = 0x1300
InstructionTLBError:
- b InstructionAccess
+ EXCEPTION_PROLOG
+ mr r4,r12
+ mr r5,r9
+ EXC_XFER_LITE(0x1300, handle_page_fault)
/* This is the data TLB error on the MPC8xx. This could be due to
* many reasons, including a dirty update to a pte. We can catch that
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 51ab9e7..4d63c96 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -526,6 +526,7 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
break;
case 0x400:
case 0x480:
+ case 0x1300:
printk(KERN_ALERT "Unable to handle kernel paging request for "
"instruction fetch\n");
break;
--
2.1.0
^ permalink raw reply related
* [PATCH v3 02/21] powerpc/8xx: Use SCRATCH0 and SCRATCH1 also for TLB handlers
From: Christophe Leroy @ 2014-09-17 16:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras
Cc: scottwood, linuxppc-dev, linux-kernel
SCRATCH0 and SCRATCH1 are only used in Exceptions prologs where no other
exception can happen. There is therefore no need to preserve them accross
TLB handlers, we can use them there as in other exceptions. One of the
advantages is that they do not suffer CPU6 errata unlike M_TW register.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
Changes in v2:
- None
Changes in v3:
- None
arch/powerpc/kernel/head_8xx.S | 104 ++++++++++++----------------------
1 files changed, 36 insertions(+), 68 deletions(-)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 1329c5a..3af6db1 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -104,12 +104,15 @@ turn_on_mmu:
* task's thread_struct.
*/
#define EXCEPTION_PROLOG \
- mtspr SPRN_SPRG_SCRATCH0,r10; \
- mtspr SPRN_SPRG_SCRATCH1,r11; \
- mfcr r10; \
+ EXCEPTION_PROLOG_0; \
EXCEPTION_PROLOG_1; \
EXCEPTION_PROLOG_2
+#define EXCEPTION_PROLOG_0 \
+ mtspr SPRN_SPRG_SCRATCH0,r10; \
+ mtspr SPRN_SPRG_SCRATCH1,r11; \
+ mfcr r10
+
#define EXCEPTION_PROLOG_1 \
mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
andi. r11,r11,MSR_PR; \
@@ -145,6 +148,14 @@ turn_on_mmu:
SAVE_2GPRS(7, r11)
/*
+ * Exception exit code.
+ */
+#define EXCEPTION_EPILOG_0 \
+ mtcr r10; \
+ mfspr r10,SPRN_SPRG_SCRATCH0; \
+ mfspr r11,SPRN_SPRG_SCRATCH1
+
+/*
* Note: code which follows this uses cr0.eq (set if from kernel),
* r11, r12 (SRR0), and r9 (SRR1).
*
@@ -293,16 +304,8 @@ InstructionTLBMiss:
#ifdef CONFIG_8xx_CPU6
stw r3, 8(r0)
#endif
- DO_8xx_CPU6(0x3f80, r3)
- mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
- mfcr r10
-#ifdef CONFIG_8xx_CPU6
- stw r10, 0(r0)
- stw r11, 4(r0)
-#else
- mtspr SPRN_DAR, r10
- mtspr SPRN_SPRG_SCRATCH2, r11
-#endif
+ EXCEPTION_PROLOG_0
+ mtspr SPRN_SPRG_SCRATCH2, r10
mfspr r10, SPRN_SRR0 /* Get effective address of fault */
#ifdef CONFIG_8xx_CPU15
addi r11, r10, 0x1000
@@ -359,18 +362,11 @@ InstructionTLBMiss:
mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
/* Restore registers */
-#ifndef CONFIG_8xx_CPU6
- mfspr r10, SPRN_DAR
- mtcr r10
- mtspr SPRN_DAR, r11 /* Tag DAR */
- mfspr r11, SPRN_SPRG_SCRATCH2
-#else
- lwz r11, 0(r0)
- mtcr r11
- lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
#endif
- mfspr r10, SPRN_M_TW
+ mfspr r10, SPRN_SPRG_SCRATCH2
+ EXCEPTION_EPILOG_0
rfi
2:
mfspr r11, SPRN_SRR1
@@ -381,19 +377,11 @@ InstructionTLBMiss:
mtspr SPRN_SRR1, r11
/* Restore registers */
-#ifndef CONFIG_8xx_CPU6
- mfspr r10, SPRN_DAR
- mtcr r10
- li r11, 0x00f0
- mtspr SPRN_DAR, r11 /* Tag DAR */
- mfspr r11, SPRN_SPRG_SCRATCH2
-#else
- lwz r11, 0(r0)
- mtcr r11
- lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
#endif
- mfspr r10, SPRN_M_TW
+ mfspr r10, SPRN_SPRG_SCRATCH2
+ EXCEPTION_EPILOG_0
b InstructionAccess
. = 0x1200
@@ -401,16 +389,8 @@ DataStoreTLBMiss:
#ifdef CONFIG_8xx_CPU6
stw r3, 8(r0)
#endif
- DO_8xx_CPU6(0x3f80, r3)
- mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
- mfcr r10
-#ifdef CONFIG_8xx_CPU6
- stw r10, 0(r0)
- stw r11, 4(r0)
-#else
- mtspr SPRN_DAR, r10
- mtspr SPRN_SPRG_SCRATCH2, r11
-#endif
+ EXCEPTION_PROLOG_0
+ mtspr SPRN_SPRG_SCRATCH2, r10
mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
/* If we are faulting a kernel address, we have to use the
@@ -483,19 +463,12 @@ DataStoreTLBMiss:
mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
/* Restore registers */
-#ifndef CONFIG_8xx_CPU6
- mfspr r10, SPRN_DAR
- mtcr r10
- mtspr SPRN_DAR, r11 /* Tag DAR */
- mfspr r11, SPRN_SPRG_SCRATCH2
-#else
- mtspr SPRN_DAR, r11 /* Tag DAR */
- lwz r11, 0(r0)
- mtcr r11
- lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
#endif
- mfspr r10, SPRN_M_TW
+ mtspr SPRN_DAR, r11 /* Tag DAR */
+ mfspr r10, SPRN_SPRG_SCRATCH2
+ EXCEPTION_EPILOG_0
rfi
/* This is an instruction TLB error on the MPC8xx. This could be due
@@ -519,23 +492,18 @@ DataTLBError:
#ifdef CONFIG_8xx_CPU6
stw r3, 8(r0)
#endif
- DO_8xx_CPU6(0x3f80, r3)
- mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
- mfcr r10
- stw r10, 0(r0)
- stw r11, 4(r0)
+ EXCEPTION_PROLOG_0
+ mtspr SPRN_SPRG_SCRATCH2, r10
mfspr r10, SPRN_DAR
cmpwi cr0, r10, 0x00f0
beq- FixupDAR /* must be a buggy dcbX, icbi insn. */
DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */
- mfspr r10, SPRN_M_TW /* Restore registers */
- lwz r11, 0(r0)
- mtcr r11
- lwz r11, 4(r0)
#ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
#endif
+ mfspr r10,SPRN_SPRG_SCRATCH2
+ EXCEPTION_EPILOG_0
b DataAccess
EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
@@ -619,8 +587,8 @@ FixupDAR:/* Entry point for dcbx workaround. */
stw r11,0(r10) /* store add/and instruction */
dcbf 0,r10 /* flush new instr. to memory. */
icbi 0,r10 /* invalidate instr. cache line */
- lwz r11, 4(r0) /* restore r11 from memory */
- mfspr r10, SPRN_M_TW /* restore r10 from M_TW */
+ mfspr r11, SPRN_SPRG_SCRATCH1 /* restore r11 */
+ mfspr r10, SPRN_SPRG_SCRATCH0 /* restore r10 */
isync /* Wait until new instr is loaded from memory */
modified_instr:
.space 4 /* this is where the add instr. is stored */
@@ -683,9 +651,9 @@ modified_instr:
b DARFixed /* Go back to normal TLB handling */
/* special handling for r10,r11 since these are modified already */
-153: lwz r11, 4(r0) /* load r11 from memory */
+153: mfspr r11, SPRN_SPRG_SCRATCH1 /* load r11 from SPRN_SPRG_SCRATCH1 */
b 155f
-154: mfspr r11, SPRN_M_TW /* load r10 from M_TW */
+154: mfspr r11, SPRN_SPRG_SCRATCH0 /* load r10 from SPRN_SPRG_SCRATCH0 */
155: add r10, r10, r11 /* add it */
mfctr r11 /* restore r11 */
b 151b
--
1.7.1
^ permalink raw reply related
* [PATCH v3 04/21] powerpc/8xx: Remove loading of r10 at end of FixupDAR
From: Christophe Leroy @ 2014-09-17 16:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras
Cc: scottwood, linuxppc-dev, linux-kernel
Since commit 2321f33790a6c5b80322d907a92d5739e7521a13, r10 is not used anymore
after FixupDAR. There is therefore no need to set it up with the value of DAR.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
Changes in v2:
- None
Changes in v3:
- None
arch/powerpc/kernel/head_8xx.S | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index fbe5d10..e59e39e 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -495,7 +495,7 @@ DataTLBError:
mfspr r10, SPRN_DAR
cmpwi cr0, r10, 0x00f0
beq- FixupDAR /* must be a buggy dcbX, icbi insn. */
-DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */
+DARFixed:/* Return from dcbx instruction bug workaround */
#ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
#endif
@@ -524,7 +524,7 @@ DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR
/* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
* by decoding the registers used by the dcbx instruction and adding them.
- * DAR is set to the calculated address and r10 also holds the EA on exit.
+ * DAR is set to the calculated address.
*/
/* define if you don't want to use self modifying code */
#define NO_SELF_MODIFYING_CODE
@@ -564,8 +564,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
beq+ 142f
cmpwi cr0, r10, 1964 /* Is icbi? */
beq+ 142f
-141: mfspr r10, SPRN_DAR /* r10 must hold DAR at exit */
- b DARFixed /* Nope, go back to normal TLB processing */
+141: b DARFixed /* Nope, go back to normal TLB processing */
144: mfspr r10, SPRN_DSISR
rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */
--
1.7.1
^ permalink raw reply related
* [PATCH v3 00/21] powerpc/8xx: Optimise MMU TLB handling and add support of 16k pages
From: Christophe Leroy @ 2014-09-17 16:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras
Cc: scottwood, linuxppc-dev, linux-kernel
This patchset:
1) provides several MMU TLB handling optimisation on MPC8xx.
2) adds support of 16k pages on MPC8xx.
All changes have been successfully tested on a custom board equipped with MPC885
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Tested-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
Changes in v2:
- Patch number 10 removed, it was implementing a 16 bit alignment of the PGDIR.
It is not worth potentially wasting up to 64k of memory just for removing one
instruction (ori).
- Preserve r11 while calculating the level 2 address, therefore no more need to
save r11 into CR.
Changes in v3:
- Few fixes following review from Joachim Tjernlund
- Removed the major hack which was saving resisters in memory for CPU6 errata
- Invalidating non present TLB entries earlier (in head_8xx instead of fault.c)
arch/powerpc/Kconfig | 2 +-
arch/powerpc/include/asm/mmu-8xx.h | 2 +
arch/powerpc/include/asm/pgtable-ppc32.h | 20 ++
arch/powerpc/include/asm/pte-8xx.h | 7 +-
arch/powerpc/include/asm/reg.h | 3 +-
arch/powerpc/kernel/head_8xx.S | 370 ++++++++++++-------------
arch/powerpc/mm/fault.c | 9 +-
7 files changed, 203 insertions(+), 210 deletions(-)
^ permalink raw reply
* [PATCH v3 05/21] powerpc/8xx: Fix comment about DIRTY update
From: Christophe Leroy @ 2014-09-17 16:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras
Cc: scottwood, linuxppc-dev, linux-kernel
Since commit 2321f33790a6c5b80322d907a92d5739e7521a13, dirty handling is not
handled here anymore. So we fix the comment.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
Changes in v2:
- None
Changes in v3:
- None
arch/powerpc/kernel/head_8xx.S | 8 ++------
1 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index e59e39e..171c6ef 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -477,12 +477,8 @@ InstructionTLBError:
EXC_XFER_LITE(0x1300, handle_page_fault)
/* This is the data TLB error on the MPC8xx. This could be due to
- * many reasons, including a dirty update to a pte. We can catch that
- * one here, but anything else is an error. First, we track down the
- * Linux pte. If it is valid, write access is allowed, but the
- * page dirty bit is not set, we will set it and reload the TLB. For
- * any other case, we bail out to a higher level function that can
- * handle it.
+ * many reasons, including a dirty update to a pte. We bail out to
+ * a higher level function that can handle it.
*/
. = 0x1400
DataTLBError:
--
1.7.1
^ permalink raw reply related
* [PATCH v3 09/21] powerpc/8xx: Optimize verification in FixupDAR
From: Christophe Leroy @ 2014-09-17 16:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras
Cc: scottwood, linuxppc-dev, linux-kernel
By XORing the upper part of the instruction code, we get a value that can
directly be verified with the second test and we can remove the first test.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
Changes in v2:
- None
Changes in v3:
- None
arch/powerpc/kernel/head_8xx.S | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index e5a250c..5037420 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -542,10 +542,8 @@ FixupDAR:/* Entry point for dcbx workaround. */
/* Check if it really is a dcbx instruction. */
/* dcbt and dcbtst does not generate DTLB Misses/Errors,
* no need to include them here */
- srwi r10, r11, 26 /* check if major OP code is 31 */
- cmpwi cr0, r10, 31
- bne- 141f
- rlwinm r10, r11, 0, 21, 30
+ xoris r10, r11, 0x7c00 /* check if major OP code is 31 */
+ rlwinm r10, r10, 0, 21, 5
cmpwi cr0, r10, 2028 /* Is dcbz? */
beq+ 142f
cmpwi cr0, r10, 940 /* Is dcbi? */
--
1.7.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox