* Re: [PATCH] powerpc: add new required termio functions
From: Geoff Levand @ 2007-09-12 2:19 UTC (permalink / raw)
To: Michael Neuling
Cc: linux-kernel, linuxppc-dev, paulus, Alan Cox, akpm,
Linus Torvalds, David S. Miller
In-Reply-To: <8018.1189562679@neuling.org>
Michael Neuling wrote:
> The "tty: termios locking functions break with new termios type" patch
> (f629307c857c030d5a3dd777fee37c8bb395e171) breaks the powerpc compile.
> This adds the required API to asm-powerpc.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> --
> This needs to go up for 2.6.23.
>
> Should we really put these definitions in asm-generic/termios.h as I'm
> guessing other architectures are broken too?
I think it would be better to do so, as that is where we pickup the defs for
the original kernel_termios_to_user_termios and user_termios_to_kernel_termios.
-Geoff
^ permalink raw reply
* Re: [PATCH] powerpc: add new required termio functions
From: Linus Torvalds @ 2007-09-12 2:17 UTC (permalink / raw)
To: Michael Neuling
Cc: linux-kernel, linuxppc-dev, paulus, Alan Cox, akpm,
David S. Miller
In-Reply-To: <8018.1189562679@neuling.org>
On Wed, 12 Sep 2007, Michael Neuling wrote:
>
> The "tty: termios locking functions break with new termios type" patch
> (f629307c857c030d5a3dd777fee37c8bb395e171) breaks the powerpc compile.
Really?
It shouldn't. The use of kernel_termios_to_user_termios_1() is conditional
on the architecture having a define for TCGETS2, and I think they match
up. I see:
[torvalds@woody linux]$ git grep -l kernel_termios_to_user_termios_1 include | wc -l
10
[torvalds@woody linux]$ git grep -l TCGETS2 include | wc -l
10
and in neither case is ppc in that list of architecures.
So maybe you just read the patch without actually testing whether it
actually broke powerpc?
Or is something subtler going on?
Linus
^ permalink raw reply
* Re: SYSFS: need a noncaching read
From: David Gibson @ 2007-09-12 2:05 UTC (permalink / raw)
To: Heiko Schocher; +Cc: linuxppc-dev, linux-kernel, Detlev Zundel
In-Reply-To: <1189503798.6674.46.camel@Zeus.EmbLux>
On Tue, Sep 11, 2007 at 11:43:17AM +0200, Heiko Schocher wrote:
> Hello,
>
> I have developed a device driver and use the sysFS to export some
> registers to userspace. I opened the sysFS File for one register and did
> some reads from this File, but I alwas becoming the same value from the
> register, whats not OK, because they are changing. So I found out that
> the sysFS caches the reads ... :-(
>
> Is there a way to retrigger the reads (in that way, that the sysFS
> rereads the values from the driver), without closing and opening the
> sysFS Files? Or must I better use the ioctl () Driver-interface for
> exporting these registers?
>
> I am asking this, because I must read every 10 ms 2 registers, so
> doing a open/read/close for reading one registers is a little bit too
> much overhead.
>
> I made a sysFS seek function, which retriggers the read, and that works
> fine, but I have again 2 syscalls, whats also is not optimal.
>
> Or can we make a open () with a (new?)Flag, that informs the sysFS to
> always reread the values from the underlying driver?
>
> Or a new flag in the "struct attribute_group" in include/linux/sysfs.h,
> which let the sysfs rereading the values?
This sounds more like sysfs is really not the right interface for
polling your registers. You would probably be better off having your
driver export a character device from which the register values could
be read.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* [PATCH] powerpc: add new required termio functions
From: Michael Neuling @ 2007-09-12 2:04 UTC (permalink / raw)
To: Linus Torvalds, akpm, paulus, Alan Cox, David S. Miller
Cc: linuxppc-dev, linux-kernel
The "tty: termios locking functions break with new termios type" patch
(f629307c857c030d5a3dd777fee37c8bb395e171) breaks the powerpc compile.
This adds the required API to asm-powerpc.
Signed-off-by: Michael Neuling <mikey@neuling.org>
--
This needs to go up for 2.6.23.
Should we really put these definitions in asm-generic/termios.h as I'm
guessing other architectures are broken too?
coopers@include/ % git grep kernel_termios_to_user_termios_1
asm-arm/termios.h:#define kernel_termios_to_user_termios_1(u, k)
asm-cris/termios.h:#define kernel_termios_to_user_termios_1(u, k)
asm-h8300/termios.h:#define kernel_termios_to_user_termios_1(u, k)
asm-i386/termios.h:#define kernel_termios_to_user_termios_1(u, k)
asm-ia64/termios.h:#define kernel_termios_to_user_termios_1(u, k)
asm-m32r/termios.h:#define kernel_termios_to_user_termios_1(u, k)
asm-m68k/termios.h:#define kernel_termios_to_user_termios_1(u, k)
asm-mips/termios.h:#define kernel_termios_to_user_termios_1(u, k)
asm-v850/termios.h:#define kernel_termios_to_user_termios_1(u, k)
asm-x86_64/termios.h:#define kernel_termios_to_user_termios_1(u, k)
include/asm-powerpc/termios.h | 3 +++
1 file changed, 3 insertions(+)
Index: linux-2.6-ozlabs/include/asm-powerpc/termios.h
===================================================================
--- linux-2.6-ozlabs.orig/include/asm-powerpc/termios.h
+++ linux-2.6-ozlabs/include/asm-powerpc/termios.h
@@ -80,6 +80,9 @@ struct termio {
#include <asm-generic/termios.h>
+#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_TERMIOS_H */
^ permalink raw reply
* Re: FDT for Microblaze and PPC405
From: David Gibson @ 2007-09-12 2:03 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, Michal Simek
In-Reply-To: <fa686aa40709111009j64925edag511078d88ff904c@mail.gmail.com>
On Tue, Sep 11, 2007 at 11:09:07AM -0600, Grant Likely wrote:
> On 9/11/07, Michal Simek <Monstr@seznam.cz> wrote:
> > For example emaclite driver needs information about turning on/off ping pong buffer...
> >
> > I would like to make this properly.
>
> FDT design is just as much art as it is science. It takes taste and
> judgement to desgin a nice set of bindings. Your best option is to
> draft something and post it to the linuxppc-embedded mailing list for
> review.
Yes, this is the preferred procedure, for now.
> > And second question is on early console logs and timers setting. I read about aliases in FDT. I think that aliases can cover this setting.
> > For example my design contain 4 serial line and I would like to know which serial line is set on early console.
>
> You use the chosen node for this. In the chosen node, you add a
> property called "linux,stdout-path" which holds the path to your
> console. You can look at examples under arch/powerpc/boot/dts/*
Yes. Currently we don't use /aliases in the flat device tree. This
is possibly a mistake, and something I'm thinking about changing.
But, for now, linux,stdout-path in /chosen is the way to do this.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* [PATCH 07/10] x86: acpi-use-cpu_physical_id (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
This is from an earlier message from Christoph Lameter:
processor_core.c currently tries to determine the apicid by special casing
for IA64 and x86. The desired information is readily available via
cpu_physical_id()
on IA64, i386 and x86_64.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Additionally, boot_cpu_id needed to be exported to fix compile errors in
dma code when !CONFIG_SMP.
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/x86_64/kernel/mpparse.c | 2 ++
drivers/acpi/processor_core.c | 8 +-------
2 files changed, 3 insertions(+), 7 deletions(-)
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -419,12 +419,6 @@
return 0;
}
-#ifdef CONFIG_IA64
-#define arch_cpu_to_apicid ia64_cpu_to_sapicid
-#else
-#define arch_cpu_to_apicid x86_cpu_to_apicid
-#endif
-
static int map_madt_entry(u32 acpi_id)
{
unsigned long madt_end, entry;
@@ -498,7 +492,7 @@
return apic_id;
for (i = 0; i < NR_CPUS; ++i) {
- if (arch_cpu_to_apicid[i] == apic_id)
+ if (cpu_physical_id(i) == apic_id)
return i;
}
return -1;
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -57,6 +57,8 @@
/* Processor that is doing the boot up */
unsigned int boot_cpu_id = -1U;
+EXPORT_SYMBOL(boot_cpu_id);
+
/* Internal processor count */
unsigned int num_processors __cpuinitdata = 0;
--
^ permalink raw reply
* [PATCH 09/10] ppc64: Convert cpu_sibling_map to a per_cpu data array (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
Convert cpu_sibling_map to a per_cpu cpumask_t array for the ppc64
architecture. This fixes build errors in block/blktrace.c and
kernel/sched.c when CONFIG_SCHED_SMT is defined.
Note: these changes have not been built nor tested.
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/powerpc/kernel/setup-common.c | 4 ++--
arch/powerpc/kernel/smp.c | 4 ++--
arch/powerpc/platforms/cell/cbe_cpufreq.c | 2 +-
include/asm-powerpc/smp.h | 4 +++-
include/asm-powerpc/topology.h | 2 +-
5 files changed, 9 insertions(+), 7 deletions(-)
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -415,9 +415,9 @@
* Do the sibling map; assume only two threads per processor.
*/
for_each_possible_cpu(cpu) {
- cpu_set(cpu, cpu_sibling_map[cpu]);
+ cpu_set(cpu, cpu_sibling_map(cpu));
if (cpu_has_feature(CPU_FTR_SMT))
- cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
+ cpu_set(cpu ^ 0x1, cpu_sibling_map(cpu));
}
vdso_data->processorCount = num_present_cpus();
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -61,11 +61,11 @@
cpumask_t cpu_possible_map = CPU_MASK_NONE;
cpumask_t cpu_online_map = CPU_MASK_NONE;
-cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
+DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
-EXPORT_SYMBOL(cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
/* SMP operations for this machine */
struct smp_ops_t *smp_ops;
--- a/arch/powerpc/platforms/cell/cbe_cpufreq.c
+++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c
@@ -119,7 +119,7 @@
policy->cur = cbe_freqs[cur_pmode].frequency;
#ifdef CONFIG_SMP
- policy->cpus = cpu_sibling_map[policy->cpu];
+ policy->cpus = cpu_sibling_map(policy->cpu);
#endif
cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
--- a/include/asm-powerpc/smp.h
+++ b/include/asm-powerpc/smp.h
@@ -25,6 +25,7 @@
#ifdef CONFIG_PPC64
#include <asm/paca.h>
+#include <asm/percpu.h>
#endif
extern int boot_cpuid;
@@ -58,7 +59,8 @@
(smp_hw_index[(cpu)] = (phys))
#endif
-extern cpumask_t cpu_sibling_map[NR_CPUS];
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
+#define cpu_sibling_map(cpu) per_cpu(cpu_sibling_map, cpu)
/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
*
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -108,7 +108,7 @@
#ifdef CONFIG_PPC64
#include <asm/smp.h>
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define topology_thread_siblings(cpu) (cpu_sibling_map(cpu))
#endif
#endif
--
^ permalink raw reply
* [PATCH 05/10] x86: Convert x86_cpu_to_apicid to be a per cpu variable (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
This patch converts the x86_cpu_to_apicid array to be a per
cpu variable. This saves sizeof(apicid) * NR unused cpus.
Access is mostly from startup and CPU HOTPLUG functions.
MP_processor_info() is one of the functions that require access
to the x86_cpu_to_apicid array before the per_cpu data area is
setup. For this case, a pointer to the __initdata array is
initialized in setup_arch() and removed in smp_prepare_cpus()
after the per_cpu data area is initialized.
A second change is included to change the initial array value
of ARCH i386 from 0xff to BAD_APICID to be consistent with
ARCH x86_64.
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/i386/kernel/acpi/boot.c | 2 +-
arch/i386/kernel/smp.c | 2 +-
arch/i386/kernel/smpboot.c | 22 +++++++++++++++-------
arch/x86_64/kernel/genapic.c | 15 ++++++++++++---
arch/x86_64/kernel/genapic_flat.c | 2 +-
arch/x86_64/kernel/mpparse.c | 15 +++++++++++++--
arch/x86_64/kernel/setup.c | 5 +++++
arch/x86_64/kernel/smpboot.c | 23 ++++++++++++++++++++++-
arch/x86_64/mm/numa.c | 2 +-
include/asm-i386/smp.h | 6 ++++--
include/asm-x86_64/ipi.h | 2 +-
include/asm-x86_64/smp.h | 6 ++++--
12 files changed, 80 insertions(+), 22 deletions(-)
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -555,7 +555,7 @@
int acpi_unmap_lsapic(int cpu)
{
- x86_cpu_to_apicid[cpu] = -1;
+ per_cpu(x86_cpu_to_apicid, cpu) = -1;
cpu_clear(cpu, cpu_present_map);
num_processors--;
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -673,7 +673,7 @@
int i;
for (i = 0; i < NR_CPUS; i++) {
- if (x86_cpu_to_apicid[i] == apic_id)
+ if (per_cpu(x86_cpu_to_apicid, i) == apic_id)
return i;
}
return -1;
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -92,9 +92,17 @@
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
EXPORT_SYMBOL(cpu_data);
-u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
- { [0 ... NR_CPUS-1] = 0xff };
-EXPORT_SYMBOL(x86_cpu_to_apicid);
+/*
+ * The following static array is used during kernel startup
+ * and the x86_cpu_to_apicid_ptr contains the address of the
+ * array during this time. Is it zeroed when the per_cpu
+ * data area is removed.
+ */
+u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata =
+ { [0 ... NR_CPUS-1] = BAD_APICID };
+void *x86_cpu_to_apicid_ptr;
+DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
+EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
u8 apicid_2_node[MAX_APICID];
@@ -804,7 +812,7 @@
irq_ctx_init(cpu);
- x86_cpu_to_apicid[cpu] = apicid;
+ per_cpu(x86_cpu_to_apicid, cpu) = apicid;
/*
* This grunge runs the startup process for
* the targeted processor.
@@ -866,7 +874,7 @@
cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
cpucount--;
} else {
- x86_cpu_to_apicid[cpu] = apicid;
+ per_cpu(x86_cpu_to_apicid, cpu) = apicid;
cpu_set(cpu, cpu_present_map);
}
@@ -915,7 +923,7 @@
struct warm_boot_cpu_info info;
int apicid, ret;
- apicid = x86_cpu_to_apicid[cpu];
+ apicid = per_cpu(x86_cpu_to_apicid, cpu);
if (apicid == BAD_APICID) {
ret = -ENODEV;
goto exit;
@@ -965,7 +973,7 @@
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
boot_cpu_logical_apicid = logical_smp_processor_id();
- x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
+ per_cpu(x86_cpu_to_apicid, 0) = boot_cpu_physical_apicid;
current_thread_info()->cpu = 0;
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -86,7 +86,7 @@
return sum & 0xFF;
}
-static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
+static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
{
int cpu;
cpumask_t tmp_map;
@@ -123,7 +123,18 @@
cpu = 0;
}
bios_cpu_apicid[cpu] = m->mpc_apicid;
- x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+ /*
+ * We get called early in the the start_kernel initialization
+ * process when the per_cpu data area is not yet setup, so we
+ * use a static array that is removed after the per_cpu data
+ * area is created.
+ */
+ if (x86_cpu_to_apicid_ptr) {
+ u8 *x86_cpu_to_apicid = (u8 *)x86_cpu_to_apicid_ptr;
+ x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+ } else {
+ per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
+ }
cpu_set(cpu, cpu_possible_map);
cpu_set(cpu, cpu_present_map);
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -701,7 +701,7 @@
clear_node_cpumask(cpu); /* was set by numa_add_cpu */
cpu_clear(cpu, cpu_present_map);
cpu_clear(cpu, cpu_possible_map);
- x86_cpu_to_apicid[cpu] = BAD_APICID;
+ per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
return -EIO;
}
@@ -848,6 +848,26 @@
}
/*
+ * Copy apicid's found by MP_processor_info from initial array to the per cpu
+ * data area. The x86_cpu_to_apicid_init array is then expendable and the
+ * x86_cpu_to_apicid_ptr is zeroed indicating that the static array is no
+ * longer available.
+ */
+void __init smp_set_apicids(void)
+{
+ int cpu;
+
+ for_each_cpu_mask(cpu, cpu_possible_map) {
+ if (per_cpu_offset(cpu))
+ per_cpu(x86_cpu_to_apicid, cpu) =
+ x86_cpu_to_apicid_init[cpu];
+ }
+
+ /* indicate the static array will be going away soon */
+ x86_cpu_to_apicid_ptr = NULL;
+}
+
+/*
* Prepare for SMP bootup. The MP table or ACPI has been read
* earlier. Just do some sanity checking here and enable APIC mode.
*/
@@ -856,6 +876,7 @@
nmi_watchdog_default();
current_cpu_data = boot_cpu_data;
current_thread_info()->cpu = 0; /* needed? */
+ smp_set_apicids();
set_cpu_sibling_map(0);
if (smp_sanity_check(max_cpus) < 0) {
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -612,7 +612,7 @@
{
int i;
for (i = 0; i < NR_CPUS; i++) {
- u8 apicid = x86_cpu_to_apicid[i];
+ u8 apicid = x86_cpu_to_apicid_init[i];
if (apicid == BAD_APICID)
continue;
if (apicid_to_node[apicid] == NUMA_NO_NODE)
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -39,9 +39,11 @@
extern void unlock_ipi_call_lock(void);
#define MAX_APICID 256
-extern u8 x86_cpu_to_apicid[];
+extern u8 __initdata x86_cpu_to_apicid_init[];
+extern void *x86_cpu_to_apicid_ptr;
+DECLARE_PER_CPU(u8, x86_cpu_to_apicid);
-#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
+#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
extern void set_cpu_sibling_map(int cpu);
--- a/include/asm-x86_64/ipi.h
+++ b/include/asm-x86_64/ipi.h
@@ -119,7 +119,7 @@
*/
local_irq_save(flags);
for_each_cpu_mask(query_cpu, mask) {
- __send_IPI_dest_field(x86_cpu_to_apicid[query_cpu],
+ __send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, query_cpu),
vector, APIC_DEST_PHYSICAL);
}
local_irq_restore(flags);
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -85,7 +85,9 @@
* Some lowlevel functions might want to know about
* the real APIC ID <-> CPU # mapping.
*/
-extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */
+extern u8 __initdata x86_cpu_to_apicid_init[];
+extern void *x86_cpu_to_apicid_ptr;
+DECLARE_PER_CPU(u8, x86_cpu_to_apicid); /* physical ID */
extern u8 bios_cpu_apicid[];
static inline int cpu_present_to_apicid(int mps_cpu)
@@ -116,7 +118,7 @@
}
#ifdef CONFIG_SMP
-#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
+#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
#else
#define cpu_physical_id(cpu) boot_cpu_id
#endif /* !CONFIG_SMP */
--- a/arch/x86_64/kernel/genapic_flat.c
+++ b/arch/x86_64/kernel/genapic_flat.c
@@ -172,7 +172,7 @@
*/
cpu = first_cpu(cpumask);
if ((unsigned)cpu < NR_CPUS)
- return x86_cpu_to_apicid[cpu];
+ return per_cpu(x86_cpu_to_apicid, cpu);
else
return BAD_APICID;
}
--- a/arch/x86_64/kernel/genapic.c
+++ b/arch/x86_64/kernel/genapic.c
@@ -24,10 +24,19 @@
#include <acpi/acpi_bus.h>
#endif
-/* which logical CPU number maps to which CPU (physical APIC ID) */
-u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly
+/*
+ * which logical CPU number maps to which CPU (physical APIC ID)
+ *
+ * The following static array is used during kernel startup
+ * and the x86_cpu_to_apicid_ptr contains the address of the
+ * array during this time. Is it zeroed when the per_cpu
+ * data area is removed.
+ */
+u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata
= { [0 ... NR_CPUS-1] = BAD_APICID };
-EXPORT_SYMBOL(x86_cpu_to_apicid);
+void *x86_cpu_to_apicid_ptr;
+DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
+EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
struct genapic __read_mostly *genapic = &apic_flat;
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -276,6 +276,11 @@
dmi_scan_machine();
+#ifdef CONFIG_SMP
+ /* setup to use the static apicid table during kernel startup */
+ x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;
+#endif
+
#ifdef CONFIG_ACPI
/*
* Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
--
^ permalink raw reply
* [PATCH 08/10] ia64: Convert cpu_sibling_map to a per_cpu data array (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
Convert cpu_sibling_map to a per_cpu cpumask_t array for the ia64
architecture. This fixes build errors in block/blktrace.c and
kernel/sched.c when CONFIG_SCHED_SMT is defined.
There was one access to cpu_sibling_map before the per_cpu data
area was created, so that step was moved to after the per_cpu
area is setup.
Tested and verified on an A4700.
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/ia64/kernel/setup.c | 4 ----
arch/ia64/kernel/smpboot.c | 18 ++++++++++--------
arch/ia64/mm/contig.c | 6 ++++++
include/asm-ia64/smp.h | 2 +-
include/asm-ia64/topology.h | 2 +-
5 files changed, 18 insertions(+), 14 deletions(-)
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -528,10 +528,6 @@
#ifdef CONFIG_SMP
cpu_physical_id(0) = hard_smp_processor_id();
-
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
-
check_for_logical_procs();
if (smp_num_cpucores > 1)
printk(KERN_INFO
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -138,7 +138,9 @@
EXPORT_SYMBOL(cpu_possible_map);
cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
-cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
+DEFINE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
+
int smp_num_siblings = 1;
int smp_num_cpucores = 1;
@@ -650,12 +652,12 @@
{
int i;
- for_each_cpu_mask(i, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[i]);
+ for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu))
+ cpu_clear(cpu, per_cpu(cpu_sibling_map, i));
for_each_cpu_mask(i, cpu_core_map[cpu])
cpu_clear(cpu, cpu_core_map[i]);
- cpu_sibling_map[cpu] = cpu_core_map[cpu] = CPU_MASK_NONE;
+ per_cpu(cpu_sibling_map, cpu) = cpu_core_map[cpu] = CPU_MASK_NONE;
}
static void
@@ -666,7 +668,7 @@
if (cpu_data(cpu)->threads_per_core == 1 &&
cpu_data(cpu)->cores_per_socket == 1) {
cpu_clear(cpu, cpu_core_map[cpu]);
- cpu_clear(cpu, cpu_sibling_map[cpu]);
+ cpu_clear(cpu, per_cpu(cpu_sibling_map, cpu));
return;
}
@@ -807,8 +809,8 @@
cpu_set(i, cpu_core_map[cpu]);
cpu_set(cpu, cpu_core_map[i]);
if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) {
- cpu_set(i, cpu_sibling_map[cpu]);
- cpu_set(cpu, cpu_sibling_map[i]);
+ cpu_set(i, per_cpu(cpu_sibling_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_sibling_map, i));
}
}
}
@@ -839,7 +841,7 @@
if (cpu_data(cpu)->threads_per_core == 1 &&
cpu_data(cpu)->cores_per_socket == 1) {
- cpu_set(cpu, cpu_sibling_map[cpu]);
+ cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, cpu_core_map[cpu]);
return 0;
}
--- a/include/asm-ia64/smp.h
+++ b/include/asm-ia64/smp.h
@@ -58,7 +58,7 @@
extern cpumask_t cpu_online_map;
extern cpumask_t cpu_core_map[NR_CPUS];
-extern cpumask_t cpu_sibling_map[NR_CPUS];
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
extern int smp_num_siblings;
extern int smp_num_cpucores;
extern void __iomem *ipi_base_addr;
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -112,7 +112,7 @@
#define topology_physical_package_id(cpu) (cpu_data(cpu)->socket_id)
#define topology_core_id(cpu) (cpu_data(cpu)->core_id)
#define topology_core_siblings(cpu) (cpu_core_map[cpu])
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#define smt_capable() (smp_num_siblings > 1)
#endif
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -212,6 +212,12 @@
cpu_data += PERCPU_PAGE_SIZE;
per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
}
+ /*
+ * cpu_sibling_map is now a per_cpu variable - it needs to
+ * be accessed after per_cpu_init() sets up the per_cpu area.
+ */
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
+ cpu_set(0, cpu_core_map[0]);
}
return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
}
--
^ permalink raw reply
* [PATCH 10/10] sparc64: Convert cpu_sibling_map to a per_cpu data array (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
Convert cpu_sibling_map to a per_cpu cpumask_t array for the sparc64
architecture. This fixes build errors in block/blktrace.c and
kernel/sched.c when CONFIG_SCHED_SMT is defined.
Note: these changes have not been built nor tested.
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/sparc64/kernel/smp.c | 17 ++++++++---------
include/asm-sparc64/smp.h | 3 ++-
include/asm-sparc64/topology.h | 2 +-
3 files changed, 11 insertions(+), 11 deletions(-)
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -52,14 +52,13 @@
cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE;
cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
-cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly =
- { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
+DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
{ [0 ... NR_CPUS-1] = CPU_MASK_NONE };
EXPORT_SYMBOL(cpu_possible_map);
EXPORT_SYMBOL(cpu_online_map);
-EXPORT_SYMBOL(cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
EXPORT_SYMBOL(cpu_core_map);
static cpumask_t smp_commenced_mask;
@@ -1259,16 +1258,16 @@
for_each_present_cpu(i) {
unsigned int j;
- cpus_clear(cpu_sibling_map[i]);
+ cpus_clear(per_cpu(cpu_sibling_map, i));
if (cpu_data(i).proc_id == -1) {
- cpu_set(i, cpu_sibling_map[i]);
+ cpu_set(i, per_cpu(cpu_sibling_map, i));
continue;
}
for_each_present_cpu(j) {
if (cpu_data(i).proc_id ==
cpu_data(j).proc_id)
- cpu_set(j, cpu_sibling_map[i]);
+ cpu_set(j, per_cpu(cpu_sibling_map, i));
}
}
}
@@ -1340,9 +1339,9 @@
cpu_clear(cpu, cpu_core_map[i]);
cpus_clear(cpu_core_map[cpu]);
- for_each_cpu_mask(i, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[i]);
- cpus_clear(cpu_sibling_map[cpu]);
+ for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu))
+ cpu_clear(cpu, per_cpu(cpu_sibling_map, i));
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
c = &cpu_data(cpu);
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -28,8 +28,9 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
+#include <asm/percpu.h>
-extern cpumask_t cpu_sibling_map[NR_CPUS];
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
extern cpumask_t cpu_core_map[NR_CPUS];
extern int sparc64_multi_core;
--- a/include/asm-sparc64/topology.h
+++ b/include/asm-sparc64/topology.h
@@ -5,7 +5,7 @@
#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).core_id)
#define topology_core_siblings(cpu) (cpu_core_map[cpu])
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#define mc_capable() (sparc64_multi_core)
#define smt_capable() (sparc64_multi_core)
#endif /* CONFIG_SMP */
--
^ permalink raw reply
* [PATCH 06/10] x86: Convert cpu_llc_id to be a per cpu variable (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
Convert cpu_llc_id from a static array sized by NR_CPUS to a
per_cpu variable. This saves sizeof(cpu_llc_id) * NR unused
cpus. Access is mostly from startup and CPU HOTPLUG functions.
Note there's an addtional change of the type of cpu_llc_id
from int to u8 for ARCH i386 to correspond with the same
type in ARCH x86_64.
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/i386/kernel/cpu/intel_cacheinfo.c | 4 ++--
arch/i386/kernel/smpboot.c | 6 +++---
arch/x86_64/kernel/smpboot.c | 6 +++---
include/asm-i386/processor.h | 6 +++++-
include/asm-x86_64/smp.h | 9 ++++-----
5 files changed, 17 insertions(+), 14 deletions(-)
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -417,14 +417,14 @@
if (new_l2) {
l2 = new_l2;
#ifdef CONFIG_X86_HT
- cpu_llc_id[cpu] = l2_id;
+ per_cpu(cpu_llc_id, cpu) = l2_id;
#endif
}
if (new_l3) {
l3 = new_l3;
#ifdef CONFIG_X86_HT
- cpu_llc_id[cpu] = l3_id;
+ per_cpu(cpu_llc_id, cpu) = l3_id;
#endif
}
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -67,7 +67,7 @@
EXPORT_SYMBOL(smp_num_siblings);
/* Last level cache ID of each logical CPU */
-int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
+DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
/* representing HT siblings of each logical CPU */
DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
@@ -348,8 +348,8 @@
}
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (cpu_llc_id[cpu] != BAD_APICID &&
- cpu_llc_id[cpu] == cpu_llc_id[i]) {
+ if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
+ per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
cpu_set(i, c[cpu].llc_shared_map);
cpu_set(cpu, c[i].llc_shared_map);
}
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -65,7 +65,7 @@
EXPORT_SYMBOL(smp_num_siblings);
/* Last level cache ID of each logical CPU */
-u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
+DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
/* Bitmask of currently online CPUs */
cpumask_t cpu_online_map __read_mostly;
@@ -285,8 +285,8 @@
}
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (cpu_llc_id[cpu] != BAD_APICID &&
- cpu_llc_id[cpu] == cpu_llc_id[i]) {
+ if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
+ per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
cpu_set(i, c[cpu].llc_shared_map);
cpu_set(cpu, c[i].llc_shared_map);
}
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -110,7 +110,11 @@
#define current_cpu_data boot_cpu_data
#endif
-extern int cpu_llc_id[NR_CPUS];
+/*
+ * the following now lives in the per cpu area:
+ * extern int cpu_llc_id[NR_CPUS];
+ */
+DECLARE_PER_CPU(u8, cpu_llc_id);
extern char ignore_fpu_irq;
void __init cpu_detect(struct cpuinfo_x86 *c);
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -39,16 +39,14 @@
extern void smp_send_reschedule(int cpu);
/*
- * cpu_sibling_map and cpu_core_map now live
- * in the per cpu area
- *
+ * the following now live in the per cpu area:
* extern cpumask_t cpu_sibling_map[NR_CPUS];
* extern cpumask_t cpu_core_map[NR_CPUS];
+ * extern u8 cpu_llc_id[NR_CPUS];
*/
DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
DECLARE_PER_CPU(cpumask_t, cpu_core_map);
-
-extern u8 cpu_llc_id[NR_CPUS];
+DECLARE_PER_CPU(u8, cpu_llc_id);
#define SMP_TRAMPOLINE_BASE 0x6000
@@ -120,6 +118,7 @@
#ifdef CONFIG_SMP
#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
#else
+extern unsigned int boot_cpu_id;
#define cpu_physical_id(cpu) boot_cpu_id
#endif /* !CONFIG_SMP */
#endif
--
^ permalink raw reply
* [PATCH 04/10] x86: Convert cpu_sibling_map to be a per cpu variable (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
Convert cpu_sibling_map from a static array sized by NR_CPUS to a
per_cpu variable. This saves sizeof(cpumask_t) * NR unused cpus.
Access is mostly from startup and CPU HOTPLUG functions.
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 2 -
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c | 2 -
arch/i386/kernel/io_apic.c | 4 +--
arch/i386/kernel/smpboot.c | 36 +++++++++++++--------------
arch/i386/oprofile/op_model_p4.c | 2 -
arch/i386/xen/smp.c | 4 +--
arch/x86_64/kernel/smpboot.c | 26 +++++++++----------
block/blktrace.c | 2 -
include/asm-i386/smp.h | 2 -
include/asm-i386/topology.h | 2 -
include/asm-x86_64/smp.h | 6 +++-
include/asm-x86_64/topology.h | 2 -
kernel/sched.c | 8 +++---
13 files changed, 50 insertions(+), 48 deletions(-)
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
@@ -200,7 +200,7 @@
unsigned int i;
#ifdef CONFIG_SMP
- policy->cpus = cpu_sibling_map[policy->cpu];
+ policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
#endif
/* Errata workaround */
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
@@ -322,7 +322,7 @@
/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
- policy->cpus = cpu_sibling_map[policy->cpu];
+ policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
#endif
cpus_allowed = current->cpus_allowed;
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -378,7 +378,7 @@
#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask)
-#define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i]))
+#define CPU_TO_PACKAGEINDEX(i) (first_cpu(per_cpu(cpu_sibling_map, i)))
static cpumask_t balance_irq_affinity[NR_IRQS] = {
[0 ... NR_IRQS-1] = CPU_MASK_ALL
@@ -598,7 +598,7 @@
* (A+B)/2 vs B
*/
load = CPU_IRQ(min_loaded) >> 1;
- for_each_cpu_mask(j, cpu_sibling_map[min_loaded]) {
+ for_each_cpu_mask(j, per_cpu(cpu_sibling_map, min_loaded)) {
if (load > CPU_IRQ(j)) {
/* This won't change cpu_sibling_map[min_loaded] */
load = CPU_IRQ(j);
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -70,8 +70,8 @@
int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
/* representing HT siblings of each logical CPU */
-cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL(cpu_sibling_map);
+DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
DEFINE_PER_CPU(cpumask_t, cpu_core_map);
@@ -319,8 +319,8 @@
for_each_cpu_mask(i, cpu_sibling_setup_map) {
if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
c[cpu].cpu_core_id == c[i].cpu_core_id) {
- cpu_set(i, cpu_sibling_map[cpu]);
- cpu_set(cpu, cpu_sibling_map[i]);
+ cpu_set(i, per_cpu(cpu_sibling_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_sibling_map, i));
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
cpu_set(i, c[cpu].llc_shared_map);
@@ -328,13 +328,13 @@
}
}
} else {
- cpu_set(cpu, cpu_sibling_map[cpu]);
+ cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
}
cpu_set(cpu, c[cpu].llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
- per_cpu(cpu_core_map, cpu) = cpu_sibling_map[cpu];
+ per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
c[cpu].booted_cores = 1;
return;
}
@@ -351,12 +351,12 @@
/*
* Does this new cpu bringup a new core?
*/
- if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
+ if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) {
/*
* for each core in package, increment
* the booted_cores for this new cpu
*/
- if (first_cpu(cpu_sibling_map[i]) == i)
+ if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
c[cpu].booted_cores++;
/*
* increment the core count for all
@@ -983,7 +983,7 @@
printk(KERN_NOTICE "Local APIC not detected."
" Using dummy APIC emulation.\n");
map_cpu_to_logical_apicid();
- cpu_set(0, cpu_sibling_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
@@ -1008,7 +1008,7 @@
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
- cpu_set(0, cpu_sibling_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
@@ -1023,7 +1023,7 @@
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
- cpu_set(0, cpu_sibling_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
@@ -1102,15 +1102,15 @@
Dprintk("Boot done.\n");
/*
- * construct cpu_sibling_map[], so that we can tell sibling CPUs
+ * construct cpu_sibling_map, so that we can tell sibling CPUs
* efficiently.
*/
for (cpu = 0; cpu < NR_CPUS; cpu++) {
- cpus_clear(cpu_sibling_map[cpu]);
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
}
- cpu_set(0, cpu_sibling_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
smpboot_setup_io_apic();
@@ -1153,13 +1153,13 @@
/*/
* last thread sibling in this cpu core going down
*/
- if (cpus_weight(cpu_sibling_map[cpu]) == 1)
+ if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
c[sibling].booted_cores--;
}
- for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[sibling]);
- cpus_clear(cpu_sibling_map[cpu]);
+ for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
+ cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
c[cpu].phys_proc_id = 0;
c[cpu].cpu_core_id = 0;
--- a/arch/i386/oprofile/op_model_p4.c
+++ b/arch/i386/oprofile/op_model_p4.c
@@ -379,7 +379,7 @@
{
#ifdef CONFIG_SMP
int cpu = smp_processor_id();
- return (cpu != first_cpu(cpu_sibling_map[cpu]));
+ return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
#endif
return 0;
}
--- a/arch/i386/xen/smp.c
+++ b/arch/i386/xen/smp.c
@@ -147,7 +147,7 @@
make_lowmem_page_readwrite(&per_cpu__gdt_page);
for (cpu = 0; cpu < NR_CPUS; cpu++) {
- cpus_clear(cpu_sibling_map[cpu]);
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
/*
* cpu_core_map lives in a per cpu area that is cleared
* when the per cpu array is allocated.
@@ -164,7 +164,7 @@
unsigned cpu;
for (cpu = 0; cpu < NR_CPUS; cpu++) {
- cpus_clear(cpu_sibling_map[cpu]);
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
/*
* cpu_core_ map will be zeroed when the per
* cpu area is allocated.
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -91,8 +91,8 @@
int smp_threads_ready;
/* representing HT siblings of each logical CPU */
-cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL(cpu_sibling_map);
+DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
DEFINE_PER_CPU(cpumask_t, cpu_core_map);
@@ -264,8 +264,8 @@
for_each_cpu_mask(i, cpu_sibling_setup_map) {
if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
c[cpu].cpu_core_id == c[i].cpu_core_id) {
- cpu_set(i, cpu_sibling_map[cpu]);
- cpu_set(cpu, cpu_sibling_map[i]);
+ cpu_set(i, per_cpu(cpu_sibling_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_sibling_map, i));
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
cpu_set(i, c[cpu].llc_shared_map);
@@ -273,13 +273,13 @@
}
}
} else {
- cpu_set(cpu, cpu_sibling_map[cpu]);
+ cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
}
cpu_set(cpu, c[cpu].llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
- per_cpu(cpu_core_map, cpu) = cpu_sibling_map[cpu];
+ per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
c[cpu].booted_cores = 1;
return;
}
@@ -296,12 +296,12 @@
/*
* Does this new cpu bringup a new core?
*/
- if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
+ if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) {
/*
* for each core in package, increment
* the booted_cores for this new cpu
*/
- if (first_cpu(cpu_sibling_map[i]) == i)
+ if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
c[cpu].booted_cores++;
/*
* increment the core count for all
@@ -741,7 +741,7 @@
phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
else
phys_cpu_present_map = physid_mask_of_physid(0);
- cpu_set(0, cpu_sibling_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
}
@@ -982,13 +982,13 @@
/*
* last thread sibling in this cpu core going down
*/
- if (cpus_weight(cpu_sibling_map[cpu]) == 1)
+ if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
c[sibling].booted_cores--;
}
- for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[sibling]);
- cpus_clear(cpu_sibling_map[cpu]);
+ for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
+ cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
c[cpu].phys_proc_id = 0;
c[cpu].cpu_core_id = 0;
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -536,7 +536,7 @@
for_each_online_cpu(cpu) {
unsigned long long *cpu_off, *sibling_off;
- for_each_cpu_mask(i, cpu_sibling_map[cpu]) {
+ for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu)) {
if (i == cpu)
continue;
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -30,7 +30,7 @@
extern void smp_alloc_memory(void);
extern int pic_mode;
extern int smp_num_siblings;
-extern cpumask_t cpu_sibling_map[];
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
DECLARE_PER_CPU(cpumask_t, cpu_core_map);
extern void (*mtrr_hook) (void);
--- a/include/asm-i386/topology.h
+++ b/include/asm-i386/topology.h
@@ -31,7 +31,7 @@
#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id)
#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id)
#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#endif
#ifdef CONFIG_NUMA
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -38,12 +38,14 @@
extern int smp_num_siblings;
extern void smp_send_reschedule(int cpu);
-extern cpumask_t cpu_sibling_map[NR_CPUS];
/*
- * cpu_core_map lives in a per cpu area
+ * cpu_sibling_map and cpu_core_map now live
+ * in the per cpu area
*
+ * extern cpumask_t cpu_sibling_map[NR_CPUS];
* extern cpumask_t cpu_core_map[NR_CPUS];
*/
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
DECLARE_PER_CPU(cpumask_t, cpu_core_map);
extern u8 cpu_llc_id[NR_CPUS];
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -59,7 +59,7 @@
#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id)
#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id)
#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#define mc_capable() (boot_cpu_data.x86_max_cores > 1)
#define smt_capable() (smp_num_siblings > 1)
#endif
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5854,7 +5854,7 @@
struct sched_group **sg)
{
int group;
- cpumask_t mask = cpu_sibling_map[cpu];
+ cpumask_t mask = per_cpu(cpu_sibling_map, cpu);
cpus_and(mask, mask, *cpu_map);
group = first_cpu(mask);
if (sg)
@@ -5883,7 +5883,7 @@
cpus_and(mask, mask, *cpu_map);
group = first_cpu(mask);
#elif defined(CONFIG_SCHED_SMT)
- cpumask_t mask = cpu_sibling_map[cpu];
+ cpumask_t mask = per_cpu(cpu_sibling_map, cpu);
cpus_and(mask, mask, *cpu_map);
group = first_cpu(mask);
#else
@@ -6118,7 +6118,7 @@
p = sd;
sd = &per_cpu(cpu_domains, i);
*sd = SD_SIBLING_INIT;
- sd->span = cpu_sibling_map[i];
+ sd->span = per_cpu(cpu_sibling_map, i);
cpus_and(sd->span, sd->span, *cpu_map);
sd->parent = p;
p->child = sd;
@@ -6129,7 +6129,7 @@
#ifdef CONFIG_SCHED_SMT
/* Set up CPU (sibling) groups */
for_each_cpu_mask(i, *cpu_map) {
- cpumask_t this_sibling_map = cpu_sibling_map[i];
+ cpumask_t this_sibling_map = per_cpu(cpu_sibling_map, i);
cpus_and(this_sibling_map, this_sibling_map, *cpu_map);
if (i != first_cpu(this_sibling_map))
continue;
--
^ permalink raw reply
* [PATCH 03/10] x86: Convert cpu_core_map to be a per cpu variable (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
This is from an earlier message from 'Christoph Lameter':
cpu_core_map is currently an array defined using NR_CPUS. This means that
we overallocate since we will rarely really use maximum configured cpu.
If we put the cpu_core_map into the per cpu area then it will be allocated
for each processor as it comes online.
This means that the core map cannot be accessed until the per cpu area
has been allocated. Xen does a weird thing here looping over all processors
and zeroing the masks that are not yet allocated and that will be zeroed
when they are allocated. I commented the code out.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 2 -
arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 10 ++++----
arch/i386/kernel/cpu/proc.c | 3 +-
arch/i386/kernel/smpboot.c | 34 ++++++++++++++--------------
arch/i386/xen/smp.c | 14 +++++++++--
arch/x86_64/kernel/mce_amd.c | 6 ++--
arch/x86_64/kernel/setup.c | 3 +-
arch/x86_64/kernel/smpboot.c | 24 +++++++++----------
include/asm-i386/smp.h | 2 -
include/asm-i386/topology.h | 2 -
include/asm-x86_64/smp.h | 8 +++++-
include/asm-x86_64/topology.h | 2 -
12 files changed, 64 insertions(+), 46 deletions(-)
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -39,7 +39,13 @@
extern void smp_send_reschedule(int cpu);
extern cpumask_t cpu_sibling_map[NR_CPUS];
-extern cpumask_t cpu_core_map[NR_CPUS];
+/*
+ * cpu_core_map lives in a per cpu area
+ *
+ * extern cpumask_t cpu_core_map[NR_CPUS];
+ */
+DECLARE_PER_CPU(cpumask_t, cpu_core_map);
+
extern u8 cpu_llc_id[NR_CPUS];
#define SMP_TRAMPOLINE_BASE 0x6000
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -595,7 +595,7 @@
dmi_check_system(sw_any_bug_dmi_table);
if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
- policy->cpus = cpu_core_map[cpu];
+ policy->cpus = per_cpu(cpu_core_map, cpu);
}
#endif
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -57,7 +57,7 @@
static int cpu_family = CPU_OPTERON;
#ifndef CONFIG_SMP
-static cpumask_t cpu_core_map[1];
+DEFINE_PER_CPU(cpumask_t, cpu_core_map);
#endif
/* Return a frequency in MHz, given an input fid */
@@ -664,7 +664,7 @@
dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
data->powernow_table = powernow_table;
- if (first_cpu(cpu_core_map[data->cpu]) == data->cpu)
+ if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
print_basics(data);
for (j = 0; j < data->numps; j++)
@@ -818,7 +818,7 @@
/* fill in data */
data->numps = data->acpi_data.state_count;
- if (first_cpu(cpu_core_map[data->cpu]) == data->cpu)
+ if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
print_basics(data);
powernow_k8_acpi_pst_values(data, 0);
@@ -1212,7 +1212,7 @@
if (cpu_family == CPU_HW_PSTATE)
pol->cpus = cpumask_of_cpu(pol->cpu);
else
- pol->cpus = cpu_core_map[pol->cpu];
+ pol->cpus = per_cpu(cpu_core_map, pol->cpu);
data->available_cores = &(pol->cpus);
/* Take a crude guess here.
@@ -1279,7 +1279,7 @@
cpumask_t oldmask = current->cpus_allowed;
unsigned int khz = 0;
- data = powernow_data[first_cpu(cpu_core_map[cpu])];
+ data = powernow_data[first_cpu(per_cpu(cpu_core_map, cpu))];
if (!data)
return -EINVAL;
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -122,7 +122,8 @@
#ifdef CONFIG_X86_HT
if (c->x86_max_cores * smp_num_siblings > 1) {
seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
- seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[n]));
+ seq_printf(m, "siblings\t: %d\n",
+ cpus_weight(per_cpu(cpu_core_map, n)));
seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
}
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -74,8 +74,8 @@
EXPORT_SYMBOL(cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
-cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL(cpu_core_map);
+DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+EXPORT_PER_CPU_SYMBOL(cpu_core_map);
/* bitmap of online cpus */
cpumask_t cpu_online_map __read_mostly;
@@ -300,7 +300,7 @@
* And for power savings, we return cpu_core_map
*/
if (sched_mc_power_savings || sched_smt_power_savings)
- return cpu_core_map[cpu];
+ return per_cpu(cpu_core_map, cpu);
else
return c->llc_shared_map;
}
@@ -321,8 +321,8 @@
c[cpu].cpu_core_id == c[i].cpu_core_id) {
cpu_set(i, cpu_sibling_map[cpu]);
cpu_set(cpu, cpu_sibling_map[i]);
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
+ cpu_set(i, per_cpu(cpu_core_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_core_map, i));
cpu_set(i, c[cpu].llc_shared_map);
cpu_set(cpu, c[i].llc_shared_map);
}
@@ -334,7 +334,7 @@
cpu_set(cpu, c[cpu].llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
- cpu_core_map[cpu] = cpu_sibling_map[cpu];
+ per_cpu(cpu_core_map, cpu) = cpu_sibling_map[cpu];
c[cpu].booted_cores = 1;
return;
}
@@ -346,8 +346,8 @@
cpu_set(cpu, c[i].llc_shared_map);
}
if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
+ cpu_set(i, per_cpu(cpu_core_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_core_map, i));
/*
* Does this new cpu bringup a new core?
*/
@@ -984,7 +984,7 @@
" Using dummy APIC emulation.\n");
map_cpu_to_logical_apicid();
cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
@@ -1009,7 +1009,7 @@
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
@@ -1024,7 +1024,7 @@
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
@@ -1107,11 +1107,11 @@
*/
for (cpu = 0; cpu < NR_CPUS; cpu++) {
cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ cpus_clear(per_cpu(cpu_core_map, cpu));
}
cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_core_map, 0));
smpboot_setup_io_apic();
@@ -1148,9 +1148,9 @@
int sibling;
struct cpuinfo_x86 *c = cpu_data;
- for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
- cpu_clear(cpu, cpu_core_map[sibling]);
- /*
+ for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
+ cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
+ /*/
* last thread sibling in this cpu core going down
*/
if (cpus_weight(cpu_sibling_map[cpu]) == 1)
@@ -1160,7 +1160,7 @@
for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
cpu_clear(cpu, cpu_sibling_map[sibling]);
cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ cpus_clear(per_cpu(cpu_core_map, cpu));
c[cpu].phys_proc_id = 0;
c[cpu].cpu_core_id = 0;
cpu_clear(cpu, cpu_sibling_setup_map);
--- a/arch/i386/xen/smp.c
+++ b/arch/i386/xen/smp.c
@@ -148,7 +148,12 @@
for (cpu = 0; cpu < NR_CPUS; cpu++) {
cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ /*
+ * cpu_core_map lives in a per cpu area that is cleared
+ * when the per cpu array is allocated.
+ *
+ * cpus_clear(per_cpu(cpu_core_map, cpu));
+ */
}
xen_setup_vcpu_info_placement();
@@ -160,7 +165,12 @@
for (cpu = 0; cpu < NR_CPUS; cpu++) {
cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ /*
+ * cpu_core_ map will be zeroed when the per
+ * cpu area is allocated.
+ *
+ * cpus_clear(per_cpu(cpu_core_map, cpu));
+ */
}
smp_store_cpu_info(0);
--- a/arch/x86_64/kernel/mce_amd.c
+++ b/arch/x86_64/kernel/mce_amd.c
@@ -472,7 +472,7 @@
#ifdef CONFIG_SMP
if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) { /* symlink */
- i = first_cpu(cpu_core_map[cpu]);
+ i = first_cpu(per_cpu(cpu_core_map, cpu));
/* first core not up yet */
if (cpu_data[i].cpu_core_id)
@@ -492,7 +492,7 @@
if (err)
goto out;
- b->cpus = cpu_core_map[cpu];
+ b->cpus = per_cpu(cpu_core_map, cpu);
per_cpu(threshold_banks, cpu)[bank] = b;
goto out;
}
@@ -509,7 +509,7 @@
#ifndef CONFIG_SMP
b->cpus = CPU_MASK_ALL;
#else
- b->cpus = cpu_core_map[cpu];
+ b->cpus = per_cpu(cpu_core_map, cpu);
#endif
err = kobject_register(&b->kobj);
if (err)
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -1041,7 +1041,8 @@
if (smp_num_siblings * c->x86_max_cores > 1) {
int cpu = c - cpu_data;
seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
- seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu]));
+ seq_printf(m, "siblings\t: %d\n",
+ cpus_weight(per_cpu(cpu_core_map, cpu)));
seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
}
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -95,8 +95,8 @@
EXPORT_SYMBOL(cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
-cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL(cpu_core_map);
+DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+EXPORT_PER_CPU_SYMBOL(cpu_core_map);
/*
* Trampoline 80x86 program as an array.
@@ -245,7 +245,7 @@
* And for power savings, we return cpu_core_map
*/
if (sched_mc_power_savings || sched_smt_power_savings)
- return cpu_core_map[cpu];
+ return per_cpu(cpu_core_map, cpu);
else
return c->llc_shared_map;
}
@@ -266,8 +266,8 @@
c[cpu].cpu_core_id == c[i].cpu_core_id) {
cpu_set(i, cpu_sibling_map[cpu]);
cpu_set(cpu, cpu_sibling_map[i]);
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
+ cpu_set(i, per_cpu(cpu_core_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_core_map, i));
cpu_set(i, c[cpu].llc_shared_map);
cpu_set(cpu, c[i].llc_shared_map);
}
@@ -279,7 +279,7 @@
cpu_set(cpu, c[cpu].llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
- cpu_core_map[cpu] = cpu_sibling_map[cpu];
+ per_cpu(cpu_core_map, cpu) = cpu_sibling_map[cpu];
c[cpu].booted_cores = 1;
return;
}
@@ -291,8 +291,8 @@
cpu_set(cpu, c[i].llc_shared_map);
}
if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
+ cpu_set(i, per_cpu(cpu_core_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_core_map, i));
/*
* Does this new cpu bringup a new core?
*/
@@ -742,7 +742,7 @@
else
phys_cpu_present_map = physid_mask_of_physid(0);
cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_core_map, 0));
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -977,8 +977,8 @@
int sibling;
struct cpuinfo_x86 *c = cpu_data;
- for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
- cpu_clear(cpu, cpu_core_map[sibling]);
+ for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
+ cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
/*
* last thread sibling in this cpu core going down
*/
@@ -989,7 +989,7 @@
for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
cpu_clear(cpu, cpu_sibling_map[sibling]);
cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ cpus_clear(per_cpu(cpu_core_map, cpu));
c[cpu].phys_proc_id = 0;
c[cpu].cpu_core_id = 0;
cpu_clear(cpu, cpu_sibling_setup_map);
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -31,7 +31,7 @@
extern int pic_mode;
extern int smp_num_siblings;
extern cpumask_t cpu_sibling_map[];
-extern cpumask_t cpu_core_map[];
+DECLARE_PER_CPU(cpumask_t, cpu_core_map);
extern void (*mtrr_hook) (void);
extern void zap_low_mappings (void);
--- a/include/asm-i386/topology.h
+++ b/include/asm-i386/topology.h
@@ -30,7 +30,7 @@
#ifdef CONFIG_X86_HT
#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id)
#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id)
-#define topology_core_siblings(cpu) (cpu_core_map[cpu])
+#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
#endif
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -58,7 +58,7 @@
#ifdef CONFIG_SMP
#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id)
#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id)
-#define topology_core_siblings(cpu) (cpu_core_map[cpu])
+#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
#define mc_capable() (boot_cpu_data.x86_max_cores > 1)
#define smt_capable() (smp_num_siblings > 1)
--
^ permalink raw reply
* [PATCH 00/10] x86: Reduce Memory Usage and Inter-Node message traffic (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
Note:
This patch consolidates all the previous patches regarding
the conversion of static arrays sized by NR_CPUS into per_cpu
data arrays and is referenced against 2.6.23-rc6 .
v1 Intro:
In x86_64 and i386 architectures most arrays that are sized
using NR_CPUS lay in local memory on node 0. Not only will most
(99%?) of the systems not use all the slots in these arrays,
particularly when NR_CPUS is increased to accommodate future
very high cpu count systems, but a number of cache lines are
passed unnecessarily on the system bus when these arrays are
referenced by cpus on other nodes.
Typically, the values in these arrays are referenced by the cpu
accessing it's own values, though when passing IPI interrupts,
the cpu does access the data relevant to the targeted cpu/node.
Of course, if the referencing cpu is not on node 0, then the
reference will still require cross node exchanges of cache
lines. A common use of this is for an interrupt service
routine to pass the interrupt to other cpus local to that node.
Ideally, all the elements in these arrays should be moved to the
per_cpu data area. In some cases (such as x86_cpu_to_apicid)
the array is referenced before the per_cpu data areas are setup.
In this case, a static array is declared in the __initdata
area and initialized by the booting cpu (BSP). The values are
then moved to the per_cpu area after it is initialized and the
original static array is freed with the rest of the __initdata.
This patch is referenced against 2.6.23-rc6.
--
Changes for version v2:
> > Note the addtional change of the cpu_llc_id type from u8
> > to int for ARCH x86_64 to correspond with ARCH i386.
> At least currently it cannot be more than 8 bit. So why
> waste memory? It would be better to change i386
Done. (x86_64 type => u8).
> > Fix four instances where cpu_to_node is referenced
> > > by array instead of via the cpu_to_node macro. This
> > > is preparation to moving it to the per_cpu data area.
> Shouldn't this patch be logically before the per cpu
> conversion (which is 3). This way the result would
> be git bisectable.
Done. (Moved to PATCH 1).
> > processor_core.c currently tries to determine the apicid by special casing
> > > for IA64 and x86. The desired information is readily available via
> > >
> > > cpu_physical_id()
> > >
> > > on IA64, i386 and x86_64.
>
> Have you tried this with a !CONFIG_SMP build? The drivers/dma code was doing
> the same and running into problems because it wasn't defined there.
Fixed. (New export in PATCH 1).
--
Changes for version v3:
cpu_sibling_map has been converted to a per_cpu data array to fix
build errors on ia64, ppc64 and sparc64 to accomodate references in
block/blktrace.c and kernel/sched.c when CONFIG_SCHED_SMT is defined.
Warning: ppc64 and sparc64 have not yet been built nor tested.
--
--
^ permalink raw reply
* [PATCH 02/10] x86: fix cpu_to_node references (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
Fix four instances where cpu_to_node is referenced
by array instead of via the cpu_to_node macro. This
is preparation to moving it to the per_cpu data area.
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/x86_64/kernel/vsyscall.c | 2 +-
arch/x86_64/mm/numa.c | 4 ++--
arch/x86_64/mm/srat.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -291,7 +291,7 @@
unsigned long *d;
unsigned long node = 0;
#ifdef CONFIG_NUMA
- node = cpu_to_node[cpu];
+ node = cpu_to_node(cpu);
#endif
if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP))
write_rdtscp_aux((node << 12) | cpu);
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -261,7 +261,7 @@
We round robin the existing nodes. */
rr = first_node(node_online_map);
for (i = 0; i < NR_CPUS; i++) {
- if (cpu_to_node[i] != NUMA_NO_NODE)
+ if (cpu_to_node(i) != NUMA_NO_NODE)
continue;
numa_set_node(i, rr);
rr = next_node(rr, node_online_map);
@@ -543,7 +543,7 @@
void __cpuinit numa_set_node(int cpu, int node)
{
cpu_pda(cpu)->nodenumber = node;
- cpu_to_node[cpu] = node;
+ cpu_to_node(cpu) = node;
}
unsigned long __init numa_free_all_bootmem(void)
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -431,9 +431,9 @@
setup_node_bootmem(i, nodes[i].start, nodes[i].end);
for (i = 0; i < NR_CPUS; i++) {
- if (cpu_to_node[i] == NUMA_NO_NODE)
+ if (cpu_to_node(i) == NUMA_NO_NODE)
continue;
- if (!node_isset(cpu_to_node[i], node_possible_map))
+ if (!node_isset(cpu_to_node(i), node_possible_map))
numa_set_node(i, NUMA_NO_NODE);
}
numa_init_array();
--
^ permalink raw reply
* [PATCH 01/10] x86: remove x86_cpu_to_log_apicid array (v3)
From: travis @ 2007-09-12 1:56 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Christoph Lameter
In-Reply-To: <20070912015644.927677070@sgi.com>
This is a copy of an older patch that is in rc3-mm1. It's needed
to allow the remaining patches to integrate correctly.
Signed-off-by: Mike Travis <travis@sgi.com>
---
arch/x86_64/kernel/genapic.c | 2 --
arch/x86_64/kernel/genapic_flat.c | 1 -
arch/x86_64/kernel/smpboot.c | 1 -
include/asm-x86_64/smp.h | 1 -
4 files changed, 5 deletions(-)
--- a/arch/x86_64/kernel/genapic.c
+++ b/arch/x86_64/kernel/genapic.c
@@ -29,8 +29,6 @@
= { [0 ... NR_CPUS-1] = BAD_APICID };
EXPORT_SYMBOL(x86_cpu_to_apicid);
-u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
-
struct genapic __read_mostly *genapic = &apic_flat;
/*
--- a/arch/x86_64/kernel/genapic_flat.c
+++ b/arch/x86_64/kernel/genapic_flat.c
@@ -52,7 +52,6 @@
num = smp_processor_id();
id = 1UL << num;
- x86_cpu_to_log_apicid[num] = id;
apic_write(APIC_DFR, APIC_DFR_FLAT);
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
val |= SET_APIC_LOGICAL_ID(id);
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -702,7 +702,6 @@
cpu_clear(cpu, cpu_present_map);
cpu_clear(cpu, cpu_possible_map);
x86_cpu_to_apicid[cpu] = BAD_APICID;
- x86_cpu_to_log_apicid[cpu] = BAD_APICID;
return -EIO;
}
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -78,7 +78,6 @@
* the real APIC ID <-> CPU # mapping.
*/
extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */
-extern u8 x86_cpu_to_log_apicid[NR_CPUS];
extern u8 bios_cpu_apicid[];
static inline int cpu_present_to_apicid(int mps_cpu)
--
^ permalink raw reply
* RE: futex priority based wakeup
From: Ilya Lipovsky @ 2007-09-12 1:09 UTC (permalink / raw)
To: 'Nguyen Nguyen'; +Cc: 'Benedict, Michael', linuxppc-embedded
In-Reply-To: <1656e050709111714g1a84656bvd7823f5fc43345dd@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4306 bytes --]
Good info. Indeed, looks like this is what glibc actually does:
http://www.cygwin.com/ml/libc-alpha/2007-06/msg00097.html
_____
From: tinghich@gmail.com [mailto:tinghich@gmail.com] On Behalf Of Nguyen
Nguyen
Sent: Tuesday, September 11, 2007 8:15 PM
To: Ilya Lipovsky
Cc: Benedict, Michael; linuxppc-embedded@ozlabs.org
Subject: Re: futex priority based wakeup
I have seen something similar before. Our fix was to use
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) so child threads
wouldn't inherit attribute from parent. Hope it helps.
On 9/11/07, Ilya Lipovsky <lipovsky@cs.bu.edu> wrote:
Hmm. Just for kicks - inside the important thread could you add:
int curpolicy;
struct sched_param sp;
pthread_getschedparam (pthread_self (), &curpolicy, &sp)
printf("important's policy is %d and priority is %d\n", curpolicy,
sp.__sched_priority);
before the very first futex syscall and after your "printf("important got
futex!\n");" line.
Do similar for the unimportant thread, and see if you get anything weird -
e.g. priorities come out to be the same for threads.
-----Original Message-----
From: linuxppc-embedded-bounces+lipovsky=cs.bu.edu@ozlabs.org
[mailto: <mailto:linuxppc-embedded-bounces+lipovsky=cs.bu.edu@ozlabs.org>
linuxppc-embedded-bounces+lipovsky=cs.bu.edu@ozlabs.org] On Behalf
Of Benedict, Michael
Sent: Monday, September 10, 2007 5:41 PM
To: linuxppc-embedded@ozlabs.org
Subject: RE: futex priority based wakeup
Ilya Lipovsky wrote:
> Your code looks correct to me, so if the kernel developers
> did their job
> correctly, the only potentially weak link is glibc.
>
Well, either the kernel developers didn't do their job, or I am missing
something. The following also fails, and it should be bypassing glibc:
#define _XOPEN_SOURCE 600
#include <linux/futex.h>
#include <sys/time.h>
#include <asm/atomic.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <sched.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int myfutex = 0;
void *important(void *ign)
{
sleep(1);
printf("important waiting for futex\n");
fflush(stdout);
if(syscall(SYS_futex, &myfutex, FUTEX_WAIT, 0, NULL)) {
perror("futex");
exit(1);
} else {
printf("important got futex!\n");
fflush(stdout);
syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
}
return NULL;
}
void *unimportant(void *ign)
{
printf("unimportant waiting for futex\n");
fflush(stdout);
if(syscall(SYS_futex, &myfutex, FUTEX_WAIT, 0, NULL)) {
perror("futex");
exit(1);
} else {
printf("unimportant got futex!\n");
fflush(stdout);
syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
}
return NULL;
}
int main()
{
struct sched_param p;
pthread_attr_t attr;
pthread_t i, u;
p.__sched_priority = sched_get_priority_min(SCHED_FIFO);
if(-1 == p.__sched_priority) {
perror("sched_get_priority_min");
return 1;
}
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
pthread_attr_setschedparam(&attr, &p);
pthread_create(&u, &attr, unimportant, NULL);
p.__sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&attr, &p);
pthread_create(&i, &attr, important, NULL);
sleep(5);
printf("futex FUTEX_WAKE\n");
fflush(stdout);
syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
pthread_join(u, NULL);
pthread_join(i, NULL);
return 0;
}
Which produces:
unimportant waiting for futex
important waiting for futex
futex FUTEX_WAKE
unimportant got futex!
important got futex!
Could someone with 2.6.22 please verify?
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org <mailto:Linuxppc-embedded@ozlabs.org>
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
[-- Attachment #2: Type: text/html, Size: 11905 bytes --]
^ permalink raw reply
* Re: Interrupt-problem mpc5200
From: WITTROCK @ 2007-09-12 0:47 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <20070911124348.GJ11807@sfrouter>
Is it possible the interrupt is going off as soon as you unmask it? Can you
show your "intmod_isr".
I had a similar problem when I pulled a "wittrock" and forgot to make the
interrupt edge sensitive, but from what I can see you have made yours edge
sensitive.
-WITTROCK
S. Fricke wrote:
>
>
> Dear Linux-enthusiasts,
>
> I'm still at the same problem.
>
> I have now implemented a irq_chip for the hardwired IRQ2. Now I have
>
>
> --==>
> volatile static struct mpc52xx_intr __iomem *intr;
> unsigned long flags;
> static DEFINE_SPINLOCK(my_irq_controller_lock);
>
> /*
> * HELPER-Function
> */
> static inline void io_be_setbit(u32 __iomem *addr, int bitno)
> {
> out_be32(addr, in_be32(addr) | (1 << bitno));
> }
>
> static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
> {
> out_be32(addr, in_be32(addr) & ~(1 << bitno));
> }
>
> /*
> * IRQ-Zeugs
> */
> static void my_irq_ack(unsigned int irq)
> {
> printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
> spin_lock_irqsave(&my_irq_controller_lock, flags);
> if(intr)
> io_be_setbit(&intr->ctrl, 25);
> spin_unlock_irqrestore(&my_irq_controller_lock, flags);
> printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
> }
>
> /* irq - disabled */
> static void my_irq_mask(unsigned int irq)
> {
> printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
> spin_lock_irqsave(&my_irq_controller_lock, flags);
> if(intr)
> io_be_clrbit(&intr->ctrl, 9);
> spin_unlock_irqrestore(&my_irq_controller_lock, flags);
> printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
> }
>
> /* irq - enable */
> static void my_irq_unmask(unsigned int irq)
> {
> printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
> spin_lock_irqsave(&my_irq_controller_lock, flags);
> if(intr)
> io_be_setbit(&intr->ctrl, 9);
> spin_unlock_irqrestore(&my_irq_controller_lock, flags);
> printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
> }
>
> static struct irq_chip my_irq_chip = {
> .typename = "MY_IRQ_TEST",
> .ack = my_irq_ack,
> .mask = my_irq_mask,
> .unmask = my_irq_unmask,
> };
>
> static int __init mod_init( void )
> {
> // ...
>
> intr = mpc52xx_find_and_map("mpc52xx-pic");
> if(!intr) {
> panic(__FILE__ ": mpc52xx-pic - MAP failed");
> }
>
> set_irq_chip(MPC52xx_IRQ2, &my_irq_chip);
> a = request_irq(2, intmod_isr, IRQF_DISABLED , "intmod",
> INTMOD_IRQ_BOARD);
> printk("a: 0x%08x\n", a);
>
> // ...
> }
>
> <==--
>
> Now my code hangs on the my_irq_unmask(...)-function on "io_be_setbit".
> Why?
> Can anyone help me, or point me to the right newsgroup/forum?
>
> So long!
>
> Silvio
>
>
> --
> -- S. Fricke ----------------------------- MAILTO:silvio.fricke@gmail.com
> --
> Diplom-Informatiker (FH)
> Linux-Entwicklung JABBER: fricke@jabber.org
> ----------------------------------------------------------------------------
>
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
--
View this message in context: http://www.nabble.com/Interrupt-problem-mpc5200-tf4413834.html#a12626802
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* Re: futex priority based wakeup
From: Nguyen Nguyen @ 2007-09-12 0:14 UTC (permalink / raw)
To: Ilya Lipovsky; +Cc: Benedict, Michael, linuxppc-embedded
In-Reply-To: <000001c7f4c7$7a7ab5c0$3a0d10ac@Radstone.Local>
[-- Attachment #1: Type: text/plain, Size: 4038 bytes --]
I have seen something similar before. Our fix was to use
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) so child threads
wouldn't inherit attribute from parent. Hope it helps.
On 9/11/07, Ilya Lipovsky <lipovsky@cs.bu.edu> wrote:
>
> Hmm. Just for kicks - inside the important thread could you add:
>
> int curpolicy;
> struct sched_param sp;
> pthread_getschedparam (pthread_self (), &curpolicy, &sp)
> printf("important's policy is %d and priority is %d\n", curpolicy,
> sp.__sched_priority);
>
> before the very first futex syscall and after your "printf("important got
> futex!\n");" line.
>
> Do similar for the unimportant thread, and see if you get anything weird -
> e.g. priorities come out to be the same for threads.
>
>
> -----Original Message-----
> From: linuxppc-embedded-bounces+lipovsky=cs.bu.edu@ozlabs.org
> [mailto:linuxppc-embedded-bounces+lipovsky=cs.bu.edu@ozlabs.org] On Behalf
> Of Benedict, Michael
> Sent: Monday, September 10, 2007 5:41 PM
> To: linuxppc-embedded@ozlabs.org
> Subject: RE: futex priority based wakeup
>
> Ilya Lipovsky wrote:
> > Your code looks correct to me, so if the kernel developers
> > did their job
> > correctly, the only potentially weak link is glibc.
> >
>
> Well, either the kernel developers didn't do their job, or I am missing
> something. The following also fails, and it should be bypassing glibc:
>
> #define _XOPEN_SOURCE 600
>
> #include <linux/futex.h>
> #include <sys/time.h>
> #include <asm/atomic.h>
>
> #include <sys/syscall.h>
> #include <unistd.h>
>
> #include <sched.h>
> #include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> int myfutex = 0;
>
> void *important(void *ign)
> {
> sleep(1);
> printf("important waiting for futex\n");
> fflush(stdout);
> if(syscall(SYS_futex, &myfutex, FUTEX_WAIT, 0, NULL)) {
> perror("futex");
> exit(1);
> } else {
> printf("important got futex!\n");
> fflush(stdout);
> syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
> }
>
> return NULL;
> }
>
>
> void *unimportant(void *ign)
> {
> printf("unimportant waiting for futex\n");
> fflush(stdout);
> if(syscall(SYS_futex, &myfutex, FUTEX_WAIT, 0, NULL)) {
> perror("futex");
> exit(1);
> } else {
> printf("unimportant got futex!\n");
> fflush(stdout);
> syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
> }
>
> return NULL;
> }
>
> int main()
> {
> struct sched_param p;
> pthread_attr_t attr;
> pthread_t i, u;
>
> p.__sched_priority = sched_get_priority_min(SCHED_FIFO);
> if(-1 == p.__sched_priority) {
> perror("sched_get_priority_min");
> return 1;
> }
> pthread_attr_init(&attr);
> pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
> pthread_attr_setschedparam(&attr, &p);
> pthread_create(&u, &attr, unimportant, NULL);
>
> p.__sched_priority = sched_get_priority_max(SCHED_FIFO);
> pthread_attr_setschedparam(&attr, &p);
> pthread_create(&i, &attr, important, NULL);
>
> sleep(5);
> printf("futex FUTEX_WAKE\n");
> fflush(stdout);
> syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
>
> pthread_join(u, NULL);
> pthread_join(i, NULL);
>
> return 0;
> }
>
> Which produces:
> unimportant waiting for futex
> important waiting for futex
> futex FUTEX_WAKE
> unimportant got futex!
> important got futex!
>
>
> Could someone with 2.6.22 please verify?
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
[-- Attachment #2: Type: text/html, Size: 7379 bytes --]
^ permalink raw reply
* Re: [PATCH] [RFC][POWERPC] Merge 32 and 64 bit pci_process_bridge_OF_ranges() instances
From: Vitaly Bordug @ 2007-09-11 23:56 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev
In-Reply-To: <200709120057.18873.arnd@arndb.de>
On Wed, 12 Sep 2007 00:57:17 +0200
Arnd Bergmann wrote:
> On Wednesday 12 September 2007, Vitaly Bordug wrote:
> >
> > We are having 2 different instances of
> > pci_process_bridge_OF_ranges(), which makes describing 64-bit
> > physical addresses in non PPC64 case impossible.
> >
> > This approach inherits pci space parsing, but has a new way to
> > behave equally good in both 32bit and 64bit environments. This
> > approach uses of_translate_address(), so implies proper ranges <>
> > definition in devicetree, where PCI node has its reg on soc bus,
> > and its ranges effectively belong to LAW addresses.
> >
> > Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
> > Signed-off-by: Stefan Roese <sr@denx.de>
>
> The patch looks really good, but it's hard to review when you move the
> code around at the same as you change it.
>
Well, it's more a rewrite than a move, based on 64-bit implementation.
> Could you perhaps split the patch into two separate changesets, one
> that makes both functions identical in place, and one that merges
> them to live in a common location?
>
I'm not sure I'm following what you are requesting. What is a benefit of code duplication? I was thinking about,
if it will look good enough, to provide this function at generic level but changing its name a little, while leaving old stuff in place, and encouraging people to use it in favour of 32 or 64-bit-specific approaches. That way we won't kill many boards at once(in case, for example,odd dts with missed ranges for pci subnode).
> > diff --git a/include/asm-powerpc/ppc-pci.h
> > b/include/asm-powerpc/ppc-pci.h index b847aa1..882b8bc 100644
> > --- a/include/asm-powerpc/ppc-pci.h
> > +++ b/include/asm-powerpc/ppc-pci.h
> > @@ -15,6 +15,13 @@
> > #include <linux/pci.h>
> > #include <asm/pci-bridge.h>
> >
> > +struct ranges_pci {
> > + unsigned int pci_space;
> > + u64 pci_addr;
> > + phys_addr_t phys_addr;
> > + u64 size;
> > +} __attribute__((packed));
> > +
>
> This structure definition uses unaligned members because of the
> 'packed' attribute. Is that really what you intended?
>
yes, exactly, because I'm mapping this struct on ranges extracted from the dts instead of juggling with ranges[foo]
offsets.
> Arnd <><
Thanks for looking at it!
--
Sincerely, Vitaly
^ permalink raw reply
* Re: [PATCH] [RFC][POWERPC] Merge 32 and 64 bit pci_process_bridge_OF_ranges() instances
From: Arnd Bergmann @ 2007-09-11 22:57 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20070911224952.9838.46644.stgit@localhost.localdomain>
On Wednesday 12 September 2007, Vitaly Bordug wrote:
>
> We are having 2 different instances of pci_process_bridge_OF_ranges(),
> which makes describing 64-bit physical addresses in non PPC64 case
> impossible.
>
> This approach inherits pci space parsing, but has a new way to behave
> equally good in both 32bit and 64bit environments. This approach uses
> of_translate_address(), so implies proper ranges <> definition in
> devicetree, where PCI node has its reg on soc bus, and its ranges
> effectively belong to LAW addresses.
>
> Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
> Signed-off-by: Stefan Roese <sr@denx.de>
The patch looks really good, but it's hard to review when you move the
code around at the same as you change it.
Could you perhaps split the patch into two separate changesets, one
that makes both functions identical in place, and one that merges
them to live in a common location?
> diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
> index b847aa1..882b8bc 100644
> --- a/include/asm-powerpc/ppc-pci.h
> +++ b/include/asm-powerpc/ppc-pci.h
> @@ -15,6 +15,13 @@
> #include <linux/pci.h>
> #include <asm/pci-bridge.h>
>
> +struct ranges_pci {
> + unsigned int pci_space;
> + u64 pci_addr;
> + phys_addr_t phys_addr;
> + u64 size;
> +} __attribute__((packed));
> +
This structure definition uses unaligned members because of the 'packed'
attribute. Is that really what you intended?
Arnd <><
^ permalink raw reply
* RE: futex priority based wakeup
From: Ilya Lipovsky @ 2007-09-11 22:59 UTC (permalink / raw)
To: 'Benedict, Michael', linuxppc-embedded
In-Reply-To: <BAF8B1E0BB28024A90895E746A3B610D1C2BE7@twx-exch01.twacs.local>
Hmm. Just for kicks - inside the important thread could you add:
int curpolicy;
struct sched_param sp;
pthread_getschedparam (pthread_self (), &curpolicy, &sp)
printf("important's policy is %d and priority is %d\n", curpolicy,
sp.__sched_priority);
before the very first futex syscall and after your "printf("important got
futex!\n");" line.
Do similar for the unimportant thread, and see if you get anything weird -
e.g. priorities come out to be the same for threads.
-----Original Message-----
From: linuxppc-embedded-bounces+lipovsky=cs.bu.edu@ozlabs.org
[mailto:linuxppc-embedded-bounces+lipovsky=cs.bu.edu@ozlabs.org] On Behalf
Of Benedict, Michael
Sent: Monday, September 10, 2007 5:41 PM
To: linuxppc-embedded@ozlabs.org
Subject: RE: futex priority based wakeup
Ilya Lipovsky wrote:
> Your code looks correct to me, so if the kernel developers
> did their job
> correctly, the only potentially weak link is glibc.
>
Well, either the kernel developers didn't do their job, or I am missing
something. The following also fails, and it should be bypassing glibc:
#define _XOPEN_SOURCE 600
#include <linux/futex.h>
#include <sys/time.h>
#include <asm/atomic.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <sched.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int myfutex = 0;
void *important(void *ign)
{
sleep(1);
printf("important waiting for futex\n");
fflush(stdout);
if(syscall(SYS_futex, &myfutex, FUTEX_WAIT, 0, NULL)) {
perror("futex");
exit(1);
} else {
printf("important got futex!\n");
fflush(stdout);
syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
}
return NULL;
}
void *unimportant(void *ign)
{
printf("unimportant waiting for futex\n");
fflush(stdout);
if(syscall(SYS_futex, &myfutex, FUTEX_WAIT, 0, NULL)) {
perror("futex");
exit(1);
} else {
printf("unimportant got futex!\n");
fflush(stdout);
syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
}
return NULL;
}
int main()
{
struct sched_param p;
pthread_attr_t attr;
pthread_t i, u;
p.__sched_priority = sched_get_priority_min(SCHED_FIFO);
if(-1 == p.__sched_priority) {
perror("sched_get_priority_min");
return 1;
}
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
pthread_attr_setschedparam(&attr, &p);
pthread_create(&u, &attr, unimportant, NULL);
p.__sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&attr, &p);
pthread_create(&i, &attr, important, NULL);
sleep(5);
printf("futex FUTEX_WAKE\n");
fflush(stdout);
syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
pthread_join(u, NULL);
pthread_join(i, NULL);
return 0;
}
Which produces:
unimportant waiting for futex
important waiting for futex
futex FUTEX_WAKE
unimportant got futex!
important got futex!
Could someone with 2.6.22 please verify?
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
^ permalink raw reply
* [PATCH] [RFC][POWERPC] Merge 32 and 64 bit pci_process_bridge_OF_ranges() instances
From: Vitaly Bordug @ 2007-09-11 22:49 UTC (permalink / raw)
To: linuxppc-dev
We are having 2 different instances of pci_process_bridge_OF_ranges(),
which makes describing 64-bit physical addresses in non PPC64 case
impossible.
This approach inherits pci space parsing, but has a new way to behave
equally good in both 32bit and 64bit environments. This approach uses
of_translate_address(), so implies proper ranges <> definition in
devicetree, where PCI node has its reg on soc bus, and its ranges
effectively belong to LAW addresses.
Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
Signed-off-by: Stefan Roese <sr@denx.de>
---
arch/powerpc/kernel/pci-common.c | 130 ++++++++++++++++++++++++++++++++++++++
arch/powerpc/kernel/pci_32.c | 114 ---------------------------------
arch/powerpc/kernel/pci_64.c | 94 ---------------------------
include/asm-powerpc/ppc-pci.h | 7 ++
4 files changed, 137 insertions(+), 208 deletions(-)
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 083cfbd..c0efd6d 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -478,3 +478,133 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
*start = rsrc->start - offset;
*end = rsrc->end - offset;
}
+
+void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+ struct device_node *dev, int prim)
+{
+ const unsigned int *ranges;
+ unsigned int pci_space;
+ u64 size = 0, pci_addr;
+ int rlen = 0;
+ int ranges_amnt, i, j, np;
+ int memno = 0;
+ struct resource *res;
+ int na = of_n_addr_cells(dev);
+ struct ranges_pci *ranges64 = NULL;
+ phys_addr_t cpu_phys_addr;
+
+ np = na + 5;
+
+ /* From "PCI Binding to 1275"
+ * The ranges property is laid out as an array of elements,
+ * each of which comprises:
+ * cells 0 - 2: a PCI address
+ * cells 3 or 3+4: a CPU physical address
+ * (size depending on dev->n_addr_cells)
+ * cells 4+5 or 5+6: the size of the range
+ */
+ ranges = of_get_property(dev, "ranges", &rlen);
+ if (!ranges)
+ return;
+ /* Map ranges to struct according to spec. */
+ ranges64 = (void *)ranges;
+ ranges_amnt = rlen / sizeof(*ranges64);
+
+ hose->io_base_phys = 0;
+ for (i = 0; i < ranges_amnt; i++) {
+ u32 *addr_ptr;
+ res = NULL;
+
+ if (ranges64[i].pci_space == 0)
+ continue;
+
+ pci_space = ranges64[i].pci_space;
+ pci_addr = ranges64[i].pci_addr;
+ addr_ptr = (u32 *)(&ranges64[i].phys_addr);
+ cpu_phys_addr =
+ (phys_addr_t)of_translate_address(dev, addr_ptr);
+ size = ranges64[i].size;
+
+ DBG("Observed: pci %llx phys %llx size %llx\n", pci_addr,
+ cpu_phys_addr, size);
+
+ /* here we need to handle contiguous ranges */
+ for (j = i+1; j < ranges_amnt; j++) {
+ /* no need to coalesce different region types */
+ if (ranges64[j].pci_space != pci_space)
+ break;
+ /* not contiguous. give up. */
+ if (ranges64[j].pci_addr != pci_addr + size ||
+ ranges64[j].phys_addr != cpu_phys_addr + size)
+ break;
+ size += ranges64[j].size;
+ i = j; /* skip this one next turn */
+ }
+ switch ((pci_space >> 24) & 0x3) {
+ case 1: /* I/O space */
+#ifdef CONFIG_PPC32
+ /*
+ * check from ppc32 pci implementation.
+ * This seems just wrong. -vitb
+ */
+ if (pci_addr != 0)
+ break;
+#endif
+ /* limit I/O space to 16MB */
+ if (size > 0x01000000)
+ size = 0x01000000;
+
+ hose->io_base_phys = cpu_phys_addr - pci_addr;
+ /* handle from 0 to top of I/O window */
+#ifdef CONFIG_PPC64
+ hose->pci_io_size = pci_addr + size;
+#endif
+ hose->io_base_virt = ioremap(hose->io_base_phys, size);
+#ifdef CONFIG_PPC32
+ if (prim)
+ isa_io_base = (unsigned long)hose->io_base_virt;
+#endif
+ res = &hose->io_resource;
+ res->flags = IORESOURCE_IO;
+ res->start = pci_addr;
+ DBG("phb%d: IO 0x%llx -> 0x%llx\n", hose->global_number,
+ (u64) res->start,
+ (u64) (res->start + size - 1));
+ DBG("IO phys %llx IO virt %p\n",
+ (u64) hose->io_base_phys, hose->io_base_virt);
+ break;
+ case 2: /* memory space */
+ memno = 0;
+#ifdef CONFIG_PPC32
+ if ((pci_addr == 0) && (size <= (16 << 20))) {
+ /* 1st 16MB, i.e. ISA memory area */
+ if (prim)
+ isa_mem_base = cpu_phys_addr;
+ memno = 1;
+ }
+#endif
+ while (memno < 3 && hose->mem_resources[memno].flags)
+ ++memno;
+
+ if (memno == 0)
+ hose->pci_mem_offset = cpu_phys_addr - pci_addr;
+ if (memno < 3) {
+ res = &hose->mem_resources[memno];
+ res->flags = IORESOURCE_MEM;
+ res->start = cpu_phys_addr;
+ DBG("phb%d: MEM 0x%llx -> 0x%llx\n",
+ hose->global_number, res->start,
+ res->start + size - 1);
+ }
+ break;
+ }
+ if (res != NULL) {
+ res->name = dev->full_name;
+ res->end = res->start + size - 1;
+ res->parent = NULL;
+ res->sibling = NULL;
+ res->child = NULL;
+ }
+ }
+}
+
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 0e2bee4..dc519e1 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -843,120 +843,6 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
}
EXPORT_SYMBOL(pci_device_from_OF_node);
-void __init
-pci_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev, int primary)
-{
- static unsigned int static_lc_ranges[256] __initdata;
- const unsigned int *dt_ranges;
- unsigned int *lc_ranges, *ranges, *prev, size;
- int rlen = 0, orig_rlen;
- int memno = 0;
- struct resource *res;
- int np, na = of_n_addr_cells(dev);
- np = na + 5;
-
- /* First we try to merge ranges to fix a problem with some pmacs
- * that can have more than 3 ranges, fortunately using contiguous
- * addresses -- BenH
- */
- dt_ranges = of_get_property(dev, "ranges", &rlen);
- if (!dt_ranges)
- return;
- /* Sanity check, though hopefully that never happens */
- if (rlen > sizeof(static_lc_ranges)) {
- printk(KERN_WARNING "OF ranges property too large !\n");
- rlen = sizeof(static_lc_ranges);
- }
- lc_ranges = static_lc_ranges;
- memcpy(lc_ranges, dt_ranges, rlen);
- orig_rlen = rlen;
-
- /* Let's work on a copy of the "ranges" property instead of damaging
- * the device-tree image in memory
- */
- ranges = lc_ranges;
- prev = NULL;
- while ((rlen -= np * sizeof(unsigned int)) >= 0) {
- if (prev) {
- if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
- (prev[2] + prev[na+4]) == ranges[2] &&
- (prev[na+2] + prev[na+4]) == ranges[na+2]) {
- prev[na+4] += ranges[na+4];
- ranges[0] = 0;
- ranges += np;
- continue;
- }
- }
- prev = ranges;
- ranges += np;
- }
-
- /*
- * The ranges property is laid out as an array of elements,
- * each of which comprises:
- * cells 0 - 2: a PCI address
- * cells 3 or 3+4: a CPU physical address
- * (size depending on dev->n_addr_cells)
- * cells 4+5 or 5+6: the size of the range
- */
- ranges = lc_ranges;
- rlen = orig_rlen;
- while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
- res = NULL;
- size = ranges[na+4];
- switch ((ranges[0] >> 24) & 0x3) {
- case 1: /* I/O space */
- if (ranges[2] != 0)
- break;
- hose->io_base_phys = ranges[na+2];
- /* limit I/O space to 16MB */
- if (size > 0x01000000)
- size = 0x01000000;
- hose->io_base_virt = ioremap(ranges[na+2], size);
- if (primary)
- isa_io_base = (unsigned long) hose->io_base_virt;
- res = &hose->io_resource;
- res->flags = IORESOURCE_IO;
- res->start = ranges[2];
- DBG("PCI: IO 0x%llx -> 0x%llx\n",
- (u64)res->start, (u64)res->start + size - 1);
- break;
- case 2: /* memory space */
- memno = 0;
- if (ranges[1] == 0 && ranges[2] == 0
- && ranges[na+4] <= (16 << 20)) {
- /* 1st 16MB, i.e. ISA memory area */
- if (primary)
- isa_mem_base = ranges[na+2];
- memno = 1;
- }
- while (memno < 3 && hose->mem_resources[memno].flags)
- ++memno;
- if (memno == 0)
- hose->pci_mem_offset = ranges[na+2] - ranges[2];
- if (memno < 3) {
- res = &hose->mem_resources[memno];
- res->flags = IORESOURCE_MEM;
- if(ranges[0] & 0x40000000)
- res->flags |= IORESOURCE_PREFETCH;
- res->start = ranges[na+2];
- DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
- (u64)res->start, (u64)res->start + size - 1);
- }
- break;
- }
- if (res != NULL) {
- res->name = dev->full_name;
- res->end = res->start + size - 1;
- res->parent = NULL;
- res->sibling = NULL;
- res->child = NULL;
- }
- ranges += np;
- }
-}
-
/* We create the "pci-OF-bus-map" property now so it appears in the
* /proc device tree
*/
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 291ffbc..68bce38 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -592,100 +592,6 @@ int pci_proc_domain(struct pci_bus *bus)
}
}
-void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev, int prim)
-{
- const unsigned int *ranges;
- unsigned int pci_space;
- unsigned long size;
- int rlen = 0;
- int memno = 0;
- struct resource *res;
- int np, na = of_n_addr_cells(dev);
- unsigned long pci_addr, cpu_phys_addr;
-
- np = na + 5;
-
- /* From "PCI Binding to 1275"
- * The ranges property is laid out as an array of elements,
- * each of which comprises:
- * cells 0 - 2: a PCI address
- * cells 3 or 3+4: a CPU physical address
- * (size depending on dev->n_addr_cells)
- * cells 4+5 or 5+6: the size of the range
- */
- ranges = of_get_property(dev, "ranges", &rlen);
- if (ranges == NULL)
- return;
- hose->io_base_phys = 0;
- while ((rlen -= np * sizeof(unsigned int)) >= 0) {
- res = NULL;
- pci_space = ranges[0];
- pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
- cpu_phys_addr = of_translate_address(dev, &ranges[3]);
- size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
- ranges += np;
- if (size == 0)
- continue;
-
- /* Now consume following elements while they are contiguous */
- while (rlen >= np * sizeof(unsigned int)) {
- unsigned long addr, phys;
-
- if (ranges[0] != pci_space)
- break;
- addr = ((unsigned long)ranges[1] << 32) | ranges[2];
- phys = ranges[3];
- if (na >= 2)
- phys = (phys << 32) | ranges[4];
- if (addr != pci_addr + size ||
- phys != cpu_phys_addr + size)
- break;
-
- size += ((unsigned long)ranges[na+3] << 32)
- | ranges[na+4];
- ranges += np;
- rlen -= np * sizeof(unsigned int);
- }
-
- switch ((pci_space >> 24) & 0x3) {
- case 1: /* I/O space */
- hose->io_base_phys = cpu_phys_addr - pci_addr;
- /* handle from 0 to top of I/O window */
- hose->pci_io_size = pci_addr + size;
-
- res = &hose->io_resource;
- res->flags = IORESOURCE_IO;
- res->start = pci_addr;
- DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number,
- res->start, res->start + size - 1);
- break;
- case 2: /* memory space */
- memno = 0;
- while (memno < 3 && hose->mem_resources[memno].flags)
- ++memno;
-
- if (memno == 0)
- hose->pci_mem_offset = cpu_phys_addr - pci_addr;
- if (memno < 3) {
- res = &hose->mem_resources[memno];
- res->flags = IORESOURCE_MEM;
- res->start = cpu_phys_addr;
- DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number,
- res->start, res->start + size - 1);
- }
- break;
- }
- if (res != NULL) {
- res->name = dev->full_name;
- res->end = res->start + size - 1;
- res->parent = NULL;
- res->sibling = NULL;
- res->child = NULL;
- }
- }
-}
-
#ifdef CONFIG_HOTPLUG
int pcibios_unmap_io_space(struct pci_bus *bus)
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index b847aa1..882b8bc 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -15,6 +15,13 @@
#include <linux/pci.h>
#include <asm/pci-bridge.h>
+struct ranges_pci {
+ unsigned int pci_space;
+ u64 pci_addr;
+ phys_addr_t phys_addr;
+ u64 size;
+} __attribute__((packed));
+
extern unsigned long isa_io_base;
extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
^ permalink raw reply related
* Re: [PATCH 2/3] pm: Handle HID0_SLEEP in the TLF_NAPPING hack.
From: Scott Wood @ 2007-09-11 21:50 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18151.2374.68378.969061@cargo.ozlabs.ibm.com>
Paul Mackerras wrote:
> Scott Wood writes:
>
>> The e300 core (and probably most other 6xx chips) can only come out of
>> sleep mode with an interrupt. However, interrupts are logically disabled
>> by the power management layer.
>>
>> This hack extends the existing doze/nap hack to also suppress the running
>> of the interrupt handler when in sleep mode.
>
> Having thought about this for a bit, I have come to the conclusion
> that it would be a lot cleaner to use a new TLF_SLEEPING bit rather
> than having to read HID0 to know whether we were napping or sleeping.
> There are plenty of bits left in thread_info.local_flags; we've only
> used 1 so far. :)
OK.
-Scott
^ permalink raw reply
* Re: [PATCH 3/3] Add 6xx-style HID0_SLEEP support.
From: Scott Wood @ 2007-09-11 21:47 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18151.2530.439805.386163@cargo.ozlabs.ibm.com>
Paul Mackerras wrote:
> Scott Wood writes:
>
>> +_GLOBAL(mpc6xx_enter_sleep)
>
> The name is slightly unfortunate as powerbooks also use 6xx-family
> processors but enter sleep in a quite different manner, because they
> exit sleep with a reset. Can you think of a better name, that gives a
> hint that this is the one to use if we are exiting sleep with an
> interrupt rather than a reset?
The nomenclature I've been using on 83xx is to call it deep sleep if you
exit with a reset, but if powerbooks can only do deep sleep, and it's
already been called plain old "sleep", then I guess something else is
warranted.
mpc6xx_enter_coreonly_sleep?
mpc6xx_enter_light_sleep?
mpc6xx_enter_standby?
-Scott
^ permalink raw reply
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