LKML Archive on 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).