Skip to contentSkip to conversation

sgi-xp: add support for UV systems

PATCH New Dean Nelson 1 participant 7 messages Jul 7, 2008 Char and misc drivers

lore
Share & tools
lore
#0 lore raw

cover sgi-xp: add support for UV systems

This patchset adds most of the necessary code to support XPC/XPNET on a SGI UV system, and as such is still under development. It compiles cleanly as is on both x86_64 and IA64. And if brought up on anything but ia64-sn2 will return an -ENODEV.

This patchset depends on the GRU driver which has recently been submitted.
http://marc.info/?l=linux-kernel&m=121512107123657&w=2

#1 lore raw

PATCH 1/6 sgi-xp: enable building of XPC/XPNET on x86_64

Get XPC/XPNET to build on x86_64. Trying to modprobe them up on a non-UV or sn2 system will result in a -ENODEV.

---

 drivers/misc/Kconfig                |    2 -
 drivers/misc/sgi-xp/Makefile        |   14 ++++++---
 drivers/misc/sgi-xp/xp.h            |   32 +++++++++++++-------
 drivers/misc/sgi-xp/xp_main.c       |   10 +++++-
 drivers/misc/sgi-xp/xp_sn2.c        |   10 ++++++
 drivers/misc/sgi-xp/xpc.h           |   34 +++++++++-------------
 drivers/misc/sgi-xp/xpc_channel.c   |   18 +++--------
 drivers/misc/sgi-xp/xpc_main.c      |   49 ++++++++++++++++----------------
 drivers/misc/sgi-xp/xpc_partition.c |   47 +++++++++++++-----------------
 drivers/misc/sgi-xp/xpc_sn2.c       |   30 ++++++++++++++++---
 drivers/misc/sgi-xp/xpc_uv.c        |    7 +---
 drivers/misc/sgi-xp/xpnet.c         |   28 +++++++-----------
 12 files changed, 155 insertions(+), 126 deletions(-)
drivers/misc/Kconfig +1 -1
Index: linux/drivers/misc/Kconfig
===================================================================
@@ -381,7 +381,7 @@ config ENCLOSURE_SERVICES
 
 config SGI_XP
 	tristate "Support communication between SGI SSIs"
-	depends on IA64_GENERIC || IA64_SGI_SN2
+	depends on IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || (X86_64 && SMP)
 	select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
 	select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
 	---help---
drivers/misc/sgi-xp/xp.h +21 -11
Index: linux/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -13,18 +13,17 @@
 #ifndef _DRIVERS_MISC_SGIXP_XP_H
 #define _DRIVERS_MISC_SGIXP_XP_H
 
-#include <linux/cache.h>
-#include <linux/hardirq.h>
 #include <linux/mutex.h>
-#include <asm/sn/types.h>
+
 #ifdef CONFIG_IA64
-#include <asm/sn/arch.h>
+#include <asm/system.h>
+#include <asm/sn/arch.h>	/* defines is_shub1() and is_shub2() */
+#define is_shub()	ia64_platform_is("sn2")
+#define is_uv()		ia64_platform_is("uv")
 #endif
-
-#ifdef USE_DBUG_ON
-#define DBUG_ON(condition)	BUG_ON(condition)
-#else
-#define DBUG_ON(condition)
+#ifdef CONFIG_X86_64
+#include <asm/genapic.h>
+#define is_uv()		is_uv_system()
 #endif
 
 #ifndef is_shub1
@@ -36,13 +35,19 @@
 #endif
 
 #ifndef is_shub
-#define is_shub()	(is_shub1() || is_shub2())
+#define is_shub()	0
 #endif
 
 #ifndef is_uv
 #define is_uv()		0
 #endif
 
+#ifdef USE_DBUG_ON
+#define DBUG_ON(condition)	BUG_ON(condition)
+#else
+#define DBUG_ON(condition)
+#endif
+
 /*
  * Define the maximum number of partitions the system can possibly support.
  * It is based on the maximum number of hardware partitionable regions. The
@@ -200,7 +205,9 @@ enum xp_retval {
 	xpPayloadTooBig,	/* 55: payload too large for message slot */
 
 	xpUnsupported,		/* 56: unsupported functionality or resource */
-	xpUnknownReason		/* 57: unknown reason - must be last in enum */
+	xpNeedMoreInfo,		/* 57: more info is needed by SAL */
+
+	xpUnknownReason		/* 58: unknown reason - must be last in enum */
 };
 
 /*
@@ -339,8 +346,11 @@ xpc_partid_to_nasids(short partid, void 
 }
 
 extern short xp_max_npartitions;
+extern short xp_partition_id;
+extern u8 xp_region_size;
 
 extern enum xp_retval (*xp_remote_memcpy) (void *, const void *, size_t);
+extern int (*xp_cpu_to_nasid) (int);
 
 extern u64 xp_nofault_PIOR_target;
 extern int xp_nofault_PIOR(void *);
drivers/misc/sgi-xp/xpc_main.c +25 -24

108 lines not on this page · raw message

drivers/misc/sgi-xp/xpc.h +15 -19
Index: linux/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -13,17 +13,10 @@
 #ifndef _DRIVERS_MISC_SGIXP_XPC_H
 #define _DRIVERS_MISC_SGIXP_XPC_H
 
-#include <linux/interrupt.h>
-#include <linux/sysctl.h>
-#include <linux/device.h>
-#include <linux/mutex.h>
+#include <linux/wait.h>
 #include <linux/completion.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/mspec.h>
-#include <asm/sn/shub_mmr.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
 #include "xp.h"
 
 /*
@@ -179,7 +172,8 @@ struct xpc_vars_part_sn2 {
 #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_sn2))
 
-#define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE))
+#define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
+				 XPC_RP_HEADER_SIZE))
 #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
 				 xpc_nasid_mask_nlongs)
 #define XPC_RP_VARS(_rp)	((struct xpc_vars_sn2 *) \
@@ -202,13 +196,13 @@ struct xpc_vars_part_sn2 {
 /*
  * Define a Get/Put value pair (pointers) used with a message queue.
  */
-struct xpc_gp {
+struct xpc_gp_sn2 {
 	s64 get;		/* Get value */
 	s64 put;		/* Put value */
 };
 
 #define XPC_GP_SIZE \
-		L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_MAX_NCHANNELS)
+		L1_CACHE_ALIGN(sizeof(struct xpc_gp_sn2) * XPC_MAX_NCHANNELS)
 
 /*
  * Define a structure that contains arguments associated with opening and
@@ -340,10 +334,10 @@ 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 */
+	struct xpc_gp_sn2 *local_GP;	/* local Get/Put values */
+	struct xpc_gp_sn2 remote_GP;	/* remote Get/Put values */
+	struct xpc_gp_sn2 w_local_GP;	/* working local Get/Put values */
+	struct xpc_gp_sn2 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 */
@@ -506,9 +500,9 @@ struct xpc_partition_sn2 {
 	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 */
+	struct xpc_gp_sn2 *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 */
+	struct xpc_gp_sn2 *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 */
@@ -629,6 +623,8 @@ 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_get_partition_rsvd_page_pa) (u64, u64 *, u64 *,
+							 size_t *);
 extern enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *);
 extern void (*xpc_heartbeat_init) (void);
 extern void (*xpc_heartbeat_exit) (void);
drivers/misc/sgi-xp/xpc_sn2.c +25 -5
Index: linux/drivers/misc/sgi-xp/xpc_sn2.c
===================================================================
@@ -13,9 +13,9 @@
  *
  */
 
-#include <linux/kernel.h>
 #include <linux/delay.h>
 #include <asm/uncached.h>
+#include <asm/sn/mspec.h>
 #include <asm/sn/sn_sal.h>
 #include "xpc.h"
 
@@ -176,7 +176,7 @@ xpc_send_IRQ_sn2(struct amo *amo, u64 fl
 
 	local_irq_restore(irq_flags);
 
-	return ((ret == 0) ? xpSuccess : xpPioReadError);
+	return (ret == 0) ? xpSuccess : xpPioReadError;
 }
 
 static struct amo *
