aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-xp/xpc_sn2.c
diff options
context:
space:
mode:
authorDean Nelson <dcn@sgi.com>2008-07-30 01:34:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-30 12:41:50 -0400
commitee6665e3b6e1283c30ae240732af1345bc02154e (patch)
tree91fbfb2a4cab26e3979df44a9bdcd6851efc9c50 /drivers/misc/sgi-xp/xpc_sn2.c
parenta7b4d509205db5e9cd3ffc77b306d7b10fe6a34d (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.c88
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 */
56static char *xpc_remote_copy_buffer_sn2;
57static void *xpc_remote_copy_buffer_base_sn2;
58
22static struct xpc_vars_sn2 *xpc_vars; /* >>> Add _sn2 suffix? */ 59static struct xpc_vars_sn2 *xpc_vars; /* >>> Add _sn2 suffix? */
23static struct xpc_vars_part_sn2 *xpc_vars_part; /* >>> Add _sn2 suffix? */ 60static 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)
455static int 492static int
456xpc_partition_engaged_sn2(short partid) 493xpc_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)
465static int 502static int
466xpc_any_partition_engaged_sn2(void) 503xpc_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)
474static void 511static void
475xpc_assume_partition_disengaged_sn2(short partid) 512xpc_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)
808static int 845static int
809xpc_partition_deactivation_requested_sn2(short partid) 846xpc_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
2334xpc_init_sn2(void) 2371xpc_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}