Skip to contentSkip to conversation

continued prepartion of XPC/XPNET to support SGI UV

PATCH In review Dean Nelson 2 participants 21 messages Jun 6, 2008 – Jun 9, 2008 Char and misc drivers

lore
Share & tools
lore
#0 lore raw

cover continued prepartion of XPC/XPNET to support SGI UV

This set of patches takes XPC/XPNET another step in the direction of being able to run on both sgi-sn2 and sgi-uv hardware. The result of this set of patches is to isolate the architecture specific code.

This patchset is based on linux-next.

There are more patches to follow.

I can't do anything about the following warning reported by checkpatch.pl. The symbol being exported resides in drivers/misc/sgi-xp/xp_nofault.S, so the EXPORT_SYMBOL_GPL(xp_nofault_PIOR) can't even be placed in the same file much less follow the function.

Quoted 3 lines

WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable #25: FILE: misc/sgi-xp/xp_sn2.c:25:
+EXPORT_SYMBOL_GPL(xp_nofault_PIOR);

#1 lore raw

PATCH 1/18 define is_shub() and is_uv() macros

Define the is_shub()/is_uv() macros if they've not already been defined.

---

 drivers/misc/sgi-xp/xp.h |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
drivers/misc/sgi-xp/xp.h +16 -0
Index: linux-2.6/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -25,6 +25,22 @@
 #define DBUG_ON(condition)
 #endif
 
+#ifndef is_shub1
+#define is_shub1()	0
+#endif
+
+#ifndef is_shub2
+#define is_shub2()	0
+#endif
+
+#ifndef is_shub
+#define is_shub()	(is_shub1() || is_shub2())
+#endif
+
+#ifndef is_uv
+#define is_uv()		0
+#endif
+
 /*
  * Define the maximum number of logically defined partitions the system
  * can support. It is constrained by the maximum number of hardware
#2 lore raw

PATCH 2/18 define xpSalError reason code

In reply to Dean Nelson

Define xpSalError reason code.

---

 drivers/misc/sgi-xp/xp.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/misc/sgi-xp/xp.h +2 -1
Index: linux-2.6/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -249,8 +249,9 @@ enum xp_retval {
 	xpDisconnected,		/* 51: channel disconnected (closed) */
 
 	xpBteCopyError,		/* 52: bte_copy() returned error */
+	xpSalError,		/* 53: sn SAL error */
 
-	xpUnknownReason		/* 53: unknown reason - must be last in enum */
+	xpUnknownReason		/* 54: unknown reason - must be last in enum */
 };
 
 /*
#3 lore raw

PATCH 3/18 define BYTES_PER_WORD

In reply to Dean Nelson

Add a BYTES_PER_WORD #define.

---

 drivers/misc/sgi-xp/xp.h |    3 +++
 1 file changed, 3 insertions(+)
drivers/misc/sgi-xp/xp.h +3 -0
Index: linux-2.6/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -19,6 +19,9 @@
 #include <asm/sn/types.h>
 #include <asm/sn/bte.h>
 
+/* >>> Add this #define to some linux header file some day. */
+#define BYTES_PER_WORD	sizeof(void *)
+
 #ifdef USE_DBUG_ON
 #define DBUG_ON(condition)	BUG_ON(condition)
 #else
#4 lore raw

Re: [Patch 03/18] define BYTES_PER_WORD

Quoted 14 lines · On Fri, 6 Jun 2008 11:44:55 -0500 Dean Nelson <[email protected]> wrote:

Add a BYTES_PER_WORD #define.

---

 drivers/misc/sgi-xp/xp.h |    3 +++
 1 file changed, 3 insertions(+)

Index: linux-2.6/drivers/misc/sgi-xp/xp.h
===================================================================

drivers/misc/sgi-xp/xp.h line 22

Quoted 4 lines
drivers/misc/sgi-xp/xp.h +1 -0
@@ -19,6 +19,9 @@
 #include <asm/sn/types.h>
 #include <asm/sn/bte.h>
 
+/* >>> Add this #define to some linux header file some day. */

The patches fill the code with this ">>>" string - which can cause false positives when people are searching for git rejects. Although I (and I suspect most other people) search for "<<<<<<<".

drivers/misc/sgi-xp/xp.h line 23

Quoted 1 line
drivers/misc/sgi-xp/xp.h +1 -0
+#define BYTES_PER_WORD	sizeof(void *)

Dunno if this is a desirable thing to have, really. A "word" is a somewhat ill-defined thing. The definition you have here is always equal to BYTES_PER_LONG. If BYTES_PER_LONG is inappropriate then BYTES_PER_POINTER would be clearer.

#5 lore raw

PATCH 4/18 support runtime selection of xp_max_npartitions

In reply to Dean Nelson

Support runtime selection of the max number of partitions based on the hardware being run on.

---

 drivers/misc/sgi-xp/Makefile        |    3 
 drivers/misc/sgi-xp/xp.h            |   53 ++++++++++------
 drivers/misc/sgi-xp/xp_main.c       |   84 ++++++++++----------------
 drivers/misc/sgi-xp/xp_sn2.c        |   92 ++++++++++++++++++++++++++++
 drivers/misc/sgi-xp/xp_uv.c         |   30 +++++++++
 drivers/misc/sgi-xp/xpc.h           |   12 ++-
 drivers/misc/sgi-xp/xpc_channel.c   |   20 +++---
 drivers/misc/sgi-xp/xpc_main.c      |  103 +++++++++++++++-----------------
 drivers/misc/sgi-xp/xpc_partition.c |   16 +---
 drivers/misc/sgi-xp/xpnet.c         |    4 -
 10 files changed, 266 insertions(+), 151 deletions(-)
drivers/misc/sgi-xp/xp.h +35 -18
Index: linux-2.6/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -18,6 +18,9 @@
 #include <linux/mutex.h>
 #include <asm/sn/types.h>
 #include <asm/sn/bte.h>
+#ifdef CONFIG_IA64
+#include <asm/sn/arch.h>
+#endif
 
 /* >>> Add this #define to some linux header file some day. */
 #define BYTES_PER_WORD	sizeof(void *)
@@ -45,17 +48,18 @@
 #endif
 
 /*
- * Define the maximum number of logically defined partitions the system
- * can support. It is constrained by the maximum number of hardware
- * partitionable regions. The term 'region' in this context refers to the
- * minimum number of nodes that can comprise an access protection grouping.
- * The access protection is in regards to memory, IPI and IOI.
+ * Define the maximum number of partitions the system can possibly support.
+ * It is based on the maximum number of hardware partitionable regions. The
+ * term 'region' in this context refers to the minimum number of nodes that
+ * can comprise an access protection grouping. The access protection is in
+ * regards to memory, IPI and IOI.
  *
  * The maximum number of hardware partitionable regions is equal to the
  * maximum number of nodes in the entire system divided by the minimum number
  * of nodes that comprise an access protection grouping.
  */
-#define XP_MAX_PARTITIONS	64
+#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
@@ -112,24 +116,28 @@ xp_bte_copy(u64 src, u64 vdst, u64 len, 
  * other partition that is currently up. Over these channels, kernel-level
  * `users' can communicate with their counterparts on the other partitions.
  *
- * The maxinum number of channels is limited to eight. For performance reasons,
- * the internal cross partition structures require sixteen bytes per channel,
- * and eight allows all of this interface-shared info to fit in one cache line.
+>>> The following described limitation of a max of eight channels possible
+>>> pertains only to ia64-sn2. THIS ISN'T TRUE SINCE I'M PLANNING TO JUST
+>>> TIE INTO THE EXISTING MECHANISM ONCE THE CHANNEL MESSAGES ARE RECEIVED.
+>>> THE 128-BYTE CACHELINE PERFORMANCE ISSUE IS TIED TO IA64-SN2.
  *
- * XPC_NCHANNELS reflects the total number of channels currently defined.
  * If the need for additional channels arises, one can simply increase
- * XPC_NCHANNELS accordingly. If the day should come where that number
- * exceeds the MAXIMUM number of channels allowed (eight), then one will need
- * to make changes to the XPC code to allow for this.
+ * XPC_MAX_NCHANNELS accordingly. If the day should come where that number
+ * exceeds the absolute MAXIMUM number of channels possible (eight), then one
+ * will need to make changes to the XPC code to accommodate for this.
+ *
+ * The absolute maximum number of channels possible is currently limited to
+ * eight for performance reasons. The internal cross partition structures
+ * require sixteen bytes per channel, and eight allows all of this
+ * interface-shared info to fit in one 128-byte cacheline.
  */
 #define XPC_MEM_CHANNEL		0	/* memory channel number */
 #define	XPC_NET_CHANNEL		1	/* network channel number */
 
-#define	XPC_NCHANNELS		2	/* #of defined channels */
-#define XPC_MAX_NCHANNELS	8	/* max #of channels allowed */
+#define XPC_MAX_NCHANNELS	2	/* max #of channels allowed */
 
-#if XPC_NCHANNELS > XPC_MAX_NCHANNELS
-#error	XPC_NCHANNELS exceeds MAXIMUM allowed.
+#if XPC_MAX_NCHANNELS > 8
+#error	XPC_MAX_NCHANNELS exceeds absolute MAXIMUM possible.
 #endif
 
 /*
@@ -254,7 +262,8 @@ enum xp_retval {
 	xpBteCopyError,		/* 52: bte_copy() returned error */
 	xpSalError,		/* 53: sn SAL error */
 
-	xpUnknownReason		/* 54: unknown reason - must be last in enum */
+	xpUnsupported,		/* 54: unsupported functionality or resource */
+	xpUnknownReason		/* 55: unknown reason - must be last in enum */
 };
 
 /*
@@ -397,8 +406,16 @@ xpc_partid_to_nasids(short partid, void 
 	return xpc_interface.partid_to_nasids(partid, nasids);
 }
 
+extern short xp_max_npartitions;
+
 extern u64 xp_nofault_PIOR_target;
 extern int xp_nofault_PIOR(void *);
 extern int xp_error_PIOR(void);
 
+extern struct device *xp;
+extern enum xp_retval xp_init_sn2(void);
+extern enum xp_retval xp_init_uv(void);
+extern void xp_exit_sn2(void);
+extern void xp_exit_uv(void);
+
 #endif /* _DRIVERS_MISC_SGIXP_XP_H */
drivers/misc/sgi-xp/xpc.h +7 -5
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -210,7 +210,7 @@ xpc_disallow_hb(short partid, struct xpc
  * the XPC running on the remote partition).
  */
 #define XPC_NOTIFY_IRQ_AMOS	   0
-#define XPC_ACTIVATE_IRQ_AMOS	   (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS)
+#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_DISENGAGE_REQUEST_AMO  (XPC_ENGAGED_PARTITIONS_AMO + 1)
 
@@ -285,7 +285,7 @@ struct xpc_gp {
 };
 
 #define XPC_GP_SIZE \
-		L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS)
+		L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_MAX_NCHANNELS)
 
 /*
  * Define a structure that contains arguments associated with opening and
@@ -300,7 +300,8 @@ struct xpc_openclose_args {
 };
 
 #define XPC_OPENCLOSE_ARGS_SIZE \
-	      L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS)
+	      L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
+	      XPC_MAX_NCHANNELS)
 
 /* struct xpc_msg flags */
 
@@ -637,7 +638,7 @@ extern int xpc_exiting;
 extern struct xpc_vars *xpc_vars;
 extern struct xpc_rsvd_page *xpc_rsvd_page;
 extern struct xpc_vars_part *xpc_vars_part;
-extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
+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 **);
@@ -1104,13 +1105,14 @@ xpc_IPI_send_local_msgrequest(struct xpc
 }
 
 /*
+>>> this block comment needs to be moved and re-written.
  * 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_PARTITIONS) for message notification and an
+ * AMO variables (based on xp_max_npartitions) for message notification and an
  * additional 128 AMO variables (based on XP_NASID_MASK_WORDS) for partition
  * activation and 2 AMO variables for partition deactivation.
  */
drivers/misc/sgi-xp/xpc_partition.c +4 -12
Index: linux-2.6/drivers/misc/sgi-xp/xpc_partition.c
===================================================================
@@ -51,13 +51,7 @@ struct xpc_vars_part *xpc_vars_part;
 static int xp_nasid_mask_bytes;	/* actual size in bytes of nasid mask */
 static int xp_nasid_mask_words;	/* actual size in words of nasid mask */
 
-/*
- * For performance reasons, each entry of xpc_partitions[] is cacheline
- * aligned. And xpc_partitions[] is padded with an additional entry at the
- * end so that the last legitimate entry doesn't share its cacheline with
- * another variable.
- */
-struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
+struct xpc_partition *xpc_partitions;
 
 /*
  * Generic buffer used to store a local copy of portions of a remote
@@ -261,7 +255,7 @@ xpc_rsvd_page_init(void)
 
 	/* clear xpc_vars_part */
 	memset((u64 *)xpc_vars_part, 0, sizeof(struct xpc_vars_part) *
-	       XP_MAX_PARTITIONS);
+	       xp_max_npartitions);
 
 	/* initialize the activate IRQ related AMO variables */
 	for (i = 0; i < xp_nasid_mask_words; i++)
@@ -408,7 +402,7 @@ xpc_check_remote_hb(void)
 
 	remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
 
-	for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+	for (partid = 0; partid < xp_max_npartitions; partid++) {
 
 		if (xpc_exiting)
 			break;
@@ -487,10 +481,8 @@ xpc_get_remote_rp(int nasid, u64 *discov
 
 	/* check that the partid is for another partition */
 
-	if (remote_rp->partid < 1 ||
-	    remote_rp->partid > (XP_MAX_PARTITIONS - 1)) {
+	if (remote_rp->partid < 0 || remote_rp->partid >= xp_max_npartitions)
 		return xpInvalidPartid;
-	}
 
 	if (remote_rp->partid == sn_partition_id)
 		return xpLocalPartid;
drivers/misc/sgi-xp/xpc_channel.c +10 -10
Index: linux-2.6/drivers/misc/sgi-xp/xpc_channel.c
===================================================================
@@ -110,14 +110,14 @@ xpc_setup_infrastructure(struct xpc_part
 	 * Allocate all of the channel structures as a contiguous chunk of
 	 * memory.
 	 */
-	part->channels = kzalloc(sizeof(struct xpc_channel) * XPC_NCHANNELS,
+	part->channels = kzalloc(sizeof(struct xpc_channel) * XPC_MAX_NCHANNELS,
 				 GFP_KERNEL);
 	if (part->channels == NULL) {
 		dev_err(xpc_chan, "can't get memory for channels\n");
 		return xpNoMemory;
 	}
 
-	part->nchannels = XPC_NCHANNELS;
+	part->nchannels = XPC_MAX_NCHANNELS;
 
 	/* allocate all the required GET/PUT values */
 
@@ -1432,9 +1432,9 @@ xpc_initiate_connect(int ch_number)
 	struct xpc_partition *part;
 	struct xpc_channel *ch;
 
-	DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
+	DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);
 
-	for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+	for (partid = 0; partid < xp_max_npartitions; partid++) {
 		part = &xpc_partitions[partid];
 
 		if (xpc_part_ref(part)) {
@@ -1488,10 +1488,10 @@ xpc_initiate_disconnect(int ch_number)
 	struct xpc_partition *part;
 	struct xpc_channel *ch;
 
-	DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
+	DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);
 
 	/* initiate the channel disconnect for every active partition */
-	for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+	for (partid = 0; partid < xp_max_npartitions; partid++) {
 		part = &xpc_partitions[partid];
 
 		if (xpc_part_ref(part)) {
@@ -1734,7 +1734,7 @@ xpc_initiate_allocate(short partid, int 
 	enum xp_retval ret = xpUnknownReason;
 	struct xpc_msg *msg = NULL;
 
-	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
 	DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
 
 	*payload = NULL;
@@ -1918,7 +1918,7 @@ xpc_initiate_send(short partid, int ch_n
 	dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg,
 		partid, ch_number);
 
-	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
 	DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
 	DBUG_ON(msg == NULL);
 
@@ -1968,7 +1968,7 @@ xpc_initiate_send_notify(short partid, i
 	dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg,
 		partid, ch_number);
 
-	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
 	DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
 	DBUG_ON(msg == NULL);
 	DBUG_ON(func == NULL);
@@ -2210,7 +2210,7 @@ xpc_initiate_received(short partid, int 
 	struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
 	s64 get, msg_number = msg->number;
 
-	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
 	DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
 
 	ch = &part->channels[ch_number];
drivers/misc/sgi-xp/xpc_main.c +50 -53

201 lines not on this page · raw message

drivers/misc/sgi-xp/xpnet.c +2 -2
Index: linux-2.6/drivers/misc/sgi-xp/xpnet.c
===================================================================
@@ -287,7 +287,7 @@ xpnet_connection_activity(enum xp_retval
 {
 	long bp;
 
-	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
 	DBUG_ON(channel != XPC_NET_CHANNEL);
 
 	switch (reason) {
@@ -513,7 +513,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff
 	/*
 	 * Main send loop.
 	 */
-	for (dest_partid = 1; dp && dest_partid < XP_MAX_PARTITIONS;
+	for (dest_partid = 0; dp && dest_partid < xp_max_npartitions;
 	     dest_partid++) {
 
 		if (!(dp & (1UL << (dest_partid - 1)))) {
drivers/misc/sgi-xp/xp_main.c +34 -50

127 lines not on this page · raw message

drivers/misc/sgi-xp/xp_sn2.c new file +92 -0

92 lines not on this page · raw message

drivers/misc/sgi-xp/xp_uv.c new file +30 -0
Index: linux-2.6/drivers/misc/sgi-xp/xp_uv.c
===================================================================
@@ -0,0 +1,30 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+/*
+ * Cross Partition (XP) uv-based functions.
+ *
+ *      Architecture specific implementation of common functions.
+ *
+ */
+
+#include "xp.h"
+
+enum xp_retval
+xp_init_uv(void)
+{
+	BUG_ON(!is_uv());
+
+	xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
+}
+
+void
+xp_exit_uv(void)
+{
+	BUG_ON(!is_uv());
+}
drivers/misc/sgi-xp/Makefile +2 -1
Index: linux-2.6/drivers/misc/sgi-xp/Makefile
===================================================================
@@ -3,7 +3,8 @@
 #
 
 obj-$(CONFIG_SGI_XP)		+= xp.o
-xp-y				:= xp_main.o xp_nofault.o
+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
#6 lore raw

PATCH 5/18 create a common xp_remote_memcpy() function

In reply to Dean Nelson

Create a common remote memcpy function that maps to what the hardware booted supports.

---

 drivers/misc/sgi-xp/xp.h            |   43 +------------------------
 drivers/misc/sgi-xp/xp_main.c       |    3 +
 drivers/misc/sgi-xp/xp_sn2.c        |   46 ++++++++++++++++++++++++++
 drivers/misc/sgi-xp/xp_uv.c         |   11 ++++++
 drivers/misc/sgi-xp/xpc.h           |    7 ----
 drivers/misc/sgi-xp/xpc_channel.c   |   20 ++++-------
 drivers/misc/sgi-xp/xpc_partition.c |   55 +++++++++++++-------------------
 drivers/misc/sgi-xp/xpnet.c         |   30 ++++++++---------
 8 files changed, 108 insertions(+), 107 deletions(-)
drivers/misc/sgi-xp/xp.h +2 -41
Index: linux-2.6/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -17,7 +17,6 @@
 #include <linux/hardirq.h>
 #include <linux/mutex.h>
 #include <asm/sn/types.h>
-#include <asm/sn/bte.h>
 #ifdef CONFIG_IA64
 #include <asm/sn/arch.h>
 #endif
@@ -72,46 +71,6 @@
 #define XP_NASID_MASK_WORDS	((XP_MAX_PHYSNODE_ID + 63) / 64)
 
 /*
- * Wrapper for bte_copy() that should it return a failure status will retry
- * the bte_copy() once in the hope that the failure was due to a temporary
- * aberration (i.e., the link going down temporarily).
- *
- * 	src - physical address of the source of the transfer.
- *	vdst - virtual address of the destination of the transfer.
- *	len - number of bytes to transfer from source to destination.
- *	mode - see bte_copy() for definition.
- *	notification - see bte_copy() for definition.
- *
- * Note: xp_bte_copy() should never be called while holding a spinlock.
- */
-static inline bte_result_t
-xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
-{
-	bte_result_t ret;
-	u64 pdst = ia64_tpa(vdst);
-
-	/*
-	 * Ensure that the physically mapped memory is contiguous.
-	 *
-	 * We do this by ensuring that the memory is from region 7 only.
-	 * If the need should arise to use memory from one of the other
-	 * regions, then modify the BUG_ON() statement to ensure that the
-	 * memory from that region is always physically contiguous.
-	 */
-	BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL);
-
-	ret = bte_copy(src, pdst, len, mode, notification);
-	if ((ret != BTE_SUCCESS) && BTE_ERROR_RETRY(ret)) {
-		if (!in_interrupt())
-			cond_resched();
-
-		ret = bte_copy(src, pdst, len, mode, notification);
-	}
-
-	return ret;
-}
-
-/*
  * XPC establishes channel connections between the local partition and any
  * other partition that is currently up. Over these channels, kernel-level
  * `users' can communicate with their counterparts on the other partitions.
@@ -408,6 +367,8 @@ xpc_partid_to_nasids(short partid, void 
 
 extern short xp_max_npartitions;
 
+extern enum xp_retval (*xp_remote_memcpy) (void *, const void *, size_t);
+
 extern u64 xp_nofault_PIOR_target;
 extern int xp_nofault_PIOR(void *);
 extern int xp_error_PIOR(void);
drivers/misc/sgi-xp/xp_main.c +3 -0
Index: linux-2.6/drivers/misc/sgi-xp/xp_main.c
===================================================================
@@ -36,6 +36,9 @@ struct device *xp = &xp_dbg_subname;
 short xp_max_npartitions;
 EXPORT_SYMBOL_GPL(xp_max_npartitions);
 
+enum xp_retval (*xp_remote_memcpy) (void *dst, const void *src, size_t len);
+EXPORT_SYMBOL_GPL(xp_remote_memcpy);
+
 /*
  * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
  * users of XPC.
drivers/misc/sgi-xp/xp_sn2.c +46 -0

64 lines not on this page · raw message

drivers/misc/sgi-xp/xp_uv.c +11 -0
Index: linux-2.6/drivers/misc/sgi-xp/xp_uv.c
===================================================================
@@ -15,12 +15,23 @@
 
 #include "xp.h"
 
+static enum xp_retval
+xp_remote_memcpy_uv(void *vdst, const void *psrc, size_t len)
+{
+	/* >>> this function needs fleshing out */
+	return xpUnsupported;
+}
+
 enum xp_retval
 xp_init_uv(void)
 {
 	BUG_ON(!is_uv());
 
 	xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
+
+	xp_remote_memcpy = xp_remote_memcpy_uv;
+
+	return xpSuccess;
 }
 
 void
drivers/misc/sgi-xp/xpc.h +0 -7
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -20,7 +20,6 @@
 #include <linux/completion.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
-#include <asm/sn/bte.h>
 #include <asm/sn/clksupport.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/mspec.h>
@@ -1125,12 +1124,6 @@ xpc_IPI_init(int index)
 	return amo;
 }
 