@@ -284,7 +284,7 @@ xpc_handle_notify_IRQ_sn2(int irq, void 
 	short partid = (short)(u64)dev_id;
 	struct xpc_partition *part = &xpc_partitions[partid];
 
-	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
+	DBUG_ON(partid < 0 || partid >= XP_MAX_NPARTITIONS_SN2);
 
 	if (xpc_part_ref(part)) {
 		xpc_check_for_sent_chctl_flags_sn2(part);
@@ -577,6 +577,25 @@ xpc_allow_amo_ops_shub_wars_1_1_sn2(void
 }
 
 static enum xp_retval
+xpc_get_partition_rsvd_page_pa_sn2(u64 buf, u64 *cookie, u64 *paddr,
+				   size_t *len)
+{
+	s64 status;
+	enum xp_retval ret;
+
+	status = sn_partition_reserved_page_pa(buf, cookie, paddr, len);
+	if (status == SALRET_OK)
+		ret = xpSuccess;
+	else if (status == SALRET_MORE_PASSES)
+		ret = xpNeedMoreInfo;
+	else
+		ret = xpSalError;
+
+	return ret;
+}
+
+
+static enum xp_retval
 xpc_rsvd_page_init_sn2(struct xpc_rsvd_page *rp)
 {
 	struct amo *amos_page;
@@ -636,7 +655,7 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_p
 
 	/* clear xpc_vars_part_sn2 */
 	memset((u64 *)xpc_vars_part_sn2, 0, sizeof(struct xpc_vars_part_sn2) *
-	       xp_max_npartitions);
+	       XP_MAX_NPARTITIONS_SN2);
 
 	/* initialize the activate IRQ related amo variables */
 	for (i = 0; i < xpc_nasid_mask_nlongs; i++)
@@ -699,7 +718,7 @@ xpc_check_remote_hb_sn2(void)
 
 	remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2;
 
-	for (partid = 0; partid < xp_max_npartitions; partid++) {
+	for (partid = 0; partid < XP_MAX_NPARTITIONS_SN2; partid++) {
 
 		if (xpc_exiting)
 			break;
@@ -2386,6 +2405,7 @@ xpc_init_sn2(void)
 	int ret;
 	size_t buf_size;
 
+	xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2;
 	xpc_rsvd_page_init = xpc_rsvd_page_init_sn2;
 	xpc_increment_heartbeat = xpc_increment_heartbeat_sn2;
 	xpc_offline_heartbeat = xpc_offline_heartbeat_sn2;
drivers/misc/sgi-xp/xp_main.c +9 -1
Index: linux/drivers/misc/sgi-xp/xp_main.c
===================================================================
@@ -14,7 +14,6 @@
  *
  */
 
-#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include "xp.h"
@@ -36,9 +35,18 @@ struct device *xp = &xp_dbg_subname;
 short xp_max_npartitions;
 EXPORT_SYMBOL_GPL(xp_max_npartitions);
 
+short xp_partition_id;
+EXPORT_SYMBOL_GPL(xp_partition_id);
+
+u8 xp_region_size;
+EXPORT_SYMBOL_GPL(xp_region_size);
+
 enum xp_retval (*xp_remote_memcpy) (void *dst, const void *src, size_t len);
 EXPORT_SYMBOL_GPL(xp_remote_memcpy);
 
+int (*xp_cpu_to_nasid) (int cpuid);
+EXPORT_SYMBOL_GPL(xp_cpu_to_nasid);
+
 /*
  * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
  * users of XPC.
drivers/misc/sgi-xp/xpc_channel.c +6 -12
Index: linux/drivers/misc/sgi-xp/xpc_channel.c
===================================================================
@@ -14,14 +14,7 @@
  *
  */
 
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/cache.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/completion.h>
-#include <asm/sn/sn_sal.h>
+#include <linux/device.h>
 #include "xpc.h"
 
 /*
@@ -373,8 +366,9 @@ again:
 		dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY (local_msgqueue_pa="
 			"0x%lx, local_nentries=%d, remote_nentries=%d) "
 			"received from partid=%d, channel=%d\n",
-			args->local_msgqueue_pa, args->local_nentries,
-			args->remote_nentries, ch->partid, ch->number);
+			(unsigned long)args->local_msgqueue_pa,
+			args->local_nentries, args->remote_nentries,
+			ch->partid, ch->number);
 
 		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
 			spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -940,7 +934,7 @@ xpc_deliver_msg(struct xpc_channel *ch)
 		if (ch->func != NULL) {
 			dev_dbg(xpc_chan, "ch->func() called, msg=0x%p, "
 				"msg_number=%ld, partid=%d, channel=%d\n",
-				(void *)msg, msg->number, ch->partid,
+				msg, (signed long)msg->number, ch->partid,
 				ch->number);
 
 			/* deliver the message to its intended recipient */
@@ -949,7 +943,7 @@ xpc_deliver_msg(struct xpc_channel *ch)
 
 			dev_dbg(xpc_chan, "ch->func() returned, msg=0x%p, "
 				"msg_number=%ld, partid=%d, channel=%d\n",
-				(void *)msg, msg->number, ch->partid,
+				msg, (signed long)msg->number, ch->partid,
 				ch->number);
 		}
 
drivers/misc/sgi-xp/xpc_partition.c +20 -27

116 lines not on this page · raw message

drivers/misc/sgi-xp/xp_sn2.c +10 -0
Index: linux/drivers/misc/sgi-xp/xp_sn2.c
===================================================================
@@ -12,6 +12,7 @@
  *      Architecture specific implementation of common functions.
  */
 
+#include <linux/module.h>
 #include <linux/device.h>
 #include <asm/sn/bte.h>
 #include <asm/sn/sn_sal.h>
@@ -116,14 +117,23 @@ xp_remote_memcpy_sn2(void *vdst, const v
 	return xpBteCopyError;
 }
 
+static int
+xp_cpu_to_nasid_sn2(int cpuid)
+{
+	return cpuid_to_nasid(cpuid);
+}
+
 enum xp_retval
 xp_init_sn2(void)
 {
 	BUG_ON(!is_shub());
 
 	xp_max_npartitions = XP_MAX_NPARTITIONS_SN2;
+	xp_partition_id = sn_partition_id;
+	xp_region_size = sn_region_size;
 
 	xp_remote_memcpy = xp_remote_memcpy_sn2;
+	xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
 
 	return xp_register_nofault_code_sn2();
 }
drivers/misc/sgi-xp/xpnet.c +11 -17
Index: linux/drivers/misc/sgi-xp/xpnet.c
===================================================================
@@ -21,17 +21,8 @@
  */
 
 #include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/delay.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/smp.h>
-#include <linux/string.h>
-#include <asm/atomic.h>
 #include "xp.h"
 
 /*
@@ -175,8 +166,9 @@ xpnet_receive(short partid, int channel,
 
 		return;
 	}
-	dev_dbg(xpnet, "received 0x%lx, %d, %d, %d\n", msg->buf_pa, msg->size,
-		msg->leadin_ignore, msg->tailout_ignore);
+	dev_dbg(xpnet, "received 0x%lx, %d, %d, %d\n",
+		(unsigned long)msg->buf_pa, msg->size, msg->leadin_ignore,
+		msg->tailout_ignore);
 
 	/* reserve an extra cache line */
 	skb = dev_alloc_skb(msg->size + L1_CACHE_BYTES);
@@ -320,8 +312,10 @@ xpnet_dev_open(struct net_device *dev)
 
 	dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, "
 		"%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
-		XPNET_MSG_SIZE, XPNET_MSG_NENTRIES, XPNET_MAX_KTHREADS,
-		XPNET_MAX_IDLE_KTHREADS);
+		(unsigned long)XPNET_MSG_SIZE,
+		(unsigned long)XPNET_MSG_NENTRIES,
+		(unsigned long)XPNET_MAX_KTHREADS,
+		(unsigned long)XPNET_MAX_IDLE_KTHREADS);
 
 	ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL,
 			  XPNET_MSG_SIZE, XPNET_MSG_NENTRIES,
@@ -439,8 +433,8 @@ xpnet_send(struct sk_buff *skb, struct x
 	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);
+		dest_partid, XPC_NET_CHANNEL, (unsigned long)msg->buf_pa,
+		msg->size, msg->leadin_ignore, msg->tailout_ignore);
 
 	atomic_inc(&queued_msg->use_count);
 
@@ -602,8 +596,8 @@ xpnet_init(void)
 	 */
 	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);
+	xpnet_device->dev_addr[XPNET_PARTID_OCTET + 1] = xp_partition_id;
+	xpnet_device->dev_addr[XPNET_PARTID_OCTET + 0] = (xp_partition_id >> 8);
 
 	/*
 	 * ether_setup() sets this to a multicast device.  We are
drivers/misc/sgi-xp/xpc_uv.c +2 -5
Index: linux/drivers/misc/sgi-xp/xpc_uv.c
===================================================================
@@ -14,11 +14,8 @@
  */
 
 #include <linux/kernel.h>
-
-/* !!! #include <gru/grukservices.h> */
-/* !!! uv_gpa() is defined in <gru/grukservices.h> */
-#define uv_gpa(_a)		((unsigned long)_a)
-
+#include <asm/uv/uv_hub.h>
+#include "../sgi-gru/grukservices.h"
 #include "xpc.h"
 
 static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
drivers/misc/sgi-xp/Makefile +10 -4
Index: linux/drivers/misc/sgi-xp/Makefile
===================================================================
@@ -3,11 +3,17 @@
 #
 
 obj-$(CONFIG_SGI_XP)		+= xp.o
-xp-y				:= xp_main.o xp_uv.o
-xp-$(CONFIG_IA64)		+= xp_sn2.o xp_nofault.o
+xp-y				:= xp_main.o
+xp-$(CONFIG_IA64_SGI_SN2)	+= xp_sn2.o xp_nofault.o
+xp-$(CONFIG_IA64_GENERIC)	+= xp_sn2.o xp_nofault.o xp_uv.o
+xp-$(CONFIG_IA64_SGI_UV)	+= xp_uv.o
+xp-$(CONFIG_X86_64)		+= xp_uv.o
 
 obj-$(CONFIG_SGI_XP)		+= xpc.o
-xpc-y				:= xpc_main.o xpc_uv.o xpc_channel.o xpc_partition.o
-xpc-$(CONFIG_IA64)		+= xpc_sn2.o
+xpc-y				:= xpc_main.o xpc_channel.o xpc_partition.o
+xpc-$(CONFIG_IA64_SGI_SN2)	+= xpc_sn2.o
+xpc-$(CONFIG_IA64_GENERIC)	+= xpc_sn2.o xpc_uv.o
+xpc-$(CONFIG_IA64_SGI_UV) 	+= xpc_uv.o
+xpc-$(CONFIG_X86_64)		+= xpc_uv.o
 
 obj-$(CONFIG_SGI_XP)		+= xpnet.o
#2 lore raw

PATCH 2/6 sgi-xp: add usage of GRU driver by xpc_remote_memcpy()

In reply to Dean Nelson

Add UV support to xpc_remote_memcpy(), which involves interfacing to the GRU driver.

---

 drivers/misc/sgi-xp/xp.h            |    8 ++-
 drivers/misc/sgi-xp/xp_main.c       |    6 ++
 drivers/misc/sgi-xp/xp_sn2.c        |   50 +++++++++++------------
 drivers/misc/sgi-xp/xp_uv.c         |   27 +++++++++++-
 drivers/misc/sgi-xp/xpc.h           |   44 ++++++++++----------
 drivers/misc/sgi-xp/xpc_channel.c   |    5 --
 drivers/misc/sgi-xp/xpc_main.c      |    8 ++-
 drivers/misc/sgi-xp/xpc_partition.c |   37 ++++++++---------
 drivers/misc/sgi-xp/xpc_sn2.c       |   68 ++++++++++++++++----------------
 drivers/misc/sgi-xp/xpc_uv.c        |    2 
 drivers/misc/sgi-xp/xpnet.c         |   26 +++++-------
 11 files changed, 154 insertions(+), 127 deletions(-)
