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

Commit bd3e57f9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 platform changes from Ingo Molnar:
 "This tree mostly involves various APIC driver cleanups/robustization,
  and vSMP motivated platform callback improvements/cleanups"

Fix up trivial conflict due to printk cleanup right next to return value
change.

* 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (29 commits)
  Revert "x86/early_printk: Replace obsolete simple_strtoul() usage with kstrtoint()"
  x86/apic/x2apic: Use multiple cluster members for the irq destination only with the explicit affinity
  x86/apic/x2apic: Limit the vector reservation to the user specified mask
  x86/apic: Optimize cpu traversal in __assign_irq_vector() using domain membership
  x86/vsmp: Fix vector_allocation_domain's return value
  irq/apic: Use config_enabled(CONFIG_SMP) checks to clean up irq_set_affinity() for UP
  x86/vsmp: Fix linker error when CONFIG_PROC_FS is not set
  x86/apic/es7000: Make apicid of a cluster (not CPU) from a cpumask
  x86/apic/es7000+summit: Always make valid apicid from a cpumask
  x86/apic/es7000+summit: Fix compile warning in cpu_mask_to_apicid()
  x86/apic: Fix ugly casting and branching in cpu_mask_to_apicid_and()
  x86/apic: Eliminate cpu_mask_to_apicid() operation
  x86/x2apic/cluster: Vector_allocation_domain() should return a value
  x86/apic/irq_remap: Silence a bogus pr_err()
  x86/vsmp: Ignore IOAPIC IRQ affinity if possible
  x86/apic: Make cpu_mask_to_apicid() operations check cpu_online_mask
  x86/apic: Make cpu_mask_to_apicid() operations return error code
  x86/apic: Avoid useless scanning thru a cpumask in assign_irq_vector()
  x86/apic: Try to spread IRQ vectors to different priority levels
  x86/apic: Factor out default vector_allocation_domain() operation
  ...
parents 3fad0953 36d93d88
Loading
Loading
Loading
Loading
+48 −13
Original line number Diff line number Diff line
@@ -306,7 +306,8 @@ struct apic {
	unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid);
	unsigned long (*check_apicid_present)(int apicid);

	void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
	void (*vector_allocation_domain)(int cpu, struct cpumask *retmask,
					 const struct cpumask *mask);
	void (*init_apic_ldr)(void);

	void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
@@ -331,9 +332,9 @@ struct apic {
	unsigned long (*set_apic_id)(unsigned int id);
	unsigned long apic_id_mask;

	unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask);
	unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
					       const struct cpumask *andmask);
	int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
				      const struct cpumask *andmask,
				      unsigned int *apicid);

	/* ipi */
	void (*send_IPI_mask)(const struct cpumask *mask, int vector);
@@ -537,6 +538,11 @@ static inline const struct cpumask *default_target_cpus(void)
#endif
}

static inline const struct cpumask *online_target_cpus(void)
{
	return cpu_online_mask;
}

DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid);


@@ -586,21 +592,50 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)

#endif

static inline unsigned int
default_cpu_mask_to_apicid(const struct cpumask *cpumask)
static inline int
flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
			    const struct cpumask *andmask,
			    unsigned int *apicid)
{
	return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
	unsigned long cpu_mask = cpumask_bits(cpumask)[0] &
				 cpumask_bits(andmask)[0] &
				 cpumask_bits(cpu_online_mask)[0] &
				 APIC_ALL_CPUS;

	if (likely(cpu_mask)) {
		*apicid = (unsigned int)cpu_mask;
		return 0;
	} else {
		return -EINVAL;
	}
}

static inline unsigned int
extern int
default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
			       const struct cpumask *andmask)
			       const struct cpumask *andmask,
			       unsigned int *apicid);

