Skip to content

Commit

Permalink
sgi-xp: prepare xpc_rsvd_page to work on either sn2 or uv hardware
Browse files Browse the repository at this point in the history
Prepare XPC's reserved page header to work for either sn2 or uv.

Signed-off-by: Dean Nelson <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Dean Nelson authored and torvalds committed Jul 30, 2008
1 parent 908787d commit 94bd270
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 133 deletions.
3 changes: 2 additions & 1 deletion drivers/misc/sgi-xp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ xp-y := xp_main.o xp_uv.o
xp-$(CONFIG_IA64) += xp_sn2.o xp_nofault.o

obj-$(CONFIG_SGI_XP) += xpc.o
xpc-y := xpc_main.o xpc_channel.o xpc_partition.o
xpc-y := xpc_main.o xpc_uv.o xpc_channel.o xpc_partition.o
xpc-$(CONFIG_IA64) += xpc_sn2.o

obj-$(CONFIG_SGI_XP) += xpnet.o
5 changes: 3 additions & 2 deletions drivers/misc/sgi-xp/xp.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,10 @@ enum xp_retval {

xpBteCopyError, /* 52: bte_copy() returned error */
xpSalError, /* 53: sn SAL error */
xpRsvdPageNotSet, /* 54: the reserved page is not set up */

xpUnsupported, /* 54: unsupported functionality or resource */
xpUnknownReason /* 55: unknown reason - must be last in enum */
xpUnsupported, /* 55: unsupported functionality or resource */
xpUnknownReason /* 56: unknown reason - must be last in enum */
};

/*
Expand Down
57 changes: 36 additions & 21 deletions drivers/misc/sgi-xp/xpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@
*
* reserved page header
*
* The first cacheline of the reserved page contains the header
* (struct xpc_rsvd_page). Before SAL initialization has completed,
* The first two 64-byte cachelines of the reserved page contain the
* header (struct xpc_rsvd_page). Before SAL initialization has completed,
* SAL has set up the following fields of the reserved page header:
* SAL_signature, SAL_version, partid, and nasids_size. The other
* fields are set up by XPC. (xpc_rsvd_page points to the local
* SAL_signature, SAL_version, SAL_partid, and SAL_nasids_size. The
* other fields are set up by XPC. (xpc_rsvd_page points to the local
* partition's reserved page.)
*
* part_nasids mask
Expand All @@ -89,37 +89,43 @@
* nasids. The part_nasids mask is located starting at the first cacheline
* following the reserved page header. The mach_nasids mask follows right
* after the part_nasids mask. The size in bytes of each mask is reflected
* by the reserved page header field 'nasids_size'. (Local partition's
* by the reserved page header field 'SAL_nasids_size'. (Local partition's
* mask pointers are xpc_part_nasids and xpc_mach_nasids.)
*
* vars
* vars part
* vars (ia64-sn2 only)
* vars part (ia64-sn2 only)
*
* Immediately following the mach_nasids mask are the XPC variables
* required by other partitions. First are those that are generic to all
* partitions (vars), followed on the next available cacheline by those
* which are partition specific (vars part). These are setup by XPC.
* (Local partition's vars pointers are xpc_vars and xpc_vars_part.)
*
* Note: Until vars_pa is set, the partition XPC code has not been initialized.
* Note: Until 'stamp' is set non-zero, the partition XPC code has not been
* initialized.
*/
struct xpc_rsvd_page {
u64 SAL_signature; /* SAL: unique signature */
u64 SAL_version; /* SAL: version */
u8 partid; /* SAL: partition ID */
short SAL_partid; /* SAL: partition ID */
short max_npartitions; /* value of XPC_MAX_PARTITIONS */
u8 version;
u8 pad1[6]; /* align to next u64 in cacheline */
u64 vars_pa; /* physical address of struct xpc_vars */
u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */
union {
u64 vars_pa; /* physical address of struct xpc_vars */
u64 activate_mq_gpa; /* global phys address of activate_mq */
} sn;
struct timespec stamp; /* time when reserved page was setup by XPC */
u64 pad2[9]; /* align to last u64 in cacheline */
u64 nasids_size; /* SAL: size of each nasid mask in bytes */
u64 pad2[9]; /* align to last u64 in 2nd 64-byte cacheline */
u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */
};

#define XPC_RP_VERSION _XPC_VERSION(1, 1) /* version 1.1 of the reserved page */
#define XPC_RP_VERSION _XPC_VERSION(2, 0) /* version 2.0 of the reserved page */