drivers/misc/sgi-xp/xp.h +6 -2
Index: linux/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -207,7 +207,9 @@ enum xp_retval {
 	xpUnsupported,		/* 56: unsupported functionality or resource */
 	xpNeedMoreInfo,		/* 57: more info is needed by SAL */
 
-	xpUnknownReason		/* 58: unknown reason - must be last in enum */
+	xpGruCopyError,		/* 58: gru_copy_gru() returned error */
+
+	xpUnknownReason		/* 59: unknown reason - must be last in enum */
 };
 
 /*
@@ -349,7 +351,9 @@ extern short xp_max_npartitions;
 extern short xp_partition_id;
 extern u8 xp_region_size;
 
-extern enum xp_retval (*xp_remote_memcpy) (void *, const void *, size_t);
+extern unsigned long (*xp_pa) (void *);
+extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
+		       size_t);
 extern int (*xp_cpu_to_nasid) (int);
 
 extern u64 xp_nofault_PIOR_target;
drivers/misc/sgi-xp/xp_main.c +5 -1
Index: linux/drivers/misc/sgi-xp/xp_main.c
===================================================================
@@ -41,7 +41,11 @@ EXPORT_SYMBOL_GPL(xp_partition_id);
 u8 xp_region_size;
 EXPORT_SYMBOL_GPL(xp_region_size);
 
-enum xp_retval (*xp_remote_memcpy) (void *dst, const void *src, size_t len);
+unsigned long (*xp_pa) (void *addr);
+EXPORT_SYMBOL_GPL(xp_pa);
+
+enum xp_retval (*xp_remote_memcpy) (unsigned long dst_gpa,
+				    const unsigned long src_gpa, size_t len);
 EXPORT_SYMBOL_GPL(xp_remote_memcpy);
 
 int (*xp_cpu_to_nasid) (int cpuid);
drivers/misc/sgi-xp/xp_sn2.c +24 -26

81 lines not on this page · raw message

drivers/misc/sgi-xp/xp_uv.c +24 -3
Index: linux/drivers/misc/sgi-xp/xp_uv.c
===================================================================
@@ -13,13 +13,33 @@
  *
  */
 
+#include <linux/device.h>
+#include <asm/uv/uv_hub.h>
+#include "../sgi-gru/grukservices.h"
 #include "xp.h"
 
+/*
+ * Convert a virtual memory address to a physical memory address.
+ */
+static unsigned long
+xp_pa_uv(void *addr)
+{
+	return uv_gpa(addr);
+}
+
 static enum xp_retval
-xp_remote_memcpy_uv(void *vdst, const void *psrc, size_t len)
+xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
+		    size_t len)
 {
-	/* !!! this function needs fleshing out */
-	return xpUnsupported;
+	int ret;
+
+	ret = gru_copy_gpa(dst_gpa, src_gpa, len);
+	if (ret == 0)
+		return xpSuccess;
+
+	dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
+		"len=%ld\n", dst_gpa, src_gpa, len);
+	return xpGruCopyError;
 }
 
 enum xp_retval
@@ -29,6 +49,7 @@ xp_init_uv(void)
 
 	xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
 
+	xp_pa = xp_pa_uv;
 	xp_remote_memcpy = xp_remote_memcpy_uv;
 
 	return xpSuccess;
drivers/misc/sgi-xp/xpc_partition.c +17 -20
Index: linux/drivers/misc/sgi-xp/xpc_partition.c
===================================================================
@@ -60,15 +60,15 @@ xpc_kmalloc_cacheline_aligned(size_t siz
  * Given a nasid, get the physical address of the  partition's reserved page
  * for that nasid. This function returns 0 on any error.
  */
-static u64
+static unsigned long
 xpc_get_rsvd_page_pa(int nasid)
 {
 	enum xp_retval ret;
 	u64 cookie = 0;
-	u64 rp_pa = nasid;	/* seed with nasid */
+	unsigned long rp_pa = nasid;	/* seed with nasid */
 	size_t len = 0;
-	u64 buf = buf;
-	u64 buf_len = 0;
+	size_t buf_len = 0;
+	void *buf = buf;
 	void *buf_base = NULL;
 
 	while (1) {
@@ -78,7 +78,7 @@ xpc_get_rsvd_page_pa(int nasid)
 
 		dev_dbg(xpc_part, "SAL returned with ret=%d, cookie=0x%016lx, "
 			"address=0x%016lx, len=0x%016lx\n", ret,
-			(unsigned long)cookie, (unsigned long)rp_pa, len);
+			(unsigned long)cookie, rp_pa, len);
 
 		if (ret != xpNeedMoreInfo)
 			break;
@@ -87,19 +87,17 @@ xpc_get_rsvd_page_pa(int nasid)
 		if (L1_CACHE_ALIGN(len) > buf_len) {
 			kfree(buf_base);
 			buf_len = L1_CACHE_ALIGN(len);
-			buf = (u64)xpc_kmalloc_cacheline_aligned(buf_len,
-								 GFP_KERNEL,
-								 &buf_base);
+			buf = xpc_kmalloc_cacheline_aligned(buf_len, GFP_KERNEL,
+							    &buf_base);
 			if (buf_base == NULL) {
 				dev_err(xpc_part, "unable to kmalloc "
-					"len=0x%016lx\n",
-					(unsigned long)buf_len);
+					"len=0x%016lx\n", buf_len);
 				ret = xpNoMemory;
 				break;
 			}
 		}
 
-		ret = xp_remote_memcpy((void *)buf, (void *)rp_pa, buf_len);
+		ret = xp_remote_memcpy(xp_pa(buf), rp_pa, buf_len);
 		if (ret != xpSuccess) {
 			dev_dbg(xpc_part, "xp_remote_memcpy failed %d\n", ret);
 			break;
@@ -111,8 +109,7 @@ xpc_get_rsvd_page_pa(int nasid)
 	if (ret != xpSuccess)
 		rp_pa = 0;
 
-	dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n",
-		(unsigned long)rp_pa);
+	dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n", rp_pa);
 	return rp_pa;
 }
 