static inline void
flat_vector_allocation_domain(int cpu, struct cpumask *retmask,
			      const struct cpumask *mask)
{
	unsigned long mask1 = cpumask_bits(cpumask)[0];
	unsigned long mask2 = cpumask_bits(andmask)[0];
	unsigned long mask3 = cpumask_bits(cpu_online_mask)[0];
	/* Careful. Some cpus do not strictly honor the set of cpus
	 * specified in the interrupt destination when using lowest
	 * priority interrupt delivery mode.
	 *
	 * In particular there was a hyperthreading cpu observed to
	 * deliver interrupts to the wrong hyperthread when only one
	 * hyperthread was specified in the interrupt desitination.
	 */
	cpumask_clear(retmask);
	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}

	return (unsigned int)(mask1 & mask2 & mask3);
static inline void
default_vector_allocation_domain(int cpu, struct cpumask *retmask,
				 const struct cpumask *mask)
{
	cpumask_copy(retmask, cpumask_of(cpu));
}

static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid)
+0 −18
Original line number Diff line number Diff line
@@ -9,15 +9,6 @@
#include <asm/ipi.h>
#include <linux/cpumask.h>

/*
 * Need to use more than cpu 0, because we need more vectors
 * when MSI-X are used.
 */
static const struct cpumask *x2apic_target_cpus(void)
{
	return cpu_online_mask;
}

static int x2apic_apic_id_valid(int apicid)
{
	return 1;
@@ -28,15 +19,6 @@ static int x2apic_apic_id_registered(void)
	return 1;
}

/*
 * For now each logical cpu is in its own vector allocation domain.
 */
static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
	cpumask_clear(retmask);
	cpumask_set_cpu(cpu, retmask);
}

static void
__x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest)
{
+2 −2
Original line number Diff line number Diff line
@@ -156,7 +156,6 @@ struct x86_cpuinit_ops {
/**
 * struct x86_platform_ops - platform specific runtime functions
 * @calibrate_tsc:		calibrate TSC
 * @wallclock_init:		init the wallclock device
 * @get_wallclock:		get time from HW clock like RTC etc.
 * @set_wallclock:		set time back to HW clock
 * @is_untracked_pat_range	exclude from PAT logic
@@ -164,10 +163,10 @@ struct x86_cpuinit_ops {
 * @i8042_detect		pre-detect if i8042 controller exists
 * @save_sched_clock_state:	save state for sched_clock() on suspend
 * @restore_sched_clock_state:	restore state for sched_clock() on resume
 * @apic_post_init:		adjust apic if neeeded
 */
struct x86_platform_ops {
	unsigned long (*calibrate_tsc)(void);
	void (*wallclock_init)(void);
	unsigned long (*get_wallclock)(void);
	int (*set_wallclock)(unsigned long nowtime);
	void (*iommu_shutdown)(void);
@@ -177,6 +176,7 @@ struct x86_platform_ops {
	int (*i8042_detect)(void);
	void (*save_sched_clock_state)(void);
	void (*restore_sched_clock_state)(void);
	void (*apic_post_init)(void);
};

struct pci_dev;
+19 −0
Original line number Diff line number Diff line
@@ -2123,6 +2123,25 @@ void default_init_apic_ldr(void)
	apic_write(APIC_LDR, val);
}

int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
				   const struct cpumask *andmask,
				   unsigned int *apicid)
{
	unsigned int cpu;

	for_each_cpu_and(cpu, cpumask, andmask) {
		if (cpumask_test_cpu(cpu, cpu_online_mask))
			break;
	}

	if (likely(cpu < nr_cpu_ids)) {
		*apicid = per_cpu(x86_cpu_to_apicid, cpu);
		return 0;
	}

	return -EINVAL;
}

/*
 * Power management
 */
+6 −70
Original line number Diff line number Diff line
@@ -36,25 +36,6 @@ static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
	return 1;
}

static const struct cpumask *flat_target_cpus(void)
{
	return cpu_online_mask;
}

