diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index efaf2d4f9c3c..2270a777d647 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/crash_dump.h> | 27 | #include <linux/crash_dump.h> |
28 | #include <linux/reboot.h> | 28 | #include <linux/reboot.h> |
29 | #include <linux/memory.h> | ||
29 | 30 | ||
30 | #include <asm/uv/uv_mmrs.h> | 31 | #include <asm/uv/uv_mmrs.h> |
31 | #include <asm/uv/uv_hub.h> | 32 | #include <asm/uv/uv_hub.h> |
@@ -392,6 +393,40 @@ extern int uv_hub_info_version(void) | |||
392 | } | 393 | } |
393 | EXPORT_SYMBOL(uv_hub_info_version); | 394 | EXPORT_SYMBOL(uv_hub_info_version); |
394 | 395 | ||
396 | /* Default UV memory block size is 2GB */ | ||
397 | static unsigned long mem_block_size = (2UL << 30); | ||
398 | |||
399 | static __init int adj_blksize(u32 lgre) | ||
400 | { | ||
401 | unsigned long base = (unsigned long)lgre << UV_GAM_RANGE_SHFT; | ||
402 | unsigned long size; | ||
403 | |||
404 | for (size = mem_block_size; size > MIN_MEMORY_BLOCK_SIZE; size >>= 1) | ||
405 | if (IS_ALIGNED(base, size)) | ||
406 | break; | ||
407 | |||
408 | if (size >= mem_block_size) | ||
409 | return 0; | ||
410 | |||
411 | mem_block_size = size; | ||
412 | return 1; | ||
413 | } | ||
414 | |||
415 | static __init void set_block_size(void) | ||
416 | { | ||
417 | unsigned int order = ffs(mem_block_size); | ||
418 | |||
419 | if (order) { | ||
420 | /* adjust for ffs return of 1..64 */ | ||
421 | set_memory_block_size_order(order - 1); | ||
422 | pr_info("UV: mem_block_size set to 0x%lx\n", mem_block_size); | ||
423 | } else { | ||
424 | /* bad or zero value, default to 1UL << 31 (2GB) */ | ||
425 | pr_err("UV: mem_block_size error with 0x%lx\n", mem_block_size); | ||
426 | set_memory_block_size_order(31); | ||
427 | } | ||
428 | } | ||
429 | |||
395 | /* Build GAM range lookup table: */ | 430 | /* Build GAM range lookup table: */ |
396 | static __init void build_uv_gr_table(void) | 431 | static __init void build_uv_gr_table(void) |
397 | { | 432 | { |
@@ -1180,23 +1215,30 @@ static void __init decode_gam_rng_tbl(unsigned long ptr) | |||
1180 | << UV_GAM_RANGE_SHFT); | 1215 | << UV_GAM_RANGE_SHFT); |
1181 | int order = 0; | 1216 | int order = 0; |
1182 | char suffix[] = " KMGTPE"; | 1217 | char suffix[] = " KMGTPE"; |
1218 | int flag = ' '; | ||
1183 | 1219 | ||
1184 | while (size > 9999 && order < sizeof(suffix)) { | 1220 | while (size > 9999 && order < sizeof(suffix)) { |
1185 | size /= 1024; | 1221 | size /= 1024; |
1186 | order++; | 1222 | order++; |
1187 | } | 1223 | } |
1188 | 1224 | ||
1225 | /* adjust max block size to current range start */ | ||
1226 | if (gre->type == 1 || gre->type == 2) | ||
1227 | if (adj_blksize(lgre)) | ||
1228 | flag = '*'; | ||
1229 | |||
1189 | if (!index) { | 1230 | if (!index) { |
1190 | pr_info("UV: GAM Range Table...\n"); | 1231 | pr_info("UV: GAM Range Table...\n"); |
1191 | pr_info("UV: # %20s %14s %5s %4s %5s %3s %2s\n", "Range", "", "Size", "Type", "NASID", "SID", "PN"); | 1232 | pr_info("UV: # %20s %14s %6s %4s %5s %3s %2s\n", "Range", "", "Size", "Type", "NASID", "SID", "PN"); |
1192 | } | 1233 | } |
1193 | pr_info("UV: %2d: 0x%014lx-0x%014lx %5lu%c %3d %04x %02x %02x\n", | 1234 | pr_info("UV: %2d: 0x%014lx-0x%014lx%c %5lu%c %3d %04x %02x %02x\n", |
1194 | index++, | 1235 | index++, |
1195 | (unsigned long)lgre << UV_GAM_RANGE_SHFT, | 1236 | (unsigned long)lgre << UV_GAM_RANGE_SHFT, |
1196 | (unsigned long)gre->limit << UV_GAM_RANGE_SHFT, | 1237 | (unsigned long)gre->limit << UV_GAM_RANGE_SHFT, |
1197 | size, suffix[order], | 1238 | flag, size, suffix[order], |
1198 | gre->type, gre->nasid, gre->sockid, gre->pnode); | 1239 | gre->type, gre->nasid, gre->sockid, gre->pnode); |
1199 | 1240 | ||
1241 | /* update to next range start */ | ||
1200 | lgre = gre->limit; | 1242 | lgre = gre->limit; |
1201 | if (sock_min > gre->sockid) | 1243 | if (sock_min > gre->sockid) |
1202 | sock_min = gre->sockid; | 1244 | sock_min = gre->sockid; |
@@ -1427,6 +1469,7 @@ static void __init uv_system_init_hub(void) | |||
1427 | 1469 | ||
1428 | build_socket_tables(); | 1470 | build_socket_tables(); |
1429 | build_uv_gr_table(); | 1471 | build_uv_gr_table(); |
1472 | set_block_size(); | ||
1430 | uv_init_hub_info(&hub_info); | 1473 | uv_init_hub_info(&hub_info); |
1431 | uv_possible_blades = num_possible_nodes(); | 1474 | uv_possible_blades = num_possible_nodes(); |
1432 | if (!_node_to_pnode) | 1475 | if (!_node_to_pnode) |