Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8293dd6f authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'x86/core' into tracing/ftrace



Semantic merge:

  kernel/trace/trace_functions_graph.c

Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parents 631595fb 467c88fe
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -3,14 +3,4 @@

#include <asm-generic/percpu.h>

#ifdef CONFIG_MODULES
#define PERCPU_MODULE_RESERVE 8192
#else
#define PERCPU_MODULE_RESERVE 0
#endif

#define PERCPU_ENOUGH_ROOM \
	(ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES) + \
	 PERCPU_MODULE_RESERVE)

#endif	/* __ARCH_BLACKFIN_PERCPU__ */
+10 −6
Original line number Diff line number Diff line
@@ -4,11 +4,6 @@
#undef notrace
#define notrace __attribute__((no_instrument_function))

#ifdef CONFIG_X86_64
#define __ALIGN .p2align 4,,15
#define __ALIGN_STR ".p2align 4,,15"
#endif

#ifdef CONFIG_X86_32
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
/*
@@ -50,16 +45,25 @@
	__asmlinkage_protect_n(ret, "g" (arg1), "g" (arg2), "g" (arg3), \
			      "g" (arg4), "g" (arg5), "g" (arg6))

#endif
#endif /* CONFIG_X86_32 */

#ifdef __ASSEMBLY__

#define GLOBAL(name)	\
	.globl name;	\
	name:

#ifdef CONFIG_X86_64
#define __ALIGN .p2align 4,,15
#define __ALIGN_STR ".p2align 4,,15"
#endif

#ifdef CONFIG_X86_ALIGNMENT_16
#define __ALIGN .align 16,0x90
#define __ALIGN_STR ".align 16,0x90"
#endif

#endif /* __ASSEMBLY__ */

#endif /* _ASM_X86_LINKAGE_H */
+52 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/apic.h>
#include <asm/cpu.h>

#ifdef CONFIG_X86_64
# include <asm/numa_64.h>
@@ -141,6 +142,55 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c)
	}
}

static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_SMP
	/* calling is from identify_secondary_cpu() ? */
	if (c->cpu_index == boot_cpu_id)
		return;

	/*
	 * Certain Athlons might work (for various values of 'work') in SMP
	 * but they are not certified as MP capable.
	 */
	/* Athlon 660/661 is valid. */
	if ((c->x86_model == 6) && ((c->x86_mask == 0) ||
	    (c->x86_mask == 1)))
		goto valid_k7;

	/* Duron 670 is valid */
	if ((c->x86_model == 7) && (c->x86_mask == 0))
		goto valid_k7;

	/*
	 * Athlon 662, Duron 671, and Athlon >model 7 have capability
	 * bit. It's worth noting that the A5 stepping (662) of some
	 * Athlon XP's have the MP bit set.
	 * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for
	 * more.
	 */
	if (((c->x86_model == 6) && (c->x86_mask >= 2)) ||
	    ((c->x86_model == 7) && (c->x86_mask >= 1)) ||
	     (c->x86_model > 7))
		if (cpu_has_mp)
			goto valid_k7;

	/* If we get here, not a certified SMP capable AMD system. */

	/*
	 * Don't taint if we are running SMP kernel on a single non-MP
	 * approved Athlon
	 */
	WARN_ONCE(1, "WARNING: This combination of AMD"
		"processors is not suitable for SMP.\n");
	if (!test_taint(TAINT_UNSAFE_SMP))
		add_taint(TAINT_UNSAFE_SMP);

valid_k7:
	;
#endif
}

static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
{
	u32 l, h;
@@ -175,6 +225,8 @@ static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
	}

	set_cpu_cap(c, X86_FEATURE_K7);

	amd_k7_smp_check(c);
}
#endif

+25 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <asm/uaccess.h>
#include <asm/ds.h>
#include <asm/bugs.h>
#include <asm/cpu.h>

#ifdef CONFIG_X86_64
#include <asm/topology.h>
@@ -116,6 +117,28 @@ static void __cpuinit trap_init_f00f_bug(void)
}
#endif

static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_SMP
	/* calling is from identify_secondary_cpu() ? */
	if (c->cpu_index == boot_cpu_id)
		return;

	/*
	 * Mask B, Pentium, but not Pentium MMX
	 */
	if (c->x86 == 5 &&
	    c->x86_mask >= 1 && c->x86_mask <= 4 &&
	    c->x86_model <= 3) {
		/*
		 * Remember we have B step Pentia with bugs
		 */
		WARN_ONCE(1, "WARNING: SMP operation may be unreliable"
				    "with B stepping processors.\n");
	}
#endif
}

static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
{
	unsigned long lo, hi;
@@ -192,6 +215,8 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
#ifdef CONFIG_X86_NUMAQ
	numaq_tsc_disable();
#endif

	intel_smp_check(c);
}
#else
static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
+52 −21
Original line number Diff line number Diff line
@@ -42,6 +42,19 @@ unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = {
};
EXPORT_SYMBOL(__per_cpu_offset);

/*
 * On x86_64 symbols referenced from code should be reachable using
 * 32bit relocations.  Reserve space for static percpu variables in
 * modules so that they are always served from the first chunk which
 * is located at the percpu segment base.  On x86_32, anything can
 * address anywhere.  No need to reserve space in the first chunk.
 */
#ifdef CONFIG_X86_64
#define PERCPU_FIRST_CHUNK_RESERVE	PERCPU_MODULE_RESERVE
#else
#define PERCPU_FIRST_CHUNK_RESERVE	0
#endif