-static inline enum xp_retval
-xpc_map_bte_errors(bte_result_t error)
-{
-	return ((error == BTE_SUCCESS) ? xpSuccess : xpBteCopyError);
-}
-
 /*
  * Check to see if there is any channel activity to/from the specified
  * partition.
drivers/misc/sgi-xp/xpc_channel.c +8 -12
Index: linux-2.6/drivers/misc/sgi-xp/xpc_channel.c
===================================================================
@@ -21,7 +21,6 @@
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/completion.h>
-#include <asm/sn/bte.h>
 #include <asm/sn/sn_sal.h>
 #include "xpc.h"
 
@@ -252,13 +251,13 @@ xpc_setup_infrastructure(struct xpc_part
  *
  * src must be a cacheline aligned physical address on the remote partition.
  * dst must be a cacheline aligned virtual address on this partition.
- * cnt must be an cacheline sized
+ * cnt must be cacheline sized
  */
 static enum xp_retval
 xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
 			   const void *src, size_t cnt)
 {
-	bte_result_t bte_ret;
+	enum xp_retval ret;
 
 	DBUG_ON((u64)src != L1_CACHE_ALIGN((u64)src));
 	DBUG_ON((u64)dst != L1_CACHE_ALIGN((u64)dst));
@@ -267,15 +266,12 @@ xpc_pull_remote_cachelines(struct xpc_pa
 	if (part->act_state == XPC_P_DEACTIVATING)
 		return part->reason;
 
-	bte_ret = xp_bte_copy((u64)src, (u64)dst, (u64)cnt,
-			      (BTE_NORMAL | BTE_WACQUIRE), NULL);
-	if (bte_ret == BTE_SUCCESS)
-		return xpSuccess;
-
-	dev_dbg(xpc_chan, "xp_bte_copy() from partition %d failed, ret=%d\n",
-		XPC_PARTID(part), bte_ret);
-
-	return xpc_map_bte_errors(bte_ret);
+	ret = xp_remote_memcpy(dst, src, cnt);
+	if (ret != xpSuccess) {
+		dev_dbg(xpc_chan, "xp_remote_memcpy() from partition %d failed,"
+			" ret=%d\n", XPC_PARTID(part), ret);
+	}
+	return ret;
 }
 
 /*
drivers/misc/sgi-xp/xpc_partition.c +24 -31

124 lines not on this page · raw message

drivers/misc/sgi-xp/xpnet.c +14 -16
Index: linux-2.6/drivers/misc/sgi-xp/xpnet.c
===================================================================
@@ -32,7 +32,6 @@
 #include <linux/mii.h>
 #include <linux/smp.h>
 #include <linux/string.h>
-#include <asm/sn/bte.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/atomic.h>
@@ -169,7 +168,7 @@ static void
 xpnet_receive(short partid, int channel, struct xpnet_message *msg)
 {
 	struct sk_buff *skb;
-	bte_result_t bret;
+	enum xp_retval ret;
 	struct xpnet_dev_private *priv =
 	    (struct xpnet_dev_private *)xpnet_device->priv;
 
@@ -201,7 +200,7 @@ xpnet_receive(short partid, int channel,
 
 	/*
 	 * The allocated skb has some reserved space.
-	 * In order to use bte_copy, we need to get the
+	 * In order to use xp_remote_memcpy(), we need to get the
 	 * skb->data pointer moved forward.
 	 */
 	skb_reserve(skb, (L1_CACHE_BYTES - ((u64)skb->data &
@@ -227,25 +226,24 @@ xpnet_receive(short partid, int channel,
 					(size_t)msg->embedded_bytes);
 	} else {
 		dev_dbg(xpnet, "transferring buffer to the skb->data area;\n\t"
-			"bte_copy(0x%p, 0x%p, %hu)\n", (void *)msg->buf_pa,
-			(void *)__pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
-			msg->size);
-
-		bret = bte_copy(msg->buf_pa,
-				__pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
-				msg->size, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+			"xp_remote_memcpy(0x%p, 0x%p, %hu)\n", (void *)
+				       ((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
+					  (void *)msg->buf_pa, msg->size);
+
+		ret = xp_remote_memcpy((void *)((u64)skb->data &
+				                ~(L1_CACHE_BYTES - 1)),
+				       (void *)msg->buf_pa, msg->size);
 
-		if (bret != BTE_SUCCESS) {
+		if (ret != xpSuccess) {
 			/*
 			 * >>> Need better way of cleaning skb.  Currently skb
 			 * >>> appears in_use and we can't just call
 			 * >>> dev_kfree_skb.
 			 */
-			dev_err(xpnet, "bte_copy(0x%p, 0x%p, 0x%hx) returned "
-				"error=0x%x\n", (void *)msg->buf_pa,
-				(void *)__pa((u64)skb->data &
-					     ~(L1_CACHE_BYTES - 1)),
-				msg->size, bret);
+			dev_err(xpnet, "xp_remote_memcpy(0x%p, 0x%p, 0x%hx) "
+				"returned error=0x%x\n", (void *)
+				((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
+				(void *)msg->buf_pa, msg->size, ret);
 
 			xpc_received(partid, channel, (void *)msg);
 
#7 lore raw

PATCH 6/18 prepare xpc_rsvd_page to work on either sn2 or uv hardware

In reply to Dean Nelson

Prepare XPC's reserved page header to work for either sn2 or uv.

---

 drivers/misc/sgi-xp/Makefile        |    3 
 drivers/misc/sgi-xp/xp.h            |    5 -
 drivers/misc/sgi-xp/xpc.h           |   57 +++++++-----
 drivers/misc/sgi-xp/xpc_main.c      |   27 ++++-
 drivers/misc/sgi-xp/xpc_partition.c |  149 +++++++++-----------------------
 drivers/misc/sgi-xp/xpc_sn2.c       |  111 +++++++++++++++++++++++
 drivers/misc/sgi-xp/xpc_uv.c        |   48 ++++++++++
 7 files changed, 267 insertions(+), 133 deletions(-)
drivers/misc/sgi-xp/xpc.h +36 -21
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -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
@@ -89,11 +89,11 @@
  *     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
@@ -101,25 +101,31 @@
  *     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:
  *
@@ -218,10 +224,10 @@ xpc_disallow_hb(short partid, struct xpc
  *
  * 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;
@@ -632,16 +638,25 @@ extern void xpc_activate_kthreads(struct
 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);
drivers/misc/sgi-xp/xpc_partition.c +44 -105

250 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_main.c +23 -4
Index: linux-2.6/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -175,6 +175,8 @@ static struct notifier_block xpc_die_not
 	.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.
  */
@@ -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);
@@ -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");
@@ -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;
@@ -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);
drivers/misc/sgi-xp/xpc_sn2.c new file +111 -0

111 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_uv.c new file +48 -0

48 lines not on this page · raw message

drivers/misc/sgi-xp/Makefile +2 -1
Index: linux-2.6/drivers/misc/sgi-xp/Makefile
===================================================================
@@ -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
drivers/misc/sgi-xp/xp.h +3 -2
Index: linux-2.6/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -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 */
 };
 
 /*
#8 lore raw

PATCH 7/18 isolate xpc_vars_part structure to sn2 only

In reply to Dean Nelson

Isolate the xpc_vars_part structure of XPC's reserved page to sn2 only.

---

 drivers/misc/sgi-xp/xpc.h           |   26 -
 drivers/misc/sgi-xp/xpc_channel.c   |  538 ------------------------------
 drivers/misc/sgi-xp/xpc_main.c      |   97 +----
 drivers/misc/sgi-xp/xpc_partition.c |    1 
 drivers/misc/sgi-xp/xpc_sn2.c       |  563 +++++++++++++++++++++++++++++++-
 drivers/misc/sgi-xp/xpc_uv.c        |   48 ++
 6 files changed, 644 insertions(+), 629 deletions(-)
drivers/misc/sgi-xp/xpc_partition.c +1 -0
Index: linux-2.6/drivers/misc/sgi-xp/xpc_partition.c
===================================================================
@@ -486,6 +486,7 @@ xpc_update_partition_info(struct xpc_par
 	dev_dbg(xpc_part, "  last_heartbeat = 0x%016lx\n",
 		part->last_heartbeat);
 
+/* >>> remote_vars_part_pa and vars_part_pa are sn2 only!!! */
 	part->remote_vars_part_pa = remote_vars->vars_part_pa;
 	dev_dbg(xpc_part, "  remote_vars_part_pa = 0x%016lx\n",
 		part->remote_vars_part_pa);
drivers/misc/sgi-xp/xpc.h +9 -17
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -227,9 +227,9 @@ xpc_disallow_hb(short partid, struct xpc
  * 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.
+ * occupies 64-bytes.
  */
-struct xpc_vars_part {
+struct xpc_vars_part_sn2 {
 	u64 magic;
 
 	u64 openclose_args_pa;	/* physical address of open and close args */
@@ -265,8 +265,6 @@ struct xpc_vars_part {
 #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words)
 #define XPC_RP_VARS(_rp)	((struct xpc_vars *)(XPC_RP_MACH_NASIDS(_rp) + \
 				    xp_nasid_mask_words))
-#define XPC_RP_VARS_PART(_rp)	((struct xpc_vars_part *) \
-				    ((u8 *)XPC_RP_VARS(_rp) + XPC_RP_VARS_SIZE))
 
 /*
  * Functions registered by add_timer() or called by kernel_thread() only
@@ -541,13 +539,6 @@ struct xpc_partition {
 	wait_queue_head_t teardown_wq;	/* kthread waiting to teardown infra */
 	atomic_t references;	/* #of references to infrastructure */
 
-	/*
-	 * NONE OF THE PRECEDING FIELDS OF THIS STRUCTURE WILL BE CLEARED WHEN
-	 * XPC SETS UP THE NECESSARY INFRASTRUCTURE TO SUPPORT CROSS PARTITION
-	 * COMMUNICATION. ALL OF THE FOLLOWING FIELDS WILL BE CLEARED. (THE
-	 * 'nchannels' FIELD MUST BE THE FIRST OF THE FIELDS TO BE CLEARED.)
-	 */
-
 	u8 nchannels;		/* #of defined channels supported */
 	atomic_t nchannels_active;  /* #of channels that are not DISCONNECTED */
 	atomic_t nchannels_engaged;  /* #of channels engaged with remote part */
@@ -613,7 +604,7 @@ struct xpc_partition {
  * dropped IPIs. These occur whenever an IPI amo write doesn't complete until
  * after the IPI was received.
  */
-#define XPC_P_DROPPED_IPI_WAIT	(0.25 * HZ)
+#define XPC_P_DROPPED_IPI_WAIT_INTERVAL	(0.25 * HZ)
 
 /* number of seconds to wait for other partitions to disengage */
 #define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT	90
@@ -637,13 +628,16 @@ extern void xpc_activate_partition(struc
 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 *);
+extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
+extern u64 (*xpc_get_IPI_flags) (struct xpc_partition *);
+extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *);
+extern enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *);
+extern void (*xpc_teardown_infrastructure) (struct xpc_partition *);
 
 /* 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);
@@ -670,6 +664,7 @@ extern void xpc_deactivate_partition(con
 extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
 
 /* found in xpc_channel.c */
+extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
 extern void xpc_initiate_connect(int);
 extern void xpc_initiate_disconnect(int);
 extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **);
@@ -677,8 +672,6 @@ extern enum xp_retval xpc_initiate_send(
 extern enum xp_retval xpc_initiate_send_notify(short, int, void *,
 					       xpc_notify_func, void *);
 extern void xpc_initiate_received(short, int, void *);
-extern enum xp_retval xpc_setup_infrastructure(struct xpc_partition *);
-extern enum xp_retval xpc_pull_remote_vars_part(struct xpc_partition *);
 extern void xpc_process_channel_activity(struct xpc_partition *);
 extern void xpc_connected_callout(struct xpc_channel *);
 extern void xpc_deliver_msg(struct xpc_channel *);
@@ -686,7 +679,6 @@ extern void xpc_disconnect_channel(const
 				   enum xp_retval, unsigned long *);
 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
 extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
-extern void xpc_teardown_infrastructure(struct xpc_partition *);
 
 static inline void
 xpc_wakeup_channel_mgr(struct xpc_partition *part)
drivers/misc/sgi-xp/xpc_channel.c +1 -537

562 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_main.c +25 -72

141 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_sn2.c +560 -3

596 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_uv.c +48 -0

58 lines not on this page · raw message

#9 lore raw

PATCH 8/18 isolate xpc_vars structure to sn2 only

In reply to Dean Nelson

Isolate the xpc_vars structure of XPC's reserved page to sn2 only.

---

 drivers/misc/sgi-xp/xpc.h           |  529 ++------------
 drivers/misc/sgi-xp/xpc_channel.c   |  315 --------
 drivers/misc/sgi-xp/xpc_main.c      |  152 ++--
 drivers/misc/sgi-xp/xpc_partition.c |  454 ------------
 drivers/misc/sgi-xp/xpc_sn2.c       | 1181 +++++++++++++++++++++++++++++++-
 drivers/misc/sgi-xp/xpc_uv.c        |   57 +
 6 files changed, 1433 insertions(+), 1255 deletions(-)
drivers/misc/sgi-xp/xpc.h +97 -432
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -159,10 +159,10 @@ xpc_compare_stamps(struct timespec *stam
  * reflected by incrementing either the major or minor version numbers
  * of struct xpc_vars.
  */
-struct xpc_vars {
+struct xpc_vars_sn2 {
 	u8 version;
 	u64 heartbeat;
-	u64 heartbeating_to_mask;
+	DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
 	u64 heartbeat_offline;	/* if 0, heartbeat should be changing */
 	int act_nasid;
 	int act_phys_cpuid;
@@ -176,46 +176,23 @@ struct xpc_vars {
 #define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \
 			(_version >= _XPC_VERSION(3, 1))
 
-static inline int
-xpc_hb_allowed(short partid, struct xpc_vars *vars)
-{
-	return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
-}
-
-static inline void
-xpc_allow_hb(short partid, struct xpc_vars *vars)
-{
-	u64 old_mask, new_mask;
-
-	do {
-		old_mask = vars->heartbeating_to_mask;
-		new_mask = (old_mask | (1UL << partid));
-	} while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
-		 old_mask);
-}
-
-static inline void
-xpc_disallow_hb(short partid, struct xpc_vars *vars)
-{
-	u64 old_mask, new_mask;
-
-	do {
-		old_mask = vars->heartbeating_to_mask;
-		new_mask = (old_mask & ~(1UL << partid));
-	} while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
-		 old_mask);
-}
-
 /*
- * The AMOs page consists of a number of AMO variables which are divided into
- * four groups, The first two groups are used to identify an IRQ's sender.
- * These two groups consist of 64 and 128 AMO variables respectively. The last
- * two groups, consisting of just one AMO variable each, are used to identify
- * the remote partitions that are currently engaged (from the viewpoint of
- * the XPC running on the remote partition).
+ * 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, and 2 AMO variables to identify which remote
+ * partitions (i.e., XPCs) consider themselves currently engaged with the
+ * local XPC.
  */
-#define XPC_NOTIFY_IRQ_AMOS	   0
-#define XPC_ACTIVATE_IRQ_AMOS	   (XPC_NOTIFY_IRQ_AMOS + XP_MAX_NPARTITIONS_SN2)
+#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_DISENGAGE_REQUEST_AMO  (XPC_ENGAGED_PARTITIONS_AMO + 1)
 
@@ -259,11 +236,11 @@ struct xpc_vars_part_sn2 {
 /* the reserved page sizes and offsets */
 
 #define XPC_RP_HEADER_SIZE	L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
-#define XPC_RP_VARS_SIZE	L1_CACHE_ALIGN(sizeof(struct xpc_vars))
+#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 *)(XPC_RP_MACH_NASIDS(_rp) + \
+#define XPC_RP_VARS(_rp)	((struct xpc_vars_sn2 *)(XPC_RP_MACH_NASIDS(_rp) + \
 				    xp_nasid_mask_words))
 
 /*
@@ -344,6 +321,7 @@ struct xpc_notify {
  * allocated at the time a partition becomes active. The array contains one
  * of these structures for each potential channel connection to that partition.
  *
+>>> sn2 only!!!
  * Each of these structures manages two message queues (circular buffers).
  * They are allocated at the time a channel connection is made. One of
  * these message queues (local_msgqueue) holds the locally created messages
@@ -622,6 +600,9 @@ extern struct device *xpc_part;
 extern struct device *xpc_chan;
 extern int xpc_disengage_request_timelimit;
 extern int xpc_disengage_request_timedout;
+extern atomic_t xpc_act_IRQ_rcvd;
+extern wait_queue_head_t xpc_act_IRQ_wq;
+extern void *xpc_heartbeating_to_mask;
 extern irqreturn_t xpc_notify_IRQ_handler(int, void *);
 extern void xpc_dropped_IPI_check(struct xpc_partition *);
 extern void xpc_activate_partition(struct xpc_partition *);
@@ -629,15 +610,48 @@ extern void xpc_activate_kthreads(struct
 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 *);
+extern void (*xpc_heartbeat_init) (void);
+extern void (*xpc_heartbeat_exit) (void);
+extern void (*xpc_increment_heartbeat) (void);
+extern void (*xpc_offline_heartbeat) (void);
+extern void (*xpc_online_heartbeat) (void);
+extern void (*xpc_check_remote_hb) (void);
 extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
 extern u64 (*xpc_get_IPI_flags) (struct xpc_partition *);
 extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *);
+extern void (*xpc_initiate_partition_activation) (struct xpc_rsvd_page *, u64,
+						  int);
+extern void (*xpc_process_act_IRQ_rcvd) (int);
 extern enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *);
 extern void (*xpc_teardown_infrastructure) (struct xpc_partition *);
+extern void (*xpc_mark_partition_engaged) (struct xpc_partition *);
+extern void (*xpc_mark_partition_disengaged) (struct xpc_partition *);
+extern void (*xpc_request_partition_disengage) (struct xpc_partition *);
+extern void (*xpc_cancel_partition_disengage_request) (struct xpc_partition *);
+extern u64 (*xpc_partition_engaged) (u64);
+extern u64 (*xpc_partition_disengage_requested) (u64);;
+extern void (*xpc_clear_partition_engaged) (u64);
+extern void (*xpc_clear_partition_disengage_request) (u64);
+
+extern void (*xpc_IPI_send_local_activate) (int);
+extern void (*xpc_IPI_send_activated) (struct xpc_partition *);
+extern void (*xpc_IPI_send_local_reactivate) (int);
+extern void (*xpc_IPI_send_disengage) (struct xpc_partition *);
+
+extern void (*xpc_IPI_send_closerequest) (struct xpc_channel *,
+					  unsigned long *);
+extern void (*xpc_IPI_send_closereply) (struct xpc_channel *, unsigned long *);
+extern void (*xpc_IPI_send_openrequest) (struct xpc_channel *, unsigned long *);
+extern void (*xpc_IPI_send_openreply) (struct xpc_channel *, unsigned long *);
+
+extern enum xp_retval (*xpc_allocate_msg) (struct xpc_channel *, u32,
+					   struct xpc_msg **);
+extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, struct xpc_msg *,
+				       u8, xpc_notify_func, void *);
+extern void (*xpc_received_msg) (struct xpc_channel *, struct xpc_msg *);
 
 /* found in xpc_sn2.c */
 extern void xpc_init_sn2(void);
-extern struct xpc_vars *xpc_vars;		/*>>> eliminate from here */
 
 /* found in xpc_uv.c */
 extern void xpc_init_uv(void);
@@ -646,6 +660,7 @@ extern void xpc_init_uv(void);
 extern int xpc_exiting;
 extern int xp_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;
@@ -658,7 +673,8 @@ extern int xpc_partition_disengaged(stru
 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
 extern void xpc_mark_partition_inactive(struct xpc_partition *);
 extern void xpc_discovery(void);
-extern void xpc_check_remote_hb(void);
+extern enum xp_retval xpc_get_remote_rp(int, u64 *, struct xpc_rsvd_page *,
+					u64 *);
 extern void xpc_deactivate_partition(const int, struct xpc_partition *,
 				     enum xp_retval);
 extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
@@ -667,6 +683,7 @@ extern enum xp_retval xpc_initiate_parti
 extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
 extern void xpc_initiate_connect(int);
 extern void xpc_initiate_disconnect(int);
+extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
 extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **);
 extern enum xp_retval xpc_initiate_send(short, int, void *);
 extern enum xp_retval xpc_initiate_send_notify(short, int, void *,
@@ -680,6 +697,40 @@ extern void xpc_disconnect_channel(const
 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
 extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
 
+static inline int
+xpc_hb_allowed(short partid, void *heartbeating_to_mask)
+{
+	return test_bit(partid, heartbeating_to_mask);
+}
+
+static inline int
+xpc_any_hbs_allowed(void)
+{
+	DBUG_ON(xpc_heartbeating_to_mask == NULL);
+	return !bitmap_empty(xpc_heartbeating_to_mask, xp_max_npartitions);
+}
+
+static inline void
+xpc_allow_hb(short partid)
+{
+	DBUG_ON(xpc_heartbeating_to_mask == NULL);
+	set_bit(partid, xpc_heartbeating_to_mask);
+}
+
+static inline void
+xpc_disallow_hb(short partid)
+{
+	DBUG_ON(xpc_heartbeating_to_mask == NULL);
+	clear_bit(partid, xpc_heartbeating_to_mask);
+}
+
+static inline void
+xpc_disallow_all_hbs(void)
+{
+	DBUG_ON(xpc_heartbeating_to_mask == NULL);
+	bitmap_zero(xpc_heartbeating_to_mask, xp_max_npartitions);
+}
+
 static inline void
 xpc_wakeup_channel_mgr(struct xpc_partition *part)
 {
@@ -749,297 +800,7 @@ xpc_part_ref(struct xpc_partition *part)
 	}
 
 /*
- * This next set of inlines are used to keep track of when a partition is
- * potentially engaged in accessing memory belonging to another partition.
- */
-
-static inline void
-xpc_mark_partition_engaged(struct xpc_partition *part)
-{
-	unsigned long irq_flags;
-	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
-				   (XPC_ENGAGED_PARTITIONS_AMO *
-				    sizeof(AMO_t)));
-
-	local_irq_save(irq_flags);
-
-	/* set bit corresponding to our partid in remote partition's AMO */
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
-			 (1UL << sn_partition_id));
-	/*
-	 * We must always use the nofault function regardless of whether we
-	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-	 * didn't, we'd never know that the other partition is down and would
-	 * keep sending IPIs and AMOs to it until the heartbeat times out.
-	 */
-	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-							       variable),
-						     xp_nofault_PIOR_target));
-
-	local_irq_restore(irq_flags);
-}
-
-static inline void
-xpc_mark_partition_disengaged(struct xpc_partition *part)
-{
-	unsigned long irq_flags;
-	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
-				   (XPC_ENGAGED_PARTITIONS_AMO *
-				    sizeof(AMO_t)));
-
-	local_irq_save(irq_flags);
-
-	/* clear bit corresponding to our partid in remote partition's AMO */
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-			 ~(1UL << sn_partition_id));
-	/*
-	 * We must always use the nofault function regardless of whether we
-	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-	 * didn't, we'd never know that the other partition is down and would
-	 * keep sending IPIs and AMOs to it until the heartbeat times out.
-	 */
-	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-							       variable),
-						     xp_nofault_PIOR_target));
-
-	local_irq_restore(irq_flags);
-}
-
-static inline void
-xpc_request_partition_disengage(struct xpc_partition *part)
-{
-	unsigned long irq_flags;
-	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
-				   (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
-
-	local_irq_save(irq_flags);
-
-	/* set bit corresponding to our partid in remote partition's AMO */
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
-			 (1UL << sn_partition_id));
-	/*
-	 * We must always use the nofault function regardless of whether we
-	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-	 * didn't, we'd never know that the other partition is down and would
-	 * keep sending IPIs and AMOs to it until the heartbeat times out.
-	 */
-	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-							       variable),
-						     xp_nofault_PIOR_target));
-
-	local_irq_restore(irq_flags);
-}
-
-static inline void
-xpc_cancel_partition_disengage_request(struct xpc_partition *part)
-{
-	unsigned long irq_flags;
-	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
-				   (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
-
-	local_irq_save(irq_flags);
-
-	/* clear bit corresponding to our partid in remote partition's AMO */
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-			 ~(1UL << sn_partition_id));
-	/*
-	 * We must always use the nofault function regardless of whether we
-	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-	 * didn't, we'd never know that the other partition is down and would
-	 * keep sending IPIs and AMOs to it until the heartbeat times out.
-	 */
-	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-							       variable),
-						     xp_nofault_PIOR_target));
-
-	local_irq_restore(irq_flags);
-}
-
-static inline u64
-xpc_partition_engaged(u64 partid_mask)
-{
-	AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
-
-	/* return our partition's AMO variable ANDed with partid_mask */
-	return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
-		partid_mask);
-}
-
-static inline u64
-xpc_partition_disengage_requested(u64 partid_mask)
-{
-	AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
-
-	/* return our partition's AMO variable ANDed with partid_mask */
-	return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
-		partid_mask);
-}
-
-static inline void
-xpc_clear_partition_engaged(u64 partid_mask)
-{
-	AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
-
-	/* clear bit(s) based on partid_mask in our partition's AMO */
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-			 ~partid_mask);
-}
-
-static inline void
-xpc_clear_partition_disengage_request(u64 partid_mask)
-{
-	AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
-
-	/* clear bit(s) based on partid_mask in our partition's AMO */
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-			 ~partid_mask);
-}
-
-/*
- * The following set of macros and inlines are used for the sending and
- * receiving of IPIs (also known as IRQs). There are two flavors of IPIs,
- * one that is associated with partition activity (SGI_XPC_ACTIVATE) and
- * the other that is associated with channel activity (SGI_XPC_NOTIFY).
- */
-
-static inline u64
-xpc_IPI_receive(AMO_t *amo)
-{
-	return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_CLEAR);
-}
-
-static inline enum xp_retval
-xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
-{
-	int ret = 0;
-	unsigned long irq_flags;
-
-	local_irq_save(irq_flags);
-
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR, flag);
-	sn_send_IPI_phys(nasid, phys_cpuid, vector, 0);
-
-	/*
-	 * We must always use the nofault function regardless of whether we
-	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-	 * didn't, we'd never know that the other partition is down and would
-	 * keep sending IPIs and AMOs to it until the heartbeat times out.
-	 */
-	ret = xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->variable),
-						     xp_nofault_PIOR_target));
-
-	local_irq_restore(irq_flags);
-
-	return ((ret == 0) ? xpSuccess : xpPioReadError);
-}
-
-/*
- * IPIs associated with SGI_XPC_ACTIVATE IRQ.
- */
-
-/*
- * Flag the appropriate AMO variable and send an IPI to the specified node.
- */
-static inline void
-xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid,
-		      int to_phys_cpuid)
-{
-	int w_index = XPC_NASID_W_INDEX(from_nasid);
-	int b_index = XPC_NASID_B_INDEX(from_nasid);
-	AMO_t *amos = (AMO_t *)__va(amos_page_pa +
-				    (XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t)));
-
-	(void)xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid,
-			   to_phys_cpuid, SGI_XPC_ACTIVATE);
-}
-
-static inline void
-xpc_IPI_send_activate(struct xpc_vars *vars)
-{
-	xpc_activate_IRQ_send(vars->amos_page_pa, cnodeid_to_nasid(0),
-			      vars->act_nasid, vars->act_phys_cpuid);
-}
-
-static inline void
-xpc_IPI_send_activated(struct xpc_partition *part)
-{
-	xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
-			      part->remote_act_nasid,
-			      part->remote_act_phys_cpuid);
-}
-
-static inline void
-xpc_IPI_send_reactivate(struct xpc_partition *part)
-{
-	xpc_activate_IRQ_send(xpc_vars->amos_page_pa, part->reactivate_nasid,
-			      xpc_vars->act_nasid, xpc_vars->act_phys_cpuid);
-}
-
-static inline void
-xpc_IPI_send_disengage(struct xpc_partition *part)
-{
-	xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
-			      part->remote_act_nasid,
-			      part->remote_act_phys_cpuid);
-}
-
-/*
- * IPIs associated with SGI_XPC_NOTIFY IRQ.
- */
-
-/*
- * Send an IPI to the remote partition that is associated with the
- * specified channel.
- */
-#define XPC_NOTIFY_IRQ_SEND(_ch, _ipi_f, _irq_f) \
-		xpc_notify_IRQ_send(_ch, _ipi_f, #_ipi_f, _irq_f)
-
-static inline void
-xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
-		    unsigned long *irq_flags)
-{
-	struct xpc_partition *part = &xpc_partitions[ch->partid];
-	enum xp_retval ret;
-
-	if (likely(part->act_state != XPC_P_DEACTIVATING)) {
-		ret = xpc_IPI_send(part->remote_IPI_amo_va,
-				   (u64)ipi_flag << (ch->number * 8),
-				   part->remote_IPI_nasid,
-				   part->remote_IPI_phys_cpuid, SGI_XPC_NOTIFY);
-		dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
-			ipi_flag_string, ch->partid, ch->number, ret);
-		if (unlikely(ret != xpSuccess)) {
-			if (irq_flags != NULL)
-				spin_unlock_irqrestore(&ch->lock, *irq_flags);
-			XPC_DEACTIVATE_PARTITION(part, ret);
-			if (irq_flags != NULL)
-				spin_lock_irqsave(&ch->lock, *irq_flags);
-		}
-	}
-}
-
-/*
- * Make it look like the remote partition, which is associated with the
- * specified channel, sent us an IPI. This faked IPI will be handled
- * by xpc_dropped_IPI_check().
- */
-#define XPC_NOTIFY_IRQ_SEND_LOCAL(_ch, _ipi_f) \
-		xpc_notify_IRQ_send_local(_ch, _ipi_f, #_ipi_f)
-
-static inline void
-xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag,
-			  char *ipi_flag_string)
-{
-	struct xpc_partition *part = &xpc_partitions[ch->partid];
-
-	FETCHOP_STORE_OP(TO_AMO((u64)&part->local_IPI_amo_va->variable),
-			 FETCHOP_OR, ((u64)ipi_flag << (ch->number * 8)));
-	dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n",
-		ipi_flag_string, ch->partid, ch->number);
-}
-
-/*
- * The sending and receiving of IPIs includes the setting of an AMO variable
+ * The sending and receiving of IPIs includes the setting of an >>>AMO variable
  * to indicate the reason the IPI was sent. The 64-bit variable is divided
  * up into eight bytes, ordered from right to left. Byte zero pertains to
  * channel 0, byte one to channel 1, and so on. Each byte is described by
@@ -1052,107 +813,11 @@ xpc_notify_IRQ_send_local(struct xpc_cha
 #define	XPC_IPI_OPENREPLY	0x08
 #define	XPC_IPI_MSGREQUEST	0x10
 
-/* given an AMO variable and a channel#, get its associated IPI flags */
+/* given an >>>AMO variable and a channel#, get its associated IPI flags */
 #define XPC_GET_IPI_FLAGS(_amo, _c)	((u8) (((_amo) >> ((_c) * 8)) & 0xff))
 #define XPC_SET_IPI_FLAGS(_amo, _c, _f)	(_amo) |= ((u64) (_f) << ((_c) * 8))
 
 #define	XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0fUL)
 #define XPC_ANY_MSG_IPI_FLAGS_SET(_amo)       ((_amo) & 0x1010101010101010UL)
 