#define XPC_SUPPORTS_RP_STAMP(_version) \
(_version >= _XPC_VERSION(1, 1))

#define ZERO_STAMP ((struct timespec){0, 0})
/*
* compare stamps - the return value is:
*
Expand Down Expand Up @@ -218,10 +224,10 @@ xpc_disallow_hb(short partid, struct xpc_vars *vars)
*
* An array of these structures, one per partition, will be defined. As a
* partition becomes active XPC will copy the array entry corresponding to
* itself from that partition. It is desirable that the size of this
* structure evenly divide into a cacheline, such that none of the entries
* in this array crosses a cacheline boundary. As it is now, each entry
* occupies half a cacheline.
* itself from that partition. It is desirable that the size of this structure
* evenly divides into a 128-byte cacheline, such that none of the entries in
* this array crosses a 128-byte cacheline boundary. As it is now, each entry
* occupies a 64-byte cacheline.
*/
struct xpc_vars_part {
u64 magic;
Expand Down Expand Up @@ -632,16 +638,25 @@ extern void xpc_activate_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int, int);
extern void xpc_disconnect_wait(int);

extern enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *);

/* found in xpc_sn2.c */
extern void xpc_init_sn2(void);
extern struct xpc_vars *xpc_vars; /*>>> eliminate from here */
extern struct xpc_vars_part *xpc_vars_part; /*>>> eliminate from here */

/* found in xpc_uv.c */
extern void xpc_init_uv(void);

/* found in xpc_partition.c */
extern int xpc_exiting;
extern struct xpc_vars *xpc_vars;
extern int xp_nasid_mask_words;
extern struct xpc_rsvd_page *xpc_rsvd_page;
extern struct xpc_vars_part *xpc_vars_part;
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_rsvd_page_init(void);
extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void);
extern void xpc_allow_IPI_ops(void);
extern void xpc_restrict_IPI_ops(void);
extern int xpc_identify_act_IRQ_sender(void);
Expand Down
27 changes: 23 additions & 4 deletions drivers/misc/sgi-xp/xpc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ static struct notifier_block xpc_die_notifier = {
.notifier_call = xpc_system_die,
};

enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *rp);

/*
* Timer function to enforce the timelimit on the partition disengage request.
*/
Expand Down Expand Up @@ -949,7 +951,7 @@ xpc_do_exit(enum xp_retval reason)
DBUG_ON(xpc_partition_engaged(-1UL));

/* indicate to others that our reserved page is uninitialized */
xpc_rsvd_page->vars_pa = 0;
xpc_rsvd_page->stamp = ZERO_STAMP;

/* now it's time to eliminate our heartbeat */
del_timer_sync(&xpc_hb_timer);
Expand Down Expand Up @@ -1128,8 +1130,24 @@ xpc_init(void)
struct task_struct *kthread;
size_t buf_size;

if (!ia64_platform_is("sn2"))
if (is_shub()) {
/*
* The ia64-sn2 architecture supports at most 64 partitions.
* And the inability to unregister remote AMOs restricts us
* further to only support exactly 64 partitions on this
* architecture, no less.
*/
if (xp_max_npartitions != 64)
return -EINVAL;

xpc_init_sn2();

} else if (is_uv()) {
xpc_init_uv();

} else {
return -ENODEV;
}

snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
Expand Down Expand Up @@ -1214,7 +1232,7 @@ xpc_init(void)
* other partitions to discover we are alive and establish initial
* communications.
*/
xpc_rsvd_page = xpc_rsvd_page_init();
xpc_rsvd_page = xpc_setup_rsvd_page();
if (xpc_rsvd_page == NULL) {
dev_err(xpc_part, "can't setup our reserved page\n");
ret = -EBUSY;
Expand Down Expand Up @@ -1273,7 +1291,8 @@ xpc_init(void)
/* initialization was not successful */
out_4:
/* indicate to others that our reserved page is uninitialized */
xpc_rsvd_page->vars_pa = 0;
xpc_rsvd_page->stamp = ZERO_STAMP;

del_timer_sync(&xpc_hb_timer);
(void)unregister_die_notifier(&xpc_die_notifier);
(void)unregister_reboot_notifier(&xpc_reboot_notifier);
Expand Down
Loading

0 comments on commit 94bd270

Please sign in to comment.