Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 5389
b: refs/heads/master
c: f8d3119
h: refs/heads/master
i:
  5387: d960a38
v: v3
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Jul 29, 2005
1 parent c4baf39 commit 34aa442
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 37a47e65fa58d413a31f27ee88f6cb98583b6157
refs/heads/master: f8d311939f9d2b2a5e935df8dceb98b7cbe08d43
33 changes: 24 additions & 9 deletions trunk/arch/x86_64/kernel/genapic.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };

extern struct genapic apic_cluster;
extern struct genapic apic_flat;
extern struct genapic apic_physflat;

struct genapic *genapic = &apic_flat;

Expand All @@ -44,12 +45,7 @@ void __init clustered_apic_check(void)
u8 clusters, max_cluster;
u8 id;
u8 cluster_cnt[NUM_APIC_CLUSTERS];

if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
/* AMD always uses flat mode right now */
genapic = &apic_flat;
goto print;
}
int num_cpus = 0;

#if defined(CONFIG_ACPI_BUS)
/*
Expand All @@ -64,15 +60,34 @@ void __init clustered_apic_check(void)
#endif

memset(cluster_cnt, 0, sizeof(cluster_cnt));

for (i = 0; i < NR_CPUS; i++) {
id = bios_cpu_apicid[i];
if (id != BAD_APICID)
cluster_cnt[APIC_CLUSTERID(id)]++;
if (id == BAD_APICID)
continue;
num_cpus++;
cluster_cnt[APIC_CLUSTERID(id)]++;
}

/* Don't use clustered mode on AMD platforms. */
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
genapic = &apic_physflat;
#ifndef CONFIG_CPU_HOTPLUG
/* In the CPU hotplug case we cannot use broadcast mode
because that opens a race when a CPU is removed.
Stay at physflat mode in this case.
It is bad to do this unconditionally though. Once
we have ACPI platform support for CPU hotplug
we should detect hotplug capablity from ACPI tables and
only do this when really needed. -AK */
if (num_cpus <= 8)
genapic = &apic_flat;
#endif
goto print;
}

clusters = 0;
max_cluster = 0;

for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
if (cluster_cnt[i] > 0) {
++clusters;
Expand Down
62 changes: 61 additions & 1 deletion trunk/arch/x86_64/kernel/genapic_flat.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright 2004 James Cleverdon, IBM.
* Subject to the GNU Public License, v.2
*
* Flat APIC subarch code. Maximum 8 CPUs, logical delivery.
* Flat APIC subarch code.
*
* Hacked for x86-64 by James Cleverdon from i386 architecture code by
* Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
Expand Down Expand Up @@ -119,3 +119,63 @@ struct genapic apic_flat = {
.cpu_mask_to_apicid = flat_cpu_mask_to_apicid,
.phys_pkg_id = phys_pkg_id,
};

/*
* Physflat mode is used when there are more than 8 CPUs on a AMD system.
* We cannot use logical delivery in this case because the mask
* overflows, so use physical mode.
*/

static cpumask_t physflat_target_cpus(void)
{
return cpumask_of_cpu(0);
}

static void physflat_send_IPI_mask(cpumask_t cpumask, int vector)
{
send_IPI_mask_sequence(cpumask, vector);
}

static void physflat_send_IPI_allbutself(int vector)
{
cpumask_t allbutme = cpu_online_map;
int me = get_cpu();
cpu_clear(me, allbutme);
physflat_send_IPI_mask(allbutme, vector);
put_cpu();
}

static void physflat_send_IPI_all(int vector)
{
physflat_send_IPI_mask(cpu_online_map, vector);
}

static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)
{
int cpu;

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

struct genapic apic_physflat = {
.name = "physical flat",
.int_delivery_mode = dest_LowestPrio,
.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
.int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_LOWEST,
.target_cpus = physflat_target_cpus,
.apic_id_registered = flat_apic_id_registered,
.init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/
.send_IPI_all = physflat_send_IPI_all,
.send_IPI_allbutself = physflat_send_IPI_allbutself,
.send_IPI_mask = physflat_send_IPI_mask,
.cpu_mask_to_apicid = physflat_cpu_mask_to_apicid,
.phys_pkg_id = phys_pkg_id,
};

0 comments on commit 34aa442

Please sign in to comment.