@@ -125,7 +122,7 @@ struct xpc_rsvd_page *
 xpc_setup_rsvd_page(void)
 {
 	struct xpc_rsvd_page *rp;
-	u64 rp_pa;
+	unsigned long rp_pa;
 	unsigned long new_ts_jiffies;
 
 	/* get the local reserved page's address */
@@ -193,7 +190,7 @@ xpc_setup_rsvd_page(void)
  */
 enum xp_retval
 xpc_get_remote_rp(int nasid, unsigned long *discovered_nasids,
-		  struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
+		  struct xpc_rsvd_page *remote_rp, unsigned long *remote_rp_pa)
 {
 	int l;
 	enum xp_retval ret;
@@ -205,7 +202,7 @@ xpc_get_remote_rp(int nasid, unsigned lo
 		return xpNoRsvdPageAddr;
 
 	/* pull over the reserved page header and part_nasids mask */
-	ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa,
+	ret = xp_remote_memcpy(xp_pa(remote_rp), *remote_rp_pa,
 			       XPC_RP_HEADER_SIZE + xpc_nasid_mask_nbytes);
 	if (ret != xpSuccess)
 		return ret;
@@ -389,7 +386,7 @@ xpc_discovery(void)
 {
 	void *remote_rp_base;
 	struct xpc_rsvd_page *remote_rp;
-	u64 remote_rp_pa;
+	unsigned long remote_rp_pa;
 	int region;
 	int region_size;
 	int max_regions;
@@ -500,7 +497,7 @@ enum xp_retval
 xpc_initiate_partid_to_nasids(short partid, void *nasid_mask)
 {
 	struct xpc_partition *part;
-	u64 part_nasid_pa;
+	unsigned long part_nasid_pa;
 
 	part = &xpc_partitions[partid];
 	if (part->remote_rp_pa == 0)
@@ -508,8 +505,8 @@ xpc_initiate_partid_to_nasids(short part
 
 	memset(nasid_mask, 0, xpc_nasid_mask_nbytes);
 
-	part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa);
+	part_nasid_pa = (unsigned long)XPC_RP_PART_NASIDS(part->remote_rp_pa);
 
-	return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa,
+	return xp_remote_memcpy(xp_pa(nasid_mask), part_nasid_pa,
 				xpc_nasid_mask_nbytes);
 }
drivers/misc/sgi-xp/xpc_sn2.c +36 -32

204 lines not on this page · raw message

drivers/misc/sgi-xp/xpnet.c +11 -15
Index: linux/drivers/misc/sgi-xp/xpnet.c
===================================================================
@@ -44,7 +44,7 @@ struct xpnet_message {
 	u16 version;		/* Version for this message */
 	u16 embedded_bytes;	/* #of bytes embedded in XPC message */
 	u32 magic;		/* Special number indicating this is xpnet */
-	u64 buf_pa;		/* phys address of buffer to retrieve */
+	unsigned long buf_pa;	/* phys address of buffer to retrieve */
 	u32 size;		/* #of bytes in buffer */
 	u8 leadin_ignore;	/* #of bytes to ignore at the beginning */
 	u8 tailout_ignore;	/* #of bytes to ignore at the end */
@@ -152,6 +152,7 @@ static void
 xpnet_receive(short partid, int channel, struct xpnet_message *msg)
 {
 	struct sk_buff *skb;
+	void *dst;
 	enum xp_retval ret;
 	struct xpnet_dev_private *priv =
 	    (struct xpnet_dev_private *)xpnet_device->priv;
@@ -166,9 +167,8 @@ xpnet_receive(short partid, int channel,
 
 		return;
 	}
-	dev_dbg(xpnet, "received 0x%lx, %d, %d, %d\n",
-		(unsigned long)msg->buf_pa, msg->size, msg->leadin_ignore,
-		msg->tailout_ignore);
+	dev_dbg(xpnet, "received 0x%lx, %d, %d, %d\n", msg->buf_pa, msg->size,
+		msg->leadin_ignore, msg->tailout_ignore);
 
 	/* reserve an extra cache line */
 	skb = dev_alloc_skb(msg->size + L1_CACHE_BYTES);
@@ -210,15 +210,12 @@ xpnet_receive(short partid, int channel,
 		skb_copy_to_linear_data(skb, &msg->data,
 					(size_t)msg->embedded_bytes);
 	} else {
+		dst = (void *)((u64)skb->data & ~(L1_CACHE_BYTES - 1));
 		dev_dbg(xpnet, "transferring buffer to the skb->data area;\n\t"
-			"xp_remote_memcpy(0x%p, 0x%p, %hu)\n", (void *)
-				       ((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
+			"xp_remote_memcpy(0x%p, 0x%p, %hu)\n", dst,
 					  (void *)msg->buf_pa, msg->size);
 
-		ret = xp_remote_memcpy((void *)((u64)skb->data &
-						~(L1_CACHE_BYTES - 1)),
-				       (void *)msg->buf_pa, msg->size);
-
+		ret = xp_remote_memcpy(xp_pa(dst), msg->buf_pa, msg->size);
 		if (ret != xpSuccess) {
 			/*
 			 * !!! Need better way of cleaning skb.  Currently skb
@@ -226,8 +223,7 @@ xpnet_receive(short partid, int channel,
 			 * !!! dev_kfree_skb.
 			 */
 			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)),
+				"returned error=0x%x\n", dst,
 				(void *)msg->buf_pa, msg->size, ret);
 
 			xpc_received(partid, channel, (void *)msg);
@@ -428,13 +424,13 @@ xpnet_send(struct sk_buff *skb, struct x
 	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);
+	msg->buf_pa = xp_pa((void *)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, (unsigned long)msg->buf_pa,
-		msg->size, msg->leadin_ignore, msg->tailout_ignore);
+		dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size,
+		msg->leadin_ignore, msg->tailout_ignore);
 
 	atomic_inc(&queued_msg->use_count);
 
drivers/misc/sgi-xp/xpc.h +23 -21

115 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_main.c +5 -3
Index: linux/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -169,8 +169,9 @@ static struct notifier_block xpc_die_not
 	.notifier_call = xpc_system_die,
 };
 
-enum xp_retval (*xpc_get_partition_rsvd_page_pa) (u64 buf, u64 *cookie,
-						  u64 *paddr, size_t *len);
+enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie,
+						  unsigned long *rp_pa,
+						  size_t *len);
 enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *rp);
 void (*xpc_heartbeat_init) (void);
 void (*xpc_heartbeat_exit) (void);
@@ -189,7 +190,8 @@ int (*xpc_n_of_deliverable_msgs) (struct
 struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *ch);
 
 void (*xpc_request_partition_activation) (struct xpc_rsvd_page *remote_rp,
-					  u64 remote_rp_pa, int nasid);
+					  unsigned long remote_rp_pa,
+					  int nasid);
 void (*xpc_request_partition_reactivation) (struct xpc_partition *part);
 void (*xpc_request_partition_deactivation) (struct xpc_partition *part);
 void (*xpc_cancel_partition_deactivation_request) (struct xpc_partition *part);
drivers/misc/sgi-xp/xpc_uv.c +1 -1
Index: linux/drivers/misc/sgi-xp/xpc_uv.c
===================================================================
@@ -61,7 +61,7 @@ xpc_heartbeat_exit_uv(void)
 
 static void
 xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
-				    u64 remote_rp_pa, int nasid)
+				    unsigned long remote_rp_pa, int nasid)
 {
 	short partid = remote_rp->SAL_partid;
 	struct xpc_partition *part = &xpc_partitions[partid];
drivers/misc/sgi-xp/xpc_channel.c +2 -3
Index: linux/drivers/misc/sgi-xp/xpc_channel.c
===================================================================
@@ -366,9 +366,8 @@ again:
 		dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY (local_msgqueue_pa="
 			"0x%lx, local_nentries=%d, remote_nentries=%d) "
 			"received from partid=%d, channel=%d\n",
-			(unsigned long)args->local_msgqueue_pa,
-			args->local_nentries, args->remote_nentries,
-			ch->partid, ch->number);
+			args->local_msgqueue_pa, args->local_nentries,
+			args->remote_nentries, ch->partid, ch->number);
 
 		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
 			spin_unlock_irqrestore(&ch->lock, irq_flags);
#3 lore raw

PATCH 3/6 sgi-xp: move xpc_check_remote_hb() to support both SN2 and UV

In reply to Dean Nelson

Move xpc_check_remote_hb() so it can support both SN2 and UV.

---

 drivers/misc/sgi-xp/xpc.h      |    2 -
 drivers/misc/sgi-xp/xpc_main.c |   34 +++++++++++++++++
 drivers/misc/sgi-xp/xpc_sn2.c  |   70 ++++++++++++-------------------------
 3 files changed, 57 insertions(+), 49 deletions(-)
drivers/misc/sgi-xp/xpc.h +1 -1
Index: linux/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -632,7 +632,7 @@ 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_get_remote_heartbeat) (struct xpc_partition *);
 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 *);
drivers/misc/sgi-xp/xpc_main.c +33 -1
Index: linux/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -178,7 +178,7 @@ void (*xpc_heartbeat_exit) (void);
 void (*xpc_increment_heartbeat) (void);
 void (*xpc_offline_heartbeat) (void);
 void (*xpc_online_heartbeat) (void);
-void (*xpc_check_remote_hb) (void);
+enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *part);
 
 enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part);
 void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *ch);
@@ -270,6 +270,38 @@ xpc_stop_hb_beater(void)
 }
 
 /*
+ * At periodic intervals, scan through all active partitions and ensure
+ * their heartbeat is still active.  If not, the partition is deactivated.
+ */
+static void
+xpc_check_remote_hb(void)
+{
+	struct xpc_partition *part;
+	short partid;
+	enum xp_retval ret;
+
+	for (partid = 0; partid < xp_max_npartitions; partid++) {
+
+		if (xpc_exiting)
+			break;
+
+		if (partid == xp_partition_id)
+			continue;
+
+		part = &xpc_partitions[partid];
+
+		if (part->act_state == XPC_P_INACTIVE ||
+		    part->act_state == XPC_P_DEACTIVATING) {
+			continue;
+		}
+
+		ret = xpc_get_remote_heartbeat(part);
+		if (ret != xpSuccess)
+			XPC_DEACTIVATE_PARTITION(part, ret);
+	}
+}
+
+/*
  * This thread is responsible for nearly all of the partition
  * activation/deactivation.
  */
drivers/misc/sgi-xp/xpc_sn2.c +23 -47

91 lines not on this page · raw message

#4 lore raw

PATCH 4/6 sgi-xp: cleanup naming of partition defines

In reply to Dean Nelson

Cleanup naming of partition defines.

---

 drivers/misc/sgi-xp/xpc.h           |   22 +++++++++++-----------
 drivers/misc/sgi-xp/xpc_channel.c   |   10 +++++-----
 drivers/misc/sgi-xp/xpc_main.c      |   32 ++++++++++++++++----------------
 drivers/misc/sgi-xp/xpc_partition.c |   18 +++++++++---------
 drivers/misc/sgi-xp/xpc_sn2.c       |   20 ++++++++++----------
 5 files changed, 51 insertions(+), 51 deletions(-)
drivers/misc/sgi-xp/xpc.h +11 -11
Index: linux/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -576,21 +576,21 @@ struct xpc_partition {
 
 /* struct xpc_partition act_state values (for XPC HB) */
 
-#define	XPC_P_INACTIVE		0x00	/* partition is not active */
-#define XPC_P_ACTIVATION_REQ	0x01	/* created thread to activate */
-#define XPC_P_ACTIVATING	0x02	/* activation thread started */
-#define XPC_P_ACTIVE		0x03	/* xpc_partition_up() was called */
-#define XPC_P_DEACTIVATING	0x04	/* partition deactivation initiated */
+#define	XPC_P_AS_INACTIVE	0x00	/* partition is not active */
+#define XPC_P_AS_ACTIVATION_REQ	0x01	/* created thread to activate */
+#define XPC_P_AS_ACTIVATING	0x02	/* activation thread started */
+#define XPC_P_AS_ACTIVE		0x03	/* xpc_partition_up() was called */
+#define XPC_P_AS_DEACTIVATING	0x04	/* partition deactivation initiated */
 
 #define XPC_DEACTIVATE_PARTITION(_p, _reason) \
 			xpc_deactivate_partition(__LINE__, (_p), (_reason))
 
 /* struct xpc_partition setup_state values */
 
-#define XPC_P_UNSET		0x00	/* infrastructure was never setup */
-#define XPC_P_SETUP		0x01	/* infrastructure is setup */
-#define XPC_P_WTEARDOWN		0x02	/* waiting to teardown infrastructure */
-#define XPC_P_TORNDOWN		0x03	/* infrastructure is torndown */
+#define XPC_P_SS_UNSET		0x00	/* infrastructure was never setup */
+#define XPC_P_SS_SETUP		0x01	/* infrastructure is setup */
+#define XPC_P_SS_WTEARDOWN	0x02	/* waiting to teardown infrastructure */
+#define XPC_P_SS_TORNDOWN	0x03	/* infrastructure is torndown */
 
 /*
  * struct xpc_partition_sn2's dropped notify IRQ timer is set to wait the
@@ -787,7 +787,7 @@ xpc_part_deref(struct xpc_partition *par
 	s32 refs = atomic_dec_return(&part->references);
 
 	DBUG_ON(refs < 0);
-	if (refs == 0 && part->setup_state == XPC_P_WTEARDOWN)
+	if (refs == 0 && part->setup_state == XPC_P_SS_WTEARDOWN)
 		wake_up(&part->teardown_wq);
 }
 
@@ -797,7 +797,7 @@ xpc_part_ref(struct xpc_partition *part)
 	int setup;
 
 	atomic_inc(&part->references);
-	setup = (part->setup_state == XPC_P_SETUP);
+	setup = (part->setup_state == XPC_P_SS_SETUP);
 	if (!setup)
 		xpc_part_deref(part);
 
drivers/misc/sgi-xp/xpc_channel.c +5 -5
Index: linux/drivers/misc/sgi-xp/xpc_channel.c
===================================================================
@@ -99,7 +99,7 @@ xpc_process_disconnect(struct xpc_channe
 	DBUG_ON((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
 		!(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE));
 
-	if (part->act_state == XPC_P_DEACTIVATING) {
+	if (part->act_state == XPC_P_AS_DEACTIVATING) {
 		/* can't proceed until the other side disengages from us */
 		if (xpc_partition_engaged(ch->partid))
 			return;
@@ -155,7 +155,7 @@ xpc_process_disconnect(struct xpc_channe
 		/* we won't lose the CPU since we're holding ch->lock */
 		complete(&ch->wdisconnect_wait);
 	} else if (ch->delayed_chctl_flags) {
-		if (part->act_state != XPC_P_DEACTIVATING) {
+		if (part->act_state != XPC_P_AS_DEACTIVATING) {
 			/* time to take action on any delayed chctl flags */
 			spin_lock(&part->chctl_lock);
 			part->chctl.flags[ch->number] |=
@@ -276,7 +276,7 @@ again:
 			"%d, channel=%d\n", ch->partid, ch->number);
 
 		if (ch->flags & XPC_C_DISCONNECTED) {
-			DBUG_ON(part->act_state != XPC_P_DEACTIVATING);
+			DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING);
 			spin_unlock_irqrestore(&ch->lock, irq_flags);
 			return;
 		}
@@ -312,7 +312,7 @@ again:
 			"channel=%d\n", args->msg_size, args->local_nentries,
 			ch->partid, ch->number);
 
-		if (part->act_state == XPC_P_DEACTIVATING ||
+		if (part->act_state == XPC_P_AS_DEACTIVATING ||
 		    (ch->flags & XPC_C_ROPENREQUEST)) {
 			spin_unlock_irqrestore(&ch->lock, irq_flags);
 			return;
@@ -546,7 +546,7 @@ xpc_process_sent_chctl_flags(struct xpc_
 			continue;
 		}
 
-		if (part->act_state == XPC_P_DEACTIVATING)
+		if (part->act_state == XPC_P_AS_DEACTIVATING)
 			continue;
 
 		if (!(ch_flags & XPC_C_CONNECTED)) {
drivers/misc/sgi-xp/xpc_main.c +16 -16
Index: linux/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -290,8 +290,8 @@ xpc_check_remote_hb(void)
 
 		part = &xpc_partitions[partid];
 
-		if (part->act_state == XPC_P_INACTIVE ||
-		    part->act_state == XPC_P_DEACTIVATING) {
+		if (part->act_state == XPC_P_AS_INACTIVE ||
+		    part->act_state == XPC_P_AS_DEACTIVATING) {
 			continue;
 		}
 
@@ -406,7 +406,7 @@ xpc_initiate_discovery(void *ignore)
 static void
 xpc_channel_mgr(struct xpc_partition *part)
 {
-	while (part->act_state != XPC_P_DEACTIVATING ||
+	while (part->act_state != XPC_P_AS_DEACTIVATING ||
 	       atomic_read(&part->nchannels_active) > 0 ||
 	       !xpc_partition_disengaged(part)) {
 
@@ -429,7 +429,7 @@ xpc_channel_mgr(struct xpc_partition *pa
 		(void)wait_event_interruptible(part->channel_mgr_wq,
 				(atomic_read(&part->channel_mgr_requests) > 0 ||
 				 part->chctl.all_flags != 0 ||
-				 (part->act_state == XPC_P_DEACTIVATING &&
+				 (part->act_state == XPC_P_AS_DEACTIVATING &&
 				 atomic_read(&part->nchannels_active) == 0 &&
 				 xpc_partition_disengaged(part))));
 		atomic_set(&part->channel_mgr_requests, 1);
@@ -458,16 +458,16 @@ xpc_activating(void *__partid)
 
 	spin_lock_irqsave(&part->act_lock, irq_flags);
 
-	if (part->act_state == XPC_P_DEACTIVATING) {
-		part->act_state = XPC_P_INACTIVE;
+	if (part->act_state == XPC_P_AS_DEACTIVATING) {
+		part->act_state = XPC_P_AS_INACTIVE;
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
 		part->remote_rp_pa = 0;
 		return 0;
 	}
 
 	/* indicate the thread is activating */
-	DBUG_ON(part->act_state != XPC_P_ACTIVATION_REQ);
-	part->act_state = XPC_P_ACTIVATING;
+	DBUG_ON(part->act_state != XPC_P_AS_ACTIVATION_REQ);
+	part->act_state = XPC_P_AS_ACTIVATING;
 
 	XPC_SET_REASON(part, 0, 0);
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
@@ -509,9 +509,9 @@ xpc_activate_partition(struct xpc_partit
 
 	spin_lock_irqsave(&part->act_lock, irq_flags);
 
-	DBUG_ON(part->act_state != XPC_P_INACTIVE);
+	DBUG_ON(part->act_state != XPC_P_AS_INACTIVE);
 
-	part->act_state = XPC_P_ACTIVATION_REQ;
+	part->act_state = XPC_P_AS_ACTIVATION_REQ;
 	XPC_SET_REASON(part, xpCloneKThread, __LINE__);
 
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
@@ -520,7 +520,7 @@ xpc_activate_partition(struct xpc_partit
 			      partid);
 	if (IS_ERR(kthread)) {
 		spin_lock_irqsave(&part->act_lock, irq_flags);
-		part->act_state = XPC_P_INACTIVE;
+		part->act_state = XPC_P_AS_INACTIVE;
 		XPC_SET_REASON(part, xpCloneKThreadFailed, __LINE__);
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
 	}
@@ -786,7 +786,7 @@ xpc_disconnect_wait(int ch_number)
 		wakeup_channel_mgr = 0;
 
 		if (ch->delayed_chctl_flags) {
-			if (part->act_state != XPC_P_DEACTIVATING) {
+			if (part->act_state != XPC_P_AS_DEACTIVATING) {
 				spin_lock(&part->chctl_lock);
 				part->chctl.flags[ch->number] |=
 				    ch->delayed_chctl_flags;
@@ -846,7 +846,7 @@ xpc_do_exit(enum xp_retval reason)
 			part = &xpc_partitions[partid];
 
 			if (xpc_partition_disengaged(part) &&
-			    part->act_state == XPC_P_INACTIVE) {
+			    part->act_state == XPC_P_AS_INACTIVE) {
 				continue;
 			}
 
@@ -962,7 +962,7 @@ xpc_die_deactivate(void)
 		part = &xpc_partitions[partid];
 
 		if (xpc_partition_engaged(partid) ||
-		    part->act_state != XPC_P_INACTIVE) {
+		    part->act_state != XPC_P_AS_INACTIVE) {
 			xpc_request_partition_deactivation(part);
 			xpc_indicate_partition_disengaged(part);
 		}
@@ -1113,7 +1113,7 @@ xpc_init(void)
 
 		part->activate_IRQ_rcvd = 0;
 		spin_lock_init(&part->act_lock);
-		part->act_state = XPC_P_INACTIVE;
+		part->act_state = XPC_P_AS_INACTIVE;
 		XPC_SET_REASON(part, 0, 0);
 
 		init_timer(&part->disengage_timer);
@@ -1121,7 +1121,7 @@ xpc_init(void)
 		    xpc_timeout_partition_disengage;
 		part->disengage_timer.data = (unsigned long)part;
 
-		part->setup_state = XPC_P_UNSET;
+		part->setup_state = XPC_P_SS_UNSET;
 		init_waitqueue_head(&part->teardown_wq);
 		atomic_set(&part->references, 0);
 	}
drivers/misc/sgi-xp/xpc_partition.c +9 -9
Index: linux/drivers/misc/sgi-xp/xpc_partition.c
===================================================================
@@ -273,9 +273,9 @@ xpc_partition_disengaged(struct xpc_part
 		if (!in_interrupt())
 			del_singleshot_timer_sync(&part->disengage_timer);
 
-		DBUG_ON(part->act_state != XPC_P_DEACTIVATING &&
-			part->act_state != XPC_P_INACTIVE);
-		if (part->act_state != XPC_P_INACTIVE)
+		DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING &&
+			part->act_state != XPC_P_AS_INACTIVE);
+		if (part->act_state != XPC_P_AS_INACTIVE)
 			xpc_wakeup_channel_mgr(part);
 
 		xpc_cancel_partition_deactivation_request(part);
@@ -295,8 +295,8 @@ xpc_mark_partition_active(struct xpc_par
 	dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part));
 
 	spin_lock_irqsave(&part->act_lock, irq_flags);
-	if (part->act_state == XPC_P_ACTIVATING) {
-		part->act_state = XPC_P_ACTIVE;
+	if (part->act_state == XPC_P_AS_ACTIVATING) {
+		part->act_state = XPC_P_AS_ACTIVE;
 		ret = xpSuccess;
 	} else {
 		DBUG_ON(part->reason == xpSuccess);
@@ -318,7 +318,7 @@ xpc_deactivate_partition(const int line,
 
 	spin_lock_irqsave(&part->act_lock, irq_flags);
 
-	if (part->act_state == XPC_P_INACTIVE) {
+	if (part->act_state == XPC_P_AS_INACTIVE) {
 		XPC_SET_REASON(part, reason, line);
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
 		if (reason == xpReactivating) {
@@ -327,7 +327,7 @@ xpc_deactivate_partition(const int line,
 		}
 		return;
 	}
-	if (part->act_state == XPC_P_DEACTIVATING) {
+	if (part->act_state == XPC_P_AS_DEACTIVATING) {
 		if ((part->reason == xpUnloading && reason != xpUnloading) ||
 		    reason == xpReactivating) {
 			XPC_SET_REASON(part, reason, line);
@@ -336,7 +336,7 @@ xpc_deactivate_partition(const int line,
 		return;
 	}
 
-	part->act_state = XPC_P_DEACTIVATING;
+	part->act_state = XPC_P_AS_DEACTIVATING;
 	XPC_SET_REASON(part, reason, line);
 
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
@@ -367,7 +367,7 @@ xpc_mark_partition_inactive(struct xpc_p
 		XPC_PARTID(part));
 
 	spin_lock_irqsave(&part->act_lock, irq_flags);
-	part->act_state = XPC_P_INACTIVE;
+	part->act_state = XPC_P_AS_INACTIVE;
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
 	part->remote_rp_pa = 0;
 }
drivers/misc/sgi-xp/xpc_sn2.c +10 -10
Index: linux/drivers/misc/sgi-xp/xpc_sn2.c
===================================================================
@@ -327,7 +327,7 @@ xpc_send_notify_IRQ_sn2(struct xpc_chann
 	union xpc_channel_ctl_flags chctl = { 0 };
 	enum xp_retval ret;
 
-	if (likely(part->act_state != XPC_P_DEACTIVATING)) {
+	if (likely(part->act_state != XPC_P_AS_DEACTIVATING)) {
 		chctl.flags[ch->number] = chctl_flag;
 		ret = xpc_send_IRQ_sn2(part_sn2->remote_chctl_amo_va,
 				       chctl.all_flags,
@@ -975,7 +975,7 @@ xpc_identify_activate_IRQ_req_sn2(int na
 		remote_vars->heartbeat, remote_vars->heartbeating_to_mask[0]);
 
 	if (xpc_partition_disengaged(part) &&
-	    part->act_state == XPC_P_INACTIVE) {
+	    part->act_state == XPC_P_AS_INACTIVE) {
 
 		xpc_update_partition_info_sn2(part, remote_rp_version,
 					      &remote_rp_ts_jiffies,
@@ -1257,10 +1257,10 @@ xpc_setup_infrastructure_sn2(struct xpc_
 	}
 
 	/*
-	 * With the setting of the partition setup_state to XPC_P_SETUP, we're
-	 * declaring that this partition is ready to go.
+	 * With the setting of the partition setup_state to XPC_P_SS_SETUP,
+	 * we're declaring that this partition is ready to go.
 	 */
-	part->setup_state = XPC_P_SETUP;
+	part->setup_state = XPC_P_SS_SETUP;
 
 	/*
 	 * Setup the per partition specific variables required by the
@@ -1323,8 +1323,8 @@ xpc_teardown_infrastructure_sn2(struct x
 
 	DBUG_ON(atomic_read(&part->nchannels_engaged) != 0);
 	DBUG_ON(atomic_read(&part->nchannels_active) != 0);
-	DBUG_ON(part->setup_state != XPC_P_SETUP);
-	part->setup_state = XPC_P_WTEARDOWN;
+	DBUG_ON(part->setup_state != XPC_P_SS_SETUP);
+	part->setup_state = XPC_P_SS_WTEARDOWN;
 
 	xpc_vars_part_sn2[partid].magic = 0;
 
@@ -1338,7 +1338,7 @@ xpc_teardown_infrastructure_sn2(struct x
 
 	/* now we can begin tearing down the infrastructure */
 
-	part->setup_state = XPC_P_TORNDOWN;
+	part->setup_state = XPC_P_SS_TORNDOWN;
 
 	/* in case we've still got outstanding timers registered... */
 	del_timer_sync(&part_sn2->dropped_notify_IRQ_timer);
@@ -1375,7 +1375,7 @@ xpc_pull_remote_cachelines_sn2(struct xp
 	DBUG_ON((unsigned long)dst != L1_CACHE_ALIGN((unsigned long)dst));
 	DBUG_ON(cnt != L1_CACHE_ALIGN(cnt));
 
-	if (part->act_state == XPC_P_DEACTIVATING)
+	if (part->act_state == XPC_P_AS_DEACTIVATING)
 		return part->reason;
 
 	ret = xp_remote_memcpy(xp_pa(dst), src_pa, cnt);
@@ -1534,7 +1534,7 @@ xpc_make_first_contact_sn2(struct xpc_pa
 		/* wait a 1/4 of a second or so */
 		(void)msleep_interruptible(250);
 
-		if (part->act_state == XPC_P_DEACTIVATING)
+		if (part->act_state == XPC_P_AS_DEACTIVATING)
 			return part->reason;
 	}
 
#5 lore raw

PATCH 5/6 sgi-xp: setup the activate GRU message queue

In reply to Dean Nelson

Setup the activate GRU message queue that is used for partition activation and channel connection on UV systems.

---

Note that the code to setup an irq on UV is incomplete, but is not an issue since there aren't any UV systems at the moment. Code to resolve this will be forthcoming.

 drivers/misc/sgi-xp/xp.h            |    3 
 drivers/misc/sgi-xp/xp_uv.c         |   10 
 drivers/misc/sgi-xp/xpc.h           |  158 +++++-
 drivers/misc/sgi-xp/xpc_channel.c   |   22 
 drivers/misc/sgi-xp/xpc_main.c      |  329 ++++++++++---
 drivers/misc/sgi-xp/xpc_partition.c |   28 -
 drivers/misc/sgi-xp/xpc_sn2.c       |  387 ++++++---------
 drivers/misc/sgi-xp/xpc_uv.c        |  781 ++++++++++++++++++++++++++++++--
 8 files changed, 1328 insertions(+), 390 deletions(-)
drivers/misc/sgi-xp/xp_uv.c +10 -0
Index: linux/drivers/misc/sgi-xp/xp_uv.c
===================================================================
@@ -42,15 +42,25 @@ xp_remote_memcpy_uv(unsigned long dst_gp
 	return xpGruCopyError;
 }
 
+static int
+xp_cpu_to_nasid_uv(int cpuid)
+{
+	/* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */
+	return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
+}
+
 enum xp_retval
 xp_init_uv(void)
 {
 	BUG_ON(!is_uv());
 
 	xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
+	xp_partition_id = 0;	/* !!! not correct value */
+	xp_region_size = 0;	/* !!! not correct value */
 
 	xp_pa = xp_pa_uv;
 	xp_remote_memcpy = xp_remote_memcpy_uv;
+	xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
 
 	return xpSuccess;
 }
drivers/misc/sgi-xp/xpc_uv.c +751 -30

879 lines not on this page · raw message

drivers/misc/sgi-xp/xpc.h +128 -30

271 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_main.c +246 -83

468 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_partition.c +22 -6
Index: linux/drivers/misc/sgi-xp/xpc_partition.c
===================================================================
@@ -73,6 +73,12 @@ xpc_get_rsvd_page_pa(int nasid)
 
 	while (1) {
 
+		/* !!! rp_pa will need to be _gpa on UV.
+		 * ??? So do we save it into the architecture specific parts
+		 * ??? of the xpc_partition structure? Do we rename this
+		 * ??? function or have two versions? Rename rp_pa for UV to
+		 * ??? rp_gpa?
+		 */
 		ret = xpc_get_partition_rsvd_page_pa(buf, &cookie, &rp_pa,
 						     &len);
 
@@ -118,9 +124,10 @@ xpc_get_rsvd_page_pa(int nasid)
  * other partitions to discover we are alive and establish initial
  * communications.
  */
-struct xpc_rsvd_page *
+int
 xpc_setup_rsvd_page(void)
 {
+	int ret;
 	struct xpc_rsvd_page *rp;
 	unsigned long rp_pa;
 	unsigned long new_ts_jiffies;
@@ -132,7 +139,7 @@ xpc_setup_rsvd_page(void)
 	preempt_enable();
 	if (rp_pa == 0) {
 		dev_err(xpc_part, "SAL failed to locate the reserved page\n");
-		return NULL;
+		return -ESRCH;
 	}
 	rp = (struct xpc_rsvd_page *)__va(rp_pa);
 
@@ -146,7 +153,7 @@ xpc_setup_rsvd_page(void)
 		dev_err(xpc_part, "the reserved page's partid of %d is outside "
 			"supported range (< 0 || >= %d)\n", rp->SAL_partid,
 			xp_max_npartitions);
-		return NULL;
+		return -EINVAL;
 	}
 
 	rp->version = XPC_RP_VERSION;
@@ -165,8 +172,9 @@ xpc_setup_rsvd_page(void)
 	xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
 	xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp);
 
-	if (xpc_rsvd_page_init(rp) != xpSuccess)
-		return NULL;
+	ret = xpc_setup_rsvd_page_sn(rp);
+	if (ret != 0)
+		return ret;
 
 	/*
 	 * Set timestamp of when reserved page was setup by XPC.
@@ -178,7 +186,15 @@ xpc_setup_rsvd_page(void)
 		new_ts_jiffies++;
 	rp->ts_jiffies = new_ts_jiffies;
 
-	return rp;
+	xpc_rsvd_page = rp;
+	return 0;
+}
+
+void
+xpc_teardown_rsvd_page(void)
+{
+	/* a zero timestamp indicates our rsvd page is not initialized */
+	xpc_rsvd_page->ts_jiffies = 0;
 }
 
 /*
drivers/misc/sgi-xp/xpc_sn2.c +154 -233

763 lines not on this page · raw message

drivers/misc/sgi-xp/xp.h +2 -1
Index: linux/drivers/misc/sgi-xp/xp.h
===================================================================
@@ -208,8 +208,9 @@ enum xp_retval {
 	xpNeedMoreInfo,		/* 57: more info is needed by SAL */
 
 	xpGruCopyError,		/* 58: gru_copy_gru() returned error */
+	xpGruSendMqError,	/* 59: gru send message queue related error */
 
-	xpUnknownReason		/* 59: unknown reason - must be last in enum */
+	xpUnknownReason		/* 60: unknown reason - must be last in enum */
 };
 
 /*
drivers/misc/sgi-xp/xpc_channel.c +15 -7
Index: linux/drivers/misc/sgi-xp/xpc_channel.c
===================================================================
@@ -39,7 +39,7 @@ xpc_process_connect(struct xpc_channel *
 
 	if (!(ch->flags & XPC_C_SETUP)) {
 		spin_unlock_irqrestore(&ch->lock, *irq_flags);
-		ret = xpc_allocate_msgqueues(ch);
+		ret = xpc_setup_msg_structures(ch);
 		spin_lock_irqsave(&ch->lock, *irq_flags);
 
 		if (ret != xpSuccess)
@@ -62,8 +62,6 @@ xpc_process_connect(struct xpc_channel *
 	if (!(ch->flags & XPC_C_ROPENREPLY))
 		return;
 
-	DBUG_ON(ch->remote_msgqueue_pa == 0);
-
 	ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP);	/* clear all else */
 
 	dev_info(xpc_chan, "channel %d to partition %d connected\n",
@@ -134,13 +132,23 @@ xpc_process_disconnect(struct xpc_channe
 		spin_lock_irqsave(&ch->lock, *irq_flags);
 	}
 
+	DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
+
 	/* it's now safe to free the channel's message queues */
-	xpc_free_msgqueues(ch);
+	xpc_teardown_msg_structures(ch);
+
+	ch->func = NULL;
+	ch->key = NULL;
+	ch->msg_size = 0;
+	ch->local_nentries = 0;
+	ch->remote_nentries = 0;
+	ch->kthreads_assigned_limit = 0;
+	ch->kthreads_idle_limit = 0;
 
 	/*
 	 * Mark the channel disconnected and clear all other flags, including
-	 * XPC_C_SETUP (because of call to xpc_free_msgqueues()) but not
-	 * including XPC_C_WDISCONNECT (if it was set).
+	 * XPC_C_SETUP (because of call to xpc_teardown_msg_structures()) but
+	 * not including XPC_C_WDISCONNECT (if it was set).
 	 */
 	ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT));
 
@@ -395,7 +403,7 @@ again:
 		DBUG_ON(args->remote_nentries == 0);
 
 		ch->flags |= XPC_C_ROPENREPLY;
-		ch->remote_msgqueue_pa = args->local_msgqueue_pa;
+		xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa);
 
 		if (args->local_nentries < ch->remote_nentries) {
 			dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new "
#6 lore raw

PATCH 6/6 sgi-xp: setup the notify GRU message queue

In reply to Dean Nelson

Setup the notify GRU message queue that is used for sending user messages on UV systems.

---

 drivers/misc/sgi-xp/xp.h          |   45 -
 drivers/misc/sgi-xp/xp_main.c     |    7 
 drivers/misc/sgi-xp/xpc.h         |  140 +++--
 drivers/misc/sgi-xp/xpc_channel.c |   63 +-
 drivers/misc/sgi-xp/xpc_main.c    |   21 
 drivers/misc/sgi-xp/xpc_sn2.c     |  178 +++---
 drivers/misc/sgi-xp/xpc_uv.c      |  943 +++++++++++++++++++++++++++-------
 drivers/misc/sgi-xp/xpnet.c       |   11 
 8 files changed, 1028 insertions(+), 380 deletions(-)
drivers/misc/sgi-xp/xpc.h +107 -33
Index: linux/drivers/misc/sgi-xp/xpc.h
===================================================================
@@ -181,8 +181,8 @@ struct xpc_vars_part_sn2 {
 				  xpc_nasid_mask_nlongs))
 
 /*
- * The activate_mq is used to send/receive messages that affect XPC's heartbeat,
- * partition active state, and channel state. This is UV only.
+ * The activate_mq is used to send/receive GRU messages that affect XPC's
+ * heartbeat, partition active state, and channel state. This is UV only.
  */
 struct xpc_activate_mq_msghdr_uv {
 	short partid;		/* sender's partid */
@@ -209,45 +209,45 @@ struct xpc_activate_mq_msghdr_uv {
 #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV		11
 
 struct xpc_activate_mq_msg_uv {
-	struct xpc_activate_mq_msghdr_uv header;
+	struct xpc_activate_mq_msghdr_uv hdr;
 };
 
 struct xpc_activate_mq_msg_heartbeat_req_uv {
-	struct xpc_activate_mq_msghdr_uv header;
+	struct xpc_activate_mq_msghdr_uv hdr;
 	u64 heartbeat;
 };
 
 struct xpc_activate_mq_msg_activate_req_uv {
-	struct xpc_activate_mq_msghdr_uv header;
+	struct xpc_activate_mq_msghdr_uv hdr;
 	unsigned long rp_gpa;
 	unsigned long activate_mq_gpa;
 };
 
 struct xpc_activate_mq_msg_deactivate_req_uv {
-	struct xpc_activate_mq_msghdr_uv header;
+	struct xpc_activate_mq_msghdr_uv hdr;
 	enum xp_retval reason;
 };
 
 struct xpc_activate_mq_msg_chctl_closerequest_uv {
-	struct xpc_activate_mq_msghdr_uv header;
+	struct xpc_activate_mq_msghdr_uv hdr;
 	short ch_number;
 	enum xp_retval reason;
 };
 
 struct xpc_activate_mq_msg_chctl_closereply_uv {
-	struct xpc_activate_mq_msghdr_uv header;
+	struct xpc_activate_mq_msghdr_uv hdr;
 	short ch_number;
 };
 
 struct xpc_activate_mq_msg_chctl_openrequest_uv {
-	struct xpc_activate_mq_msghdr_uv header;
+	struct xpc_activate_mq_msghdr_uv hdr;
 	short ch_number;
-	short msg_size;		/* size of notify_mq's messages */
+	short entry_size;	/* size of notify_mq's GRU messages */
 	short local_nentries;	/* ??? Is this needed? What is? */
 };
 
 struct xpc_activate_mq_msg_chctl_openreply_uv {
-	struct xpc_activate_mq_msghdr_uv header;
+	struct xpc_activate_mq_msghdr_uv hdr;
 	short ch_number;
 	short remote_nentries;	/* ??? Is this needed? What is? */
 	short local_nentries;	/* ??? Is this needed? What is? */
@@ -284,7 +284,7 @@ struct xpc_gp_sn2 {
  */
 struct xpc_openclose_args {
 	u16 reason;		/* reason why channel is closing */
-	u16 msg_size;		/* sizeof each message entry */
+	u16 entry_size;		/* sizeof each message entry */
 	u16 remote_nentries;	/* #of message entries in remote msg queue */
 	u16 local_nentries;	/* #of message entries in local msg queue */
 	unsigned long local_msgqueue_pa; /* phys addr of local message queue */
@@ -294,22 +294,79 @@ struct xpc_openclose_args {
 	      L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
 	      XPC_MAX_NCHANNELS)
 
-/* struct xpc_msg flags */
 
-#define	XPC_M_DONE		0x01	/* msg has been received/consumed */
-#define	XPC_M_READY		0x02	/* msg is ready to be sent */
-#define	XPC_M_INTERRUPT		0x04	/* send interrupt when msg consumed */
+/*
+ * Structures to define a fifo singly-linked list.
+ */
+
+struct xpc_fifo_entry_uv {
+	struct xpc_fifo_entry_uv *next;
+};
+
+struct xpc_fifo_head_uv {
+	struct xpc_fifo_entry_uv *first;
+	struct xpc_fifo_entry_uv *last;
+	spinlock_t lock;
+	int n_entries;
+};
+
+/*
+ * Define a sn2 styled message.
+ *
+ * A user-defined message resides in the payload area. The max size of the
+ * payload is defined by the user via xpc_connect().
+ *
+ * The size of a message entry (within a message queue) must be a 128-byte
+ * cacheline sized multiple in order to facilitate the BTE transfer of messages
+ * from one message queue to another.
+ */
+struct xpc_msg_sn2 {
+	u8 flags;		/* FOR XPC INTERNAL USE ONLY */
+	u8 reserved[7];		/* FOR XPC INTERNAL USE ONLY */
+	s64 number;		/* FOR XPC INTERNAL USE ONLY */
+
+	u64 payload;		/* user defined portion of message */
+};
+
+/* struct xpc_msg_sn2 flags */
+
+#define	XPC_M_SN2_DONE		0x01	/* msg has been received/consumed */
+#define	XPC_M_SN2_READY		0x02	/* msg is ready to be sent */
+#define	XPC_M_SN2_INTERRUPT	0x04	/* send interrupt when msg consumed */
+
+/*
+ * The format of a uv XPC notify_mq GRU message is as follows:
+ *
+ * A user-defined message resides in the payload area. The max size of the
+ * payload is defined by the user via xpc_connect().
+ *
+ * The size of a message (payload and header) sent via the GRU must be either 1
+ * or 2 GRU_CACHE_LINE_BYTES in length.
+ */
 
-#define XPC_MSG_ADDRESS(_payload) \
-		((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET))
+struct xpc_notify_mq_msghdr_uv {
+	union {
+		unsigned int gru_msg_hdr;	/* FOR GRU INTERNAL USE ONLY */
+		struct xpc_fifo_entry_uv next;	/* FOR XPC INTERNAL USE ONLY */
+	} u;
+	short partid;		/* FOR XPC INTERNAL USE ONLY */
+	u8 ch_number;		/* FOR XPC INTERNAL USE ONLY */
+	u8 size;		/* FOR XPC INTERNAL USE ONLY */
+	unsigned int msg_slot_number;	/* FOR XPC INTERNAL USE ONLY */
+};
+
+struct xpc_notify_mq_msg_uv {
+	struct xpc_notify_mq_msghdr_uv hdr;
+	unsigned long payload;
+};
 
 /*
- * Defines notify entry.
+ * Define sn2's notify entry.
  *
  * This is used to notify a message's sender that their message was received
  * and consumed by the intended recipient.
  */
-struct xpc_notify {
+struct xpc_notify_sn2 {
 	u8 type;		/* type of notification */
 
 	/* the following two fields are only used if type == XPC_N_CALL */
@@ -317,9 +374,20 @@ struct xpc_notify {
 	void *key;		/* pointer to user's key */
 };
 
-/* struct xpc_notify type of notification */
+/* struct xpc_notify_sn2 type of notification */
 
-#define	XPC_N_CALL		0x01	/* notify function provided by user */
+#define	XPC_N_CALL	0x01	/* notify function provided by user */
+
+/*
+ * Define uv's version of the notify entry. It additionally is used to allocate
+ * a msg slot on the remote partition into which is copied a sent message.
+ */
+struct xpc_send_msg_slot_uv {
+	struct xpc_fifo_entry_uv next;
+	unsigned int msg_slot_number;
+	xpc_notify_func func;	/* user's notify function */
+	void *key;		/* pointer to user's key */
+};
 
 /*
  * Define the structure that manages all the stuff required by a channel. In
@@ -409,14 +477,14 @@ struct xpc_channel_sn2 {
 					     /* opening or closing of channel */
 
 	void *local_msgqueue_base;	/* base address of kmalloc'd space */
-	struct xpc_msg *local_msgqueue;	/* local message queue */
+	struct xpc_msg_sn2 *local_msgqueue;	/* local message queue */
 	void *remote_msgqueue_base;	/* base address of kmalloc'd space */
-	struct xpc_msg *remote_msgqueue; /* cached copy of remote partition's */
-					 /* local message queue */
+	struct xpc_msg_sn2 *remote_msgqueue; /* cached copy of remote */
+					   /* partition's local message queue */
 	unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */
 					  /* local message queue */
 
-	struct xpc_notify *notify_queue;    /* notify queue for messages sent */
+	struct xpc_notify_sn2 *notify_queue;/* notify queue for messages sent */
 
 	/* various flavors of local and remote Get/Put values */
 
@@ -432,6 +500,12 @@ struct xpc_channel_sn2 {
 struct xpc_channel_uv {
 	unsigned long remote_notify_mq_gpa;	/* gru phys address of remote */
 						/* partition's notify mq */
+
+	struct xpc_send_msg_slot_uv *send_msg_slots;
+	struct xpc_notify_mq_msg_uv *recv_msg_slots;
+
+	struct xpc_fifo_head_uv msg_slot_free_list;
+	struct xpc_fifo_head_uv recv_msg_list;	/* deliverable payloads */
 };
 
 struct xpc_channel {
@@ -444,7 +518,7 @@ struct xpc_channel {
 
 	u16 number;		/* channel # */
 
-	u16 msg_size;		/* sizeof each msg entry */
+	u16 entry_size;		/* sizeof each msg entry */
 	u16 local_nentries;	/* #of msg entries in local msg queue */
 	u16 remote_nentries;	/* #of msg entries in remote msg queue */
 
@@ -733,8 +807,8 @@ extern enum xp_retval (*xpc_setup_msg_st
 extern void (*xpc_teardown_msg_structures) (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 *);
-extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *);
+extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *);
+extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *);
 extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *,
 						 unsigned long, int);
 extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
@@ -762,9 +836,9 @@ extern void (*xpc_send_chctl_openreply) 
 extern void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
 					    unsigned long);
 
-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 *);
+extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
+					   u16, u8, xpc_notify_func, void *);
+extern void (*xpc_received_payload) (struct xpc_channel *, void *);
 
 /* found in xpc_sn2.c */
 extern int xpc_init_sn2(void);
@@ -805,7 +879,7 @@ extern enum xp_retval xpc_initiate_send_
 extern void xpc_initiate_received(short, int, void *);
 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_deliver_payload(struct xpc_channel *);
 extern void xpc_disconnect_channel(const int, struct xpc_channel *,
 				   enum xp_retval, unsigned long *);
 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
drivers/misc/sgi-xp/xpc_sn2.c +96 -82

429 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_uv.c +759 -184

1,058 lines not on this page · raw message

drivers/misc/sgi-xp/xp.h +15 -30

74 lines not on this page · raw message

drivers/misc/sgi-xp/xpc_channel.c +29 -34

160 lines not on this page · raw message

drivers/misc/sgi-xp/xp_main.c +5 -2
Index: linux/drivers/misc/sgi-xp/xp_main.c
===================================================================
@@ -154,6 +154,9 @@ xpc_connect(int ch_number, xpc_channel_f
 	DBUG_ON(func == NULL);
 	DBUG_ON(assigned_limit == 0 || idle_limit > assigned_limit);
 
+	if (XPC_MSG_SIZE(payload_size) > XPC_MSG_MAX_SIZE)
+		return xpPayloadTooBig;
+
 	registration = &xpc_registrations[ch_number];
 
 	if (mutex_lock_interruptible(&registration->mutex) != 0)
@@ -166,7 +169,7 @@ xpc_connect(int ch_number, xpc_channel_f
 	}
 
 	/* register the channel for connection */
-	registration->msg_size = XPC_MSG_SIZE(payload_size);
+	registration->entry_size = XPC_MSG_SIZE(payload_size);
 	registration->nentries = nentries;
 	registration->assigned_limit = assigned_limit;
 	registration->idle_limit = idle_limit;
@@ -220,7 +223,7 @@ xpc_disconnect(int ch_number)
 	registration->func = NULL;
 	registration->key = NULL;
 	registration->nentries = 0;
-	registration->msg_size = 0;
+	registration->entry_size = 0;
 	registration->assigned_limit = 0;
 	registration->idle_limit = 0;
 
drivers/misc/sgi-xp/xpc_main.c +11 -10
Index: linux/drivers/misc/sgi-xp/xpc_main.c
===================================================================
@@ -188,8 +188,8 @@ u64 (*xpc_get_chctl_all_flags) (struct x
 enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *ch);
 void (*xpc_teardown_msg_structures) (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);
+int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *ch);
+void *(*xpc_get_deliverable_payload) (struct xpc_channel *ch);
 
 void (*xpc_request_partition_activation) (struct xpc_rsvd_page *remote_rp,
 					  unsigned long remote_rp_pa,
@@ -220,10 +220,11 @@ void (*xpc_send_chctl_openreply) (struct
 void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch,
 				     unsigned long msgqueue_pa);
 
-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);
+enum xp_retval (*xpc_send_payload) (struct xpc_channel *ch, u32 flags,
+				    void *payload, u16 payload_size,
+				    u8 notify_type, xpc_notify_func func,
+				    void *key);
+void (*xpc_received_payload) (struct xpc_channel *ch, void *payload);
 
 /*
  * Timer function to enforce the timelimit on the partition disengage.
@@ -714,9 +715,9 @@ xpc_kthread_waitmsgs(struct xpc_partitio
 	do {
 		/* deliver messages to their intended recipients */
 
-		while (xpc_n_of_deliverable_msgs(ch) > 0 &&
+		while (xpc_n_of_deliverable_payloads(ch) > 0 &&
 		       !(ch->flags & XPC_C_DISCONNECTING)) {
-			xpc_deliver_msg(ch);
+			xpc_deliver_payload(ch);
 		}
 
 		if (atomic_inc_return(&ch->kthreads_idle) >
@@ -730,7 +731,7 @@ xpc_kthread_waitmsgs(struct xpc_partitio
 			"wait_event_interruptible_exclusive()\n");
 
 		(void)wait_event_interruptible_exclusive(ch->idle_wq,
-				(xpc_n_of_deliverable_msgs(ch) > 0 ||
+				(xpc_n_of_deliverable_payloads(ch) > 0 ||
 				 (ch->flags & XPC_C_DISCONNECTING)));
 
 		atomic_dec(&ch->kthreads_idle);
@@ -775,7 +776,7 @@ xpc_kthread_start(void *args)
 			 * additional kthreads to help deliver them. We only
 			 * need one less than total #of messages to deliver.
 			 */
-			n_needed = xpc_n_of_deliverable_msgs(ch) - 1;
+			n_needed = xpc_n_of_deliverable_payloads(ch) - 1;
 			if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING))
 				xpc_activate_kthreads(ch, n_needed);
 
drivers/misc/sgi-xp/xpnet.c +6 -5
Index: linux/drivers/misc/sgi-xp/xpnet.c
===================================================================
@@ -57,11 +57,10 @@ struct xpnet_message {
  *
  * XPC expects each message to exist in an individual cacheline.
  */
-#define XPNET_MSG_SIZE		(L1_CACHE_BYTES - XPC_MSG_PAYLOAD_OFFSET)
+#define XPNET_MSG_SIZE		XPC_MSG_PAYLOAD_MAX_SIZE
 #define XPNET_MSG_DATA_MAX	\
-		(XPNET_MSG_SIZE - (u64)(&((struct xpnet_message *)0)->data))
-#define XPNET_MSG_ALIGNED_SIZE	(L1_CACHE_ALIGN(XPNET_MSG_SIZE))
-#define XPNET_MSG_NENTRIES	(PAGE_SIZE / XPNET_MSG_ALIGNED_SIZE)
+		(XPNET_MSG_SIZE - offsetof(struct xpnet_message, data))
+#define XPNET_MSG_NENTRIES	(PAGE_SIZE / XPC_MSG_MAX_SIZE)
 
 #define XPNET_MAX_KTHREADS	(XPNET_MSG_NENTRIES + 1)
 #define XPNET_MAX_IDLE_KTHREADS	(XPNET_MSG_NENTRIES + 1)
@@ -408,6 +407,7 @@ xpnet_send(struct sk_buff *skb, struct x
 {
 	u8 msg_buffer[XPNET_MSG_SIZE];
 	struct xpnet_message *msg = (struct xpnet_message *)&msg_buffer;
+	u16 msg_size = sizeof(struct xpnet_message);
 	enum xp_retval ret;
 
 	msg->embedded_bytes = embedded_bytes;
@@ -417,6 +417,7 @@ xpnet_send(struct sk_buff *skb, struct x
 			&msg->data, skb->data, (size_t)embedded_bytes);
 		skb_copy_from_linear_data(skb, &msg->data,
 					  (size_t)embedded_bytes);
+		msg_size += embedded_bytes - 1;
 	} else {
 		msg->version = XPNET_VERSION;
 	}
@@ -435,7 +436,7 @@ xpnet_send(struct sk_buff *skb, struct x
 	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);
+			      msg_size, xpnet_send_completed, queued_msg);
 	if (unlikely(ret != xpSuccess))
 		atomic_dec(&queued_msg->use_count);
 }