All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] sgi-xp: add low-level hardware specific functionality
@ 2008-10-21 21:20 Dean Nelson
  2008-10-21 21:22 ` [PATCH 1/4] sgi-xp: define xp_expand_memprotect() and xp_restrict_memprotect() Dean Nelson
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Dean Nelson @ 2008-10-21 21:20 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

This patchset adds some low-level hardware specific functionality to the
xp/xpc drivers.

To build cleanly this patchset is dependent on the following patches
submitted by Russ Anderson <rja@sgi.com>.

[PATCH] x86: Use consistent names for region size and conherence id on x86 and ia64.
 (see http://marc.info/?l=linux-kernel&m=122461625304772&w=2)

[PATCH 1/3] x86: Add UV watchlist bios call
 (see http://marc.info/?l=linux-kernel&m=122461934110503&w=2)
[PATCH 2/3] x86: Add UV memory protection bios call
 (see http://marc.info/?l=linux-kernel&m=122461934110506&w=2)
[PATCH 3/3] x86: Add UV reserved page bios call
 (see http://marc.info/?l=linux-kernel&m=122461934210509&w=2)

[PATCH] Add UV watchlist support
 (see http://marc.info/?l=linux-ia64&m=122462371418298&w=2)


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] sgi-xp: define xp_expand_memprotect() and xp_restrict_memprotect()
  2008-10-21 21:20 [PATCH 0/4] sgi-xp: add low-level hardware specific functionality Dean Nelson
@ 2008-10-21 21:22 ` Dean Nelson
  2008-10-21 21:23 ` [PATCH 2/4] sgi-xp: create activate and notify gru message queues Dean Nelson
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Dean Nelson @ 2008-10-21 21:22 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

Define xp_expand_memprotect() and xp_restrict_memprotect() so they can be
tailered to the hardware they are run on.

Signed-off-by: Dean Nelson <dcn@sgi.com>

---

 drivers/misc/sgi-xp/xp.h      |    7 ++--
 drivers/misc/sgi-xp/xp_main.c |    7 ++++
 drivers/misc/sgi-xp/xp_sn2.c  |   34 +++++++++++++++++++
 drivers/misc/sgi-xp/xp_uv.c   |   66 ++++++++++++++++++++++++++++++++++++++
 drivers/misc/sgi-xp/xpc_sn2.c |   15 ++------
 5 files changed, 117 insertions(+), 12 deletions(-)

Index: linux/drivers/misc/sgi-xp/xp_sn2.c
===================================================================
--- linux.orig/drivers/misc/sgi-xp/xp_sn2.c	2008-10-09 11:14:24.000000000 -0500
+++ linux/drivers/misc/sgi-xp/xp_sn2.c	2008-10-09 13:18:36.000000000 -0500
@@ -120,6 +120,38 @@ xp_cpu_to_nasid_sn2(int cpuid)
 	return cpuid_to_nasid(cpuid);
 }
 
+static enum xp_retval
+xp_expand_memprotect_sn2(unsigned long phys_addr, unsigned long size)
+{
+	u64 nasid_array = 0;
+	int ret;
+
+	ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
+				   &nasid_array);
+	if (ret != 0) {
+		dev_err(xp, "sn_change_memprotect(,, "
+			"SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
+		return xpSalError;
+	}
+	return xpSuccess;
+}
+
+static enum xp_retval
+xp_restrict_memprotect_sn2(unsigned long phys_addr, unsigned long size)
+{
+	u64 nasid_array = 0;
+	int ret;
+
+	ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
+				   &nasid_array);
+	if (ret != 0) {
+		dev_err(xp, "sn_change_memprotect(,, "
+			"SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
+		return xpSalError;
+	}
+	return xpSuccess;
+}
+
 enum xp_retval
 xp_init_sn2(void)
 {
@@ -132,6 +164,8 @@ xp_init_sn2(void)
 	xp_pa = xp_pa_sn2;
 	xp_remote_memcpy = xp_remote_memcpy_sn2;
 	xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
+	xp_expand_memprotect = xp_expand_memprotect_sn2;
+	xp_restrict_memprotect = xp_restrict_memprotect_sn2;
 
 	return xp_register_nofault_code_sn2();
 }
Index: linux/drivers/misc/sgi-xp/xp_uv.c
===================================================================
--- linux.orig/drivers/misc/sgi-xp/xp_uv.c	2008-10-09 11:14:24.000000000 -0500
+++ linux/drivers/misc/sgi-xp/xp_uv.c	2008-10-09 13:43:27.000000000 -0500
@@ -15,6 +15,11 @@
 
 #include <linux/device.h>
 #include <asm/uv/uv_hub.h>
+#if defined CONFIG_X86_64
+#include <asm/uv/bios.h>
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#include <asm/sn/sn_sal.h>
+#endif
 #include "../sgi-gru/grukservices.h"
 #include "xp.h"
 
@@ -49,6 +54,65 @@ xp_cpu_to_nasid_uv(int cpuid)
 	return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
 }
 
+static enum xp_retval
+xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
+{
+	int ret;
+
+#if defined CONFIG_X86_64
+	ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW);
+	if (ret != BIOS_STATUS_SUCCESS) {
+		dev_err(xp, "uv_bios_change_memprotect(,, "
+			"UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
+		return xpBiosError;
+	}
+
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+	u64 nasid_array;
+
+	ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
+				   &nasid_array);
+	if (ret != 0) {
+		dev_err(xp, "sn_change_memprotect(,, "
+			"SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
+		return xpSalError;
+	}
+#else
+	#error not a supported configuration
+#endif
+	return xpSuccess;
+}
+
+static enum xp_retval
+xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
+{
+	int ret;
+
+#if defined CONFIG_X86_64
+	ret = uv_bios_change_memprotect(phys_addr, size,
+					UV_MEMPROT_RESTRICT_ACCESS);
+	if (ret != BIOS_STATUS_SUCCESS) {
+		dev_err(xp, "uv_bios_change_memprotect(,, "
+			"UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
+		return xpBiosError;
+	}
+
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+	u64 nasid_array;
+
+	ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
+				   &nasid_array);
+	if (ret != 0) {
+		dev_err(xp, "sn_change_memprotect(,, "
+			"SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
+		return xpSalError;
+	}
+#else
+	#error not a supported configuration
+#endif
+	return xpSuccess;
+}
+
 enum xp_retval
 xp_init_uv(void)
 {
@@ -61,6 +125,8 @@ xp_init_uv(void)
 	xp_pa = xp_pa_uv;
 	xp_remote_memcpy = xp_remote_memcpy_uv;
 	xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
+	xp_expand_memprotect = xp_expand_memprotect_uv;
+	xp_restrict_memprotect = xp_restrict_memprotect_uv;
 
 	return xpSuccess;
 }
Index: linux/drivers/misc/sgi-xp/xp.h
===================================================================
--- linux.orig/drivers/misc/sgi-xp/xp.h	2008-10-09 11:14:24.000000000 -0500
+++ linux/drivers/misc/sgi-xp/xp.h	2008-10-09 13:19:24.000000000 -0500
@@ -190,9 +190,10 @@ enum xp_retval {
 	xpGruSendMqError,	/* 59: gru send message queue related error */
 
 	xpBadChannelNumber,	/* 60: invalid channel number */
-	xpBadMsgType,		/* 60: invalid message type */
+	xpBadMsgType,		/* 61: invalid message type */
+	xpBiosError,		/* 62: BIOS error */
 
-	xpUnknownReason		/* 61: unknown reason - must be last in enum */
+	xpUnknownReason		/* 63: unknown reason - must be last in enum */
 };
 
 /*
@@ -341,6 +342,8 @@ 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 enum xp_retval (*xp_expand_memprotect) (unsigned long, unsigned long);
+extern enum xp_retval (*xp_restrict_memprotect) (unsigned long, unsigned long);
 
 extern u64 xp_nofault_PIOR_target;
 extern int xp_nofault_PIOR(void *);
Index: linux/drivers/misc/sgi-xp/xp_main.c
===================================================================
--- linux.orig/drivers/misc/sgi-xp/xp_main.c	2008-10-09 11:14:24.000000000 -0500
+++ linux/drivers/misc/sgi-xp/xp_main.c	2008-10-09 13:18:08.000000000 -0500
@@ -51,6 +51,13 @@ EXPORT_SYMBOL_GPL(xp_remote_memcpy);
 int (*xp_cpu_to_nasid) (int cpuid);
 EXPORT_SYMBOL_GPL(xp_cpu_to_nasid);
 
+enum xp_retval (*xp_expand_memprotect) (unsigned long phys_addr,
+					unsigned long size);
+EXPORT_SYMBOL_GPL(xp_expand_memprotect);
+enum xp_retval (*xp_restrict_memprotect) (unsigned long phys_addr,
+					  unsigned long size);
+EXPORT_SYMBOL_GPL(xp_restrict_memprotect);
+
 /*
  * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
  * users of XPC.
Index: linux/drivers/misc/sgi-xp/xpc_sn2.c
===================================================================
--- linux.orig/drivers/misc/sgi-xp/xpc_sn2.c	2008-10-09 11:14:24.000000000 -0500
+++ linux/drivers/misc/sgi-xp/xpc_sn2.c	2008-10-09 13:20:21.000000000 -0500
@@ -553,22 +553,17 @@ static u64 xpc_prot_vec_sn2[MAX_NUMNODES
 static enum xp_retval
 xpc_allow_amo_ops_sn2(struct amo *amos_page)
 {
-	u64 nasid_array = 0;
-	int ret;
+	enum xp_retval ret = xpSuccess;
 
 	/*
 	 * On SHUB 1.1, we cannot call sn_change_memprotect() since the BIST
 	 * collides with memory operations. On those systems we call
 	 * xpc_allow_amo_ops_shub_wars_1_1_sn2() instead.
 	 */
-	if (!enable_shub_wars_1_1()) {
-		ret = sn_change_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE,
-					   SN_MEMPROT_ACCESS_CLASS_1,
-					   &nasid_array);
-		if (ret != 0)
-			return xpSalError;
-	}
-	return xpSuccess;
+	if (!enable_shub_wars_1_1())
+		ret = xp_expand_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE);
+
+	return ret;
 }
 
 /*

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/4] sgi-xp: create activate and notify gru message queues
  2008-10-21 21:20 [PATCH 0/4] sgi-xp: add low-level hardware specific functionality Dean Nelson
  2008-10-21 21:22 ` [PATCH 1/4] sgi-xp: define xp_expand_memprotect() and xp_restrict_memprotect() Dean Nelson
@ 2008-10-21 21:23 ` Dean Nelson
  2008-10-21 21:24 ` [PATCH 3/4] sgi-xp: define xp_partition_id and xp_region_size Dean Nelson
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Dean Nelson @ 2008-10-21 21:23 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

For UV add the code to create the activate and notify gru message queues.

Signed-off-by: Dean Nelson <dcn@sgi.com>

---

 drivers/misc/sgi-xp/xpc.h    |   26 +
 drivers/misc/sgi-xp/xpc_uv.c |  532 +++++++++++++++++++++++++++++++--------
 2 files changed, 452 insertions(+), 106 deletions(-)

Index: linux/drivers/misc/sgi-xp/xpc_uv.c
===================================================================
--- linux.orig/drivers/misc/sgi-xp/xpc_uv.c	2008-10-21 09:30:36.000000000 -0500
+++ linux/drivers/misc/sgi-xp/xpc_uv.c	2008-10-21 12:15:03.000000000 -0500
@@ -18,7 +18,15 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/err.h>
 #include <asm/uv/uv_hub.h>
+#if defined CONFIG_X86_64
+#include <asm/uv/bios.h>
+#include <asm/uv/uv_irq.h>
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#include <asm/sn/intr.h>
+#include <asm/sn/sn_sal.h>
+#endif
 #include "../sgi-gru/gru.h"
 #include "../sgi-gru/grukservices.h"
 #include "xpc.h"
@@ -27,15 +35,17 @@ static atomic64_t xpc_heartbeat_uv;
 static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
 
 #define XPC_ACTIVATE_MSG_SIZE_UV	(1 * GRU_CACHE_LINE_BYTES)
-#define XPC_NOTIFY_MSG_SIZE_UV		(2 * GRU_CACHE_LINE_BYTES)
+#define XPC_ACTIVATE_MQ_SIZE_UV		(4 * XP_MAX_NPARTITIONS_UV * \
+					 XPC_ACTIVATE_MSG_SIZE_UV)
+#define XPC_ACTIVATE_IRQ_NAME		"xpc_activate"
 
-#define XPC_ACTIVATE_MQ_SIZE_UV	(4 * XP_MAX_NPARTITIONS_UV * \
-				 XPC_ACTIVATE_MSG_SIZE_UV)
-#define XPC_NOTIFY_MQ_SIZE_UV	(4 * XP_MAX_NPARTITIONS_UV * \
-				 XPC_NOTIFY_MSG_SIZE_UV)
+#define XPC_NOTIFY_MSG_SIZE_UV		(2 * GRU_CACHE_LINE_BYTES)
+#define XPC_NOTIFY_MQ_SIZE_UV		(4 * XP_MAX_NPARTITIONS_UV * \
+					 XPC_NOTIFY_MSG_SIZE_UV)
+#define XPC_NOTIFY_IRQ_NAME		"xpc_notify"
 
