Commit ee6665e3 authored by Dean Nelson's avatar Dean Nelson Committed by Linus Torvalds

sgi-xp: isolate remote copy buffer to sn2 only

Make the remote copy buffer an sn2 only item.
Signed-off-by: default avatarDean Nelson <dcn@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a7b4d509
...@@ -60,16 +60,6 @@ ...@@ -60,16 +60,6 @@
#define XP_MAX_NPARTITIONS_SN2 64 #define XP_MAX_NPARTITIONS_SN2 64
#define XP_MAX_NPARTITIONS_UV 256 #define XP_MAX_NPARTITIONS_UV 256
/*
* Define the number of u64s required to represent all the C-brick nasids
* as a bitmap. The cross-partition kernel modules deal only with
* C-brick nasids, thus the need for bitmaps which don't account for
* odd-numbered (non C-brick) nasids.
*/
#define XP_MAX_PHYSNODE_ID (MAX_NUMALINK_NODES / 2)
#define XP_NASID_MASK_BYTES ((XP_MAX_PHYSNODE_ID + 7) / 8)
#define XP_NASID_MASK_WORDS ((XP_MAX_PHYSNODE_ID + 63) / 64)
/* /*
* XPC establishes channel connections between the local partition and any * XPC establishes channel connections between the local partition and any
* other partition that is currently up. Over these channels, kernel-level * other partition that is currently up. Over these channels, kernel-level
......
...@@ -150,26 +150,6 @@ struct xpc_vars_sn2 { ...@@ -150,26 +150,6 @@ struct xpc_vars_sn2 {
#define XPC_V_VERSION _XPC_VERSION(3, 1) /* version 3.1 of the cross vars */ #define XPC_V_VERSION _XPC_VERSION(3, 1) /* version 3.1 of the cross vars */
/*
* The following pertains to ia64-sn2 only.
*
* Memory for XPC's amo variables is allocated by the MSPEC driver. These
* pages are located in the lowest granule. The lowest granule uses 4k pages
* for cached references and an alternate TLB handler to never provide a
* cacheable mapping for the entire region. This will prevent speculative
* reading of cached copies of our lines from being issued which will cause
* a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
* amo variables (based on XP_MAX_NPARTITIONS_SN2) to identify the senders of
* NOTIFY IRQs, 128 amo variables (based on XP_NASID_MASK_WORDS) to identify
* the senders of ACTIVATE IRQs, 1 amo variable to identify which remote
* partitions (i.e., XPCs) consider themselves currently engaged with the
* local XPC and 1 amo variable to request partition deactivation.
*/
#define XPC_NOTIFY_IRQ_AMOS 0
#define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_NPARTITIONS_SN2)
#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)
#define XPC_DEACTIVATE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1)
/* /*
* The following structure describes the per partition specific variables. * The following structure describes the per partition specific variables.
* *
...@@ -214,9 +194,10 @@ struct xpc_vars_part_sn2 { ...@@ -214,9 +194,10 @@ struct xpc_vars_part_sn2 {
#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2)) #define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2))
#define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE)) #define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE))
#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words) #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xpc_nasid_mask_words)
#define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *)(XPC_RP_MACH_NASIDS(_rp) + \ #define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *) \
xp_nasid_mask_words)) (XPC_RP_MACH_NASIDS(_rp) + \
xpc_nasid_mask_words))
/* /*
* Functions registered by add_timer() or called by kernel_thread() only * Functions registered by add_timer() or called by kernel_thread() only
...@@ -225,11 +206,11 @@ struct xpc_vars_part_sn2 { ...@@ -225,11 +206,11 @@ struct xpc_vars_part_sn2 {
* the passed argument. * the passed argument.
*/ */
#define XPC_PACK_ARGS(_arg1, _arg2) \ #define XPC_PACK_ARGS(_arg1, _arg2) \
((((u64) _arg1) & 0xffffffff) | \ ((((u64)_arg1) & 0xffffffff) | \
((((u64) _arg2) & 0xffffffff) << 32)) ((((u64)_arg2) & 0xffffffff) << 32))
#define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff) #define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff)
#define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff) #define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)
/* /*
* Define a Get/Put value pair (pointers) used with a message queue. * Define a Get/Put value pair (pointers) used with a message queue.
...@@ -710,12 +691,10 @@ extern void xpc_exit_uv(void); ...@@ -710,12 +691,10 @@ extern void xpc_exit_uv(void);
/* found in xpc_partition.c */ /* found in xpc_partition.c */
extern int xpc_exiting; extern int xpc_exiting;
extern int xp_nasid_mask_words; extern int xpc_nasid_mask_words;
extern struct xpc_rsvd_page *xpc_rsvd_page; extern struct xpc_rsvd_page *xpc_rsvd_page;
extern u64 *xpc_mach_nasids; extern u64 *xpc_mach_nasids;
extern struct xpc_partition *xpc_partitions; extern struct xpc_partition *xpc_partitions;
extern char *xpc_remote_copy_buffer;
extern void *xpc_remote_copy_buffer_base;
extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **); extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void); extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void);
extern int xpc_identify_activate_IRQ_sender(void); extern int xpc_identify_activate_IRQ_sender(void);
......
...@@ -877,7 +877,6 @@ xpc_do_exit(enum xp_retval reason) ...@@ -877,7 +877,6 @@ xpc_do_exit(enum xp_retval reason)
unregister_sysctl_table(xpc_sysctl); unregister_sysctl_table(xpc_sysctl);
kfree(xpc_partitions); kfree(xpc_partitions);
kfree(xpc_remote_copy_buffer_base);
if (is_shub()) if (is_shub())
xpc_exit_sn2(); xpc_exit_sn2();
...@@ -1031,7 +1030,9 @@ xpc_init(void) ...@@ -1031,7 +1030,9 @@ xpc_init(void)
short partid; short partid;
struct xpc_partition *part; struct xpc_partition *part;
struct task_struct *kthread; struct task_struct *kthread;
size_t buf_size;
snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
if (is_shub()) { if (is_shub()) {
/* /*
...@@ -1054,26 +1055,12 @@ xpc_init(void) ...@@ -1054,26 +1055,12 @@ xpc_init(void)
return -ENODEV; return -ENODEV;
} }
snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
buf_size = max(XPC_RP_VARS_SIZE,
XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES);
xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size,
GFP_KERNEL,
&xpc_remote_copy_buffer_base);
if (xpc_remote_copy_buffer == NULL) {
dev_err(xpc_part, "can't get memory for remote copy buffer\n");
ret = -ENOMEM;
goto out_1;
}
xpc_partitions = kzalloc(sizeof(struct xpc_partition) * xpc_partitions = kzalloc(sizeof(struct xpc_partition) *
xp_max_npartitions, GFP_KERNEL); xp_max_npartitions, GFP_KERNEL);
if (xpc_partitions == NULL) { if (xpc_partitions == NULL) {
dev_err(xpc_part, "can't get memory for partition structure\n"); dev_err(xpc_part, "can't get memory for partition structure\n");
ret = -ENOMEM; ret = -ENOMEM;
goto out_2; goto out_1;
} }
/* /*
...@@ -1115,7 +1102,7 @@ xpc_init(void) ...@@ -1115,7 +1102,7 @@ xpc_init(void)
if (xpc_rsvd_page == NULL) { if (xpc_rsvd_page == NULL) {
dev_err(xpc_part, "can't setup our reserved page\n"); dev_err(xpc_part, "can't setup our reserved page\n");
ret = -EBUSY; ret = -EBUSY;
goto out_3; goto out_2;
} }
/* add ourselves to the reboot_notifier_list */ /* add ourselves to the reboot_notifier_list */
...@@ -1136,7 +1123,7 @@ xpc_init(void) ...@@ -1136,7 +1123,7 @@ xpc_init(void)
if (IS_ERR(kthread)) { if (IS_ERR(kthread)) {
dev_err(xpc_part, "failed while forking hb check thread\n"); dev_err(xpc_part, "failed while forking hb check thread\n");
ret = -EBUSY; ret = -EBUSY;
goto out_4; goto out_3;
} }
/* /*
...@@ -1164,18 +1151,16 @@ xpc_init(void) ...@@ -1164,18 +1151,16 @@ xpc_init(void)
return 0; return 0;
/* initialization was not successful */ /* initialization was not successful */
out_4: out_3:
/* indicate to others that our reserved page is uninitialized */ /* indicate to others that our reserved page is uninitialized */
xpc_rsvd_page->stamp = 0; xpc_rsvd_page->stamp = 0;
(void)unregister_die_notifier(&xpc_die_notifier); (void)unregister_die_notifier(&xpc_die_notifier);
(void)unregister_reboot_notifier(&xpc_reboot_notifier); (void)unregister_reboot_notifier(&xpc_reboot_notifier);
out_3: out_2:
if (xpc_sysctl) if (xpc_sysctl)
unregister_sysctl_table(xpc_sysctl); unregister_sysctl_table(xpc_sysctl);
kfree(xpc_partitions); kfree(xpc_partitions);
out_2:
kfree(xpc_remote_copy_buffer_base);
out_1: out_1:
if (is_shub()) if (is_shub())
xpc_exit_sn2(); xpc_exit_sn2();
......
...@@ -34,20 +34,11 @@ struct xpc_rsvd_page *xpc_rsvd_page; ...@@ -34,20 +34,11 @@ struct xpc_rsvd_page *xpc_rsvd_page;
static u64 *xpc_part_nasids; static u64 *xpc_part_nasids;
u64 *xpc_mach_nasids; u64 *xpc_mach_nasids;
/* >>> next two variables should be 'xpc_' if they remain here */ static int xpc_sizeof_nasid_mask; /* actual size in bytes of nasid mask */
static int xp_sizeof_nasid_mask; /* actual size in bytes of nasid mask */ int xpc_nasid_mask_words; /* actual size in words of nasid mask */
int xp_nasid_mask_words; /* actual size in words of nasid mask */
struct xpc_partition *xpc_partitions; struct xpc_partition *xpc_partitions;
/*
* Generic buffer used to store a local copy of portions of a remote
* partition's reserved page (either its header and part_nasids mask,
* or its vars).
*/
char *xpc_remote_copy_buffer;
void *xpc_remote_copy_buffer_base;
/* /*
* Guarantee that the kmalloc'd memory is cacheline aligned. * Guarantee that the kmalloc'd memory is cacheline aligned.
*/ */
...@@ -176,8 +167,8 @@ xpc_setup_rsvd_page(void) ...@@ -176,8 +167,8 @@ xpc_setup_rsvd_page(void)
/* SAL_version 1 didn't set the nasids_size field */ /* SAL_version 1 didn't set the nasids_size field */
rp->SAL_nasids_size = 128; rp->SAL_nasids_size = 128;
} }
xp_sizeof_nasid_mask = rp->SAL_nasids_size; xpc_sizeof_nasid_mask = rp->SAL_nasids_size;
xp_nasid_mask_words = DIV_ROUND_UP(xp_sizeof_nasid_mask, xpc_nasid_mask_words = DIV_ROUND_UP(xpc_sizeof_nasid_mask,
BYTES_PER_WORD); BYTES_PER_WORD);
/* setup the pointers to the various items in the reserved page */ /* setup the pointers to the various items in the reserved page */
...@@ -222,14 +213,14 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, ...@@ -222,14 +213,14 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
/* pull over the reserved page header and part_nasids mask */ /* pull over the reserved page header and part_nasids mask */
ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa, ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa,
XPC_RP_HEADER_SIZE + xp_sizeof_nasid_mask); XPC_RP_HEADER_SIZE + xpc_sizeof_nasid_mask);
if (ret != xpSuccess) if (ret != xpSuccess)
return ret; return ret;
if (discovered_nasids != NULL) { if (discovered_nasids != NULL) {
u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp); u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp);
for (i = 0; i < xp_nasid_mask_words; i++) for (i = 0; i < xpc_nasid_mask_words; i++)
discovered_nasids[i] |= remote_part_nasids[i]; discovered_nasids[i] |= remote_part_nasids[i];
} }
...@@ -414,12 +405,12 @@ xpc_discovery(void) ...@@ -414,12 +405,12 @@ xpc_discovery(void)
enum xp_retval ret; enum xp_retval ret;
remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE + remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
xp_sizeof_nasid_mask, xpc_sizeof_nasid_mask,
GFP_KERNEL, &remote_rp_base); GFP_KERNEL, &remote_rp_base);
if (remote_rp == NULL) if (remote_rp == NULL)
return; return;
discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words, discovered_nasids = kzalloc(sizeof(u64) * xpc_nasid_mask_words,
GFP_KERNEL); GFP_KERNEL);
if (discovered_nasids == NULL) { if (discovered_nasids == NULL) {
kfree(remote_rp_base); kfree(remote_rp_base);
...@@ -521,10 +512,10 @@ xpc_initiate_partid_to_nasids(short partid, void *nasid_mask) ...@@ -521,10 +512,10 @@ xpc_initiate_partid_to_nasids(short partid, void *nasid_mask)
if (part->remote_rp_pa == 0) if (part->remote_rp_pa == 0)
return xpPartitionDown; return xpPartitionDown;
memset(nasid_mask, 0, XP_NASID_MASK_BYTES); memset(nasid_mask, 0, xpc_sizeof_nasid_mask);
part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa); part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa);
return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa, return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa,
xp_sizeof_nasid_mask); xpc_sizeof_nasid_mask);
} }
...@@ -19,6 +19,43 @@ ...@@ -19,6 +19,43 @@
#include <asm/sn/sn_sal.h> #include <asm/sn/sn_sal.h>
#include "xpc.h" #include "xpc.h"
/*
* Define the number of u64s required to represent all the C-brick nasids
* as a bitmap. The cross-partition kernel modules deal only with
* C-brick nasids, thus the need for bitmaps which don't account for
* odd-numbered (non C-brick) nasids.
*/
#define XPC_MAX_PHYSNODES_SN2 (MAX_NUMALINK_NODES / 2)
#define XP_NASID_MASK_BYTES_SN2 ((XPC_MAX_PHYSNODES_SN2 + 7) / 8)
#define XP_NASID_MASK_WORDS_SN2 ((XPC_MAX_PHYSNODES_SN2 + 63) / 64)
/*
* Memory for XPC's amo variables is allocated by the MSPEC driver. These
* pages are located in the lowest granule. The lowest granule uses 4k pages
* for cached references and an alternate TLB handler to never provide a
* cacheable mapping for the entire region. This will prevent speculative
* reading of cached copies of our lines from being issued which will cause
* a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
* amo variables (based on XP_MAX_NPARTITIONS_SN2) to identify the senders of
* NOTIFY IRQs, 128 amo variables (based on XP_NASID_MASK_WORDS_SN2) to identify
* the senders of ACTIVATE IRQs, 1 amo variable to identify which remote
* partitions (i.e., XPCs) consider themselves currently engaged with the
* local XPC and 1 amo variable to request partition deactivation.
*/
#define XPC_NOTIFY_IRQ_AMOS_SN2 0
#define XPC_ACTIVATE_IRQ_AMOS_SN2 (XPC_NOTIFY_IRQ_AMOS_SN2 + \
XP_MAX_NPARTITIONS_SN2)
#define XPC_ENGAGED_PARTITIONS_AMO_SN2 (XPC_ACTIVATE_IRQ_AMOS_SN2 + \
XP_NASID_MASK_WORDS_SN2)
#define XPC_DEACTIVATE_REQUEST_AMO_SN2 (XPC_ENGAGED_PARTITIONS_AMO_SN2 + 1)
/*
* Buffer used to store a local copy of portions of a remote partition's
* reserved page (either its header and part_nasids mask, or its vars).
*/
static char *xpc_remote_copy_buffer_sn2;
static void *xpc_remote_copy_buffer_base_sn2;
static struct xpc_vars_sn2 *xpc_vars; /* >>> Add _sn2 suffix? */ static struct xpc_vars_sn2 *xpc_vars; /* >>> Add _sn2 suffix? */
static struct xpc_vars_part_sn2 *xpc_vars_part; /* >>> Add _sn2 suffix? */ static struct xpc_vars_part_sn2 *xpc_vars_part; /* >>> Add _sn2 suffix? */
...@@ -176,7 +213,7 @@ xpc_send_activate_IRQ_sn2(u64 amos_page_pa, int from_nasid, int to_nasid, ...@@ -176,7 +213,7 @@ xpc_send_activate_IRQ_sn2(u64 amos_page_pa, int from_nasid, int to_nasid,
int w_index = XPC_NASID_W_INDEX(from_nasid); int w_index = XPC_NASID_W_INDEX(from_nasid);
int b_index = XPC_NASID_B_INDEX(from_nasid); int b_index = XPC_NASID_B_INDEX(from_nasid);
struct amo *amos = (struct amo *)__va(amos_page_pa + struct amo *amos = (struct amo *)__va(amos_page_pa +
(XPC_ACTIVATE_IRQ_AMOS * (XPC_ACTIVATE_IRQ_AMOS_SN2 *
sizeof(struct amo))); sizeof(struct amo)));
(void)xpc_send_IRQ_sn2(&amos[w_index], (1UL << b_index), to_nasid, (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,7 +226,7 @@ xpc_send_local_activate_IRQ_sn2(int from_nasid)
int w_index = XPC_NASID_W_INDEX(from_nasid); int w_index = XPC_NASID_W_INDEX(from_nasid);
int b_index = XPC_NASID_B_INDEX(from_nasid); int b_index = XPC_NASID_B_INDEX(from_nasid);
struct amo *amos = (struct amo *)__va(xpc_vars->amos_page_pa + struct amo *amos = (struct amo *)__va(xpc_vars->amos_page_pa +
(XPC_ACTIVATE_IRQ_AMOS * (XPC_ACTIVATE_IRQ_AMOS_SN2 *
sizeof(struct amo))); sizeof(struct amo)));
/* fake the sending and receipt of an activate IRQ from remote nasid */ /* 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,7 +432,7 @@ xpc_indicate_partition_engaged_sn2(struct xpc_partition *part)
{ {
unsigned long irq_flags; unsigned long irq_flags;
struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa + struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa +
(XPC_ENGAGED_PARTITIONS_AMO * (XPC_ENGAGED_PARTITIONS_AMO_SN2 *
sizeof(struct amo))); sizeof(struct amo)));
local_irq_save(irq_flags); local_irq_save(irq_flags);
...@@ -422,7 +459,7 @@ xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part) ...@@ -422,7 +459,7 @@ xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part)
struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
unsigned long irq_flags; unsigned long irq_flags;
struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa + struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa +
(XPC_ENGAGED_PARTITIONS_AMO * (XPC_ENGAGED_PARTITIONS_AMO_SN2 *
sizeof(struct amo))); sizeof(struct amo)));
local_irq_save(irq_flags); local_irq_save(irq_flags);
...@@ -455,7 +492,7 @@ xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part) ...@@ -455,7 +492,7 @@ xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part)
static int static int
xpc_partition_engaged_sn2(short partid) xpc_partition_engaged_sn2(short partid)
{ {
struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2;
/* our partition's amo variable ANDed with partid mask */ /* our partition's amo variable ANDed with partid mask */
return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) & return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
...@@ -465,7 +502,7 @@ xpc_partition_engaged_sn2(short partid) ...@@ -465,7 +502,7 @@ xpc_partition_engaged_sn2(short partid)
static int static int
xpc_any_partition_engaged_sn2(void) xpc_any_partition_engaged_sn2(void)
{ {
struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2;
/* our partition's amo variable */ /* our partition's amo variable */
return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0; return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0;
...@@ -474,7 +511,7 @@ xpc_any_partition_engaged_sn2(void) ...@@ -474,7 +511,7 @@ xpc_any_partition_engaged_sn2(void)
static void static void
xpc_assume_partition_disengaged_sn2(short partid) xpc_assume_partition_disengaged_sn2(short partid)
{ {
struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2;
/* clear bit(s) based on partid mask in our partition's amo */ /* clear bit(s) based on partid mask in our partition's amo */
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND, 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,12 +636,12 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_page *rp)
xp_max_npartitions); xp_max_npartitions);
/* initialize the activate IRQ related amo variables */ /* initialize the activate IRQ related amo variables */
for (i = 0; i < xp_nasid_mask_words; i++) for (i = 0; i < xpc_nasid_mask_words; i++)
(void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS + i); (void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS_SN2 + i);
/* initialize the engaged remote partitions related amo variables */ /* initialize the engaged remote partitions related amo variables */
(void)xpc_init_IRQ_amo_sn2(XPC_ENGAGED_PARTITIONS_AMO); (void)xpc_init_IRQ_amo_sn2(XPC_ENGAGED_PARTITIONS_AMO_SN2);
(void)xpc_init_IRQ_amo_sn2(XPC_DEACTIVATE_REQUEST_AMO); (void)xpc_init_IRQ_amo_sn2(XPC_DEACTIVATE_REQUEST_AMO_SN2);
return xpSuccess; return xpSuccess;
} }
...@@ -657,7 +694,7 @@ xpc_check_remote_hb_sn2(void) ...@@ -657,7 +694,7 @@ xpc_check_remote_hb_sn2(void)
short partid; short partid;
enum xp_retval ret; enum xp_retval ret;
remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer; remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2;
for (partid = 0; partid < xp_max_npartitions; partid++) { for (partid = 0; partid < xp_max_npartitions; partid++) {
...@@ -749,7 +786,7 @@ xpc_request_partition_deactivation_sn2(struct xpc_partition *part) ...@@ -749,7 +786,7 @@ xpc_request_partition_deactivation_sn2(struct xpc_partition *part)
struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
unsigned long irq_flags; unsigned long irq_flags;
struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa + struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa +
(XPC_DEACTIVATE_REQUEST_AMO * (XPC_DEACTIVATE_REQUEST_AMO_SN2 *
sizeof(struct amo))); sizeof(struct amo)));
local_irq_save(irq_flags); local_irq_save(irq_flags);
...@@ -784,7 +821,7 @@ xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part) ...@@ -784,7 +821,7 @@ xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part)
{ {
unsigned long irq_flags; unsigned long irq_flags;
struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa + struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa +
(XPC_DEACTIVATE_REQUEST_AMO * (XPC_DEACTIVATE_REQUEST_AMO_SN2 *
sizeof(struct amo))); sizeof(struct amo)));
local_irq_save(irq_flags); local_irq_save(irq_flags);
...@@ -808,7 +845,7 @@ xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part) ...@@ -808,7 +845,7 @@ xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part)
static int static int
xpc_partition_deactivation_requested_sn2(short partid) xpc_partition_deactivation_requested_sn2(short partid)
{ {
struct amo *amo = xpc_vars->amos_page + XPC_DEACTIVATE_REQUEST_AMO; struct amo *amo = xpc_vars->amos_page + XPC_DEACTIVATE_REQUEST_AMO_SN2;
/* our partition's amo variable ANDed with partid mask */ /* our partition's amo variable ANDed with partid mask */
return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) & return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
...@@ -898,7 +935,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid) ...@@ -898,7 +935,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid)
/* pull over the reserved page structure */ /* pull over the reserved page structure */
remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer; remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer_sn2;
ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa); ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
if (ret != xpSuccess) { if (ret != xpSuccess) {
...@@ -917,7 +954,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid) ...@@ -917,7 +954,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid)
/* pull over the cross partition variables */ /* pull over the cross partition variables */
remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer; remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2;
ret = xpc_get_remote_vars_sn2(remote_vars_pa, remote_vars); ret = xpc_get_remote_vars_sn2(remote_vars_pa, remote_vars);
if (ret != xpSuccess) { if (ret != xpSuccess) {
...@@ -996,10 +1033,10 @@ xpc_identify_activate_IRQ_sender_sn2(void) ...@@ -996,10 +1033,10 @@ xpc_identify_activate_IRQ_sender_sn2(void)
int n_IRQs_detected = 0; int n_IRQs_detected = 0;
struct amo *act_amos; struct amo *act_amos;
act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS; act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS_SN2;
/* scan through act amo variable looking for non-zero entries */ /* scan through act amo variable looking for non-zero entries */
for (word = 0; word < xp_nasid_mask_words; word++) { for (word = 0; word < xpc_nasid_mask_words; word++) {
if (xpc_exiting) if (xpc_exiting)
break; break;
...@@ -2334,6 +2371,7 @@ int ...@@ -2334,6 +2371,7 @@ int
xpc_init_sn2(void) xpc_init_sn2(void)
{ {
int ret; int ret;
size_t buf_size;
xpc_rsvd_page_init = xpc_rsvd_page_init_sn2; xpc_rsvd_page_init = xpc_rsvd_page_init_sn2;
xpc_increment_heartbeat = xpc_increment_heartbeat_sn2; xpc_increment_heartbeat = xpc_increment_heartbeat_sn2;
...@@ -2378,6 +2416,16 @@ xpc_init_sn2(void) ...@@ -2378,6 +2416,16 @@ xpc_init_sn2(void)
xpc_send_msg = xpc_send_msg_sn2; xpc_send_msg = xpc_send_msg_sn2;
xpc_received_msg = xpc_received_msg_sn2; xpc_received_msg = xpc_received_msg_sn2;
buf_size = max(XPC_RP_VARS_SIZE,
XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES_SN2);
xpc_remote_copy_buffer_sn2 = xpc_kmalloc_cacheline_aligned(buf_size,
GFP_KERNEL,
&xpc_remote_copy_buffer_base_sn2);
if (xpc_remote_copy_buffer_sn2 == NULL) {
dev_err(xpc_part, "can't get memory for remote copy buffer\n");
return -ENOMEM;
}
/* open up protections for IPI and [potentially] amo operations */ /* open up protections for IPI and [potentially] amo operations */
xpc_allow_IPI_ops_sn2(); xpc_allow_IPI_ops_sn2();
xpc_allow_amo_ops_shub_wars_1_1_sn2(); xpc_allow_amo_ops_shub_wars_1_1_sn2();
...@@ -2394,6 +2442,7 @@ xpc_init_sn2(void) ...@@ -2394,6 +2442,7 @@ xpc_init_sn2(void)
dev_err(xpc_part, "can't register ACTIVATE IRQ handler, " dev_err(xpc_part, "can't register ACTIVATE IRQ handler, "
"errno=%d\n", -ret); "errno=%d\n", -ret);
xpc_disallow_IPI_ops_sn2(); xpc_disallow_IPI_ops_sn2();
kfree(xpc_remote_copy_buffer_base_sn2);
} }
return ret; return ret;
} }
...@@ -2403,4 +2452,5 @@ xpc_exit_sn2(void) ...@@ -2403,4 +2452,5 @@ xpc_exit_sn2(void)
{ {
free_irq(SGI_XPC_ACTIVATE, NULL); free_irq(SGI_XPC_ACTIVATE, NULL);
xpc_disallow_IPI_ops_sn2(); xpc_disallow_IPI_ops_sn2();
kfree(xpc_remote_copy_buffer_base_sn2);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment