diff options
author | Dean Nelson <dcn@sgi.com> | 2008-07-30 01:34:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-30 12:41:50 -0400 |
commit | ee6665e3b6e1283c30ae240732af1345bc02154e (patch) | |
tree | 91fbfb2a4cab26e3979df44a9bdcd6851efc9c50 /drivers/misc/sgi-xp/xpc_sn2.c | |
parent | a7b4d509205db5e9cd3ffc77b306d7b10fe6a34d (diff) |
sgi-xp: isolate remote copy buffer to sn2 only
Make the remote copy buffer an sn2 only item.
Signed-off-by: Dean Nelson <dcn@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-xp/xpc_sn2.c')
-rw-r--r-- | drivers/misc/sgi-xp/xpc_sn2.c | 88 |
1 files changed, 69 insertions, 19 deletions
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index e5dc8c44c6fb..9c0c29a2ac86 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c +++ b/drivers/misc/sgi-xp/xpc_sn2.c | |||
@@ -19,6 +19,43 @@ | |||
19 | #include <asm/sn/sn_sal.h> | 19 | #include <asm/sn/sn_sal.h> |
20 | #include "xpc.h" | 20 | #include "xpc.h" |
21 | 21 | ||
22 | /* | ||
23 | * Define the number of u64s required to represent all the C-brick nasids | ||
24 | * as a bitmap. The cross-partition kernel modules deal only with | ||
25 | * C-brick nasids, thus the need for bitmaps which don't account for | ||
26 | * odd-numbered (non C-brick) nasids. | ||
27 | */ | ||
28 | #define XPC_MAX_PHYSNODES_SN2 (MAX_NUMALINK_NODES / 2) | ||
29 | #define XP_NASID_MASK_BYTES_SN2 ((XPC_MAX_PHYSNODES_SN2 + 7) / 8) | ||
30 | #define XP_NASID_MASK_WORDS_SN2 ((XPC_MAX_PHYSNODES_SN2 + 63) / 64) | ||
31 | |||
32 | /* | ||
33 | * Memory for XPC's amo variables is allocated by the MSPEC driver. These | ||
34 | * pages are located in the lowest granule. The lowest granule uses 4k pages | ||
35 | * for cached references and an alternate TLB handler to never provide a | ||
36 | * cacheable mapping for the entire region. This will prevent speculative | ||
37 | * reading of cached copies of our lines from being issued which will cause | ||
38 | * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64 | ||
39 | * amo variables (based on XP_MAX_NPARTITIONS_SN2) to identify the senders of | ||
40 | * NOTIFY IRQs, 128 amo variables (based on XP_NASID_MASK_WORDS_SN2) to identify | ||
41 | * the senders of ACTIVATE IRQs, 1 amo variable to identify which remote | ||
42 | * partitions (i.e., XPCs) consider themselves currently engaged with the | ||
43 | * local XPC and 1 amo variable to request partition deactivation. | ||
44 | */ | ||
45 | #define XPC_NOTIFY_IRQ_AMOS_SN2 0 | ||
46 | #define XPC_ACTIVATE_IRQ_AMOS_SN2 (XPC_NOTIFY_IRQ_AMOS_SN2 + \ | ||
47 | XP_MAX_NPARTITIONS_SN2) | ||
48 | #define XPC_ENGAGED_PARTITIONS_AMO_SN2 (XPC_ACTIVATE_IRQ_AMOS_SN2 + \ | ||
49 | XP_NASID_MASK_WORDS_SN2) | ||
50 | #define XPC_DEACTIVATE_REQUEST_AMO_SN2 (XPC_ENGAGED_PARTITIONS_AMO_SN2 + 1) | ||
51 | |||
52 | /* | ||
53 | * Buffer used to store a local copy of portions of a remote partition's | ||
54 | * reserved page (either its header and part_nasids mask, or its vars). | ||
55 | */ | ||
56 | static char *xpc_remote_copy_buffer_sn2; | ||
57 | static void *xpc_remote_copy_buffer_base_sn2; | ||
58 | |||
22 | static struct xpc_vars_sn2 *xpc_vars; /* >>> Add _sn2 suffix? */ | 59 | static struct xpc_vars_sn2 *xpc_vars; /* >>> Add _sn2 suffix? */ |
23 | static struct xpc_vars_part_sn2 *xpc_vars_part; /* >>> Add _sn2 suffix? */ | 60 | static struct xpc_vars_part_sn2 *xpc_vars_part; /* >>> Add _sn2 suffix? */ |
24 | 61 | ||
@@ -176,7 +213,7 @@ xpc_send_activate_IRQ_sn2(u64 amos_page_pa, int from_nasid, int to_nasid, | |||
176 | int w_index = XPC_NASID_W_INDEX(from_nasid); | 213 | int w_index = XPC_NASID_W_INDEX(from_nasid); |
177 | int b_index = XPC_NASID_B_INDEX(from_nasid); | 214 | int b_index = XPC_NASID_B_INDEX(from_nasid); |
178 | struct amo *amos = (struct amo *)__va(amos_page_pa + | 215 | struct amo *amos = (struct amo *)__va(amos_page_pa + |
179 | (XPC_ACTIVATE_IRQ_AMOS * | 216 | (XPC_ACTIVATE_IRQ_AMOS_SN2 * |
180 | sizeof(struct amo))); | 217 | sizeof(struct amo))); |
181 | 218 | ||
182 | (void)xpc_send_IRQ_sn2(&amos[w_index], (1UL << b_index), to_nasid, | 219 | (void)xpc_send_IRQ_sn2(&amos[w_index], (1UL << b_index), to_nasid, |
@@ -189,7 +226,7 @@ xpc_send_local_activate_IRQ_sn2(int from_nasid) | |||
189 | int w_index = XPC_NASID_W_INDEX(from_nasid); | 226 | int w_index = XPC_NASID_W_INDEX(from_nasid); |
190 | int b_index = XPC_NASID_B_INDEX(from_nasid); | 227 | int b_index = XPC_NASID_B_INDEX(from_nasid); |
191 | struct amo *amos = (struct amo *)__va(xpc_vars->amos_page_pa + | 228 | struct amo *amos = (struct amo *)__va(xpc_vars->amos_page_pa + |
192 | (XPC_ACTIVATE_IRQ_AMOS * | 229 | (XPC_ACTIVATE_IRQ_AMOS_SN2 * |
193 | sizeof(struct amo))); | 230 | sizeof(struct amo))); |
194 | 231 | ||
195 | /* fake the sending and receipt of an activate IRQ from remote nasid */ | 232 | /* fake the sending and receipt of an activate IRQ from remote nasid */ |
@@ -395,7 +432,7 @@ xpc_indicate_partition_engaged_sn2(struct xpc_partition *part) | |||
395 | { | 432 | { |
396 | unsigned long irq_flags; | 433 | unsigned long irq_flags; |
397 | struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa + | 434 | struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa + |
398 | (XPC_ENGAGED_PARTITIONS_AMO * | 435 | (XPC_ENGAGED_PARTITIONS_AMO_SN2 * |
399 | sizeof(struct amo))); | 436 | sizeof(struct amo))); |
400 | 437 | ||
401 | local_irq_save(irq_flags); | 438 | local_irq_save(irq_flags); |
@@ -422,7 +459,7 @@ xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part) | |||
422 | struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; | 459 | struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; |
423 | unsigned long irq_flags; | 460 | unsigned long irq_flags; |
424 | struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa + | 461 | struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa + |
425 | (XPC_ENGAGED_PARTITIONS_AMO * | 462 | (XPC_ENGAGED_PARTITIONS_AMO_SN2 * |
426 | sizeof(struct amo))); | 463 | sizeof(struct amo))); |
427 | 464 | ||
428 | local_irq_save(irq_flags); | 465 | local_irq_save(irq_flags); |
@@ -455,7 +492,7 @@ xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part) | |||
455 | static int | 492 | static int |
456 | xpc_partition_engaged_sn2(short partid) | 493 | xpc_partition_engaged_sn2(short partid) |
457 | { | 494 | { |
458 | struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; | 495 | struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2; |
459 | 496 | ||
460 | /* our partition's amo variable ANDed with partid mask */ | 497 | /* our partition's amo variable ANDed with partid mask */ |
461 | return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) & | 498 | return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) & |
@@ -465,7 +502,7 @@ xpc_partition_engaged_sn2(short partid) | |||
465 | static int | 502 | static int |
466 | xpc_any_partition_engaged_sn2(void) | 503 | xpc_any_partition_engaged_sn2(void) |
467 | { | 504 | { |
468 | struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; | 505 | struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2; |
469 | 506 | ||
470 | /* our partition's amo variable */ | 507 | /* our partition's amo variable */ |
471 | return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0; | 508 | return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0; |
@@ -474,7 +511,7 @@ xpc_any_partition_engaged_sn2(void) | |||
474 | static void | 511 | static void |
475 | xpc_assume_partition_disengaged_sn2(short partid) | 512 | xpc_assume_partition_disengaged_sn2(short partid) |
476 | { | 513 | { |
477 | struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; | 514 | struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2; |
478 | 515 | ||
479 | /* clear bit(s) based on partid mask in our partition's amo */ | 516 | /* clear bit(s) based on partid mask in our partition's amo */ |
480 | FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND, | 517 | FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND, |
@@ -599,12 +636,12 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_page *rp) | |||
599 | xp_max_npartitions); | 636 | xp_max_npartitions); |
600 | 637 | ||
601 | /* initialize the activate IRQ related amo variables */ | 638 | /* initialize the activate IRQ related amo variables */ |
602 | for (i = 0; i < xp_nasid_mask_words; i++) | 639 | for (i = 0; i < xpc_nasid_mask_words; i++) |
603 | (void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS + i); | 640 | (void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS_SN2 + i); |
604 | 641 | ||
605 | /* initialize the engaged remote partitions related amo variables */ | 642 | /* initialize the engaged remote partitions related amo variables */ |
606 | (void)xpc_init_IRQ_amo_sn2(XPC_ENGAGED_PARTITIONS_AMO); | 643 | (void)xpc_init_IRQ_amo_sn2(XPC_ENGAGED_PARTITIONS_AMO_SN2); |
607 | (void)xpc_init_IRQ_amo_sn2(XPC_DEACTIVATE_REQUEST_AMO); | 644 | (void)xpc_init_IRQ_amo_sn2(XPC_DEACTIVATE_REQUEST_AMO_SN2); |
608 | 645 | ||
609 | return xpSuccess; | 646 | return xpSuccess; |
610 | } | 647 | } |
@@ -657,7 +694,7 @@ xpc_check_remote_hb_sn2(void) | |||
657 | short partid; | 694 | short partid; |
658 | enum xp_retval ret; | 695 | enum xp_retval ret; |
659 | 696 | ||
660 | remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer; | 697 | remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2; |
661 | 698 | ||
662 | for (partid = 0; partid < xp_max_npartitions; partid++) { | 699 | for (partid = 0; partid < xp_max_npartitions; partid++) { |
663 | 700 | ||
@@ -749,7 +786,7 @@ xpc_request_partition_deactivation_sn2(struct xpc_partition *part) | |||
749 | struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; | 786 | struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; |
750 | unsigned long irq_flags; | 787 | unsigned long irq_flags; |
751 | struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa + | 788 | struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa + |
752 | (XPC_DEACTIVATE_REQUEST_AMO * | 789 | (XPC_DEACTIVATE_REQUEST_AMO_SN2 * |
753 | sizeof(struct amo))); | 790 | sizeof(struct amo))); |
754 | 791 | ||
755 | local_irq_save(irq_flags); | 792 | local_irq_save(irq_flags); |
@@ -784,7 +821,7 @@ xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part) | |||
784 | { | 821 | { |
785 | unsigned long irq_flags; | 822 | unsigned long irq_flags; |
786 | struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa + | 823 | struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa + |
787 | (XPC_DEACTIVATE_REQUEST_AMO * | 824 | (XPC_DEACTIVATE_REQUEST_AMO_SN2 * |
788 | sizeof(struct amo))); | 825 | sizeof(struct amo))); |
789 | 826 | ||
790 | local_irq_save(irq_flags); | 827 | local_irq_save(irq_flags); |
@@ -808,7 +845,7 @@ xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part) | |||
808 | static int | 845 | static int |
809 | xpc_partition_deactivation_requested_sn2(short partid) | 846 | xpc_partition_deactivation_requested_sn2(short partid) |
810 | { | 847 | { |
811 | struct amo *amo = xpc_vars->amos_page + XPC_DEACTIVATE_REQUEST_AMO; | 848 | struct amo *amo = xpc_vars->amos_page + XPC_DEACTIVATE_REQUEST_AMO_SN2; |
812 | 849 | ||
813 | /* our partition's amo variable ANDed with partid mask */ | 850 | /* our partition's amo variable ANDed with partid mask */ |
814 | return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) & | 851 | return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) & |
@@ -898,7 +935,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid) | |||
898 | 935 | ||
899 | /* pull over the reserved page structure */ | 936 | /* pull over the reserved page structure */ |
900 | 937 | ||
901 | remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer; | 938 | remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer_sn2; |
902 | 939 | ||
903 | ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa); | 940 | ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa); |
904 | if (ret != xpSuccess) { | 941 | if (ret != xpSuccess) { |
@@ -917,7 +954,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid) | |||
917 | 954 | ||
918 | /* pull over the cross partition variables */ | 955 | /* pull over the cross partition variables */ |
919 | 956 | ||
920 | remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer; | 957 | remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2; |
921 | 958 | ||
922 | ret = xpc_get_remote_vars_sn2(remote_vars_pa, remote_vars); | 959 | ret = xpc_get_remote_vars_sn2(remote_vars_pa, remote_vars); |
923 | if (ret != xpSuccess) { | 960 | if (ret != xpSuccess) { |
@@ -996,10 +1033,10 @@ xpc_identify_activate_IRQ_sender_sn2(void) | |||
996 | int n_IRQs_detected = 0; | 1033 | int n_IRQs_detected = 0; |
997 | struct amo *act_amos; | 1034 | struct amo *act_amos; |
998 | 1035 | ||
999 | act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS; | 1036 | act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS_SN2; |
1000 | 1037 | ||
1001 | /* scan through act amo variable looking for non-zero entries */ | 1038 | /* scan through act amo variable looking for non-zero entries */ |
1002 | for (word = 0; word < xp_nasid_mask_words; word++) { | 1039 | for (word = 0; word < xpc_nasid_mask_words; word++) { |
1003 | 1040 | ||
1004 | if (xpc_exiting) | 1041 | if (xpc_exiting) |
1005 | break; | 1042 | break; |
@@ -2334,6 +2371,7 @@ int | |||
2334 | xpc_init_sn2(void) | 2371 | xpc_init_sn2(void) |
2335 | { | 2372 | { |
2336 | int ret; | 2373 | int ret; |
2374 | size_t buf_size; | ||
2337 | 2375 | ||
2338 | xpc_rsvd_page_init = xpc_rsvd_page_init_sn2; | 2376 | xpc_rsvd_page_init = xpc_rsvd_page_init_sn2; |
2339 | xpc_increment_heartbeat = xpc_increment_heartbeat_sn2; | 2377 | xpc_increment_heartbeat = xpc_increment_heartbeat_sn2; |
@@ -2378,6 +2416,16 @@ xpc_init_sn2(void) | |||
2378 | xpc_send_msg = xpc_send_msg_sn2; | 2416 | xpc_send_msg = xpc_send_msg_sn2; |
2379 | xpc_received_msg = xpc_received_msg_sn2; | 2417 | xpc_received_msg = xpc_received_msg_sn2; |
2380 | 2418 | ||
2419 | buf_size = max(XPC_RP_VARS_SIZE, | ||
2420 | XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES_SN2); | ||
2421 | xpc_remote_copy_buffer_sn2 = xpc_kmalloc_cacheline_aligned(buf_size, | ||
2422 | GFP_KERNEL, | ||
2423 | &xpc_remote_copy_buffer_base_sn2); | ||
2424 | if (xpc_remote_copy_buffer_sn2 == NULL) { | ||
2425 | dev_err(xpc_part, "can't get memory for remote copy buffer\n"); | ||
2426 | return -ENOMEM; | ||
2427 | } | ||
2428 | |||
2381 | /* open up protections for IPI and [potentially] amo operations */ | 2429 | /* open up protections for IPI and [potentially] amo operations */ |
2382 | xpc_allow_IPI_ops_sn2(); | 2430 | xpc_allow_IPI_ops_sn2(); |
2383 | xpc_allow_amo_ops_shub_wars_1_1_sn2(); | 2431 | xpc_allow_amo_ops_shub_wars_1_1_sn2(); |
@@ -2394,6 +2442,7 @@ xpc_init_sn2(void) | |||
2394 | dev_err(xpc_part, "can't register ACTIVATE IRQ handler, " | 2442 | dev_err(xpc_part, "can't register ACTIVATE IRQ handler, " |
2395 | "errno=%d\n", -ret); | 2443 | "errno=%d\n", -ret); |
2396 | xpc_disallow_IPI_ops_sn2(); | 2444 | xpc_disallow_IPI_ops_sn2(); |
2445 | kfree(xpc_remote_copy_buffer_base_sn2); | ||
2397 | } | 2446 | } |
2398 | return ret; | 2447 | return ret; |
2399 | } | 2448 | } |
@@ -2403,4 +2452,5 @@ xpc_exit_sn2(void) | |||
2403 | { | 2452 | { |
2404 | free_irq(SGI_XPC_ACTIVATE, NULL); | 2453 | free_irq(SGI_XPC_ACTIVATE, NULL); |
2405 | xpc_disallow_IPI_ops_sn2(); | 2454 | xpc_disallow_IPI_ops_sn2(); |
2455 | kfree(xpc_remote_copy_buffer_base_sn2); | ||
2406 | } | 2456 | } |