-static void *xpc_activate_mq_uv;
-static void *xpc_notify_mq_uv;
+static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
+static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
 
 static int
 xpc_setup_partitions_sn_uv(void)
@@ -52,62 +62,209 @@ xpc_setup_partitions_sn_uv(void)
 	return 0;
 }
 
-static void *
-xpc_create_gru_mq_uv(unsigned int mq_size, int cpuid, unsigned int irq,
+static int
+xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
+{
+#if defined CONFIG_X86_64
+	mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset);
+	if (mq->irq < 0) {
+		dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
+			mq->irq);
+	}
+
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+	int mmr_pnode;
+	unsigned long mmr_value;
+
+	if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0)
+		mq->irq = SGI_XPC_ACTIVATE;
+	else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0)
+		mq->irq = SGI_XPC_NOTIFY;
+	else
+		return -EINVAL;
+
+	mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
+	mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
+
+	uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
+#else
+	#error not a supported configuration
+#endif
+
+	return 0;
+}
+
+static void
+xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq)
+{
+#if defined CONFIG_X86_64
+	uv_teardown_irq(mq->irq, mq->mmr_blade, mq->mmr_offset);
+
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+	int mmr_pnode;
+	unsigned long mmr_value;
+
+	mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
+	mmr_value = 1UL << 16;
+
+	uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
+#else
+	#error not a supported configuration
+#endif
+}
+
+static int
+xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
+{
+	int ret;
+
+#if defined CONFIG_X86_64
+	ret = uv_bios_mq_watchlist_alloc(mq->mmr_blade, mq->address, mq->order,
+					 &mq->mmr_offset);
+	if (ret < 0) {
+		dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, "
+			"ret=%d\n", ret);
+		return ret;
+	}
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+	ret = sn_mq_watchlist_alloc(mq->mmr_blade, mq->address, mq->order,
+				    &mq->mmr_offset);
+	if (ret < 0) {
+		dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
+			ret);
+		return -EBUSY;
+	}
+#else
+	#error not a supported configuration
+#endif
+
+	mq->watchlist_num = ret;
+	return 0;
+}
+
+static void
+xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq)
+{
+	int ret;
+
+#if defined CONFIG_X86_64
+	ret = uv_bios_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
+	BUG_ON(ret != BIOS_STATUS_SUCCESS);
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+	ret = sn_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
+	BUG_ON(ret != SALRET_OK);
+#else
+	#error not a supported configuration
+#endif
+}
+
+static struct xpc_gru_mq_uv *
+xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
 		     irq_handler_t irq_handler)
 {
+	enum xp_retval xp_ret;
 	int ret;
 	int nid;
-	int mq_order;
+	int pg_order;
 	struct page *page;
-	void *mq;
+	struct xpc_gru_mq_uv *mq;
+
+	mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL);
+	if (mq == NULL) {
+		dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
+			"a xpc_gru_mq_uv structure\n");
+		ret = -ENOMEM;
+		goto out_1;
+	}
+
+	pg_order = get_order(mq_size);
+	mq->order = pg_order + PAGE_SHIFT;
+	mq_size = 1UL << mq->order;
 