-static inline void
-xpc_IPI_send_closerequest(struct xpc_channel *ch, unsigned long *irq_flags)
-{
-	struct xpc_openclose_args *args = ch->local_openclose_args;
-
-	args->reason = ch->reason;
-
-	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREQUEST, irq_flags);
-}
-
-static inline void
-xpc_IPI_send_closereply(struct xpc_channel *ch, unsigned long *irq_flags)
-{
-	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREPLY, irq_flags);
-}
-
-static inline void
-xpc_IPI_send_openrequest(struct xpc_channel *ch, unsigned long *irq_flags)
-{
-	struct xpc_openclose_args *args = ch->local_openclose_args;
-
-	args->msg_size = ch->msg_size;
-	args->local_nentries = ch->local_nentries;
-
-	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREQUEST, irq_flags);
-}
-
-static inline void
-xpc_IPI_send_openreply(struct xpc_channel *ch, unsigned long *irq_flags)
-{
-	struct xpc_openclose_args *args = ch->local_openclose_args;
-
-	args->remote_nentries = ch->remote_nentries;
-	args->local_nentries = ch->local_nentries;
-	args->local_msgqueue_pa = __pa(ch->local_msgqueue);
-
-	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREPLY, irq_flags);
-}
-
-static inline void
-xpc_IPI_send_msgrequest(struct xpc_channel *ch)
-{
-	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_MSGREQUEST, NULL);
-}
-
-static inline void
-xpc_IPI_send_local_msgrequest(struct xpc_channel *ch)
-{
-	XPC_NOTIFY_IRQ_SEND_LOCAL(ch, XPC_IPI_MSGREQUEST);
-}
-
-/*
->>> this block comment needs to be moved and re-written.
- * 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) for message notification and an
- * additional 128 AMO variables (based on XP_NASID_MASK_WORDS) for partition
- * activation and 2 AMO variables for partition deactivation.
- */
-static inline AMO_t *
-xpc_IPI_init(int index)
-{
-	AMO_t *amo = xpc_vars->amos_page + index;
-
-	(void)xpc_IPI_receive(amo);	/* clear AMO variable */
-	return amo;
-}
-
-/*
- * Check to see if there is any channel activity to/from the specified
- * partition.
- */
-static inline void
-xpc_check_for_channel_activity(struct xpc_partition *part)
-{
-	u64 IPI_amo;
-	unsigned long irq_flags;
-
-	IPI_amo = xpc_IPI_receive(part->local_IPI_amo_va);
-	if (IPI_amo == 0)
-		return;
-
-	spin_lock_irqsave(&part->IPI_lock, irq_flags);
-	part->local_IPI_amo |= IPI_amo;
-	spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
-
-	dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n",
-		XPC_PARTID(part), IPI_amo);
-
-	xpc_wakeup_channel_mgr(part);
-}
-
 #endif /* _DRIVERS_MISC_SGIXP_XPC_H */
drivers/misc/sgi-xp/xpc_sn2.c +1175 -6

1,234 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_partition.c +6 -448

514 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_main.c +101 -51

272 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_uv.c +52 -5

79 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_channel.c +2 -313

281 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

#10 lore raw

PATCH 9/18 base xpc_rsvd_page's timestamp on jiffies

In reply to Dean Nelson

Change XPC's reserved page timestamp to be based on jiffies.

 drivers/misc/sgi-xp/xpc.h           |   26 ++-----------------------
 drivers/misc/sgi-xp/xpc_main.c      |   16 +++++++--------
 drivers/misc/sgi-xp/xpc_partition.c |   33 ++++++++++++++++----------------
 drivers/misc/sgi-xp/xpc_sn2.c       |   16 +++++----------
 4 files changed, 34 insertions(+), 57 deletions(-)
drivers/misc/sgi-xp/xpc.h +3 -23
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -115,8 +115,8 @@ struct xpc_rsvd_page {
 		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 2nd 64-byte cacheline */
+	unsigned long stamp;	/* time when reserved page was setup by XPC */
+	u64 pad2[10];		/* align to last u64 in 2nd 64-byte cacheline */
 	u64 SAL_nasids_size;	/* SAL: size of each nasid mask in bytes */
 };
 
@@ -125,26 +125,6 @@ struct xpc_rsvd_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:
- *
- *	< 0,	if stamp1 < stamp2
- *	= 0,	if stamp1 == stamp2
- *	> 0,	if stamp1 > stamp2
- */
-static inline int
-xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2)
-{
-	int ret;
-
-	ret = stamp1->tv_sec - stamp2->tv_sec;
-	if (ret == 0)
-		ret = stamp1->tv_nsec - stamp2->tv_nsec;
-
-	return ret;
-}
-
 /*
  * Define the structures by which XPC variables can be exported to other
  * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
@@ -492,7 +472,7 @@ struct xpc_partition {
 	/* XPC HB infrastructure */
 
 	u8 remote_rp_version;	/* version# of partition's rsvd pg */
