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 | |
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')
-rw-r--r-- | drivers/misc/sgi-xp/xp.h | 10 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc.h | 39 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_main.c | 31 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_partition.c | 31 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_sn2.c | 88 |
5 files changed, 97 insertions, 102 deletions
diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h index 43bf2470850e..955b5b913235 100644 --- a/drivers/misc/sgi-xp/xp.h +++ b/drivers/misc/sgi-xp/xp.h | |||
@@ -61,16 +61,6 @@ | |||
61 | #define XP_MAX_NPARTITIONS_UV 256 | 61 | #define XP_MAX_NPARTITIONS_UV 256 |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * Define the number of u64s required to represent all the C-brick nasids | ||
65 | * as a bitmap. The cross-partition kernel modules deal only with | ||
66 | * C-brick nasids, thus the need for bitmaps which don't account for | ||
67 | * odd-numbered (non C-brick) nasids. | ||
68 | */ | ||
69 | #define XP_MAX_PHYSNODE_ID (MAX_NUMALINK_NODES / 2) | ||
70 | #define XP_NASID_MASK_BYTES ((XP_MAX_PHYSNODE_ID + 7) / 8) | ||
71 | #define XP_NASID_MASK_WORDS ((XP_MAX_PHYSNODE_ID + 63) / 64) | ||
72 | |||
73 | /* | ||
74 | * XPC establishes channel connections between the local partition and any | 64 | * XPC establishes channel connections between the local partition and any |
75 | * other partition that is currently up. Over these channels, kernel-level | 65 | * other partition that is currently up. Over these channels, kernel-level |
76 | * `users' can communicate with their counterparts on the other partitions. | 66 | * `users' can communicate with their counterparts on the other partitions. |
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h index defd08881184..2111723553bf 100644 --- a/drivers/misc/sgi-xp/xpc.h +++ b/drivers/misc/sgi-xp/xpc.h | |||
@@ -151,26 +151,6 @@ struct xpc_vars_sn2 { | |||
151 | #define XPC_V_VERSION _XPC_VERSION(3, 1) /* version 3.1 of the cross vars */ | 151 | #define XPC_V_VERSION _XPC_VERSION(3, 1) /* version 3.1 of the cross vars */ |
152 | 152 | ||
153 | /* | 153 | /* |
154 | * The following pertains to ia64-sn2 only. | ||
155 | * | ||
156 | * Memory for XPC's amo variables is allocated by the MSPEC driver. These | ||
157 | * pages are located in the lowest granule. The lowest granule uses 4k pages | ||
158 | * for cached references and an alternate TLB handler to never provide a | ||
159 | * cacheable mapping for the entire region. This will prevent speculative | ||
160 | * reading of cached copies of our lines from being issued which will cause | ||
161 | * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64 | ||
162 | * amo variables (based on XP_MAX_NPARTITIONS_SN2) to identify the senders of | ||
163 | * NOTIFY IRQs, 128 amo variables (based on XP_NASID_MASK_WORDS) to identify | ||
164 | * the senders of ACTIVATE IRQs, 1 amo variable to identify which remote | ||
165 | * partitions (i.e., XPCs) consider themselves currently engaged with the | ||
166 | * local XPC and 1 amo variable to request partition deactivation. | ||
167 | */ | ||
168 | #define XPC_NOTIFY_IRQ_AMOS 0 | ||
169 | #define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_NPARTITIONS_SN2) | ||
170 | #define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS) | ||
171 | #define XPC_DEACTIVATE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1) | ||
172 | |||
173 | /* | ||
174 | * The following structure describes the per partition specific variables. | 154 | * The following structure describes the per partition specific variables. |
175 | * | 155 | * |
176 | * An array of these structures, one per partition, will be defined. As a | 156 | * An array of these structures, one per partition, will be defined. As a |
@@ -214,9 +194,10 @@ struct xpc_vars_part_sn2 { | |||
214 | #define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2)) | 194 | #define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2)) |
215 | 195 | ||
216 | #define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE)) | 196 | #define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE)) |
217 | #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words) | 197 | #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xpc_nasid_mask_words) |
218 | #define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *)(XPC_RP_MACH_NASIDS(_rp) + \ | 198 | #define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *) \ |
219 | xp_nasid_mask_words)) | 199 | (XPC_RP_MACH_NASIDS(_rp) + \ |
200 | xpc_nasid_mask_words)) | ||
220 | 201 | ||
221 | /* | 202 | /* |
222 | * Functions registered by add_timer() or called by kernel_thread() only | 203 | * Functions registered by add_timer() or called by kernel_thread() only |
@@ -225,11 +206,11 @@ struct xpc_vars_part_sn2 { | |||
225 | * the passed argument. | 206 | * the passed argument. |
226 | */ | 207 | */ |
227 | #define XPC_PACK_ARGS(_arg1, _arg2) \ | 208 | #define XPC_PACK_ARGS(_arg1, _arg2) \ |
228 | ((((u64) _arg1) & 0xffffffff) | \ | 209 | ((((u64)_arg1) & 0xffffffff) | \ |
229 | ((((u64) _arg2) & 0xffffffff) << 32)) | 210 | ((((u64)_arg2) & 0xffffffff) << 32)) |
230 | 211 | ||
231 | #define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff) | 212 | #define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff) |
232 | #define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff) | 213 | #define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff) |
233 | 214 | ||
234 | /* | 215 | /* |
235 | * Define a Get/Put value pair (pointers) used with a message queue. | 216 | * Define a Get/Put value pair (pointers) used with a message queue. |
@@ -710,12 +691,10 @@ extern void xpc_exit_uv(void); | |||
710 | 691 | ||
711 | /* found in xpc_partition.c */ | 692 | /* found in xpc_partition.c */ |
712 | extern int xpc_exiting; | 693 | extern int xpc_exiting; |
713 | extern int xp_nasid_mask_words; | 694 | extern int xpc_nasid_mask_words; |
714 | extern struct xpc_rsvd_page *xpc_rsvd_page; | 695 | extern struct xpc_rsvd_page *xpc_rsvd_page; |
715 | extern u64 *xpc_mach_nasids; | 696 | extern u64 *xpc_mach_nasids; |
716 | extern struct xpc_partition *xpc_partitions; | 697 | extern struct xpc_partition *xpc_partitions; |
717 | extern char *xpc_remote_copy_buffer; | ||
718 | extern void *xpc_remote_copy_buffer_base; | ||
719 | extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **); | 698 | extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **); |
720 | extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void); | 699 | extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void); |
721 | extern int xpc_identify_activate_IRQ_sender(void); | 700 | extern int xpc_identify_activate_IRQ_sender(void); |
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index b5f3c5e59db0..36dfccea5247 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c | |||
@@ -877,7 +877,6 @@ xpc_do_exit(enum xp_retval reason) | |||
877 | unregister_sysctl_table(xpc_sysctl); | 877 | unregister_sysctl_table(xpc_sysctl); |
878 | 878 | ||
879 | kfree(xpc_partitions); | 879 | kfree(xpc_partitions); |
880 | kfree(xpc_remote_copy_buffer_base); | ||
881 | 880 | ||
882 | if (is_shub()) | 881 | if (is_shub()) |
883 | xpc_exit_sn2(); | 882 | xpc_exit_sn2(); |
@@ -1031,7 +1030,9 @@ xpc_init(void) | |||
1031 | short partid; | 1030 | short partid; |
1032 | struct xpc_partition *part; | 1031 | struct xpc_partition *part; |
1033 | struct task_struct *kthread; | 1032 | struct task_struct *kthread; |
1034 | size_t buf_size; | 1033 | |
1034 | snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); | ||
1035 | snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); | ||
1035 | 1036 | ||
1036 | if (is_shub()) { | 1037 | if (is_shub()) { |
1037 | /* | 1038 | /* |
@@ -1054,26 +1055,12 @@ xpc_init(void) | |||
1054 | return -ENODEV; | 1055 | return -ENODEV; |
1055 | } | 1056 | } |
1056 | 1057 | ||
1057 | snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); | ||
1058 | snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); | ||
1059 | |||
1060 | buf_size = max(XPC_RP_VARS_SIZE, | ||
1061 | XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES); | ||
1062 | xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size, | ||
1063 | GFP_KERNEL, | ||
1064 | &xpc_remote_copy_buffer_base); | ||
1065 | if (xpc_remote_copy_buffer == NULL) { | ||
1066 | dev_err(xpc_part, "can't get memory for remote copy buffer\n"); | ||
1067 | ret = -ENOMEM; | ||
1068 | goto out_1; | ||
1069 | } | ||
1070 | |||
1071 | xpc_partitions = kzalloc(sizeof(struct xpc_partition) * | 1058 | xpc_partitions = kzalloc(sizeof(struct xpc_partition) * |
1072 | xp_max_npartitions, GFP_KERNEL); | 1059 | xp_max_npartitions, GFP_KERNEL); |
1073 | if (xpc_partitions == NULL) { | 1060 | if (xpc_partitions == NULL) { |
1074 | dev_err(xpc_part, "can't get memory for partition structure\n"); | 1061 | dev_err(xpc_part, "can't get memory for partition structure\n"); |
1075 | ret = -ENOMEM; | 1062 | ret = -ENOMEM; |
1076 | goto out_2; | 1063 | goto out_1; |
1077 | } | 1064 | } |
1078 | 1065 | ||
1079 | /* | 1066 | /* |
@@ -1115,7 +1102,7 @@ xpc_init(void) | |||
1115 | if (xpc_rsvd_page == NULL) { | 1102 | if (xpc_rsvd_page == NULL) { |
1116 | dev_err(xpc_part, "can't setup our reserved page\n"); | 1103 | dev_err(xpc_part, "can't setup our reserved page\n"); |
1117 | ret = -EBUSY; | 1104 | ret = -EBUSY; |
1118 | goto out_3; | 1105 | goto out_2; |
1119 | } | 1106 | } |
1120 | 1107 | ||
1121 | /* add ourselves to the reboot_notifier_list */ | 1108 | /* add ourselves to the reboot_notifier_list */ |
@@ -1136,7 +1123,7 @@ xpc_init(void) | |||
1136 | if (IS_ERR(kthread)) { | 1123 | if (IS_ERR(kthread)) { |
1137 | dev_err(xpc_part, "failed while forking hb check thread\n"); | 1124 | dev_err(xpc_part, "failed while forking hb check thread\n"); |
1138 | ret = -EBUSY; | 1125 | ret = -EBUSY; |
1139 | goto out_4; | 1126 | goto out_3; |
1140 | } | 1127 | } |
1141 | 1128 | ||
1142 | /* | 1129 | /* |
@@ -1164,18 +1151,16 @@ xpc_init(void) | |||
1164 | return 0; | 1151 | return 0; |
1165 | 1152 | ||
1166 | /* initialization was not successful */ | 1153 | /* initialization was not successful */ |
1167 | out_4: | 1154 | out_3: |
1168 | /* indicate to others that our reserved page is uninitialized */ | 1155 | /* indicate to others that our reserved page is uninitialized */ |
1169 | xpc_rsvd_page->stamp = 0; | 1156 | xpc_rsvd_page->stamp = 0; |
1170 | 1157 | ||
1171 | (void)unregister_die_notifier(&xpc_die_notifier); | 1158 | (void)unregister_die_notifier(&xpc_die_notifier); |
1172 | (void)unregister_reboot_notifier(&xpc_reboot_notifier); | 1159 | (void)unregister_reboot_notifier(&xpc_reboot_notifier); |
1173 | out_3: | 1160 | out_2: |
1174 | if (xpc_sysctl) | 1161 | if (xpc_sysctl) |
1175 | unregister_sysctl_table(xpc_sysctl); | 1162 | unregister_sysctl_table(xpc_sysctl); |
1176 | kfree(xpc_partitions); | 1163 | kfree(xpc_partitions); |
1177 | out_2: | ||
1178 | kfree(xpc_remote_copy_buffer_base); | ||
1179 | out_1: | 1164 | out_1: |
1180 | if (is_shub()) | 1165 | if (is_shub()) |
1181 | xpc_exit_sn2(); | 1166 | xpc_exit_sn2(); |
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index c769ab8f74ef..9f104450478f 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c | |||
@@ -34,21 +34,12 @@ struct xpc_rsvd_page *xpc_rsvd_page; | |||
34 | static u64 *xpc_part_nasids; | 34 | static u64 *xpc_part_nasids; |
35 | u64 *xpc_mach_nasids; | 35 | u64 *xpc_mach_nasids; |
36 | 36 | ||
37 | /* >>> next two variables should be 'xpc_' if they remain here */ | 37 | static int xpc_sizeof_nasid_mask; /* actual size in bytes of nasid mask */ |
38 | static int xp_sizeof_nasid_mask; /* actual size in bytes of nasid mask */ | 38 | int xpc_nasid_mask_words; /* actual size in words of nasid mask */ |
39 | int xp_nasid_mask_words; /* actual size in words of nasid mask */ | ||
40 | 39 | ||
41 | struct xpc_partition *xpc_partitions; | 40 | struct xpc_partition *xpc_partitions; |
42 | 41 | ||
43 | /* | 42 | /* |
44 | * Generic buffer used to store a local copy of portions of a remote | ||
45 | * partition's reserved page (either its header and part_nasids mask, | ||
46 | * or its vars). | ||
47 | */ | ||
48 | char *xpc_remote_copy_buffer; | ||
49 | void *xpc_remote_copy_buffer_base; | ||
50 | |||
51 | /* | ||
52 | * Guarantee that the kmalloc'd memory is cacheline aligned. | 43 | * Guarantee that the kmalloc'd memory is cacheline aligned. |
53 | */ | 44 | */ |
54 | void * | 45 | void * |
@@ -176,9 +167,9 @@ xpc_setup_rsvd_page(void) | |||
176 | /* SAL_version 1 didn't set the nasids_size field */ | 167 | /* SAL_version 1 didn't set the nasids_size field */ |
177 | rp->SAL_nasids_size = 128; | 168 | rp->SAL_nasids_size = 128; |
178 | } | 169 | } |
179 | xp_sizeof_nasid_mask = rp->SAL_nasids_size; | 170 | xpc_sizeof_nasid_mask = rp->SAL_nasids_size; |
180 | xp_nasid_mask_words = DIV_ROUND_UP(xp_sizeof_nasid_mask, | 171 | xpc_nasid_mask_words = DIV_ROUND_UP(xpc_sizeof_nasid_mask, |
181 | BYTES_PER_WORD); | 172 | BYTES_PER_WORD); |
182 | 173 | ||
183 | /* setup the pointers to the various items in the reserved page */ | 174 | /* setup the pointers to the various items in the reserved page */ |
184 | xpc_part_nasids = XPC_RP_PART_NASIDS(rp); | 175 | xpc_part_nasids = XPC_RP_PART_NASIDS(rp); |
@@ -222,14 +213,14 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, | |||
222 | 213 | ||
223 | /* pull over the reserved page header and part_nasids mask */ | 214 | /* pull over the reserved page header and part_nasids mask */ |
224 | ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa, | 215 | ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa, |
225 | XPC_RP_HEADER_SIZE + xp_sizeof_nasid_mask); | 216 | XPC_RP_HEADER_SIZE + xpc_sizeof_nasid_mask); |
226 | if (ret != xpSuccess) | 217 | if (ret != xpSuccess) |
227 | return ret; | 218 | return ret; |
228 | 219 | ||
229 | if (discovered_nasids != NULL) { | 220 | if (discovered_nasids != NULL) { |
230 | u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp); | 221 | u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp); |
231 | 222 | ||
232 | for (i = 0; i < xp_nasid_mask_words; i++) | 223 | for (i = 0; i < xpc_nasid_mask_words; i++) |
233 | discovered_nasids[i] |= remote_part_nasids[i]; | 224 | discovered_nasids[i] |= remote_part_nasids[i]; |
234 | } | 225 | } |
235 | 226 | ||
@@ -414,12 +405,12 @@ xpc_discovery(void) | |||
414 | enum xp_retval ret; | 405 | enum xp_retval ret; |
415 | 406 | ||
416 | remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE + | 407 | remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE + |
417 | xp_sizeof_nasid_mask, | 408 | xpc_sizeof_nasid_mask, |
418 | GFP_KERNEL, &remote_rp_base); | 409 | GFP_KERNEL, &remote_rp_base); |
419 | if (remote_rp == NULL) | 410 | if (remote_rp == NULL) |
420 | return; | 411 | return; |
421 | 412 | ||
422 | discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words, | 413 | discovered_nasids = kzalloc(sizeof(u64) * xpc_nasid_mask_words, |
423 | GFP_KERNEL); | 414 | GFP_KERNEL); |
424 | if (discovered_nasids == NULL) { | 415 | if (discovered_nasids == NULL) { |
425 | kfree(remote_rp_base); | 416 | kfree(remote_rp_base); |
@@ -521,10 +512,10 @@ xpc_initiate_partid_to_nasids(short partid, void *nasid_mask) | |||
521 | if (part->remote_rp_pa == 0) | 512 | if (part->remote_rp_pa == 0) |
522 | return xpPartitionDown; | 513 | return xpPartitionDown; |
523 | 514 | ||
524 | memset(nasid_mask, 0, XP_NASID_MASK_BYTES); | 515 | memset(nasid_mask, 0, xpc_sizeof_nasid_mask); |
525 | 516 | ||
526 | part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa); | 517 | part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa); |
527 | 518 | ||
528 | return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa, | 519 | return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa, |
529 | xp_sizeof_nasid_mask); | 520 | xpc_sizeof_nasid_mask); |
530 | } | 521 | } |
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 | } |