-	nid = cpu_to_node(cpuid);
-	mq_order = get_order(mq_size);
+	mq->mmr_blade = uv_cpu_to_blade_id(cpu);
+
+	nid = cpu_to_node(cpu);
 	page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
-				mq_order);
+				pg_order);
 	if (page == NULL) {
 		dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d "
 			"bytes of memory on nid=%d for GRU mq\n", mq_size, nid);
-		return NULL;
+		ret = -ENOMEM;
+		goto out_2;
 	}
+	mq->address = page_address(page);
 
-	mq = page_address(page);
-	ret = gru_create_message_queue(mq, mq_size);
+	ret = gru_create_message_queue(mq->address, mq_size);
 	if (ret != 0) {
 		dev_err(xpc_part, "gru_create_message_queue() returned "
 			"error=%d\n", ret);
-		free_pages((unsigned long)mq, mq_order);
-		return NULL;
+		ret = -EINVAL;
+		goto out_3;
 	}
 
-	/* !!! Need to do some other things to set up IRQ */
+	/* enable generation of irq when GRU mq operation occurs to this mq */
+	ret = xpc_gru_mq_watchlist_alloc_uv(mq);
+	if (ret != 0)
+		goto out_3;
+
+	ret = xpc_get_gru_mq_irq_uv(mq, cpu, irq_name);
+	if (ret != 0)
+		goto out_4;
 
-	ret = request_irq(irq, irq_handler, 0, "xpc", NULL);
+	ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL);
 	if (ret != 0) {
 		dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n",
-			irq, ret);
-		free_pages((unsigned long)mq, mq_order);
-		return NULL;
+			mq->irq, ret);
+		goto out_5;
 	}
 
-	/* !!! enable generation of irq when GRU mq op occurs to this mq */
-
-	/* ??? allow other partitions to access GRU mq? */
+	/* allow other partitions to access this GRU mq */
+	xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size);
+	if (xp_ret != xpSuccess) {
+		ret = -EACCES;
+		goto out_6;
+	}
 
 	return mq;
+
+	/* something went wrong */
+out_6:
+	free_irq(mq->irq, NULL);
+out_5:
+	xpc_release_gru_mq_irq_uv(mq);
+out_4:
+	xpc_gru_mq_watchlist_free_uv(mq);
+out_3:
+	free_pages((unsigned long)mq->address, pg_order);
+out_2:
+	kfree(mq);
+out_1:
+	return ERR_PTR(ret);
 }
 
 static void
-xpc_destroy_gru_mq_uv(void *mq, unsigned int mq_size, unsigned int irq)
+xpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq)
 {
-	/* ??? disallow other partitions to access GRU mq? */
+	unsigned int mq_size;
+	int pg_order;
+	int ret;
+
+	/* disallow other partitions to access GRU mq */
+	mq_size = 1UL << mq->order;
+	ret = xp_restrict_memprotect(xp_pa(mq->address), mq_size);
+	BUG_ON(ret != xpSuccess);
+
+	/* unregister irq handler and release mq irq/vector mapping */
+	free_irq(mq->irq, NULL);
+	xpc_release_gru_mq_irq_uv(mq);
 
-	/* !!! disable generation of irq when GRU mq op occurs to this mq */
+	/* disable generation of irq when GRU mq op occurs to this mq */
+	xpc_gru_mq_watchlist_free_uv(mq);
 
-	free_irq(irq, NULL);
+	pg_order = mq->order - PAGE_SHIFT;
+	free_pages((unsigned long)mq->address, pg_order);
 
-	free_pages((unsigned long)mq, get_order(mq_size));
+	kfree(mq);
 }
 
 static enum xp_retval
@@ -402,7 +559,10 @@ xpc_handle_activate_IRQ_uv(int irq, void
 	struct xpc_partition *part;
 	int wakeup_hb_checker = 0;
 
-	while ((msg_hdr = gru_get_next_message(xpc_activate_mq_uv)) != NULL) {
+	while (1) {
+		msg_hdr = gru_get_next_message(xpc_activate_mq_uv->address);
+		if (msg_hdr == NULL)
+			break;
 
 		partid = msg_hdr->partid;
 		if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) {
@@ -418,7 +578,7 @@ xpc_handle_activate_IRQ_uv(int irq, void
 			}
 		}
 
-		gru_free_message(xpc_activate_mq_uv, msg_hdr);
+		gru_free_message(xpc_activate_mq_uv->address, msg_hdr);
 	}
 
 	if (wakeup_hb_checker)
@@ -507,7 +667,7 @@ xpc_get_partition_rsvd_page_pa_uv(void *
 static int
 xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp)
 {
-	rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv);
+	rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv->address);
 	return 0;
 }
 
@@ -1411,22 +1571,18 @@ xpc_init_uv(void)
 		return -E2BIG;
 	}
 
-	/* ??? The cpuid argument's value is 0, is that what we want? */
-	/* !!! The irq argument's value isn't correct. */
-	xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, 0,
+	xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0,
+						  XPC_ACTIVATE_IRQ_NAME,
 						  xpc_handle_activate_IRQ_uv);
-	if (xpc_activate_mq_uv == NULL)
-		return -ENOMEM;
+	if (IS_ERR(xpc_activate_mq_uv))
+		return PTR_ERR(xpc_activate_mq_uv);
 
-	/* ??? The cpuid argument's value is 0, is that what we want? */
-	/* !!! The irq argument's value isn't correct. */
-	xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, 0,
+	xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0,
+						XPC_NOTIFY_IRQ_NAME,
 						xpc_handle_notify_IRQ_uv);
-	if (xpc_notify_mq_uv == NULL) {
-		/* !!! The irq argument's value isn't correct. */
-		xpc_destroy_gru_mq_uv(xpc_activate_mq_uv,
-				      XPC_ACTIVATE_MQ_SIZE_UV, 0);
-		return -ENOMEM;
+	if (IS_ERR(xpc_notify_mq_uv)) {
+		xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
+		return PTR_ERR(xpc_notify_mq_uv);
 	}
 
 	return 0;
@@ -1435,9 +1591,6 @@ xpc_init_uv(void)
 void
 xpc_exit_uv(void)
 {
-	/* !!! The irq argument's value isn't correct. */
-	xpc_destroy_gru_mq_uv(xpc_notify_mq_uv, XPC_NOTIFY_MQ_SIZE_UV, 0);
-
-	/* !!! The irq argument's value isn't correct. */
-	xpc_destroy_gru_mq_uv(xpc_activate_mq_uv, XPC_ACTIVATE_MQ_SIZE_UV, 0);
+	xpc_destroy_gru_mq_uv(xpc_notify_mq_uv);
+	xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
 }
Index: linux/drivers/misc/sgi-xp/xpc.h
===================================================================
--- linux.orig/drivers/misc/sgi-xp/xpc.h	2008-10-21 09:30:36.000000000 -0500
+++ linux/drivers/misc/sgi-xp/xpc.h	2008-10-21 11:28:31.000000000 -0500
@@ -181,6 +181,18 @@ struct xpc_vars_part_sn2 {
 				  xpc_nasid_mask_nlongs))
 
 /*
+ * Info pertinent to a GRU message queue using a watch list for irq generation.
+ */
+struct xpc_gru_mq_uv {
+	void *address;		/* address of GRU message queue */
+	unsigned int order;	/* size of GRU message queue as a power of 2 */
+	int irq;		/* irq raised when message is received in mq */
+	int mmr_blade;		/* blade where watchlist was allocated from */
+	unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */
+	int watchlist_num;	/* number of watchlist allocatd by BIOS */
+};
+
+/*
  * 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.
  */

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/4] sgi-xp: define xp_partition_id and xp_region_size
  2008-10-21 21:20 [PATCH 0/4] sgi-xp: add low-level hardware specific functionality Dean Nelson
  2008-10-21 21:22 ` [PATCH 1/4] sgi-xp: define xp_expand_memprotect() and xp_restrict_memprotect() Dean Nelson
  2008-10-21 21:23 ` [PATCH 2/4] sgi-xp: create activate and notify gru message queues Dean Nelson
@ 2008-10-21 21:24 ` Dean Nelson
  2008-10-21 21:25 ` [PATCH 4/4] sgi-xp: support getting the address of a partition's reserved page Dean Nelson
  2008-10-21 22:45 ` [PATCH 0/4] sgi-xp: add low-level hardware specific functionality Andrew Morton
  4 siblings, 0 replies; 6+ messages in thread
From: Dean Nelson @ 2008-10-21 21:24 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

Define xp_partition_id and xp_region_size to their correct values.

Signed-off-by: Dean Nelson <dcn@sgi.com>

---

 drivers/misc/sgi-xp/xp_uv.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux/drivers/misc/sgi-xp/xp_uv.c
===================================================================
--- linux.orig/drivers/misc/sgi-xp/xp_uv.c	2008-10-20 14:21:31.000000000 -0500
+++ linux/drivers/misc/sgi-xp/xp_uv.c	2008-10-20 14:29:31.000000000 -0500
@@ -119,8 +119,8 @@ 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_partition_id = sn_partition_id;
+	xp_region_size = sn_region_size;
 
 	xp_pa = xp_pa_uv;
 	xp_remote_memcpy = xp_remote_memcpy_uv;

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/4] sgi-xp: support getting the address of a partition's reserved page
  2008-10-21 21:20 [PATCH 0/4] sgi-xp: add low-level hardware specific functionality Dean Nelson
                   ` (2 preceding siblings ...)
  2008-10-21 21:24 ` [PATCH 3/4] sgi-xp: define xp_partition_id and xp_region_size Dean Nelson
@ 2008-10-21 21:25 ` Dean Nelson
  2008-10-21 22:45 ` [PATCH 0/4] sgi-xp: add low-level hardware specific functionality Andrew Morton
  4 siblings, 0 replies; 6+ messages in thread
From: Dean Nelson @ 2008-10-21 21:25 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

Add support for getting the address of a partition's reserved page.

Signed-off-by: Dean Nelson <dcn@sgi.com>

---

 drivers/misc/sgi-xp/xpc_uv.c |   31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

Index: linux/drivers/misc/sgi-xp/xpc_uv.c
===================================================================
--- linux.orig/drivers/misc/sgi-xp/xpc_uv.c	2008-10-21 12:50:18.000000000 -0500
+++ linux/drivers/misc/sgi-xp/xpc_uv.c	2008-10-21 14:00:13.000000000 -0500
@@ -642,7 +642,7 @@ xpc_send_local_activate_IRQ_uv(struct xp
 	struct xpc_partition_uv *part_uv = &part->sn.uv;
 
 	/*
-	 * !!! Make our side think that the remote parition sent an activate
+	 * !!! Make our side think that the remote partition sent an activate
 	 * !!! message our way by doing what the activate IRQ handler would
 	 * !!! do had one really been sent.
 	 */
@@ -660,8 +660,33 @@ static enum xp_retval
 xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
 				  size_t *len)
 {
-	/* !!! call the UV version of sn_partition_reserved_page_pa() */
-	return xpUnsupported;
+	s64 status;
+	enum xp_retval ret;
+
+#if defined CONFIG_X86_64
+	status = uv_bios_reserved_page_pa((u64)buf, cookie, (u64 *)rp_pa,
+					  (u64 *)len);
+	if (status == BIOS_STATUS_SUCCESS)
+		ret = xpSuccess;
+	else if (status == BIOS_STATUS_MORE_PASSES)
+		ret = xpNeedMoreInfo;
+	else
+		ret = xpBiosError;
+
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+	status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len);
+	if (status == SALRET_OK)
+		ret = xpSuccess;
+	else if (status == SALRET_MORE_PASSES)
+		ret = xpNeedMoreInfo;
+	else
+		ret = xpSalError;
+
+#else
+	#error not a supported configuration
+#endif
+
+	return ret;
 }
 
 static int

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] sgi-xp: add low-level hardware specific functionality
  2008-10-21 21:20 [PATCH 0/4] sgi-xp: add low-level hardware specific functionality Dean Nelson
                   ` (3 preceding siblings ...)
  2008-10-21 21:25 ` [PATCH 4/4] sgi-xp: support getting the address of a partition's reserved page Dean Nelson
@ 2008-10-21 22:45 ` Andrew Morton
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Morton @ 2008-10-21 22:45 UTC (permalink / raw)
  To: Dean Nelson; +Cc: linux-kernel, Ingo Molnar, Thomas Gleixner