-	struct timespec remote_rp_stamp; /* time when rsvd pg was initialized */
+	unsigned long remote_rp_stamp; /* time when rsvd pg was initialized */
 	u64 remote_rp_pa;	/* phys addr of partition's rsvd pg */
 	u64 remote_vars_pa;	/* phys addr of partition's vars */
 	u64 remote_vars_part_pa;	/* phys addr of partition's vars part */
drivers/misc/sgi-xp/xpc_sn2.c +6 -10
Index: linux-2.6/drivers/misc/sgi-xp/xpc_sn2.c
===================================================================
@@ -597,8 +597,8 @@ xpc_initiate_partition_activation_sn2(st
  */
 static void
 xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version,
-			      struct timespec *remote_rp_stamp,
-			      u64 remote_rp_pa, u64 remote_vars_pa,
+			      unsigned long *remote_rp_stamp, u64 remote_rp_pa,
+			      u64 remote_vars_pa,
 			      struct xpc_vars_sn2 *remote_vars)
 {
 	part->remote_rp_version = remote_rp_version;
@@ -606,8 +606,8 @@ xpc_update_partition_info_sn2(struct xpc
 		part->remote_rp_version);
 
 	part->remote_rp_stamp = *remote_rp_stamp;
-	dev_dbg(xpc_part, "  remote_rp_stamp (tv_sec = 0x%lx tv_nsec = 0x%lx\n",
-		part->remote_rp_stamp.tv_sec, part->remote_rp_stamp.tv_nsec);
+	dev_dbg(xpc_part, "  remote_rp_stamp = 0x%016lx\n",
+		part->remote_rp_stamp);
 
 	part->remote_rp_pa = remote_rp_pa;
 	dev_dbg(xpc_part, "  remote_rp_pa = 0x%016lx\n", part->remote_rp_pa);
@@ -664,8 +664,7 @@ xpc_identify_act_IRQ_req_sn2(int nasid)
 	u64 remote_vars_pa;
 	int remote_rp_version;
 	int reactivate = 0;
-	int stamp_diff;
-	struct timespec remote_rp_stamp = { 0, 0 }; /*>>> ZERO_STAMP */
+	unsigned long remote_rp_stamp = 0;
 	short partid;
 	struct xpc_partition *part;
 	enum xp_retval ret;
@@ -788,10 +787,7 @@ xpc_identify_act_IRQ_req_sn2(int nasid)
 	} else {
 		DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version));
 