static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
	/* Careful. Some cpus do not strictly honor the set of cpus
	 * specified in the interrupt destination when using lowest
	 * priority interrupt delivery mode.
	 *
	 * In particular there was a hyperthreading cpu observed to
	 * deliver interrupts to the wrong hyperthread when only one
	 * hyperthread was specified in the interrupt desitination.
	 */
	cpumask_clear(retmask);
	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}

/*
 * Set up the logical destination ID.
 *
@@ -186,7 +167,7 @@ static struct apic apic_flat = {
	.irq_delivery_mode		= dest_LowestPrio,
	.irq_dest_mode			= 1, /* logical */

	.target_cpus			= flat_target_cpus,
	.target_cpus			= online_target_cpus,
	.disable_esr			= 0,
	.dest_logical			= APIC_DEST_LOGICAL,
	.check_apicid_used		= NULL,
@@ -210,8 +191,7 @@ static struct apic apic_flat = {
	.set_apic_id			= set_apic_id,
	.apic_id_mask			= 0xFFu << 24,

	.cpu_mask_to_apicid		= default_cpu_mask_to_apicid,
	.cpu_mask_to_apicid_and		= default_cpu_mask_to_apicid_and,
	.cpu_mask_to_apicid_and		= flat_cpu_mask_to_apicid_and,

	.send_IPI_mask			= flat_send_IPI_mask,
	.send_IPI_mask_allbutself	= flat_send_IPI_mask_allbutself,
@@ -262,17 +242,6 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
	return 0;
}

static const struct cpumask *physflat_target_cpus(void)
{
	return cpu_online_mask;
}

static void physflat_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
	cpumask_clear(retmask);
	cpumask_set_cpu(cpu, retmask);
}

static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector)
{
	default_send_IPI_mask_sequence_phys(cpumask, vector);
@@ -294,38 +263,6 @@ static void physflat_send_IPI_all(int vector)
	physflat_send_IPI_mask(cpu_online_mask, vector);
}

static unsigned int physflat_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
	int cpu;

	/*
	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
	 * May as well be the first.
	 */
	cpu = cpumask_first(cpumask);
	if ((unsigned)cpu < nr_cpu_ids)
		return per_cpu(x86_cpu_to_apicid, cpu);
	else
		return BAD_APICID;
}

static unsigned int
physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
				const struct cpumask *andmask)
{
	int cpu;

	/*
	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
	 * May as well be the first.
	 */
	for_each_cpu_and(cpu, cpumask, andmask) {
		if (cpumask_test_cpu(cpu, cpu_online_mask))
			break;
	}
	return per_cpu(x86_cpu_to_apicid, cpu);
}

static int physflat_probe(void)
{
	if (apic == &apic_physflat || num_possible_cpus() > 8)
@@ -345,13 +282,13 @@ static struct apic apic_physflat = {
	.irq_delivery_mode		= dest_Fixed,
	.irq_dest_mode			= 0, /* physical */

	.target_cpus			= physflat_target_cpus,
	.target_cpus			= online_target_cpus,
	.disable_esr			= 0,
	.dest_logical			= 0,
	.check_apicid_used		= NULL,
	.check_apicid_present		= NULL,

	.vector_allocation_domain	= physflat_vector_allocation_domain,
	.vector_allocation_domain	= default_vector_allocation_domain,
	/* not needed, but shouldn't hurt: */
	.init_apic_ldr			= flat_init_apic_ldr,

@@ -370,8 +307,7 @@ static struct apic apic_physflat = {
	.set_apic_id			= set_apic_id,
	.apic_id_mask			= 0xFFu << 24,

	.cpu_mask_to_apicid		= physflat_cpu_mask_to_apicid,
	.cpu_mask_to_apicid_and		= physflat_cpu_mask_to_apicid_and,
	.cpu_mask_to_apicid_and		= default_cpu_mask_to_apicid_and,

	.send_IPI_mask			= physflat_send_IPI_mask,
	.send_IPI_mask_allbutself	= physflat_send_IPI_mask_allbutself,
Loading