On Tue, 21 Oct 2008 16:20:54 -0500
Dean Nelson <dcn@sgi.com> wrote:

> This patchset adds some low-level hardware specific functionality to the
> xp/xpc drivers.
> 
> To build cleanly this patchset is dependent on the following patches
> submitted by Russ Anderson <rja@sgi.com>.
> 
> [PATCH] x86: Use consistent names for region size and conherence id on x86 and ia64.
>  (see http://marc.info/?l=linux-kernel&m=122461625304772&w=2)
> 
> [PATCH 1/3] x86: Add UV watchlist bios call
>  (see http://marc.info/?l=linux-kernel&m=122461934110503&w=2)
> [PATCH 2/3] x86: Add UV memory protection bios call
>  (see http://marc.info/?l=linux-kernel&m=122461934110506&w=2)
> [PATCH 3/3] x86: Add UV reserved page bios call
>  (see http://marc.info/?l=linux-kernel&m=122461934210509&w=2)
> 
> [PATCH] Add UV watchlist support
>  (see http://marc.info/?l=linux-ia64&m=122462371418298&w=2)

OK, so I need to go into hiding until/unless those patches turn up in
linux-next.

Please poke me if I forget.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-10-21 22:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-21 21:20 [PATCH 0/4] sgi-xp: add low-level hardware specific functionality Dean Nelson
2008-10-21 21:22 ` [PATCH 1/4] sgi-xp: define xp_expand_memprotect() and xp_restrict_memprotect() Dean Nelson
2008-10-21 21:23 ` [PATCH 2/4] sgi-xp: create activate and notify gru message queues Dean Nelson
2008-10-21 21:24 ` [PATCH 3/4] sgi-xp: define xp_partition_id and xp_region_size Dean Nelson
2008-10-21 21:25 ` [PATCH 4/4] sgi-xp: support getting the address of a partition's reserved page Dean Nelson
2008-10-21 22:45 ` [PATCH 0/4] sgi-xp: add low-level hardware specific functionality Andrew Morton

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.