Skip to content

Commit

Permalink
sgi-xp: isolate remote copy buffer to sn2 only
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dean Nelson authored and Linus Torvalds committed Jul 30, 2008
1 parent a7b4d50 commit ee6665e
Showing 5 changed files with 97 additions and 102 deletions.
10 changes: 0 additions & 10 deletions drivers/misc/sgi-xp/xp.h
Original file line number Diff line number Diff line change
@@ -60,16 +60,6 @@
#define XP_MAX_NPARTITIONS_SN2 64
#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
* other partition that is currently up. Over these channels, kernel-level
39 changes: 9 additions & 30 deletions drivers/misc/sgi-xp/xpc.h
Original file line number Diff line number Diff line change
@@ -150,26 +150,6 @@ struct xpc_vars_sn2 {

#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.
*
@@ -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_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_VARS(_rp) ((struct xpc_vars_sn2 *)(XPC_RP_MACH_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) + \
xpc_nasid_mask_words))

/*
* Functions registered by add_timer() or called by kernel_thread() only
@@ -225,11 +206,11 @@ struct xpc_vars_part_sn2 {
* the passed argument.
*/
#define XPC_PACK_ARGS(_arg1, _arg2) \
((((u64) _arg1) & 0xffffffff) | \
((((u64) _arg2) & 0xffffffff) << 32))
((((u64)_arg1) & 0xffffffff) | \
((((u64)_arg2) & 0xffffffff) << 32))

#define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff)
#define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff)
#define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff)
#define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)

/*
* Define a Get/Put value pair (pointers) used with a message queue.
@@ -710,12 +691,10 @@ extern void xpc_exit_uv(void);

/* found in xpc_partition.c */
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 u64 *xpc_mach_nasids;
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 struct xpc_rsvd_page *xpc_setup_rsvd_page(void);
extern int xpc_identify_activate_IRQ_sender(void);
31 changes: 8 additions & 23 deletions drivers/misc/sgi-xp/xpc_main.c
Original file line number Diff line number Diff line change
@@ -877,7 +877,6 @@ xpc_do_exit(enum xp_retval reason)
unregister_sysctl_table(xpc_sysctl);

kfree(xpc_partitions);
kfree(xpc_remote_copy_buffer_base);

if (is_shub())
xpc_exit_sn2();
@@ -1031,7 +1030,9 @@ xpc_init(void)
short partid;
struct xpc_partition *part;
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()) {
/*
@@ -1054,26 +1055,12 @@ xpc_init(void)
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) *
xp_max_npartitions, GFP_KERNEL);
if (xpc_partitions == NULL) {
dev_err(xpc_part, "can't get memory for partition structure\n");
ret = -ENOMEM;
goto out_2;
goto out_1;
}

/*
@@ -1115,7 +1102,7 @@ xpc_init(void)
if (xpc_rsvd_page == NULL) {
dev_err(xpc_part, "can't setup our reserved page\n");
ret = -EBUSY;
goto out_3;
goto out_2;
}

/* add ourselves to the reboot_notifier_list */
@@ -1136,7 +1123,7 @@ xpc_init(void)
if (IS_ERR(kthread)) {
dev_err(xpc_part, "failed while forking hb check thread\n");
ret = -EBUSY;
goto out_4;
goto out_3;
}

/*
@@ -1164,18 +1151,16 @@ xpc_init(void)
return 0;

/* initialization was not successful */
out_4:
out_3:
/* indicate to others that our reserved page is uninitialized */
xpc_rsvd_page->stamp = 0;

(void)unregister_die_notifier(&xpc_die_notifier);
(void)unregister_reboot_notifier(&xpc_reboot_notifier);
out_3:
out_2:
if (xpc_sysctl)
unregister_sysctl_table(xpc_sysctl);
kfree(xpc_partitions);
out_2:
kfree(xpc_remote_copy_buffer_base);
out_1:
if (is_shub())
xpc_exit_sn2();
31 changes: 11 additions & 20 deletions drivers/misc/sgi-xp/xpc_partition.c
Original file line number Diff line number Diff line change
@@ -34,20 +34,11 @@ struct xpc_rsvd_page *xpc_rsvd_page;
static u64 *xpc_part_nasids;
u64 *xpc_mach_nasids;

/* >>> next two variables should be 'xpc_' if they remain here */
static int xp_sizeof_nasid_mask; /* actual size in bytes of nasid mask */
int xp_nasid_mask_words; /* actual size in words of nasid mask */
static int xpc_sizeof_nasid_mask; /* actual size in bytes of nasid mask */
int xpc_nasid_mask_words; /* actual size in words of nasid mask */

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.
*/
@@ -176,9 +167,9 @@ xpc_setup_rsvd_page(void)
/* SAL_version 1 didn't set the nasids_size field */
rp->SAL_nasids_size = 128;
}
xp_sizeof_nasid_mask = rp->SAL_nasids_size;
xp_nasid_mask_words = DIV_ROUND_UP(xp_sizeof_nasid_mask,
BYTES_PER_WORD);
xpc_sizeof_nasid_mask = rp->SAL_nasids_size;
xpc_nasid_mask_words = DIV_ROUND_UP(xpc_sizeof_nasid_mask,
BYTES_PER_WORD);

/* setup the pointers to the various items in the reserved page */
xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
@@ -222,14 +213,14 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,

/* pull over the reserved page header and part_nasids mask */
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)
return ret;

if (discovered_nasids != NULL) {
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];
}

@@ -414,12 +405,12 @@ xpc_discovery(void)
enum xp_retval ret;

remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
xp_sizeof_nasid_mask,
xpc_sizeof_nasid_mask,
GFP_KERNEL, &remote_rp_base);
if (remote_rp == NULL)
return;

discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words,
discovered_nasids = kzalloc(sizeof(u64) * xpc_nasid_mask_words,
GFP_KERNEL);
if (discovered_nasids == NULL) {
kfree(remote_rp_base);
@@ -521,10 +512,10 @@ xpc_initiate_partid_to_nasids(short partid, void *nasid_mask)
if (part->remote_rp_pa == 0)
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);

return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa,
xp_sizeof_nasid_mask);
xpc_sizeof_nasid_mask);
}
Loading

0 comments on commit ee6665e

Please sign in to comment.