-		stamp_diff = xpc_compare_stamps(&part->remote_rp_stamp,
-						&remote_rp_stamp);
-		if (stamp_diff != 0) {
-			DBUG_ON(stamp_diff >= 0);
+		if (remote_rp_stamp != part->remote_rp_stamp) {
 
 			/*
 			 * Other side rebooted and the previous XPC did support
drivers/misc/sgi-xp/xpc_main.c +8 -8
Index: linux-2.6/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -233,7 +233,7 @@ xpc_timeout_partition_disengage_request(
 {
 	struct xpc_partition *part = (struct xpc_partition *)data;
 
-	DBUG_ON(time_before(jiffies, part->disengage_request_timeout));
+	DBUG_ON(time_is_after_jiffies(part->disengage_request_timeout));
 
 	(void)xpc_partition_disengaged(part);
 
@@ -262,7 +262,7 @@ xpc_hb_beater(unsigned long dummy)
 {
 	xpc_increment_heartbeat();
 
-	if (time_after_eq(jiffies, xpc_hb_check_timeout))
+	if (time_is_before_eq_jiffies(xpc_hb_check_timeout))
 		wake_up_interruptible(&xpc_act_IRQ_wq);
 
 	xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ);
@@ -312,7 +312,7 @@ xpc_hb_checker(void *ignore)
 			atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count);
 
 		/* checking of remote heartbeats is skewed by IRQ handling */
-		if (time_after_eq(jiffies, xpc_hb_check_timeout)) {
+		if (time_is_before_eq_jiffies(xpc_hb_check_timeout)) {
 			dev_dbg(xpc_part, "checking remote heartbeats\n");
 			xpc_check_remote_hb();
 
@@ -344,8 +344,8 @@ xpc_hb_checker(void *ignore)
 		(void)wait_event_interruptible(xpc_act_IRQ_wq,
 					       (last_IRQ_count <
 						atomic_read(&xpc_act_IRQ_rcvd)
-						|| time_after_eq(jiffies,
-							xpc_hb_check_timeout) ||
+						|| time_is_before_eq_jiffies(
+						xpc_hb_check_timeout) ||
 						xpc_exiting));
 	}
 
@@ -929,7 +929,7 @@ xpc_do_exit(enum xp_retval reason)
 		}
 
 		if (xpc_partition_engaged(-1UL)) {
-			if (time_after(jiffies, printmsg_time)) {
+			if (time_is_before_jiffies(printmsg_time)) {
 				dev_info(xpc_part, "waiting for remote "
 					 "partitions to disengage, timeout in "
 					 "%ld seconds\n",
@@ -964,7 +964,7 @@ xpc_do_exit(enum xp_retval reason)
 	DBUG_ON(xpc_any_hbs_allowed() != 0);
 
 	/* indicate to others that our reserved page is uninitialized */
-	xpc_rsvd_page->stamp = ZERO_STAMP;
+	xpc_rsvd_page->stamp = 0;
 
 	if (reason == xpUnloading) {
 		(void)unregister_die_notifier(&xpc_die_notifier);
@@ -1295,7 +1295,7 @@ xpc_init(void)
 	/* initialization was not successful */
 out_4:
 	/* indicate to others that our reserved page is uninitialized */
-	xpc_rsvd_page->stamp = ZERO_STAMP;
+	xpc_rsvd_page->stamp = 0;
 
 	(void)unregister_die_notifier(&xpc_die_notifier);
 	(void)unregister_reboot_notifier(&xpc_reboot_notifier);
drivers/misc/sgi-xp/xpc_partition.c +17 -16
Index: linux-2.6/drivers/misc/sgi-xp/xpc_partition.c
===================================================================
@@ -152,6 +152,7 @@ xpc_setup_rsvd_page(void)
 {
 	struct xpc_rsvd_page *rp;
 	u64 rp_pa;
+	unsigned long new_stamp;
 
 	/* get the local reserved page's address */
 
@@ -201,7 +202,10 @@ xpc_setup_rsvd_page(void)
 	 * This signifies to the remote partition that our reserved
 	 * page is initialized.
 	 */
-	rp->stamp = CURRENT_TIME;
+	new_stamp = jiffies;
+	if (new_stamp == 0 || new_stamp == rp->stamp)
+		new_stamp++;
+	rp->stamp = new_stamp;
 
 	return rp;
 }
@@ -350,18 +354,8 @@ xpc_get_remote_rp(int nasid, u64 *discov
 			discovered_nasids[i] |= remote_part_nasids[i];
 	}
 
-	/* check that the partid is valid and is for another partition */
-
-	if (remote_rp->SAL_partid < 0 ||
-	    remote_rp->SAL_partid >= xp_max_npartitions) {
-		return xpInvalidPartid;
-	}
-
-	if (remote_rp->SAL_partid == sn_partition_id)
-		return xpLocalPartid;
-
-	/* see if the rest of the reserved page has been set up by XPC */
-	if (timespec_equal(&remote_rp->stamp, &ZERO_STAMP))
+	/* see if the reserved page has been set up by XPC */
+	if (remote_rp->stamp == 0)
 		return xpRsvdPageNotSet;
 
 	if (XPC_VERSION_MAJOR(remote_rp->version) !=
@@ -369,8 +363,15 @@ xpc_get_remote_rp(int nasid, u64 *discov
 		return xpBadVersion;
 	}
 
-	if (remote_rp->max_npartitions <= sn_partition_id)
+	/* check that both local and remote partids are valid for each side */
+	if (remote_rp->SAL_partid < 0 ||
+	    remote_rp->SAL_partid >= xp_max_npartitions ||
+	    remote_rp->max_npartitions <= sn_partition_id) {
 		return xpInvalidPartid;
+	}
+
+	if (remote_rp->SAL_partid == sn_partition_id)
+		return xpLocalPartid;
 
 	return xpSuccess;
 }
@@ -388,8 +389,8 @@ xpc_partition_disengaged(struct xpc_part
 	disengaged = (xpc_partition_engaged(1UL << partid) == 0);
 	if (part->disengage_request_timeout) {
 		if (!disengaged) {
-			if (time_before(jiffies,
-			    part->disengage_request_timeout)) {
+			if (time_is_after_jiffies(part->
+						  disengage_request_timeout)) {
 				/* timelimit hasn't been reached yet */
 				return 0;
 			}
#11 lore raw

Re: [Patch 09/18] base xpc_rsvd_page's timestamp on jiffies

drivers/misc/sgi-xp/xpc.h struct xpc_rsvd_page { · line 118

Quoted 1 line · On Fri, 6 Jun 2008 11:52:16 -0500 Dean Nelson <[email protected]> wrote:
drivers/misc/sgi-xp/xpc.h +1 -0
+	unsigned long stamp;	/* time when reserved page was setup by XPC */

"time" is a rubbery concept in-kernel. What are the units of this? microseconds? jiffies? seconds?

At the least, the covering comment should make clear what units this variable is using. Better would be to actually embed the units in the variable's identifier. Because it's awfulyl easy to make mistakes over this, and not knowing the units makes the code harder to follow.

#12 lore raw

PATCH 10/18 move xpc_allocate() into xpc_send()/xpc_send_notify()

In reply to Dean Nelson

Move xpc_allocate() functionality into xpc_send()/xpc_send_notify() so xpc_allocate() no longer needs to be called by XPNET.

---

 drivers/misc/sgi-xp/xp.h          |   44 +++++--------
 drivers/misc/sgi-xp/xp_main.c     |   23 ++----
 drivers/misc/sgi-xp/xpc.h         |    9 --
 drivers/misc/sgi-xp/xpc_channel.c |  112 +++++++++++-----------------------
 drivers/misc/sgi-xp/xpc_main.c    |   14 +---
 drivers/misc/sgi-xp/xpc_sn2.c     |   64 ++++++++-----------
 drivers/misc/sgi-xp/xpnet.c       |   11 +--
 7 files changed, 106 insertions(+), 171 deletions(-)
drivers/misc/sgi-xp/xpc.h +3 -6
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -624,9 +624,7 @@ extern void (*xpc_IPI_send_closereply) (
 extern void (*xpc_IPI_send_openrequest) (struct xpc_channel *, unsigned long *);
 extern void (*xpc_IPI_send_openreply) (struct xpc_channel *, unsigned long *);
 
-extern enum xp_retval (*xpc_allocate_msg) (struct xpc_channel *, u32,
-					   struct xpc_msg **);
-extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, struct xpc_msg *,
+extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, u32, void *, u16,
 				       u8, xpc_notify_func, void *);
 extern void (*xpc_received_msg) (struct xpc_channel *, struct xpc_msg *);
 
@@ -664,9 +662,8 @@ extern void *xpc_kzalloc_cacheline_align
 extern void xpc_initiate_connect(int);
 extern void xpc_initiate_disconnect(int);
 extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
-extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **);
-extern enum xp_retval xpc_initiate_send(short, int, void *);
-extern enum xp_retval xpc_initiate_send_notify(short, int, void *,
+extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16);
+extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
 					       xpc_notify_func, void *);
 extern void xpc_initiate_received(short, int, void *);
 extern void xpc_process_channel_activity(struct xpc_partition *);
drivers/misc/sgi-xp/xpc_main.c +5 -9
Index: linux-2.6/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -217,12 +217,9 @@ void (*xpc_IPI_send_openrequest) (struct
 void (*xpc_IPI_send_openreply) (struct xpc_channel *ch,
 				unsigned long *irq_flags);
 
-enum xp_retval (*xpc_allocate_msg) (struct xpc_channel *ch, u32 flags,
-				    struct xpc_msg **address_of_msg);
-
-enum xp_retval (*xpc_send_msg) (struct xpc_channel *ch, struct xpc_msg *msg,
-				u8 notify_type, xpc_notify_func func,
-				void *key);
+enum xp_retval (*xpc_send_msg) (struct xpc_channel *ch, u32 flags,
+				void *payload, u16 payload_size, u8 notify_type,
+				xpc_notify_func func, void *key);
 void (*xpc_received_msg) (struct xpc_channel *ch, struct xpc_msg *msg);
 
 /*
@@ -1286,9 +1283,8 @@ xpc_init(void)
 
 	/* set the interface to point at XPC's functions */
 	xpc_set_interface(xpc_initiate_connect, xpc_initiate_disconnect,
-			  xpc_initiate_allocate, xpc_initiate_send,
-			  xpc_initiate_send_notify, xpc_initiate_received,
-			  xpc_initiate_partid_to_nasids);
+			  xpc_initiate_send, xpc_initiate_send_notify,
+			  xpc_initiate_received, xpc_initiate_partid_to_nasids);
 
 	return 0;
 
drivers/misc/sgi-xp/xpc_sn2.c +29 -35

121 lines not on this page · raw message

drivers/misc/sgi-xp/xp.h +17 -27

86 lines not on this page · raw message

drivers/misc/sgi-xp/xpnet.c +4 -7
Index: linux-2.6/drivers/misc/sgi-xp/xpnet.c
===================================================================
@@ -438,7 +438,8 @@ xpnet_dev_hard_start_xmit(struct sk_buff
 {
 	struct xpnet_pending_msg *queued_msg;
 	enum xp_retval ret;
-	struct xpnet_message *msg;
+	u8 msg_buffer[XPNET_MSG_SIZE];
+	struct xpnet_message *msg = (struct xpnet_message *)&msg_buffer[0];
 	u64 start_addr, end_addr;
 	long dp;
 	u8 second_mac_octet;
@@ -524,11 +525,6 @@ xpnet_dev_hard_start_xmit(struct sk_buff
 
 		/* found a partition to send to */
 
-		ret = xpc_allocate(dest_partid, XPC_NET_CHANNEL,
-				   XPC_NOWAIT, (void **)&msg);
-		if (unlikely(ret != xpSuccess))
-			continue;
-
 		msg->embedded_bytes = embedded_bytes;
 		if (unlikely(embedded_bytes != 0)) {
 			msg->version = XPNET_VERSION_EMBED;
@@ -553,7 +549,8 @@ xpnet_dev_hard_start_xmit(struct sk_buff
 
 		atomic_inc(&queued_msg->use_count);
 
-		ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, msg,
+		ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, XPC_NOWAIT,
+				      &msg, sizeof(msg) + embedded_bytes - 1,
 				      xpnet_send_completed, queued_msg);
 		if (unlikely(ret != xpSuccess)) {
 			atomic_dec(&queued_msg->use_count);
drivers/misc/sgi-xp/xp_main.c +9 -14
Index: linux-2.6/drivers/misc/sgi-xp/xp_main.c
===================================================================
@@ -58,10 +58,9 @@ xpc_notloaded(void)
 struct xpc_interface xpc_interface = {
 	(void (*)(int))xpc_notloaded,
 	(void (*)(int))xpc_notloaded,
-	(enum xp_retval(*)(short, int, u32, void **))xpc_notloaded,
-	(enum xp_retval(*)(short, int, void *))xpc_notloaded,
-	(enum xp_retval(*)(short, int, void *, xpc_notify_func, void *))
-	    xpc_notloaded,
+	(enum xp_retval(*)(short, int, u32, void *, u16))xpc_notloaded,
+	(enum xp_retval(*)(short, int, u32, void *, u16, xpc_notify_func,
+			   void *))xpc_notloaded,
 	(void (*)(short, int, void *))xpc_notloaded,
 	(enum xp_retval(*)(short, void *))xpc_notloaded
 };
@@ -73,16 +72,14 @@ EXPORT_SYMBOL_GPL(xpc_interface);
 void
 xpc_set_interface(void (*connect) (int),
 		  void (*disconnect) (int),
-		  enum xp_retval (*allocate) (short, int, u32, void **),
-		  enum xp_retval (*send) (short, int, void *),
-		  enum xp_retval (*send_notify) (short, int, void *,
+		  enum xp_retval (*send) (short, int, u32, void *, u16),
+		  enum xp_retval (*send_notify) (short, int, u32, void *, u16,
 						  xpc_notify_func, void *),
 		  void (*received) (short, int, void *),
 		  enum xp_retval (*partid_to_nasids) (short, void *))
 {
 	xpc_interface.connect = connect;
 	xpc_interface.disconnect = disconnect;
-	xpc_interface.allocate = allocate;
 	xpc_interface.send = send;
 	xpc_interface.send_notify = send_notify;
 	xpc_interface.received = received;
@@ -98,13 +95,11 @@ xpc_clear_interface(void)
 {
 	xpc_interface.connect = (void (*)(int))xpc_notloaded;
 	xpc_interface.disconnect = (void (*)(int))xpc_notloaded;
-	xpc_interface.allocate = (enum xp_retval(*)(short, int, u32,
-						     void **))xpc_notloaded;
-	xpc_interface.send = (enum xp_retval(*)(short, int, void *))
+	xpc_interface.send = (enum xp_retval(*)(short, int, u32, void *, u16))
 	    xpc_notloaded;
-	xpc_interface.send_notify = (enum xp_retval(*)(short, int, void *,
-							xpc_notify_func,
-							void *))xpc_notloaded;
+	xpc_interface.send_notify = (enum xp_retval(*)(short, int, u32, void *,
+						       u16, xpc_notify_func,
+						       void *))xpc_notloaded;
 	xpc_interface.received = (void (*)(short, int, void *))
 	    xpc_notloaded;
 	xpc_interface.partid_to_nasids = (enum xp_retval(*)(short, void *))
drivers/misc/sgi-xp/xpc_channel.c +39 -73

171 lines not on this page · raw message

#13 lore raw

PATCH 11/18 isolate activate IRQ's hardware specific components

In reply to Dean Nelson

Isolate architecture specific code related to XPC's activate IRQ.

---

 drivers/misc/sgi-xp/xpc.h           |   14 +-
 drivers/misc/sgi-xp/xpc_main.c      |   96 ++++----------
 drivers/misc/sgi-xp/xpc_partition.c |  121 -----------------
 drivers/misc/sgi-xp/xpc_sn2.c       |  217 ++++++++++++++++++++++++++++----
 4 files changed, 229 insertions(+), 219 deletions(-)
drivers/misc/sgi-xp/xpc_main.c +31 -65
Index: linux-2.6/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -147,11 +147,11 @@ static struct ctl_table_header *xpc_sysc
 /* non-zero if any remote partition disengage request was timed out */
 int xpc_disengage_request_timedout;
 
-/* #of IRQs received */
-atomic_t xpc_act_IRQ_rcvd;
+/* #of activate IRQs received */
+atomic_t xpc_activate_IRQ_rcvd = ATOMIC_INIT(0);
 
 /* IRQ handler notifies this wait queue on receipt of an IRQ */
-DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
+DECLARE_WAIT_QUEUE_HEAD(xpc_activate_IRQ_wq);
 
 static unsigned long xpc_hb_check_timeout;
 static struct timer_list xpc_hb_timer;
@@ -190,7 +190,7 @@ struct xpc_msg *(*xpc_get_deliverable_ms
 void (*xpc_initiate_partition_activation) (struct xpc_rsvd_page *remote_rp,
 					   u64 remote_rp_pa, int nasid);
 
-void (*xpc_process_act_IRQ_rcvd) (int n_IRQs_expected);
+void (*xpc_process_activate_IRQ_rcvd) (int n_IRQs_expected);
 enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *part);
 void (*xpc_teardown_infrastructure) (struct xpc_partition *part);
 
@@ -239,17 +239,6 @@ xpc_timeout_partition_disengage_request(
 }
 
 /*
- * Notify the heartbeat check thread that an IRQ has been received.
- */
-static irqreturn_t
-xpc_act_IRQ_handler(int irq, void *dev_id)
-{
-	atomic_inc(&xpc_act_IRQ_rcvd);
-	wake_up_interruptible(&xpc_act_IRQ_wq);
-	return IRQ_HANDLED;
-}
-
-/*
  * Timer to produce the heartbeat.  The timer structures function is
  * already set when this is initially called.  A tunable is used to
  * specify when the next timeout should occur.
@@ -260,7 +249,7 @@ xpc_hb_beater(unsigned long dummy)
 	xpc_increment_heartbeat();
 
 	if (time_is_before_eq_jiffies(xpc_hb_check_timeout))
-		wake_up_interruptible(&xpc_act_IRQ_wq);
+		wake_up_interruptible(&xpc_activate_IRQ_wq);
 
 	xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ);
 	add_timer(&xpc_hb_timer);
@@ -306,7 +295,7 @@ xpc_hb_checker(void *ignore)
 		dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have "
 			"been received\n",
 			(int)(xpc_hb_check_timeout - jiffies),
-			atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count);
+			atomic_read(&xpc_activate_IRQ_rcvd) - last_IRQ_count);
 
 		/* checking of remote heartbeats is skewed by IRQ handling */
 		if (time_is_before_eq_jiffies(xpc_hb_check_timeout)) {
@@ -322,15 +311,15 @@ xpc_hb_checker(void *ignore)
 		}
 
 		/* check for outstanding IRQs */
-		new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd);
+		new_IRQ_count = atomic_read(&xpc_activate_IRQ_rcvd);
 		if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) {
 			force_IRQ = 0;
 
 			dev_dbg(xpc_part, "found an IRQ to process; will be "
 				"resetting xpc_hb_check_timeout\n");
 
-			xpc_process_act_IRQ_rcvd(new_IRQ_count -
-						 last_IRQ_count);
+			xpc_process_activate_IRQ_rcvd(new_IRQ_count -
+						      last_IRQ_count);
 			last_IRQ_count = new_IRQ_count;
 
 			xpc_hb_check_timeout = jiffies +
@@ -338,9 +327,9 @@ xpc_hb_checker(void *ignore)
 		}
 
 		/* wait for IRQ or timeout */
-		(void)wait_event_interruptible(xpc_act_IRQ_wq,
-					       (last_IRQ_count <
-						atomic_read(&xpc_act_IRQ_rcvd)
+		(void)wait_event_interruptible(xpc_activate_IRQ_wq,
+					       (last_IRQ_count < atomic_read(
+						&xpc_activate_IRQ_rcvd)
 						|| time_is_before_eq_jiffies(
 						xpc_hb_check_timeout) ||
 						xpc_exiting));
@@ -884,10 +873,7 @@ xpc_do_exit(enum xp_retval reason)
 	 * the heartbeat checker thread in case it's sleeping.
 	 */
 	xpc_exiting = 1;
-	wake_up_interruptible(&xpc_act_IRQ_wq);
-
-	/* ignore all incoming interrupts */
-	free_irq(SGI_XPC_ACTIVATE, NULL);
+	wake_up_interruptible(&xpc_activate_IRQ_wq);
 
 	/* wait for the discovery thread to exit */
 	wait_for_completion(&xpc_discovery_exited);
@@ -968,9 +954,6 @@ xpc_do_exit(enum xp_retval reason)
 		(void)unregister_reboot_notifier(&xpc_reboot_notifier);
 	}
 
-	/* close down protections for IPI operations */
-	xpc_restrict_IPI_ops();
-
 	/* clear the interface to XPC's functions */
 	xpc_clear_interface();
 
@@ -979,6 +962,11 @@ xpc_do_exit(enum xp_retval reason)
 
 	kfree(xpc_partitions);
 	kfree(xpc_remote_copy_buffer_base);
+
+	if (is_shub())
+		xpc_exit_sn2();
+	else
+		xpc_exit_uv();
 }
 
 /*
@@ -1144,7 +1132,9 @@ xpc_init(void)
 		if (xp_max_npartitions != 64)
 			return -EINVAL;
 
-		xpc_init_sn2();
+		ret = xpc_init_sn2();
+		if (ret != 0)
+			return ret;
 
 	} else if (is_uv()) {
 		xpc_init_uv();
@@ -1163,7 +1153,8 @@ xpc_init(void)
 						  &xpc_remote_copy_buffer_base);
 	if (xpc_remote_copy_buffer == NULL) {
 		dev_err(xpc_part, "can't get memory for remote copy buffer\n");
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out_1;
 	}
 
 	xpc_partitions = kzalloc(sizeof(struct xpc_partition) *
@@ -1171,7 +1162,7 @@ xpc_init(void)
 	if (xpc_partitions == NULL) {
 		dev_err(xpc_part, "can't get memory for partition structure\n");
 		ret = -ENOMEM;
-		goto out_1;
+		goto out_2;
 	}
 
 	/*
@@ -1187,7 +1178,7 @@ xpc_init(void)
 
 		DBUG_ON((u64)part != L1_CACHE_ALIGN((u64)part));
 
-		part->act_IRQ_rcvd = 0;
+		part->activate_IRQ_rcvd = 0;
 		spin_lock_init(&part->act_lock);
 		part->act_state = XPC_P_INACTIVE;
 		XPC_SET_REASON(part, 0, 0);
@@ -1205,33 +1196,6 @@ xpc_init(void)
 	xpc_sysctl = register_sysctl_table(xpc_sys_dir);
 
 	/*
-	 * Open up protections for IPI operations (and AMO operations on
-	 * Shub 1.1 systems).
-	 */
-	xpc_allow_IPI_ops();
-
-	/*
-	 * Interrupts being processed will increment this atomic variable and
-	 * awaken the heartbeat thread which will process the interrupts.
-	 */
-	atomic_set(&xpc_act_IRQ_rcvd, 0);
-
-	/*
-	 * This is safe to do before the xpc_hb_checker thread has started
-	 * because the handler releases a wait queue.  If an interrupt is
-	 * received before the thread is waiting, it will not go to sleep,
-	 * but rather immediately process the interrupt.
-	 */
-	ret = request_irq(SGI_XPC_ACTIVATE, xpc_act_IRQ_handler, 0,
-			  "xpc hb", NULL);
-	if (ret != 0) {
-		dev_err(xpc_part, "can't register ACTIVATE IRQ handler, "
-			"errno=%d\n", -ret);
-		ret = -EBUSY;
-		goto out_2;
-	}
-
-	/*
 	 * Fill the partition reserved page with the information needed by
 	 * other partitions to discover we are alive and establish initial
 	 * communications.
@@ -1296,14 +1260,16 @@ out_4:
 	(void)unregister_die_notifier(&xpc_die_notifier);
 	(void)unregister_reboot_notifier(&xpc_reboot_notifier);
 out_3:
-	free_irq(SGI_XPC_ACTIVATE, NULL);
-out_2:
-	xpc_restrict_IPI_ops();
 	if (xpc_sysctl)
 		unregister_sysctl_table(xpc_sysctl);
 	kfree(xpc_partitions);
-out_1:
+out_2:
 	kfree(xpc_remote_copy_buffer_base);
+out_1:
+	if (is_shub())
+		xpc_exit_sn2();
+	else
+		xpc_exit_uv();
 	return ret;
 }
 
drivers/misc/sgi-xp/xpc_partition.c +0 -121

133 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_sn2.c +190 -27

312 lines not on this page · raw message

drivers/misc/sgi-xp/xpc.h +8 -6
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -480,7 +480,7 @@ struct xpc_partition {
 	u64 remote_amos_page_pa;	/* phys addr of partition's amos page */
 	int remote_act_nasid;	/* active part's act/deact nasid */
 	int remote_act_phys_cpuid;	/* active part's act/deact phys cpuid */
-	u32 act_IRQ_rcvd;	/* IRQs since activation */
+	u32 activate_IRQ_rcvd;	/* IRQs since activation */
 	spinlock_t act_lock;	/* protect updating of act_state */
 	u8 act_state;		/* from XPC HB viewpoint */
 	u8 remote_vars_version;	/* version# of partition's vars */
@@ -580,8 +580,8 @@ extern struct device *xpc_part;
 extern struct device *xpc_chan;
 extern int xpc_disengage_request_timelimit;
 extern int xpc_disengage_request_timedout;
-extern atomic_t xpc_act_IRQ_rcvd;
-extern wait_queue_head_t xpc_act_IRQ_wq;
+extern atomic_t xpc_activate_IRQ_rcvd;
+extern wait_queue_head_t xpc_activate_IRQ_wq;
 extern void *xpc_heartbeating_to_mask;
 extern irqreturn_t xpc_notify_IRQ_handler(int, void *);
 extern void xpc_dropped_IPI_check(struct xpc_partition *);
@@ -601,7 +601,7 @@ extern u64 (*xpc_get_IPI_flags) (struct 
 extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *);
 extern void (*xpc_initiate_partition_activation) (struct xpc_rsvd_page *, u64,
 						  int);
-extern void (*xpc_process_act_IRQ_rcvd) (int);
+extern void (*xpc_process_activate_IRQ_rcvd) (int);
 extern enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *);
 extern void (*xpc_teardown_infrastructure) (struct xpc_partition *);
 extern void (*xpc_mark_partition_engaged) (struct xpc_partition *);
@@ -629,10 +629,12 @@ extern enum xp_retval (*xpc_send_msg) (s
 extern void (*xpc_received_msg) (struct xpc_channel *, struct xpc_msg *);
 
 /* found in xpc_sn2.c */
-extern void xpc_init_sn2(void);
+extern int xpc_init_sn2(void);
+extern void xpc_exit_sn2(void);
 
 /* found in xpc_uv.c */
 extern void xpc_init_uv(void);
+extern void xpc_exit_uv(void);
 
 /* found in xpc_partition.c */
 extern int xpc_exiting;
@@ -646,7 +648,7 @@ extern void *xpc_kmalloc_cacheline_align
 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);
+extern int xpc_identify_activate_IRQ_sender(void);
 extern int xpc_partition_disengaged(struct xpc_partition *);
 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
 extern void xpc_mark_partition_inactive(struct xpc_partition *);
#14 lore raw

PATCH 12/18 isolate additional sn2 specific code

In reply to Dean Nelson

Move additional sn2 specific code into xpc_sn2.c.

---

 drivers/misc/sgi-xp/xpc.h           |  173 +++---
 drivers/misc/sgi-xp/xpc_channel.c   |  214 --------
 drivers/misc/sgi-xp/xpc_main.c      |  278 +++-------
 drivers/misc/sgi-xp/xpc_partition.c |   61 +-
 drivers/misc/sgi-xp/xpc_sn2.c       |  853 ++++++++++++++++++++------------
 drivers/misc/sgi-xp/xpc_uv.c        |   15 
 6 files changed, 786 insertions(+), 808 deletions(-)
drivers/misc/sgi-xp/xpc.h +97 -76
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -122,9 +122,6 @@ struct xpc_rsvd_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 the structures by which XPC variables can be exported to other
  * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
@@ -144,8 +141,8 @@ struct xpc_vars_sn2 {
 	u64 heartbeat;
 	DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
 	u64 heartbeat_offline;	/* if 0, heartbeat should be changing */
-	int act_nasid;
-	int act_phys_cpuid;
+	int activate_IRQ_nasid;
+	int activate_IRQ_phys_cpuid;
 	u64 vars_part_pa;
 	u64 amos_page_pa;	/* paddr of page of AMOs from MSPEC driver */
 	AMO_t *amos_page;	/* vaddr of page of AMOs from MSPEC driver */
@@ -153,9 +150,6 @@ struct xpc_vars_sn2 {
 
 #define XPC_V_VERSION _XPC_VERSION(3, 1)    /* version 3.1 of the cross vars */
 
-#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \
-			(_version >= _XPC_VERSION(3, 1))
-
 /*
  * The following pertains to ia64-sn2 only.
  *
@@ -167,14 +161,14 @@ struct xpc_vars_sn2 {
  * 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, and 2 AMO variables to identify which remote
+ * the senders of ACTIVATE IRQs, 1 AMO variable to identify which remote
  * partitions (i.e., XPCs) consider themselves currently engaged with the
- * local XPC.
+ * 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_DISENGAGE_REQUEST_AMO  (XPC_ENGAGED_PARTITIONS_AMO + 1)
+#define XPC_DEACTIVATE_REQUEST_AMO  (XPC_ENGAGED_PARTITIONS_AMO + 1)
 
 /*
  * The following structure describes the per partition specific variables.
@@ -369,6 +363,23 @@ struct xpc_notify {
  *	new messages, by the clearing of the message flags of the acknowledged
  *	messages.
  */
+struct xpc_channel_sn2 {
+
+	/* various flavors of local and remote Get/Put values */
+
+	struct xpc_gp *local_GP;	/* local Get/Put values */
+	struct xpc_gp remote_GP;	/* remote Get/Put values */
+	struct xpc_gp w_local_GP;	/* working local Get/Put values */
+	struct xpc_gp w_remote_GP;	/* working remote Get/Put values */
+	s64 next_msg_to_pull;	/* Put value of next msg to pull */
+
+	struct mutex msg_to_pull_mutex;	/* next msg to pull serialization */
+};
+
+struct xpc_channel_uv {
+	/* >>> code is coming */
+};
+
 struct xpc_channel {
 	short partid;		/* ID of remote partition connected */
 	spinlock_t lock;	/* lock for updating this structure */
@@ -407,20 +418,11 @@ struct xpc_channel {
 	xpc_channel_func func;	/* user's channel function */
 	void *key;		/* pointer to user's key */
 
-	struct mutex msg_to_pull_mutex;	/* next msg to pull serialization */
 	struct completion wdisconnect_wait;    /* wait for channel disconnect */
 
 	struct xpc_openclose_args *local_openclose_args; /* args passed on */
 					     /* opening or closing of channel */
 
-	/* various flavors of local and remote Get/Put values */
-
-	struct xpc_gp *local_GP;	/* local Get/Put values */
-	struct xpc_gp remote_GP;	/* remote Get/Put values */
-	struct xpc_gp w_local_GP;	/* working local Get/Put values */
-	struct xpc_gp w_remote_GP;	/* working remote Get/Put values */
-	s64 next_msg_to_pull;	/* Put value of next msg to pull */
-
 	/* kthread management related fields */
 
 	atomic_t kthreads_assigned;	/* #of kthreads assigned to channel */
@@ -431,6 +433,11 @@ struct xpc_channel {
 
 	wait_queue_head_t idle_wq;	/* idle kthread wait queue */
 
+	union {
+		struct xpc_channel_sn2 sn2;
+		struct xpc_channel_uv uv;
+	} sn;
+
 } ____cacheline_aligned;
 
 /* struct xpc_channel flags */
@@ -467,6 +474,40 @@ struct xpc_channel {
  * for each partition (a partition will never utilize the structure that
  * represents itself).
  */
+
+struct xpc_partition_sn2 {
+	u64 remote_amos_page_pa;	/* phys addr of partition's amos page */
+	int activate_IRQ_nasid;	/* active partition's act/deact nasid */
+	int activate_IRQ_phys_cpuid;	/* active part's act/deact phys cpuid */
+
+	u64 remote_vars_pa;	/* phys addr of partition's vars */
+	u64 remote_vars_part_pa;	/* phys addr of partition's vars part */
+	u8 remote_vars_version;	/* version# of partition's vars */
+
+	void *local_GPs_base;	/* base address of kmalloc'd space */
+	struct xpc_gp *local_GPs;	/* local Get/Put values */
+	void *remote_GPs_base;	/* base address of kmalloc'd space */
+	struct xpc_gp *remote_GPs;	/* copy of remote partition's local */
+					/* Get/Put values */
+	u64 remote_GPs_pa;	/* phys address of remote partition's local */
+				/* Get/Put values */
+
+	u64 remote_openclose_args_pa;	/* phys addr of remote's args */
+
+	int remote_IPI_nasid;	/* nasid of where to send IPIs */
+	int remote_IPI_phys_cpuid;	/* phys CPU ID of where to send IPIs */
+	char IPI_owner[8];	/* IPI owner's name */
+
+	AMO_t *remote_IPI_amo_va;    /* address of remote IPI AMO_t structure */
+	AMO_t *local_IPI_amo_va;	/* address of IPI AMO_t structure */
+
+	struct timer_list dropped_notify_IRQ_timer;	/* dropped IRQ timer */
+};
+
+struct xpc_partition_uv {
+	/* >>> code is coming */
+};
+
 struct xpc_partition {
 
 	/* XPC HB infrastructure */
@@ -474,22 +515,15 @@ struct xpc_partition {
 	u8 remote_rp_version;	/* version# of partition's rsvd pg */
 	unsigned long remote_rp_stamp; /* time when rsvd pg was initialized */
 	u64 remote_rp_pa;	/* phys addr of partition's rsvd pg */
-	u64 remote_vars_pa;	/* phys addr of partition's vars */
-	u64 remote_vars_part_pa;	/* phys addr of partition's vars part */
 	u64 last_heartbeat;	/* HB at last read */
-	u64 remote_amos_page_pa;	/* phys addr of partition's amos page */
-	int remote_act_nasid;	/* active part's act/deact nasid */
-	int remote_act_phys_cpuid;	/* active part's act/deact phys cpuid */
 	u32 activate_IRQ_rcvd;	/* IRQs since activation */
 	spinlock_t act_lock;	/* protect updating of act_state */
 	u8 act_state;		/* from XPC HB viewpoint */
-	u8 remote_vars_version;	/* version# of partition's vars */
 	enum xp_retval reason;	/* reason partition is deactivating */
 	int reason_line;	/* line# deactivation initiated from */
-	int reactivate_nasid;	/* nasid in partition to reactivate */
 
-	unsigned long disengage_request_timeout;	/* timeout in jiffies */
-	struct timer_list disengage_request_timer;
+	unsigned long disengage_timeout;	/* timeout in jiffies */
+	struct timer_list disengage_timer;
 
 	/* XPC infrastructure referencing and teardown control */
 
@@ -502,14 +536,6 @@ struct xpc_partition {
 	atomic_t nchannels_engaged;  /* #of channels engaged with remote part */
 	struct xpc_channel *channels;	/* array of channel structures */
 
-	void *local_GPs_base;	/* base address of kmalloc'd space */
-	struct xpc_gp *local_GPs;	/* local Get/Put values */
-	void *remote_GPs_base;	/* base address of kmalloc'd space */
-	struct xpc_gp *remote_GPs;	/* copy of remote partition's local */
-					/* Get/Put values */
-	u64 remote_GPs_pa;	/* phys address of remote partition's local */
-				/* Get/Put values */
-
 	/* fields used to pass args when opening or closing a channel */
 
 	void *local_openclose_args_base;   /* base address of kmalloc'd space */
@@ -517,19 +543,10 @@ struct xpc_partition {
 	void *remote_openclose_args_base;  /* base address of kmalloc'd space */
 	struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
 							  /* args */
-	u64 remote_openclose_args_pa;	/* phys addr of remote's args */
 
 	/* IPI sending, receiving and handling related fields */
 
-	int remote_IPI_nasid;	/* nasid of where to send IPIs */
-	int remote_IPI_phys_cpuid;	/* phys CPU ID of where to send IPIs */
-	AMO_t *remote_IPI_amo_va;    /* address of remote IPI AMO_t structure */
-
-	AMO_t *local_IPI_amo_va;	/* address of IPI AMO_t structure */
 	u64 local_IPI_amo;	/* IPI amo flags yet to be handled */
-	char IPI_owner[8];	/* IPI owner's name */
-	struct timer_list dropped_IPI_timer;	/* dropped IPI timer */
-
 	spinlock_t IPI_lock;	/* IPI handler lock */
 
 	/* channel manager related fields */
@@ -537,6 +554,11 @@ struct xpc_partition {
 	atomic_t channel_mgr_requests;	/* #of requests to activate chan mgr */
 	wait_queue_head_t channel_mgr_wq;	/* channel mgr's wait queue */
 
+	union {
+		struct xpc_partition_sn2 sn2;
+		struct xpc_partition_uv uv;
+	} sn;
+
 } ____cacheline_aligned;
 
 /* struct xpc_partition act_state values (for XPC HB) */
@@ -565,10 +587,10 @@ struct xpc_partition {
 #define XPC_P_DROPPED_IPI_WAIT_INTERVAL	(0.25 * HZ)
 
 /* number of seconds to wait for other partitions to disengage */
-#define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT	90
+#define XPC_DISENGAGE_DEFAULT_TIMELIMIT		90
 
-/* interval in seconds to print 'waiting disengagement' messages */
-#define XPC_DISENGAGE_PRINTMSG_INTERVAL		10
+/* interval in seconds to print 'waiting deactivation' messages */
+#define XPC_DEACTIVATE_PRINTMSG_INTERVAL	10
 
 #define XPC_PARTID(_p)	((short)((_p) - &xpc_partitions[0]))
 
@@ -578,13 +600,11 @@ extern struct xpc_registration xpc_regis
 /* found in xpc_main.c */
 extern struct device *xpc_part;
 extern struct device *xpc_chan;
-extern int xpc_disengage_request_timelimit;
-extern int xpc_disengage_request_timedout;
+extern int xpc_disengage_timelimit;
+extern int xpc_disengage_timedout;
 extern atomic_t xpc_activate_IRQ_rcvd;
 extern wait_queue_head_t xpc_activate_IRQ_wq;
 extern void *xpc_heartbeating_to_mask;
-extern irqreturn_t xpc_notify_IRQ_handler(int, void *);
-extern void xpc_dropped_IPI_check(struct xpc_partition *);
 extern void xpc_activate_partition(struct xpc_partition *);
 extern void xpc_activate_kthreads(struct xpc_channel *, int);
 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
@@ -598,31 +618,34 @@ extern void (*xpc_online_heartbeat) (voi
 extern void (*xpc_check_remote_hb) (void);
 extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
 extern u64 (*xpc_get_IPI_flags) (struct xpc_partition *);
+extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
+extern void (*xpc_process_msg_IPI) (struct xpc_partition *, int);
+extern int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *);
 extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *);
-extern void (*xpc_initiate_partition_activation) (struct xpc_rsvd_page *, u64,
-						  int);
+extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *, u64,
+						 int);
+extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
+extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
+extern void (*xpc_cancel_partition_deactivation_request) (
+							struct xpc_partition *);
 extern void (*xpc_process_activate_IRQ_rcvd) (int);
 extern enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *);
 extern void (*xpc_teardown_infrastructure) (struct xpc_partition *);
-extern void (*xpc_mark_partition_engaged) (struct xpc_partition *);
-extern void (*xpc_mark_partition_disengaged) (struct xpc_partition *);
-extern void (*xpc_request_partition_disengage) (struct xpc_partition *);
-extern void (*xpc_cancel_partition_disengage_request) (struct xpc_partition *);
-extern u64 (*xpc_partition_engaged) (u64);
-extern u64 (*xpc_partition_disengage_requested) (u64);;
-extern void (*xpc_clear_partition_engaged) (u64);
-extern void (*xpc_clear_partition_disengage_request) (u64);
-
-extern void (*xpc_IPI_send_local_activate) (int);
-extern void (*xpc_IPI_send_activated) (struct xpc_partition *);
-extern void (*xpc_IPI_send_local_reactivate) (int);
-extern void (*xpc_IPI_send_disengage) (struct xpc_partition *);
-
-extern void (*xpc_IPI_send_closerequest) (struct xpc_channel *,
-					  unsigned long *);
-extern void (*xpc_IPI_send_closereply) (struct xpc_channel *, unsigned long *);
-extern void (*xpc_IPI_send_openrequest) (struct xpc_channel *, unsigned long *);
-extern void (*xpc_IPI_send_openreply) (struct xpc_channel *, unsigned long *);
+
+extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
+extern int (*xpc_partition_engaged) (short);
+extern int (*xpc_any_partition_engaged) (void);
+extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
+extern void (*xpc_assume_partition_disengaged) (short);
+
+extern void (*xpc_send_channel_closerequest) (struct xpc_channel *,
+					      unsigned long *);
+extern void (*xpc_send_channel_closereply) (struct xpc_channel *,
+					    unsigned long *);
+extern void (*xpc_send_channel_openrequest) (struct xpc_channel *,
+					     unsigned long *);
+extern void (*xpc_send_channel_openreply) (struct xpc_channel *,
+					   unsigned long *);
 
 extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, u32, void *, u16,
 				       u8, xpc_notify_func, void *);
@@ -646,8 +669,6 @@ 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 void xpc_allow_IPI_ops(void);
-extern void xpc_restrict_IPI_ops(void);
 extern int xpc_identify_activate_IRQ_sender(void);
 extern int xpc_partition_disengaged(struct xpc_partition *);
 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
drivers/misc/sgi-xp/xpc_channel.c +17 -197

274 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_main.c +94 -184

480 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_sn2.c +540 -313

1,398 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_partition.c +27 -34

122 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_uv.c +11 -4
Index: linux-2.6/drivers/misc/sgi-xp/xpc_uv.c
===================================================================
@@ -63,8 +63,8 @@ xpc_heartbeat_exit_uv(void)
 }
 
 static void
-xpc_initiate_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
-				     u64 remote_rp_pa, int nasid)
+xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
+				    u64 remote_rp_pa, int nasid)
 {
 	short partid = remote_rp->SAL_partid;
 	struct xpc_partition *part = &xpc_partitions[partid];
@@ -78,6 +78,12 @@ xpc_initiate_partition_activation_uv(str
 	xpc_IPI_send_local_activate_uv(part);
 }
 
+static void
+xpc_request_partition_reactivation_uv(struct xpc_partition *part)
+{
+	xpc_IPI_send_local_activate_uv(part);
+}
+
 /*
  * Setup the infrastructure necessary to support XPartition Communication
  * between the specified remote partition and the local one.
@@ -128,8 +134,9 @@ xpc_init_uv(void)
 	xpc_increment_heartbeat = xpc_increment_heartbeat_uv;
 	xpc_heartbeat_init = xpc_heartbeat_init_uv;
 	xpc_heartbeat_exit = xpc_heartbeat_exit_uv;
-	xpc_initiate_partition_activation =
-	    xpc_initiate_partition_activation_uv;
+	xpc_request_partition_activation = xpc_request_partition_activation_uv;
+	xpc_request_partition_reactivation =
+	    xpc_request_partition_reactivation_uv;
 	xpc_setup_infrastructure = xpc_setup_infrastructure_uv;
 	xpc_teardown_infrastructure = xpc_teardown_infrastructure_uv;
 	xpc_make_first_contact = xpc_make_first_contact_uv;
#15 lore raw

PATCH 13/18 separate chctl_flags from XPC's notify IRQ

In reply to Dean Nelson

Tie current IPI references to either XPC's notify IRQ or channel control flags.

---

 drivers/misc/sgi-xp/xpc.h         |  124 ++++++++-----
 drivers/misc/sgi-xp/xpc_channel.c |  133 +++++++-------
 drivers/misc/sgi-xp/xpc_main.c    |   59 +++---
 drivers/misc/sgi-xp/xpc_sn2.c     |  303 +++++++++++++++++-----------------
 drivers/misc/sgi-xp/xpc_uv.c      |   10 -
 5 files changed, 327 insertions(+), 302 deletions(-)
drivers/misc/sgi-xp/xpc.h +75 -49
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -186,9 +186,10 @@ struct xpc_vars_part_sn2 {
 	u64 openclose_args_pa;	/* physical address of open and close args */
 	u64 GPs_pa;		/* physical address of Get/Put values */
 
-	u64 IPI_amo_pa;		/* physical address of IPI AMO_t structure */
-	int IPI_nasid;		/* nasid of where to send IPIs */
-	int IPI_phys_cpuid;	/* physical CPU ID of where to send IPIs */
+	u64 chctl_amo_pa;	/* physical address of chctl flags' AMO_t */
+
+	int notify_IRQ_nasid;	/* nasid of where to send notify IRQs */
+	int notify_IRQ_phys_cpuid;	/* CPUID of where to send notify IRQs */
 
 	u8 nchannels;		/* #of defined channels supported */
 
@@ -407,7 +408,7 @@ struct xpc_channel {
 	atomic_t n_on_msg_allocate_wq;	/* #on msg allocation wait queue */
 	wait_queue_head_t msg_allocate_wq;	/* msg allocation wait queue */
 
-	u8 delayed_IPI_flags;	/* IPI flags received, but delayed */
+	u8 delayed_chctl_flags;	/* chctl flags received, but delayed */
 				/* action until channel disconnected */
 
 	/* queue of msg senders who want to be notified when msg received */
@@ -470,6 +471,54 @@ struct xpc_channel {
 #define	XPC_C_WDISCONNECT	0x00040000  /* waiting for channel disconnect */
 
 /*
+ * The channel control flags (chctl) union consists of a 64-bit variable which
+ * is divided up into eight bytes, ordered from right to left. Byte zero
+ * pertains to channel 0, byte one to channel 1, and so on. Each channel's byte
+ * can have one or more of the chctl flags set in it.
+ */
+
+union xpc_channel_ctl_flags {
+	u64 all_flags;
+	u8 flags[XPC_MAX_NCHANNELS];
+};
+
+/* chctl flags */
+#define	XPC_CHCTL_CLOSEREQUEST	0x01
+#define	XPC_CHCTL_CLOSEREPLY	0x02
+#define	XPC_CHCTL_OPENREQUEST	0x04
+#define	XPC_CHCTL_OPENREPLY	0x08
+#define	XPC_CHCTL_MSGREQUEST	0x10
+
+#define XPC_OPENCLOSE_CHCTL_FLAGS \
+			(XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
+			 XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY)
+#define XPC_MSG_CHCTL_FLAGS	XPC_CHCTL_MSGREQUEST
+
+static inline int
+xpc_any_openclose_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
+{
+	int ch_number;
+
+	for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
+		if (chctl->flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS)
+			return 1;
+	}
+	return 0;
+}
+
+static inline int
+xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
+{
+	int ch_number;
+
+	for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
+		if (chctl->flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
+			return 1;
+	}
+	return 0;
+}
+
+/*
  * Manages channels on a partition basis. There is one of these structures
  * for each partition (a partition will never utilize the structure that
  * represents itself).
@@ -494,12 +543,12 @@ struct xpc_partition_sn2 {
 
 	u64 remote_openclose_args_pa;	/* phys addr of remote's args */
 
-	int remote_IPI_nasid;	/* nasid of where to send IPIs */
-	int remote_IPI_phys_cpuid;	/* phys CPU ID of where to send IPIs */
-	char IPI_owner[8];	/* IPI owner's name */
+	int notify_IRQ_nasid;	/* nasid of where to send notify IRQs */
+	int notify_IRQ_phys_cpuid;	/* CPUID of where to send notify IRQs */
+	char notify_IRQ_owner[8];	/* notify IRQ's owner's name */
 
-	AMO_t *remote_IPI_amo_va;    /* address of remote IPI AMO_t structure */
-	AMO_t *local_IPI_amo_va;	/* address of IPI AMO_t structure */
+	AMO_t *remote_chctl_amo_va; /* address of remote chctl flags' AMO_t */
+	AMO_t *local_chctl_amo_va;	/* address of chctl flags' AMO_t */
 
 	struct timer_list dropped_notify_IRQ_timer;	/* dropped IRQ timer */
 };
@@ -536,7 +585,10 @@ struct xpc_partition {
 	atomic_t nchannels_engaged;  /* #of channels engaged with remote part */
 	struct xpc_channel *channels;	/* array of channel structures */
 
-	/* fields used to pass args when opening or closing a channel */
+	/* fields used for managing channel avialability and activity */
+
+	union xpc_channel_ctl_flags chctl; /* chctl flags yet to be processed */
+	spinlock_t chctl_lock;	/* chctl flags lock */
 
 	void *local_openclose_args_base;   /* base address of kmalloc'd space */
 	struct xpc_openclose_args *local_openclose_args;      /* local's args */
@@ -544,11 +596,6 @@ struct xpc_partition {
 	struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
 							  /* args */
 
-	/* IPI sending, receiving and handling related fields */
-
-	u64 local_IPI_amo;	/* IPI amo flags yet to be handled */
-	spinlock_t IPI_lock;	/* IPI handler lock */
-
 	/* channel manager related fields */
 
 	atomic_t channel_mgr_requests;	/* #of requests to activate chan mgr */
@@ -580,11 +627,12 @@ struct xpc_partition {
 #define XPC_P_TORNDOWN		0x03	/* infrastructure is torndown */
 
 /*
- * struct xpc_partition IPI_timer #of seconds to wait before checking for
- * dropped IPIs. These occur whenever an IPI amo write doesn't complete until
- * after the IPI was received.
+ * struct xpc_partition_sn2's dropped notify IRQ timer is set to wait the
+ * following interval #of seconds before checking for dropped notify IRQs.
+ * These can occur whenever an IRQ's associated amo write doesn't complete
+ * until after the IRQ was received.
  */
-#define XPC_P_DROPPED_IPI_WAIT_INTERVAL	(0.25 * HZ)
+#define XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL	(0.25 * HZ)
 
 /* number of seconds to wait for other partitions to disengage */
 #define XPC_DISENGAGE_DEFAULT_TIMELIMIT		90
@@ -617,9 +665,9 @@ extern void (*xpc_offline_heartbeat) (vo
 extern void (*xpc_online_heartbeat) (void);
 extern void (*xpc_check_remote_hb) (void);
 extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
-extern u64 (*xpc_get_IPI_flags) (struct xpc_partition *);
+extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
 extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
-extern void (*xpc_process_msg_IPI) (struct xpc_partition *, int);
+extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
 extern int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *);
 extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *);
 extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *, u64,
@@ -638,14 +686,13 @@ extern int (*xpc_any_partition_engaged) 
 extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
 extern void (*xpc_assume_partition_disengaged) (short);
 
-extern void (*xpc_send_channel_closerequest) (struct xpc_channel *,
-					      unsigned long *);
-extern void (*xpc_send_channel_closereply) (struct xpc_channel *,
+extern void (*xpc_send_chctl_closerequest) (struct xpc_channel *,
 					    unsigned long *);
-extern void (*xpc_send_channel_openrequest) (struct xpc_channel *,
-					     unsigned long *);
-extern void (*xpc_send_channel_openreply) (struct xpc_channel *,
+extern void (*xpc_send_chctl_closereply) (struct xpc_channel *,
+					  unsigned long *);
+extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
 					   unsigned long *);
+extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
 
 extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, u32, void *, u16,
 				       u8, xpc_notify_func, void *);
@@ -689,7 +736,7 @@ extern enum xp_retval xpc_initiate_send(
 extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
 					       xpc_notify_func, void *);
 extern void xpc_initiate_received(short, int, void *);
-extern void xpc_process_channel_activity(struct xpc_partition *);
+extern void xpc_process_sent_chctl_flags(struct xpc_partition *);
 extern void xpc_connected_callout(struct xpc_channel *);
 extern void xpc_deliver_msg(struct xpc_channel *);
 extern void xpc_disconnect_channel(const int, struct xpc_channel *,
@@ -799,25 +846,4 @@ xpc_part_ref(struct xpc_partition *part)
 		(_p)->reason_line = _line; \
 	}
 
-/*
- * The sending and receiving of IPIs includes the setting of an >>>AMO variable
- * to indicate the reason the IPI was sent. The 64-bit variable is divided
- * up into eight bytes, ordered from right to left. Byte zero pertains to
- * channel 0, byte one to channel 1, and so on. Each byte is described by
- * the following IPI flags.
- */
-
-#define	XPC_IPI_CLOSEREQUEST	0x01
-#define	XPC_IPI_CLOSEREPLY	0x02
-#define	XPC_IPI_OPENREQUEST	0x04
-#define	XPC_IPI_OPENREPLY	0x08
-#define	XPC_IPI_MSGREQUEST	0x10
-
-/* given an >>>AMO variable and a channel#, get its associated IPI flags */
-#define XPC_GET_IPI_FLAGS(_amo, _c)	((u8) (((_amo) >> ((_c) * 8)) & 0xff))
-#define XPC_SET_IPI_FLAGS(_amo, _c, _f)	(_amo) |= ((u64) (_f) << ((_c) * 8))
-
-#define	XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0fUL)
-#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo)       ((_amo) & 0x1010101010101010UL)
-
 #endif /* _DRIVERS_MISC_SGIXP_XPC_H */
drivers/misc/sgi-xp/xpc_channel.c +65 -68

289 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_main.c +29 -30

106 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_sn2.c +153 -150

718 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_uv.c +5 -5
Index: linux-2.6/drivers/misc/sgi-xp/xpc_uv.c
===================================================================
@@ -26,7 +26,7 @@ static DECLARE_BITMAP(xpc_heartbeating_t
 static void *xpc_activate_mq;
 
 static void
-xpc_IPI_send_local_activate_uv(struct xpc_partition *part)
+xpc_send_local_activate_IRQ_uv(struct xpc_partition *part)
 {
 	/*
 	 * >>> make our side think that the remote parition sent an activate
@@ -75,13 +75,13 @@ xpc_request_partition_activation_uv(stru
  * >>>	part->sn.uv.activate_mq_gpa = remote_rp->sn.activate_mq_gpa;
  */
 
-	xpc_IPI_send_local_activate_uv(part);
+	xpc_send_local_activate_IRQ_uv(part);
 }
 
 static void
 xpc_request_partition_reactivation_uv(struct xpc_partition *part)
 {
-	xpc_IPI_send_local_activate_uv(part);
+	xpc_send_local_activate_IRQ_uv(part);
 }
 
 /*
@@ -114,7 +114,7 @@ xpc_make_first_contact_uv(struct xpc_par
 }
 
 static u64
-xpc_get_IPI_flags_uv(struct xpc_partition *part)
+xpc_get_chctl_all_flags_uv(struct xpc_partition *part)
 {
 	/* >>> this function needs fleshing out */
 	return 0UL;
@@ -140,7 +140,7 @@ xpc_init_uv(void)
 	xpc_setup_infrastructure = xpc_setup_infrastructure_uv;
 	xpc_teardown_infrastructure = xpc_teardown_infrastructure_uv;
 	xpc_make_first_contact = xpc_make_first_contact_uv;
-	xpc_get_IPI_flags = xpc_get_IPI_flags_uv;
+	xpc_get_chctl_all_flags = xpc_get_chctl_all_flags_uv;
 	xpc_get_deliverable_msg = xpc_get_deliverable_msg_uv;
 }
 
#16 lore raw

PATCH 14/18 replace AMO_t typedef by struct amo

In reply to Dean Nelson

Replace the AMO_t typedef by a direct reference to 'struct amo'.

---

 drivers/misc/sgi-xp/xp_sn2.c   |    2 
 drivers/misc/sgi-xp/xpc.h      |   24 +++---
 drivers/misc/sgi-xp/xpc_main.c |   16 ++--
 drivers/misc/sgi-xp/xpc_sn2.c  |  139 +++++++++++++++++++------------------
 include/asm-ia64/sn/mspec.h    |   16 ++--
 5 files changed, 101 insertions(+), 96 deletions(-)
drivers/misc/sgi-xp/xpc.h +12 -12
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -38,8 +38,8 @@
 /*
  * The next macros define word or bit representations for given
  * C-brick nasid in either the SAL provided bit array representing
- * nasids in the partition/machine or the AMO_t array used for
- * inter-partition initiation communications.
+ * nasids in the partition/machine or the array of amo structures used
+ * for inter-partition initiation communications.
  *
  * For SN2 machines, C-Bricks are alway even numbered NASIDs.  As
  * such, some space will be saved by insisting that nasid information
@@ -144,8 +144,8 @@ struct xpc_vars_sn2 {
 	int activate_IRQ_nasid;
 	int activate_IRQ_phys_cpuid;
 	u64 vars_part_pa;
-	u64 amos_page_pa;	/* paddr of page of AMOs from MSPEC driver */
-	AMO_t *amos_page;	/* vaddr of page of AMOs from MSPEC driver */
+	u64 amos_page_pa;	/* paddr of page of amos from MSPEC driver */
+	struct amo *amos_page;	/* vaddr of page of amos from MSPEC driver */
 };
 
 #define XPC_V_VERSION _XPC_VERSION(3, 1)    /* version 3.1 of the cross vars */
@@ -153,17 +153,17 @@ struct xpc_vars_sn2 {
 /*
  * The following pertains to ia64-sn2 only.
  *
- * Memory for XPC's AMO variables is allocated by the MSPEC driver. These
+ * 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
+ * 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.
+ * 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)
@@ -186,7 +186,7 @@ struct xpc_vars_part_sn2 {
 	u64 openclose_args_pa;	/* physical address of open and close args */
 	u64 GPs_pa;		/* physical address of Get/Put values */
 
-	u64 chctl_amo_pa;	/* physical address of chctl flags' AMO_t */
+	u64 chctl_amo_pa;	/* physical address of chctl flags' amo */
 
 	int notify_IRQ_nasid;	/* nasid of where to send notify IRQs */
 	int notify_IRQ_phys_cpuid;	/* CPUID of where to send notify IRQs */
@@ -547,8 +547,8 @@ struct xpc_partition_sn2 {
 	int notify_IRQ_phys_cpuid;	/* CPUID of where to send notify IRQs */
 	char notify_IRQ_owner[8];	/* notify IRQ's owner's name */
 
-	AMO_t *remote_chctl_amo_va; /* address of remote chctl flags' AMO_t */
-	AMO_t *local_chctl_amo_va;	/* address of chctl flags' AMO_t */
+	struct amo *remote_chctl_amo_va; /* addr of remote chctl flags' amo */
+	struct amo *local_chctl_amo_va;	/* address of chctl flags' amo */
 
 	struct timer_list dropped_notify_IRQ_timer;	/* dropped IRQ timer */
 };
include/asm-ia64/sn/mspec.h +8 -8
Index: linux-2.6/include/asm-ia64/sn/mspec.h
===================================================================
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2004 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2008 Silicon Graphics, Inc.  All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_MSPEC_H
@@ -32,26 +32,26 @@
 #ifdef __KERNEL__
 
 /*
- * Each Atomic Memory Operation (AMO formerly known as fetchop)
+ * Each Atomic Memory Operation (amo, formerly known as fetchop)
  * variable is 64 bytes long.  The first 8 bytes are used.  The
  * remaining 56 bytes are unaddressable due to the operation taking
  * that portion of the address.
  *
- * NOTE: The AMO_t _MUST_ be placed in either the first or second half
- * of the cache line.  The cache line _MUST NOT_ be used for anything
- * other than additional AMO_t entries.  This is because there are two
+ * NOTE: The amo structure _MUST_ be placed in either the first or second
+ * half of the cache line.  The cache line _MUST NOT_ be used for anything
+ * other than additional amo entries.  This is because there are two
  * addresses which reference the same physical cache line.  One will
  * be a cached entry with the memory type bits all set.  This address
- * may be loaded into processor cache.  The AMO_t will be referenced
+ * may be loaded into processor cache.  The amo will be referenced
  * uncached via the memory special memory type.  If any portion of the
  * cached cache-line is modified, when that line is flushed, it will
  * overwrite the uncached value in physical memory and lead to
  * inconsistency.
  */
-typedef struct {
+struct amo {
         u64 variable;
         u64 unused[7];
-} AMO_t;
+};
 
 
 #endif /* __KERNEL__ */
drivers/misc/sgi-xp/xpc_sn2.c +72 -67

394 lines not on this page · raw message

drivers/misc/sgi-xp/xp_sn2.c +1 -1
Index: linux-2.6/drivers/misc/sgi-xp/xp_sn2.c
===================================================================
@@ -32,7 +32,7 @@ EXPORT_SYMBOL_GPL(xp_nofault_PIOR_target
  * If the PIO read times out, the MCA handler will consume the error and
  * return to a kernel-provided instruction to indicate an error. This PIO read
  * exists because it is guaranteed to timeout if the destination is down
- * (AMO operations do not timeout on at least some CPUs on Shubs <= v1.2,
+ * (amo operations do not timeout on at least some CPUs on Shubs <= v1.2,
  * which unfortunately we have to work around).
  */
 static enum xp_retval
drivers/misc/sgi-xp/xpc_main.c +8 -8
Index: linux-2.6/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -26,16 +26,16 @@
  *	Caveats:
  *
  *	  . Currently on sn2, we have no way to determine which nasid an IRQ
- *	    came from. Thus, xpc_send_IRQ_sn2() does a remote AMO write
- *	    followed by an IPI. The AMO indicates where data is to be pulled
- *	    from, so after the IPI arrives, the remote partition checks the AMO
- *	    word. The IPI can actually arrive before the AMO however, so other
- *	    code must periodically check for this case. Also, remote AMO
+ *	    came from. Thus, xpc_send_IRQ_sn2() does a remote amo write
+ *	    followed by an IPI. The amo indicates where data is to be pulled
+ *	    from, so after the IPI arrives, the remote partition checks the amo
+ *	    word. The IPI can actually arrive before the amo however, so other
+ *	    code must periodically check for this case. Also, remote amo
  *	    operations do not reliably time out. Thus we do a remote PIO read
  *	    solely to know whether the remote partition is down and whether we
  *	    should stop sending IPIs to it. This remote PIO read operation is
  *	    set up in a special nofault region so SAL knows to ignore (and
- *	    cleanup) any errors due to the remote AMO write, PIO read, and/or
+ *	    cleanup) any errors due to the remote amo write, PIO read, and/or
  *	    PIO write operations.
  *
  *	    If/when new hardware solves this IPI problem, we should abandon
@@ -302,7 +302,7 @@ xpc_hb_checker(void *ignore)
 
 			/*
 			 * We need to periodically recheck to ensure no
-			 * IRQ/AMO pairs have been missed.  That check
+			 * IRQ/amo pairs have been missed.  That check
 			 * must always reset xpc_hb_check_timeout.
 			 */
 			force_IRQ = 1;
@@ -1034,7 +1034,7 @@ xpc_init(void)
 	if (is_shub()) {
 		/*
 		 * The ia64-sn2 architecture supports at most 64 partitions.
-		 * And the inability to unregister remote AMOs restricts us
+		 * And the inability to unregister remote amos restricts us
 		 * further to only support exactly 64 partitions on this
 		 * architecture, no less.
 		 */
#17 lore raw

PATCH 15/18 isolate allocation of XPC's msgqueues to sn2 only

In reply to Dean Nelson

Move the allocation of XPC's msgqueues to xpc_sn2.c.

---

 drivers/misc/sgi-xp/xpc.h         |    3 
 drivers/misc/sgi-xp/xpc_channel.c |  197 +-------------------------------
 drivers/misc/sgi-xp/xpc_main.c    |    2 
 drivers/misc/sgi-xp/xpc_sn2.c     |  205 ++++++++++++++++++++++++++++++++--
 4 files changed, 204 insertions(+), 203 deletions(-)
drivers/misc/sgi-xp/xpc.h +2 -1
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -666,6 +666,8 @@ extern void (*xpc_online_heartbeat) (voi
 extern void (*xpc_check_remote_hb) (void);
 extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
 extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
+extern enum xp_retval (*xpc_allocate_msgqueues) (struct xpc_channel *);
+extern void (*xpc_free_msgqueues) (struct xpc_channel *);
 extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
 extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
 extern int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *);
@@ -728,7 +730,6 @@ extern void xpc_deactivate_partition(con
 extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
 
 /* found in xpc_channel.c */
-extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
 extern void xpc_initiate_connect(int);
 extern void xpc_initiate_disconnect(int);
 extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
drivers/misc/sgi-xp/xpc_channel.c +7 -190

224 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_main.c +2 -0
Index: linux-2.6/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -186,6 +186,8 @@ void (*xpc_check_remote_hb) (void);
 enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part);
 void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *ch);
 u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *part);
+enum xp_retval (*xpc_allocate_msgqueues) (struct xpc_channel *ch);
+void (*xpc_free_msgqueues) (struct xpc_channel *ch);
 void (*xpc_process_msg_chctl_flags) (struct xpc_partition *part, int ch_number);
 int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *ch);
 struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *ch);
drivers/misc/sgi-xp/xpc_sn2.c +193 -12

247 lines not on this page · raw message

#18 lore raw

PATCH 16/18 enable XPNET to handle more than 64 partitions

In reply to Dean Nelson

Enable XPNET to support more than 64 partitions.

---

 drivers/misc/sgi-xp/xpc.h         |    3 
 drivers/misc/sgi-xp/xpc_channel.c |  197 +-------------------------------
 drivers/misc/sgi-xp/xpc_main.c    |    2 
 drivers/misc/sgi-xp/xpc_sn2.c     |  205 ++++++++++++++++++++++++++++++++--
 4 files changed, 204 insertions(+), 203 deletions(-)
drivers/misc/sgi-xp/xpnet.c +94 -119
Index: linux-2.6/drivers/misc/sgi-xp/xpnet.c
===================================================================
@@ -21,7 +21,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -32,8 +31,6 @@
 #include <linux/mii.h>
 #include <linux/smp.h>
 #include <linux/string.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_sal.h>
 #include <asm/atomic.h>
 #include "xp.h"
 
@@ -104,7 +101,6 @@ struct xpnet_message {
  * then be released.
  */
 struct xpnet_pending_msg {
-	struct list_head free_list;
 	struct sk_buff *skb;
 	atomic_t use_count;
 };
@@ -120,7 +116,7 @@ struct net_device *xpnet_device;
  * When we are notified of other partitions activating, we add them to
  * our bitmask of partitions to which we broadcast.
  */
-static u64 xpnet_broadcast_partitions;
+static unsigned long *xpnet_broadcast_partitions;
 /* protect above */
 static DEFINE_SPINLOCK(xpnet_broadcast_lock);
 
@@ -140,16 +136,13 @@ static DEFINE_SPINLOCK(xpnet_broadcast_l
 #define XPNET_DEF_MTU (0x8000UL)
 
 /*
- * The partition id is encapsulated in the MAC address.  The following
- * define locates the octet the partid is in.
+ * The partid is encapsulated in the MAC address beginning in the following
+ * octet and it consists of two octets.
  */
-#define XPNET_PARTID_OCTET	1
-#define XPNET_LICENSE_OCTET	2
+#define XPNET_PARTID_OCTET	2
+
+/* Define the XPNET debug device structures to be used with dev_dbg() et al */
 
-/*
- * Define the XPNET debug device structure that is to be used with dev_dbg(),
- * dev_err(), dev_warn(), and dev_info().
- */
 struct device_driver xpnet_dbg_name = {
 	.name = "xpnet"
 };
@@ -231,7 +224,7 @@ xpnet_receive(short partid, int channel,
 					  (void *)msg->buf_pa, msg->size);
 
 		ret = xp_remote_memcpy((void *)((u64)skb->data &
-				                ~(L1_CACHE_BYTES - 1)),
+						~(L1_CACHE_BYTES - 1)),
 				       (void *)msg->buf_pa, msg->size);
 
 		if (ret != xpSuccess) {
@@ -283,8 +276,6 @@ static void
 xpnet_connection_activity(enum xp_retval reason, short partid, int channel,
 			  void *data, void *key)
 {
-	long bp;
-
 	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
 	DBUG_ON(channel != XPC_NET_CHANNEL);
 
@@ -297,31 +288,28 @@ xpnet_connection_activity(enum xp_retval
 
 	case xpConnected:	/* connection completed to a partition */
 		spin_lock_bh(&xpnet_broadcast_lock);
-		xpnet_broadcast_partitions |= 1UL << (partid - 1);
-		bp = xpnet_broadcast_partitions;
+		__set_bit(partid, xpnet_broadcast_partitions);
 		spin_unlock_bh(&xpnet_broadcast_lock);
 
 		netif_carrier_on(xpnet_device);
 
-		dev_dbg(xpnet, "%s connection created to partition %d; "
-			"xpnet_broadcast_partitions=0x%lx\n",
-			xpnet_device->name, partid, bp);
+		dev_dbg(xpnet, "%s connected to partition %d\n",
+			xpnet_device->name, partid);
 		break;
 
 	default:
 		spin_lock_bh(&xpnet_broadcast_lock);
-		xpnet_broadcast_partitions &= ~(1UL << (partid - 1));
-		bp = xpnet_broadcast_partitions;
+		__clear_bit(partid, xpnet_broadcast_partitions);
 		spin_unlock_bh(&xpnet_broadcast_lock);
 
-		if (bp == 0)
+		if (bitmap_empty((unsigned long *)xpnet_broadcast_partitions,
+				 xp_max_npartitions)) {
 			netif_carrier_off(xpnet_device);
+		}
 
-		dev_dbg(xpnet, "%s disconnected from partition %d; "
-			"xpnet_broadcast_partitions=0x%lx\n",
-			xpnet_device->name, partid, bp);
+		dev_dbg(xpnet, "%s disconnected from partition %d\n",
+			xpnet_device->name, partid);
 		break;
-
 	}
 }
 
@@ -424,36 +412,72 @@ xpnet_send_completed(enum xp_retval reas
 	}
 }
 
+static void
+xpnet_send(struct sk_buff *skb, struct xpnet_pending_msg *queued_msg,
+	   u64 start_addr, u64 end_addr, u16 embedded_bytes, int dest_partid)
+{
+	u8 msg_buffer[XPNET_MSG_SIZE];
+	struct xpnet_message *msg = (struct xpnet_message *)&msg_buffer;
+	enum xp_retval ret;
+
+	msg->embedded_bytes = embedded_bytes;
+	if (unlikely(embedded_bytes != 0)) {
+		msg->version = XPNET_VERSION_EMBED;
+		dev_dbg(xpnet, "calling memcpy(0x%p, 0x%p, 0x%lx)\n",
+			&msg->data, skb->data, (size_t)embedded_bytes);
+		skb_copy_from_linear_data(skb, &msg->data,
+					  (size_t)embedded_bytes);
+	} else {
+		msg->version = XPNET_VERSION;
+	}
+	msg->magic = XPNET_MAGIC;
+	msg->size = end_addr - start_addr;
+	msg->leadin_ignore = (u64)skb->data - start_addr;
+	msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb);
+	msg->buf_pa = __pa(start_addr);
+
+	dev_dbg(xpnet, "sending XPC message to %d:%d\n"
+		KERN_DEBUG "msg->buf_pa=0x%lx, msg->size=%u, "
+		"msg->leadin_ignore=%u, msg->tailout_ignore=%u\n",
+		dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size,
+		msg->leadin_ignore, msg->tailout_ignore);
+
+	atomic_inc(&queued_msg->use_count);
+
+	ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, XPC_NOWAIT, msg,
+			      XPNET_MSG_SIZE, xpnet_send_completed, queued_msg);
+	if (unlikely(ret != xpSuccess))
+		atomic_dec(&queued_msg->use_count);
+}
+
 /*
  * Network layer has formatted a packet (skb) and is ready to place it
  * "on the wire".  Prepare and send an xpnet_message to all partitions
  * which have connected with us and are targets of this packet.
  *
  * MAC-NOTE:  For the XPNET driver, the MAC address contains the
- * destination partition_id.  If the destination partition id word
- * is 0xff, this packet is to broadcast to all partitions.
+ * destination partid.  If the destination partid octets are 0xffff,
+ * this packet is to be broadcast to all connected partitions.
  */
 static int
 xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct xpnet_pending_msg *queued_msg;
-	enum xp_retval ret;
-	u8 msg_buffer[XPNET_MSG_SIZE];
-	struct xpnet_message *msg = (struct xpnet_message *)&msg_buffer[0];
 	u64 start_addr, end_addr;
-	long dp;
-	u8 second_mac_octet;
 	short dest_partid;
-	struct xpnet_dev_private *priv;
-	u16 embedded_bytes;
-
-	priv = (struct xpnet_dev_private *)dev->priv;
+	struct xpnet_dev_private *priv = (struct xpnet_dev_private *)dev->priv;
+	u16 embedded_bytes = 0;
 
 	dev_dbg(xpnet, ">skb->head=0x%p skb->data=0x%p skb->tail=0x%p "
 		"skb->end=0x%p skb->len=%d\n", (void *)skb->head,
 		(void *)skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
 		skb->len);
 
+	if (skb->data[0] == 0x33) {
+		dev_kfree_skb(skb);
+		return 0;	/* nothing needed to be done */
+	}
+
 	/*
 	 * The xpnet_pending_msg tracks how many outstanding
 	 * xpc_send_notifies are relying on this skb.  When none
@@ -465,7 +489,6 @@ xpnet_dev_hard_start_xmit(struct sk_buff
 			 "packet\n", sizeof(struct xpnet_pending_msg));
 
 		priv->stats.tx_errors++;
-
 		return -ENOMEM;
 	}
 
@@ -474,7 +497,6 @@ xpnet_dev_hard_start_xmit(struct sk_buff
 	end_addr = L1_CACHE_ALIGN((u64)skb_tail_pointer(skb));
 
 	/* calculate how many bytes to embed in the XPC message */
-	embedded_bytes = 0;
 	if (unlikely(skb->len <= XPNET_MSG_DATA_MAX)) {
 		/* skb->data does fit so embed */
 		embedded_bytes = skb->len;
@@ -490,78 +512,28 @@ xpnet_dev_hard_start_xmit(struct sk_buff
 	atomic_set(&queued_msg->use_count, 1);
 	queued_msg->skb = skb;
 
-	second_mac_octet = skb->data[XPNET_PARTID_OCTET];
-	if (second_mac_octet == 0xff) {
+	if (skb->data[0] == 0xff) {
 		/* we are being asked to broadcast to all partitions */
-		dp = xpnet_broadcast_partitions;
-	} else if (second_mac_octet != 0) {
-		dp = xpnet_broadcast_partitions &
-		    (1UL << (second_mac_octet - 1));
-	} else {
-		/* 0 is an invalid partid.  Ignore */
-		dp = 0;
-	}
-	dev_dbg(xpnet, "destination Partitions mask (dp) = 0x%lx\n", dp);
-
-	/*
-	 * If we wanted to allow promiscuous mode to work like an
-	 * unswitched network, this would be a good point to OR in a
-	 * mask of partitions which should be receiving all packets.
-	 */
-
-	/*
-	 * Main send loop.
-	 */
-	for (dest_partid = 0; dp && dest_partid < xp_max_npartitions;
-	     dest_partid++) {
+		for_each_bit(dest_partid, xpnet_broadcast_partitions,
+			     xp_max_npartitions) {
 
-		if (!(dp & (1UL << (dest_partid - 1)))) {
-			/* not destined for this partition */
-			continue;
+			xpnet_send(skb, queued_msg, start_addr, end_addr,
+				   embedded_bytes, dest_partid);
 		}
+	} else {
+		dest_partid = (short)skb->data[XPNET_PARTID_OCTET + 1];
+		dest_partid |= (short)skb->data[XPNET_PARTID_OCTET + 0] << 8;
 
-		/* remove this partition from the destinations mask */
-		dp &= ~(1UL << (dest_partid - 1));
-
-		/* found a partition to send to */
+		if (dest_partid >= 0 &&
+		    dest_partid < xp_max_npartitions &&
+		    test_bit(dest_partid, xpnet_broadcast_partitions) != 0) {
 
-		msg->embedded_bytes = embedded_bytes;
-		if (unlikely(embedded_bytes != 0)) {
-			msg->version = XPNET_VERSION_EMBED;
-			dev_dbg(xpnet, "calling memcpy(0x%p, 0x%p, 0x%lx)\n",
-				&msg->data, skb->data, (size_t)embedded_bytes);
-			skb_copy_from_linear_data(skb, &msg->data,
-						  (size_t)embedded_bytes);
-		} else {
-			msg->version = XPNET_VERSION;
-		}
-		msg->magic = XPNET_MAGIC;
-		msg->size = end_addr - start_addr;
-		msg->leadin_ignore = (u64)skb->data - start_addr;
-		msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb);
-		msg->buf_pa = __pa(start_addr);
-
-		dev_dbg(xpnet, "sending XPC message to %d:%d\n"
-			KERN_DEBUG "msg->buf_pa=0x%lx, msg->size=%u, "
-			"msg->leadin_ignore=%u, msg->tailout_ignore=%u\n",
-			dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size,
-			msg->leadin_ignore, msg->tailout_ignore);
-
-		atomic_inc(&queued_msg->use_count);
-
-		ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, XPC_NOWAIT,
-				      &msg, sizeof(msg) + embedded_bytes - 1,
-				      xpnet_send_completed, queued_msg);
-		if (unlikely(ret != xpSuccess)) {
-			atomic_dec(&queued_msg->use_count);
-			continue;
+			xpnet_send(skb, queued_msg, start_addr, end_addr,
+				   embedded_bytes, dest_partid);
 		}
 	}
 
 	if (atomic_dec_return(&queued_msg->use_count) == 0) {
-		dev_dbg(xpnet, "no partitions to receive packet destined for "
-			"%d\n", dest_partid);
-
 		dev_kfree_skb(skb);
 		kfree(queued_msg);
 	}
@@ -589,23 +561,28 @@ xpnet_dev_tx_timeout(struct net_device *
 static int __init
 xpnet_init(void)
 {
-	int i;
-	u32 license_num;
-	int result = -ENOMEM;
+	int result;
 
-	if (!ia64_platform_is("sn2"))
+	if (!is_shub() && !is_uv())
 		return -ENODEV;
 
 	dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
 
+	xpnet_broadcast_partitions = kzalloc(BITS_TO_LONGS(xp_max_npartitions) *
+					     sizeof(long), GFP_KERNEL);
+	if (xpnet_broadcast_partitions == NULL)
+		return -ENOMEM;
+
 	/*
 	 * use ether_setup() to init the majority of our device
 	 * structure and then override the necessary pieces.
 	 */
 	xpnet_device = alloc_netdev(sizeof(struct xpnet_dev_private),
 				    XPNET_DEVICE_NAME, ether_setup);
-	if (xpnet_device == NULL)
+	if (xpnet_device == NULL) {
+		kfree(xpnet_broadcast_partitions);
 		return -ENOMEM;
+	}
 
 	netif_carrier_off(xpnet_device);
 
@@ -623,14 +600,10 @@ xpnet_init(void)
 	 * MAC addresses.  We chose the first octet of the MAC to be unlikely
 	 * to collide with any vendor's officially issued MAC.
 	 */
-	xpnet_device->dev_addr[0] = 0xfe;
-	xpnet_device->dev_addr[XPNET_PARTID_OCTET] = sn_partition_id;
-	license_num = sn_partition_serial_number_val();
-	for (i = 3; i >= 0; i--) {
-		xpnet_device->dev_addr[XPNET_LICENSE_OCTET + i] =
-		    license_num & 0xff;
-		license_num = license_num >> 8;
-	}
+	xpnet_device->dev_addr[0] = 0x02;     /* locally administered, no OUI */
+
+	xpnet_device->dev_addr[XPNET_PARTID_OCTET + 1] = sn_partition_id;
+	xpnet_device->dev_addr[XPNET_PARTID_OCTET + 0] = (sn_partition_id >> 8);
 
 	/*
 	 * ether_setup() sets this to a multicast device.  We are
@@ -646,8 +619,10 @@ xpnet_init(void)
 	xpnet_device->features = NETIF_F_NO_CSUM;
 
 	result = register_netdev(xpnet_device);
-	if (result != 0)
+	if (result != 0) {
 		free_netdev(xpnet_device);
+		kfree(xpnet_broadcast_partitions);
+	}
 
 	return result;
 }
@@ -661,8 +636,8 @@ xpnet_exit(void)
 		 xpnet_device[0].name);
 
 	unregister_netdev(xpnet_device);
-
 	free_netdev(xpnet_device);
+	kfree(xpnet_broadcast_partitions);
 }
 
 module_exit(xpnet_exit);
#19 lore raw

PATCH 17/18 isolate remote copy buffer to sn2 only

In reply to Dean Nelson

Make the remote copy buffer an sn2 only item.

---

 drivers/misc/sgi-xp/xp.h            |   10 ---
 drivers/misc/sgi-xp/xpc.h           |   39 +++-----------
 drivers/misc/sgi-xp/xpc_main.c      |   31 ++---------
 drivers/misc/sgi-xp/xpc_partition.c |   31 ++++-------
 drivers/misc/sgi-xp/xpc_sn2.c       |   88 +++++++++++++++++++++++++-------
 5 files changed, 97 insertions(+), 102 deletions(-)
drivers/misc/sgi-xp/xpc.h +9 -30
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -151,26 +151,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.
  *
  * An array of these structures, one per partition, will be defined. As a
@@ -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);
drivers/misc/sgi-xp/xpc_main.c +8 -23
Index: linux-2.6/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -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();
drivers/misc/sgi-xp/xpc_partition.c +11 -20
Index: linux-2.6/drivers/misc/sgi-xp/xpc_partition.c
===================================================================
@@ -34,21 +34,12 @@ 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.
  */
 void *
@@ -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 *discov
 
 	/* 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 part
 	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);
 }
drivers/misc/sgi-xp/xpc_sn2.c +69 -19

210 lines not on this page · raw message

drivers/misc/sgi-xp/xp.h +0 -10
Index: linux-2.6/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -61,16 +61,6 @@
 #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
  * `users' can communicate with their counterparts on the other partitions.
#20 lore raw

PATCH 18/18 add _sn2 suffix to a few variables

In reply to Dean Nelson

Add an '_sn2' suffix to some variables found in xpc_sn2.c.

---

 drivers/misc/sgi-xp/xpc_sn2.c |  124 +++++++++++++++++++-------------------
 1 file changed, 65 insertions(+), 59 deletions(-)
drivers/misc/sgi-xp/xpc_sn2.c +65 -59
Index: linux-2.6/drivers/misc/sgi-xp/xpc_sn2.c
===================================================================
@@ -56,15 +56,15 @@
 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_part_sn2 *xpc_vars_part; /* >>> Add _sn2 suffix? */
+static struct xpc_vars_sn2 *xpc_vars_sn2;
+static struct xpc_vars_part_sn2 *xpc_vars_part_sn2;
 
 /* SH_IPI_ACCESS shub register value on startup */
-static u64 xpc_sh1_IPI_access;
-static u64 xpc_sh2_IPI_access0;
-static u64 xpc_sh2_IPI_access1;
-static u64 xpc_sh2_IPI_access2;
-static u64 xpc_sh2_IPI_access3;
+static u64 xpc_sh1_IPI_access_sn2;
+static u64 xpc_sh2_IPI_access0_sn2;
+static u64 xpc_sh2_IPI_access1_sn2;
+static u64 xpc_sh2_IPI_access2_sn2;
+static u64 xpc_sh2_IPI_access3_sn2;
 
 /*
  * Change protections to allow IPI operations.
@@ -77,13 +77,13 @@ xpc_allow_IPI_ops_sn2(void)
 
 	/* >>> The following should get moved into SAL. */
 	if (is_shub2()) {
-		xpc_sh2_IPI_access0 =
+		xpc_sh2_IPI_access0_sn2 =
 		    (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS0));
-		xpc_sh2_IPI_access1 =
+		xpc_sh2_IPI_access1_sn2 =
 		    (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS1));
-		xpc_sh2_IPI_access2 =
+		xpc_sh2_IPI_access2_sn2 =
 		    (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS2));
-		xpc_sh2_IPI_access3 =
+		xpc_sh2_IPI_access3_sn2 =
 		    (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS3));
 
 		for_each_online_node(node) {
@@ -98,7 +98,7 @@ xpc_allow_IPI_ops_sn2(void)
 			      -1UL);
 		}
 	} else {
-		xpc_sh1_IPI_access =
+		xpc_sh1_IPI_access_sn2 =
 		    (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH1_IPI_ACCESS));
 
 		for_each_online_node(node) {
@@ -123,19 +123,19 @@ xpc_disallow_IPI_ops_sn2(void)
 		for_each_online_node(node) {
 			nasid = cnodeid_to_nasid(node);
 			HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
-			      xpc_sh2_IPI_access0);
+			      xpc_sh2_IPI_access0_sn2);
 			HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
-			      xpc_sh2_IPI_access1);
+			      xpc_sh2_IPI_access1_sn2);
 			HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
-			      xpc_sh2_IPI_access2);
+			      xpc_sh2_IPI_access2_sn2);
 			HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
-			      xpc_sh2_IPI_access3);
+			      xpc_sh2_IPI_access3_sn2);
 		}
 	} else {
 		for_each_online_node(node) {
 			nasid = cnodeid_to_nasid(node);
 			HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
-			      xpc_sh1_IPI_access);
+			      xpc_sh1_IPI_access_sn2);
 		}
 	}
 }
@@ -182,7 +182,7 @@ xpc_send_IRQ_sn2(struct amo *amo, u64 fl
 static struct amo *
 xpc_init_IRQ_amo_sn2(int index)
 {
-	struct amo *amo = xpc_vars->amos_page + index;
+	struct amo *amo = xpc_vars_sn2->amos_page + index;
 
 	(void)xpc_receive_IRQ_amo_sn2(amo);	/* clear amo variable */
 	return amo;
@@ -225,7 +225,7 @@ xpc_send_local_activate_IRQ_sn2(int from
 {
 	int w_index = XPC_NASID_W_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_sn2->amos_page_pa +
 					      (XPC_ACTIVATE_IRQ_AMOS_SN2 *
 					      sizeof(struct amo)));
 
@@ -492,7 +492,8 @@ xpc_indicate_partition_disengaged_sn2(st
 static int
 xpc_partition_engaged_sn2(short partid)
 {
-	struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2;
+	struct amo *amo = xpc_vars_sn2->amos_page +
+			  XPC_ENGAGED_PARTITIONS_AMO_SN2;
 
 	/* our partition's amo variable ANDed with partid mask */
 	return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
@@ -502,7 +503,8 @@ xpc_partition_engaged_sn2(short partid)
 static int
 xpc_any_partition_engaged_sn2(void)
 {
-	struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2;
+	struct amo *amo = xpc_vars_sn2->amos_page +
+			  XPC_ENGAGED_PARTITIONS_AMO_SN2;
 
 	/* our partition's amo variable */
 	return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0;
@@ -511,7 +513,8 @@ xpc_any_partition_engaged_sn2(void)
 static void
 xpc_assume_partition_disengaged_sn2(short partid)
 {
-	struct amo *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO_SN2;
+	struct amo *amo = xpc_vars_sn2->amos_page +
+			  XPC_ENGAGED_PARTITIONS_AMO_SN2;
 
 	/* clear bit(s) based on partid mask in our partition's amo */
 	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
@@ -580,27 +583,27 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_p
 	int i;
 	int ret;
 
-	xpc_vars = XPC_RP_VARS(rp);
+	xpc_vars_sn2 = XPC_RP_VARS(rp);
 
-	rp->sn.vars_pa = __pa(xpc_vars);
+	rp->sn.vars_pa = __pa(xpc_vars_sn2);
 
 	/* vars_part array follows immediately after vars */
-	xpc_vars_part = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) +
-						     XPC_RP_VARS_SIZE);
+	xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) +
+							 XPC_RP_VARS_SIZE);
 
 	/*
-	 * Before clearing xpc_vars, see if a page of amos had been previously
-	 * allocated. If not we'll need to allocate one and set permissions
-	 * so that cross-partition amos are allowed.
+	 * Before clearing xpc_vars_sn2, see if a page of amos had been
+	 * previously allocated. If not we'll need to allocate one and set
+	 * permissions so that cross-partition amos are allowed.
 	 *
 	 * The allocated amo page needs MCA reporting to remain disabled after
 	 * XPC has unloaded.  To make this work, we keep a copy of the pointer
-	 * to this page (i.e., amos_page) in the struct xpc_vars structure,
+	 * to this page (i.e., amos_page) in the struct xpc_vars_sn2 structure,
 	 * which is pointed to by the reserved page, and re-use that saved copy
 	 * on subsequent loads of XPC. This amo page is never freed, and its
 	 * memory protections are never restricted.
 	 */
-	amos_page = xpc_vars->amos_page;
+	amos_page = xpc_vars_sn2->amos_page;
 	if (amos_page == NULL) {
 		amos_page = (struct amo *)TO_AMO(uncached_alloc_page(0, 1));
 		if (amos_page == NULL) {
@@ -621,18 +624,18 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_p
 		}
 	}
 
-	/* clear xpc_vars */
-	memset(xpc_vars, 0, sizeof(struct xpc_vars_sn2));
+	/* clear xpc_vars_sn2 */
+	memset(xpc_vars_sn2, 0, sizeof(struct xpc_vars_sn2));
 
-	xpc_vars->version = XPC_V_VERSION;
-	xpc_vars->activate_IRQ_nasid = cpuid_to_nasid(0);
-	xpc_vars->activate_IRQ_phys_cpuid = cpu_physical_id(0);
-	xpc_vars->vars_part_pa = __pa(xpc_vars_part);
-	xpc_vars->amos_page_pa = ia64_tpa((u64)amos_page);
-	xpc_vars->amos_page = amos_page;	/* save for next load of XPC */
+	xpc_vars_sn2->version = XPC_V_VERSION;
+	xpc_vars_sn2->activate_IRQ_nasid = cpuid_to_nasid(0);
+	xpc_vars_sn2->activate_IRQ_phys_cpuid = cpu_physical_id(0);
+	xpc_vars_sn2->vars_part_pa = __pa(xpc_vars_part_sn2);
+	xpc_vars_sn2->amos_page_pa = ia64_tpa((u64)amos_page);
+	xpc_vars_sn2->amos_page = amos_page;	/* save for next load of XPC */
 
-	/* clear xpc_vars_part */
-	memset((u64 *)xpc_vars_part, 0, sizeof(struct xpc_vars_part_sn2) *
+	/* clear xpc_vars_part_sn2 */
+	memset((u64 *)xpc_vars_part_sn2, 0, sizeof(struct xpc_vars_part_sn2) *
 	       xp_max_npartitions);
 
 	/* initialize the activate IRQ related amo variables */
@@ -649,30 +652,30 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_p
 static void
 xpc_increment_heartbeat_sn2(void)
 {
-	xpc_vars->heartbeat++;
+	xpc_vars_sn2->heartbeat++;
 }
 
 static void
 xpc_offline_heartbeat_sn2(void)
 {
 	xpc_increment_heartbeat_sn2();
-	xpc_vars->heartbeat_offline = 1;
+	xpc_vars_sn2->heartbeat_offline = 1;
 }
 
 static void
 xpc_online_heartbeat_sn2(void)
 {
 	xpc_increment_heartbeat_sn2();
-	xpc_vars->heartbeat_offline = 0;
+	xpc_vars_sn2->heartbeat_offline = 0;
 }
 
 static void
 xpc_heartbeat_init_sn2(void)
 {
-	DBUG_ON(xpc_vars == NULL);
+	DBUG_ON(xpc_vars_sn2 == NULL);
 
-	bitmap_zero(xpc_vars->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
-	xpc_heartbeating_to_mask = &xpc_vars->heartbeating_to_mask[0];
+	bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
+	xpc_heartbeating_to_mask = &xpc_vars_sn2->heartbeating_to_mask[0];
 	xpc_online_heartbeat_sn2();
 }
 
@@ -845,7 +848,8 @@ xpc_cancel_partition_deactivation_reques
 static int
 xpc_partition_deactivation_requested_sn2(short partid)
 {
-	struct amo *amo = xpc_vars->amos_page + XPC_DEACTIVATE_REQUEST_AMO_SN2;
+	struct amo *amo = xpc_vars_sn2->amos_page +
+			  XPC_DEACTIVATE_REQUEST_AMO_SN2;
 
 	/* our partition's amo variable ANDed with partid mask */
 	return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
@@ -1033,7 +1037,7 @@ xpc_identify_activate_IRQ_sender_sn2(voi
 	int n_IRQs_detected = 0;
 	struct amo *act_amos;
 
-	act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS_SN2;
+	act_amos = xpc_vars_sn2->amos_page + XPC_ACTIVATE_IRQ_AMOS_SN2;
 
 	/* scan through act amo variable looking for non-zero entries */
 	for (word = 0; word < xpc_nasid_mask_words; word++) {
@@ -1261,15 +1265,17 @@ xpc_setup_infrastructure_sn2(struct xpc_
 	 * The setting of the magic # indicates that these per partition
 	 * specific variables are ready to be used.
 	 */
-	xpc_vars_part[partid].GPs_pa = __pa(part_sn2->local_GPs);
-	xpc_vars_part[partid].openclose_args_pa =
+	xpc_vars_part_sn2[partid].GPs_pa = __pa(part_sn2->local_GPs);
+	xpc_vars_part_sn2[partid].openclose_args_pa =
 	    __pa(part->local_openclose_args);
-	xpc_vars_part[partid].chctl_amo_pa = __pa(part_sn2->local_chctl_amo_va);
+	xpc_vars_part_sn2[partid].chctl_amo_pa =
+	    __pa(part_sn2->local_chctl_amo_va);
 	cpuid = raw_smp_processor_id();	/* any CPU in this partition will do */
-	xpc_vars_part[partid].notify_IRQ_nasid = cpuid_to_nasid(cpuid);
-	xpc_vars_part[partid].notify_IRQ_phys_cpuid = cpu_physical_id(cpuid);
-	xpc_vars_part[partid].nchannels = part->nchannels;
-	xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
+	xpc_vars_part_sn2[partid].notify_IRQ_nasid = cpuid_to_nasid(cpuid);
+	xpc_vars_part_sn2[partid].notify_IRQ_phys_cpuid =
+	    cpu_physical_id(cpuid);
+	xpc_vars_part_sn2[partid].nchannels = part->nchannels;
+	xpc_vars_part_sn2[partid].magic = XPC_VP_MAGIC1;
 
 	return xpSuccess;
 
@@ -1316,7 +1322,7 @@ xpc_teardown_infrastructure_sn2(struct x
 	DBUG_ON(part->setup_state != XPC_P_SETUP);
 	part->setup_state = XPC_P_WTEARDOWN;
 
-	xpc_vars_part[partid].magic = 0;
+	xpc_vars_part_sn2[partid].magic = 0;
 
 	free_irq(SGI_XPC_NOTIFY, (void *)(u64)partid);
 
@@ -1432,7 +1438,7 @@ xpc_pull_remote_vars_part_sn2(struct xpc
 		return xpRetry;
 	}
 
-	if (xpc_vars_part[partid].magic == XPC_VP_MAGIC1) {
+	if (xpc_vars_part_sn2[partid].magic == XPC_VP_MAGIC1) {
 
 		/* validate the variables */
 
@@ -1462,7 +1468,7 @@ xpc_pull_remote_vars_part_sn2(struct xpc
 
 		/* let the other side know that we've pulled their variables */
 
-		xpc_vars_part[partid].magic = XPC_VP_MAGIC2;
+		xpc_vars_part_sn2[partid].magic = XPC_VP_MAGIC2;
 	}
 
 	if (pulled_entry->magic == XPC_VP_MAGIC1)