/**
 * pcpu_need_numa - determine percpu allocation needs to consider NUMA
 *
@@ -141,7 +154,7 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
{
	static struct vm_struct vm;
	pg_data_t *last;
	size_t ptrs_size;
	size_t ptrs_size, dyn_size;
	unsigned int cpu;
	ssize_t ret;

@@ -169,12 +182,14 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
	 * Currently supports only single page.  Supporting multiple
	 * pages won't be too difficult if it ever becomes necessary.
	 */
	pcpur_size = PFN_ALIGN(static_size + PERCPU_DYNAMIC_RESERVE);
	pcpur_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE +
			       PERCPU_DYNAMIC_RESERVE);
	if (pcpur_size > PMD_SIZE) {
		pr_warning("PERCPU: static data is larger than large page, "
			   "can't use large page\n");
		return -EINVAL;
	}
	dyn_size = pcpur_size - static_size - PERCPU_FIRST_CHUNK_RESERVE;

	/* allocate pointer array and alloc large pages */
	ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0]));
@@ -217,8 +232,9 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
	pr_info("PERCPU: Remapped at %p with large pages, static data "
		"%zu bytes\n", vm.addr, static_size);

	ret = pcpu_setup_first_chunk(pcpur_get_page, static_size, PMD_SIZE,
				     pcpur_size - static_size, vm.addr, NULL);
	ret = pcpu_setup_first_chunk(pcpur_get_page, static_size,
				     PERCPU_FIRST_CHUNK_RESERVE,
				     PMD_SIZE, dyn_size, vm.addr, NULL);
	goto out_free_ar;

enomem:
@@ -241,24 +257,31 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
 * Embedding allocator
 *
 * The first chunk is sized to just contain the static area plus
 * PERCPU_DYNAMIC_RESERVE and allocated as a contiguous area using
 * bootmem allocator and used as-is without being mapped into vmalloc
 * area.  This enables the first chunk to piggy back on the linear
 * physical PMD mapping and doesn't add any additional pressure to
 * TLB.
 * module and dynamic reserves, and allocated as a contiguous area
 * using bootmem allocator and used as-is without being mapped into
 * vmalloc area.  This enables the first chunk to piggy back on the
 * linear physical PMD mapping and doesn't add any additional pressure
 * to TLB.  Note that if the needed size is smaller than the minimum
 * unit size, the leftover is returned to the bootmem allocator.
 */
static void *pcpue_ptr __initdata;
static size_t pcpue_size __initdata;
static size_t pcpue_unit_size __initdata;

static struct page * __init pcpue_get_page(unsigned int cpu, int pageno)
{
	return virt_to_page(pcpue_ptr + cpu * pcpue_unit_size
			    + ((size_t)pageno << PAGE_SHIFT));
	size_t off = (size_t)pageno << PAGE_SHIFT;

	if (off >= pcpue_size)
		return NULL;

	return virt_to_page(pcpue_ptr + cpu * pcpue_unit_size + off);
}

static ssize_t __init setup_pcpu_embed(size_t static_size)
{
	unsigned int cpu;
	size_t dyn_size;

	/*
	 * If large page isn't supported, there's no benefit in doing
@@ -269,25 +292,32 @@ static ssize_t __init setup_pcpu_embed(size_t static_size)
		return -EINVAL;

	/* allocate and copy */
	pcpue_unit_size = PFN_ALIGN(static_size + PERCPU_DYNAMIC_RESERVE);
	pcpue_unit_size = max_t(size_t, pcpue_unit_size, PCPU_MIN_UNIT_SIZE);
	pcpue_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE +
			       PERCPU_DYNAMIC_RESERVE);
	pcpue_unit_size = max_t(size_t, pcpue_size, PCPU_MIN_UNIT_SIZE);
	dyn_size = pcpue_size - static_size - PERCPU_FIRST_CHUNK_RESERVE;

	pcpue_ptr = pcpu_alloc_bootmem(0, num_possible_cpus() * pcpue_unit_size,
				       PAGE_SIZE);
	if (!pcpue_ptr)
		return -ENOMEM;

	for_each_possible_cpu(cpu)
		memcpy(pcpue_ptr + cpu * pcpue_unit_size, __per_cpu_load,
		       static_size);
	for_each_possible_cpu(cpu) {
		void *ptr = pcpue_ptr + cpu * pcpue_unit_size;

		free_bootmem(__pa(ptr + pcpue_size),
			     pcpue_unit_size - pcpue_size);
		memcpy(ptr, __per_cpu_load, static_size);
	}

	/* we're ready, commit */
	pr_info("PERCPU: Embedded %zu pages at %p, static data %zu bytes\n",
		pcpue_unit_size >> PAGE_SHIFT, pcpue_ptr, static_size);
		pcpue_size >> PAGE_SHIFT, pcpue_ptr, static_size);

	return pcpu_setup_first_chunk(pcpue_get_page, static_size,
				      pcpue_unit_size,
				      pcpue_unit_size - static_size, pcpue_ptr,
				      NULL);
				      PERCPU_FIRST_CHUNK_RESERVE,
				      pcpue_unit_size, dyn_size,
				      pcpue_ptr, NULL);
}

/*
@@ -344,7 +374,8 @@ static ssize_t __init setup_pcpu_4k(size_t static_size)
	pr_info("PERCPU: Allocated %d 4k pages, static data %zu bytes\n",
		pcpu4k_nr_static_pages, static_size);

	ret = pcpu_setup_first_chunk(pcpu4k_get_page, static_size, 0, 0, NULL,
	ret = pcpu_setup_first_chunk(pcpu4k_get_page, static_size,
				     PERCPU_FIRST_CHUNK_RESERVE, -1, -1, NULL,
				     pcpu4k_populate_pte);
	goto out_free_ar;

Loading