Prepared XPC and XPNET for future support of SGI's UV architecture. Made
changes so it compiles on x86_64. Added support for up to 256 partitions.
Cleaned up BTE error conversion for is64 sn2.
Signed-off-by: Dean Nelson <dcn@sgi.com>
---
arch/ia64/sn/kernel/setup.c | 4
drivers/misc/Kconfig | 2
drivers/misc/xp/Makefile | 5
drivers/misc/xp/xp.h | 382 ++++++++++----------
drivers/misc/xp/xp_main.c | 181 ++++++---
drivers/misc/xp/xp_nofault.S | 2
drivers/misc/xp/xp_sn2.c | 487 ++++++++++++++++++++++++++
drivers/misc/xp/xp_uv.c | 194 ++++++++++
drivers/misc/xp/xpc.h | 594 +++++++++++++++----------------
drivers/misc/xp/xpc_channel.c | 357 +++++++++----------
drivers/misc/xp/xpc_main.c | 273 +++++++-------
drivers/misc/xp/xpc_partition.c | 670 +++++++++++++++---------------------
drivers/misc/xp/xpnet.c | 280 ++++++---------
include/asm-ia64/sn/arch.h | 5
include/asm-ia64/sn/bte.h | 5
15 files changed, 2010 insertions(+), 1431 deletions(-)
Index: linux-2.6/drivers/misc/xp/xp.h
===================================================================
--- linux-2.6.orig/drivers/misc/xp/xp.h 2008-03-26 10:40:03.156341458 -0500
+++ linux-2.6/drivers/misc/xp/xp.h 2008-03-26 10:41:15.529157874 -0500
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004-2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2004-2008 Silicon Graphics, Inc. All rights reserved.
*/
@@ -12,15 +12,28 @@
*/
-#ifndef _ASM_IA64_SN_XP_H
-#define _ASM_IA64_SN_XP_H
+#ifndef _DRIVERS_MISC_XP_XP_H
+#define _DRIVERS_MISC_XP_XP_H
#include <linux/cache.h>
#include <linux/hardirq.h>
#include <linux/mutex.h>
-#include <asm/sn/types.h>
-#include <asm/sn/bte.h>
+#ifdef CONFIG_IA64
+#include <asm/sn/arch.h>
+#endif
+
+/* >>> Add these two #defines to some linux header file some day. */
+#define BYTES_PER_WORD sizeof(void *)
+#define BITS_PER_WORD (BYTES_PER_WORD * BITS_PER_BYTE)
+
+#if defined(CONFIG_IA64)
+#define U64_ELL "l"
+#elif defined(CONFIG_X86_64)
+#define U64_ELL "ll"
+#else
+#error architecture is NOT supported
+#endif
#ifdef USE_DBUG_ON
@@ -30,6 +43,23 @@
#endif
+#ifndef is_shub1
+#define is_shub1() 0
+#endif
+
+#ifndef is_shub2
+#define is_shub2() 0
+#endif
+
+#ifndef is_shub
+#define is_shub() 0
+#endif
+
+#ifndef is_uv
+#define is_uv() 0
+#endif
+
+
/*
* Define the maximum number of logically defined partitions the system
* can support. It is constrained by the maximum number of hardware
@@ -41,60 +71,15 @@
* maximum number of nodes in the entire system divided by the minimum number
* of nodes that comprise an access protection grouping.
*/
-#define XP_MAX_PARTITIONS 64
-
-
-/*
- * Define the number of u64s required to represent all the C-brick nasids
- * as a bitmap. The cross-partition kernel modules deal only with
- * C-brick nasids, thus the need for bitmaps which don't account for
- * odd-numbered (non C-brick) nasids.
- */
-#define XP_MAX_PHYSNODE_ID (MAX_NUMALINK_NODES / 2)
-#define XP_NASID_MASK_BYTES ((XP_MAX_PHYSNODE_ID + 7) / 8)
-#define XP_NASID_MASK_WORDS ((XP_MAX_PHYSNODE_ID + 63) / 64)
-
+#define XP_NPARTITIONS 64 /* #of partitions allowed */
+#define XP_MAX_NPARTITIONS 256 /* max #of partitions possible */
-/*
- * Wrapper for bte_copy() that should it return a failure status will retry
- * the bte_copy() once in the hope that the failure was due to a temporary
- * aberration (i.e., the link going down temporarily).
- *
- * src - physical address of the source of the transfer.
- * vdst - virtual address of the destination of the transfer.
- * len - number of bytes to transfer from source to destination.
- * mode - see bte_copy() for definition.
- * notification - see bte_copy() for definition.
- *
- * Note: xp_bte_copy() should never be called while holding a spinlock.
- */
-static inline bte_result_t
-xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
-{
- bte_result_t ret;
- u64 pdst = ia64_tpa(vdst);
-
-
- /*
- * Ensure that the physically mapped memory is contiguous.
- *
- * We do this by ensuring that the memory is from region 7 only.
- * If the need should arise to use memory from one of the other
- * regions, then modify the BUG_ON() statement to ensure that the
- * memory from that region is always physically contiguous.
- */
- BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL);
-
- ret = bte_copy(src, pdst, len, mode, notification);
- if ((ret != BTE_SUCCESS) && BTE_ERROR_RETRY(ret)) {
- if (!in_interrupt()) {
- cond_resched();
- }
- ret = bte_copy(src, pdst, len, mode, notification);
- }
+#if XP_NPARTITIONS > XP_MAX_NPARTITIONS
+#error XP_NPARTITIONS exceeds MAXIMUM possible.
+#endif
- return ret;
-}
+#define XP_MIN_PARTID 1 /* inclusive */
+#define XP_MAX_PARTID (XP_NPARTITIONS - 1) /* inclusive */
/*
@@ -115,11 +100,11 @@ xp_bte_copy(u64 src, u64 vdst, u64 len,
#define XPC_MEM_CHANNEL 0 /* memory channel number */
#define XPC_NET_CHANNEL 1 /* network channel number */
-#define XPC_NCHANNELS 2 /* #of defined channels */
-#define XPC_MAX_NCHANNELS 8 /* max #of channels allowed */
+#define XPC_NCHANNELS 2 /* #of channels allowed */
+#define XPC_MAX_NCHANNELS 8 /* max #of channels possible */
#if XPC_NCHANNELS > XPC_MAX_NCHANNELS
-#error XPC_NCHANNELS exceeds MAXIMUM allowed.
+#error XPC_NCHANNELS exceeds MAXIMUM possible.
#endif
@@ -133,7 +118,7 @@ xp_bte_copy(u64 src, u64 vdst, u64 len,
* +----------------------------------------+
* | payload (user-defined message) |
* | |
- * :
+ * :
* | |
* +----------------------------------------+
*
@@ -169,106 +154,103 @@ struct xpc_msg {
/*
* Define the return values and values passed to user's callout functions.
* (It is important to add new value codes at the end just preceding
- * xpcUnknownReason, which must have the highest numerical value.)
+ * xpUnknownReason, which must have the highest numerical value.)
*/
-enum xpc_retval {
- xpcSuccess = 0,
-
- xpcNotConnected, /* 1: channel is not connected */
- xpcConnected, /* 2: channel connected (opened) */
- xpcRETIRED1, /* 3: (formerly xpcDisconnected) */
-
- xpcMsgReceived, /* 4: message received */
- xpcMsgDelivered, /* 5: message delivered and acknowledged */
-
- xpcRETIRED2, /* 6: (formerly xpcTransferFailed) */
-
- xpcNoWait, /* 7: operation would require wait */
- xpcRetry, /* 8: retry operation */
- xpcTimeout, /* 9: timeout in xpc_allocate_msg_wait() */
- xpcInterrupted, /* 10: interrupted wait */
-
- xpcUnequalMsgSizes, /* 11: message size disparity between sides */
- xpcInvalidAddress, /* 12: invalid address */
+enum xp_retval {
+ xpSuccess = 0,
- xpcNoMemory, /* 13: no memory available for XPC structures */
- xpcLackOfResources, /* 14: insufficient resources for operation */
- xpcUnregistered, /* 15: channel is not registered */
- xpcAlreadyRegistered, /* 16: channel is already registered */
+ xpNotConnected, /* 1: channel is not connected */
+ xpConnected, /* 2: channel connected (opened) */
+ xpRETIRED1, /* 3: (formerly xpDisconnected) */
- xpcPartitionDown, /* 17: remote partition is down */
- xpcNotLoaded, /* 18: XPC module is not loaded */
- xpcUnloading, /* 19: this side is unloading XPC module */
+ xpMsgReceived, /* 4: message received */
+ xpMsgDelivered, /* 5: message delivered and acknowledged */
- xpcBadMagic, /* 20: XPC MAGIC string not found */
+ xpRETIRED2, /* 6: (formerly xpTransferFailed) */
- xpcReactivating, /* 21: remote partition was reactivated */
+ xpNoWait, /* 7: operation would require wait */
+ xpRetry, /* 8: retry operation */
+ xpTimeout, /* 9: timeout in xpc_allocate_msg_wait() */
+ xpInterrupted, /* 10: interrupted wait */
- xpcUnregistering, /* 22: this side is unregistering channel */
- xpcOtherUnregistering, /* 23: other side is unregistering channel */
+ xpUnequalMsgSizes, /* 11: message size disparity between sides */
+ xpInvalidAddress, /* 12: invalid address */
- xpcCloneKThread, /* 24: cloning kernel thread */
- xpcCloneKThreadFailed, /* 25: cloning kernel thread failed */
+ xpNoMemory, /* 13: no memory available for XPC structures */
+ xpLackOfResources, /* 14: insufficient resources for operation */
+ xpUnregistered, /* 15: channel is not registered */
+ xpAlreadyRegistered, /* 16: channel is already registered */
- xpcNoHeartbeat, /* 26: remote partition has no heartbeat */
+ xpPartitionDown, /* 17: remote partition is down */
+ xpNotLoaded, /* 18: XPC module is not loaded */
+ xpUnloading, /* 19: this side is unloading XPC module */
- xpcPioReadError, /* 27: PIO read error */
- xpcPhysAddrRegFailed, /* 28: registration of phys addr range failed */
+ xpBadMagic, /* 20: XPC MAGIC string not found */
- xpcBteDirectoryError, /* 29: maps to BTEFAIL_DIR */
- xpcBtePoisonError, /* 30: maps to BTEFAIL_POISON */
- xpcBteWriteError, /* 31: maps to BTEFAIL_WERR */
- xpcBteAccessError, /* 32: maps to BTEFAIL_ACCESS */
- xpcBtePWriteError, /* 33: maps to BTEFAIL_PWERR */
- xpcBtePReadError, /* 34: maps to BTEFAIL_PRERR */
- xpcBteTimeOutError, /* 35: maps to BTEFAIL_TOUT */
- xpcBteXtalkError, /* 36: maps to BTEFAIL_XTERR */
- xpcBteNotAvailable, /* 37: maps to BTEFAIL_NOTAVAIL */
- xpcBteUnmappedError, /* 38: unmapped BTEFAIL_ error */
+ xpReactivating, /* 21: remote partition was reactivated */
- xpcBadVersion, /* 39: bad version number */
- xpcVarsNotSet, /* 40: the XPC variables are not set up */
- xpcNoRsvdPageAddr, /* 41: unable to get rsvd page's phys addr */
- xpcInvalidPartid, /* 42: invalid partition ID */
- xpcLocalPartid, /* 43: local partition ID */
+ xpUnregistering, /* 22: this side is unregistering channel */
+ xpOtherUnregistering, /* 23: other side is unregistering channel */
- xpcOtherGoingDown, /* 44: other side going down, reason unknown */
- xpcSystemGoingDown, /* 45: system is going down, reason unknown */
- xpcSystemHalt, /* 46: system is being halted */
- xpcSystemReboot, /* 47: system is being rebooted */
- xpcSystemPoweroff, /* 48: system is being powered off */
+ xpCloneKThread, /* 24: cloning kernel thread */
+ xpCloneKThreadFailed, /* 25: cloning kernel thread failed */
- xpcDisconnecting, /* 49: channel disconnecting (closing) */
+ xpNoHeartbeat, /* 26: remote partition has no heartbeat */
- xpcOpenCloseError, /* 50: channel open/close protocol error */
+ xpPioReadError, /* 27: PIO read error */
+ xpPhysAddrRegFailed, /* 28: registration of phys addr range failed */
- xpcDisconnected, /* 51: channel disconnected (closed) */
+ xpRETIRED3, /* 29: (formerly xpBteDirectoryError) */
+ xpRETIRED4, /* 30: (formerly xpBtePoisonError) */
+ xpRETIRED5, /* 31: (formerly xpBteWriteError) */
+ xpRETIRED6, /* 32: (formerly xpBteAccessError) */
+ xpRETIRED7, /* 33: (formerly xpBtePWriteError) */
+ xpRETIRED8, /* 34: (formerly xpBtePReadError) */
+ xpRETIRED9, /* 35: (formerly xpBteTimeOutError) */
+ xpRETIRED10, /* 36: (formerly xpBteXtalkError) */
+ xpRETIRED11, /* 37: (formerly xpBteNotAvailable) */
+ xpRETIRED12, /* 38: (formerly xpBteUnmappedError) */
- xpcBteSh2Start, /* 52: BTE CRB timeout */
+ xpBadVersion, /* 39: bad version number */
+ xpVarsNotSet, /* 40: the XPC variables are not set up */
+ xpNoRsvdPageAddr, /* 41: unable to get rsvd page's phys addr */
+ xpInvalidPartid, /* 42: invalid partition ID */
+ xpLocalPartid, /* 43: local partition ID */
- /* 53: 0x1 BTE Error Response Short */
- xpcBteSh2RspShort = xpcBteSh2Start + BTEFAIL_SH2_RESP_SHORT,
+ xpOtherGoingDown, /* 44: other side going down, reason unknown */
+ xpSystemGoingDown, /* 45: system is going down, reason unknown */
+ xpSystemHalt, /* 46: system is being halted */
+ xpSystemReboot, /* 47: system is being rebooted */
+ xpSystemPoweroff, /* 48: system is being powered off */
- /* 54: 0x2 BTE Error Response Long */
- xpcBteSh2RspLong = xpcBteSh2Start + BTEFAIL_SH2_RESP_LONG,
+ xpDisconnecting, /* 49: channel disconnecting (closing) */
- /* 56: 0x4 BTE Error Response DSB */
- xpcBteSh2RspDSB = xpcBteSh2Start + BTEFAIL_SH2_RESP_DSP,
+ xpOpenCloseError, /* 50: channel open/close protocol error */
- /* 60: 0x8 BTE Error Response Access */
- xpcBteSh2RspAccess = xpcBteSh2Start + BTEFAIL_SH2_RESP_ACCESS,
+ xpDisconnected, /* 51: channel disconnected (closed) */
- /* 68: 0x10 BTE Error CRB timeout */
- xpcBteSh2CRBTO = xpcBteSh2Start + BTEFAIL_SH2_CRB_TO,
+ xpBteCopyError, /* 52: bte_copy() returned error */
+ xpSalError, /* 53: sn SAL error */
+ xpNeedMoreInfo, /* 54: more info is needed by SAL */
- /* 84: 0x20 BTE Error NACK limit */
- xpcBteSh2NACKLimit = xpcBteSh2Start + BTEFAIL_SH2_NACK_LIMIT,
+ xpUnsupported, /* 55: unsupported functionality or resource */
+ xpUnknownReason /* 56: unknown reason (must be last in list) */
+};
- /* 115: BTE end */
- xpcBteSh2End = xpcBteSh2Start + BTEFAIL_SH2_ALL,
- xpcUnknownReason /* 116: unknown reason -- must be last in list */
-};
+/* the following are valid xp_set_amo() ops */
+#define XP_AMO_OR 1 /* set variable to (variable | operand) */
+#define XP_AMO_AND 2 /* set variable to (variable & operand) */
+
+/* the following are valid xp_get_amo() ops */
+#define XP_AMO_LOAD 1 /* get variable contents */
+#define XP_AMO_CLEAR 2 /* get variable contents and clear variable */
+
+/* the following are valid xp_change_memprotect() ops */
+#define XP_MEMPROT_DISALLOW_ALL 0
+#define XP_MEMPROT_ALLOW_CPU_AMO 1
+#define XP_MEMPROT_ALLOW_CPU_MEM 2
+#define XP_MEMPROT_ALLOW_ALL 3 /* Shub 1.1 only */
/*
@@ -302,83 +284,83 @@ enum xpc_retval {
*
* Reason Code | Cause | Optional Data
* =====================+================================+=====================
- * xpcConnected | connection has been established| max #of entries
+ * xpConnected | connection has been established| max #of entries
* | to the specified partition on | allowed in message
* | the specified channel | queue
* ---------------------+--------------------------------+---------------------
- * xpcMsgReceived | an XPC message arrived from | address of payload
+ * xpMsgReceived | an XPC message arrived from | address of payload
* | the specified partition on the |
* | specified channel | [the user must call
* | | xpc_received() when
* | | finished with the
* | | payload]
* ---------------------+--------------------------------+---------------------
- * xpcMsgDelivered | notification that the message | NA
+ * xpMsgDelivered | notification that the message | NA
* | was delivered to the intended |
* | recipient and that they have |
* | acknowledged its receipt by |
* | calling xpc_received() |
* =====================+================================+=====================
- * xpcUnequalMsgSizes | can't connect to the specified | NULL
+ * xpUnequalMsgSizes | can't connect to the specified | NULL
* | partition on the specified |
* | channel because of mismatched |
* | message sizes |
* ---------------------+--------------------------------+---------------------
- * xpcNoMemory | insufficient memory avaiable | NULL
+ * xpNoMemory | insufficient memory avaiable | NULL
* | to allocate message queue |
* ---------------------+--------------------------------+---------------------
- * xpcLackOfResources | lack of resources to create | NULL
+ * xpLackOfResources | lack of resources to create | NULL
* | the necessary kthreads to |
* | support the channel |
* ---------------------+--------------------------------+---------------------
- * xpcUnregistering | this side's user has | NULL or NA
+ * xpUnregistering | this side's user has | NULL or NA
* | unregistered by calling |
* | xpc_disconnect() |
* ---------------------+--------------------------------+---------------------
- * xpcOtherUnregistering| the other side's user has | NULL or NA
+ * xpOtherUnregistering | the other side's user has | NULL or NA
* | unregistered by calling |
* | xpc_disconnect() |
* ---------------------+--------------------------------+---------------------
- * xpcNoHeartbeat | the other side's XPC is no | NULL or NA
+ * xpNoHeartbeat | the other side's XPC is no | NULL or NA
* | longer heartbeating |
* | |
* ---------------------+--------------------------------+---------------------
- * xpcUnloading | this side's XPC module is | NULL or NA
+ * xpUnloading | this side's XPC module is | NULL or NA
* | being unloaded |
* | |
* ---------------------+--------------------------------+---------------------
- * xpcOtherUnloading | the other side's XPC module is | NULL or NA
+ * xpOtherUnloading | the other side's XPC module is | NULL or NA
* | is being unloaded |
* | |
* ---------------------+--------------------------------+---------------------
- * xpcPioReadError | xp_nofault_PIOR() returned an | NULL or NA
+ * xpPioReadError | xp_nofault_PIOR() returned an | NULL or NA
* | error while sending an IPI |
* | |
* ---------------------+--------------------------------+---------------------
- * xpcInvalidAddress | the address either received or | NULL or NA
+ * xpInvalidAddress | the address either received or | NULL or NA
* | sent by the specified partition|
* | is invalid |
* ---------------------+--------------------------------+---------------------
- * xpcBteNotAvailable | attempt to pull data from the | NULL or NA
- * xpcBtePoisonError | specified partition over the |
- * xpcBteWriteError | specified channel via a |
- * xpcBteAccessError | bte_copy() failed |
- * xpcBteTimeOutError | |
- * xpcBteXtalkError | |
- * xpcBteDirectoryError | |
- * xpcBteGenericError | |
- * xpcBteUnmappedError | |
+ * xpBteNotAvailable | attempt to pull data from the | NULL or NA
+ * xpBtePoisonError | specified partition over the |
+ * xpBteWriteError | specified channel via a |
+ * xpBteAccessError | bte_copy() failed |
+ * xpBteTimeOutError | |
+ * xpBteXtalkError | |
+ * xpBteDirectoryError | |
+ * xpBteGenericError | |
+ * xpBteUnmappedError | |
* ---------------------+--------------------------------+---------------------
- * xpcUnknownReason | the specified channel to the | NULL or NA
+ * xpUnknownReason | the specified channel to the | NULL or NA
* | specified partition was |
* | unavailable for unknown reasons|
* =====================+================================+=====================
*/
-typedef void (*xpc_channel_func)(enum xpc_retval reason, partid_t partid,
+typedef void (*xpc_channel_func)(enum xp_retval reason, short partid,
int ch_number, void *data, void *key);
-typedef void (*xpc_notify_func)(enum xpc_retval reason, partid_t partid,
+typedef void (*xpc_notify_func)(enum xp_retval reason, short partid,
int ch_number, void *key);
@@ -418,12 +400,12 @@ struct xpc_registration {
struct xpc_interface {
void (*connect)(int);
void (*disconnect)(int);
- enum xpc_retval (*allocate)(partid_t, int, u32, void **);
- enum xpc_retval (*send)(partid_t, int, void *);
- enum xpc_retval (*send_notify)(partid_t, int, void *,
+ enum xp_retval (*allocate)(short, int, u32, void **);
+ enum xp_retval (*send)(short, int, void *);
+ enum xp_retval (*send_notify)(short, int, void *,
xpc_notify_func, void *);
- void (*received)(partid_t, int, void *);
- enum xpc_retval (*partid_to_nasids)(partid_t, void *);
+ void (*received)(short, int, void *);
+ enum xp_retval (*partid_to_nasids)(short, void *);
};
@@ -431,55 +413,91 @@ extern struct xpc_interface xpc_interfac
extern void xpc_set_interface(void (*)(int),
void (*)(int),
- enum xpc_retval (*)(partid_t, int, u32, void **),
- enum xpc_retval (*)(partid_t, int, void *),
- enum xpc_retval (*)(partid_t, int, void *, xpc_notify_func,
+ enum xp_retval (*)(short, int, u32, void **),
+ enum xp_retval (*)(short, int, void *),
+ enum xp_retval (*)(short, int, void *, xpc_notify_func,
void *),
- void (*)(partid_t, int, void *),
- enum xpc_retval (*)(partid_t, void *));
+ void (*)(short, int, void *),
+ enum xp_retval (*)(short, void *));
extern void xpc_clear_interface(void);
-extern enum xpc_retval xpc_connect(int, xpc_channel_func, void *, u16,
+extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16,
u16, u32, u32);
extern void xpc_disconnect(int);
-static inline enum xpc_retval
-xpc_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
+static inline enum xp_retval
+xpc_allocate(short partid, int ch_number, u32 flags, void **payload)
{
return xpc_interface.allocate(partid, ch_number, flags, payload);
}
-static inline enum xpc_retval
-xpc_send(partid_t partid, int ch_number, void *payload)
+static inline enum xp_retval
+xpc_send(short partid, int ch_number, void *payload)
{
return xpc_interface.send(partid, ch_number, payload);
}
-static inline enum xpc_retval
-xpc_send_notify(partid_t partid, int ch_number, void *payload,
+static inline enum xp_retval
+xpc_send_notify(short partid, int ch_number, void *payload,
xpc_notify_func func, void *key)
{
return xpc_interface.send_notify(partid, ch_number, payload, func, key);
}
static inline void
-xpc_received(partid_t partid, int ch_number, void *payload)
+xpc_received(short partid, int ch_number, void *payload)
{
return xpc_interface.received(partid, ch_number, payload);
}
-static inline enum xpc_retval
-xpc_partid_to_nasids(partid_t partid, void *nasids)
+static inline enum xp_retval
+xpc_partid_to_nasids(short partid, void *nasids)
{
return xpc_interface.partid_to_nasids(partid, nasids);
}
+extern short xp_partition_id;
+extern u8 xp_region_size;
+extern unsigned long xp_rtc_cycles_per_second;
+extern enum xp_retval (*xp_remote_memcpy)(void *, const void *, size_t);
+extern enum xp_retval (*xp_register_remote_amos)(u64, size_t);
+extern enum xp_retval (*xp_unregister_remote_amos)(u64, size_t);
+extern int xp_sizeof_nasid_mask;
+extern int xp_sizeof_amo;
+extern u64 *(*xp_alloc_amos)(int);
+extern void (*xp_free_amos)(u64 *, int);
+extern enum xp_retval (*xp_set_amo)(u64 *, int, u64, int);
+extern enum xp_retval (*xp_set_amo_with_interrupt)(u64 *, int, u64, int, int,
+ int, int);
+extern enum xp_retval (*xp_get_amo)(u64 *, int, u64 *);
+extern enum xp_retval (*xp_get_partition_rsvd_page_pa)(u64, u64 *, u64 *,
+ size_t *);
+extern enum xp_retval (*xp_change_memprotect)(u64, size_t, int, u64 *);
+extern void (*xp_change_memprotect_shub_wars_1_1)(int);
+extern void (*xp_allow_IPI_ops)(void);
+extern void (*xp_disallow_IPI_ops)(void);
+
+extern int (*xp_cpu_to_nasid)(int);
+extern int (*xp_node_to_nasid)(int);
extern u64 xp_nofault_PIOR_target;
extern int xp_nofault_PIOR(void *);
extern int xp_error_PIOR(void);
-#endif /* _ASM_IA64_SN_XP_H */
+static inline int
+xp_partid_mask_words(int npartitions)
+{
+ return DIV_ROUND_UP(npartitions, BITS_PER_WORD);
+}
+
+static inline int
+xp_nasid_mask_words(void)
+{
+ return DIV_ROUND_UP(xp_sizeof_nasid_mask, BYTES_PER_WORD);
+}
+
+
+#endif /* _DRIVERS_MISC_XP_XP_H */
Index: linux-2.6/drivers/misc/xp/xp_main.c
===================================================================
--- linux-2.6.orig/drivers/misc/xp/xp_main.c 2008-03-26 10:40:03.160341945 -0500
+++ linux-2.6/drivers/misc/xp/xp_main.c 2008-03-26 10:41:24.502251175 -0500
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
*/
@@ -17,41 +17,77 @@
#include <linux/kernel.h>
-#include <linux/interrupt.h>
#include <linux/module.h>
-#include <linux/mutex.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/xp.h>
+#include <linux/device.h>
+#include "xp.h"
+/* Define the XP debug device structures to be used with dev_dbg() et al */
+
+struct device_driver xp_dbg_name = {
+ .name = "xp"
+};
+
+struct device xp_dbg_subname = {
+ .bus_id = {0}, /* set to "" */
+ .driver = &xp_dbg_name
+};
+
+struct device *xp = &xp_dbg_subname;
/*
* Target of nofault PIO read.
*/
u64 xp_nofault_PIOR_target;
+short xp_partition_id;
+u8 xp_region_size;
+unsigned long xp_rtc_cycles_per_second;
-/*
- * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
- * users of XPC.
- */
-struct xpc_registration xpc_registrations[XPC_NCHANNELS];
+enum xp_retval (*xp_remote_memcpy)(void *dst, const void *src, size_t len);
+
+enum xp_retval (*xp_register_remote_amos)(u64 paddr, size_t len);
+enum xp_retval (*xp_unregister_remote_amos)(u64 paddr, size_t len);
+
+int xp_sizeof_nasid_mask;
+int xp_sizeof_amo;
+
+u64 *(*xp_alloc_amos)(int n_amos);
+void (*xp_free_amos)(u64 *amos_page, int n_amos);
+
+enum xp_retval (*xp_set_amo)(u64 *amo_va, int op, u64 operand, int remote);
+enum xp_retval (*xp_set_amo_with_interrupt)(u64 *amo_va, int op, u64 operand,
+ int remote, int nasid,
+ int phys_cpuid, int vector);
+
+enum xp_retval (*xp_get_amo)(u64 *amo_va, int op, u64 *amo_value_addr);
+
+enum xp_retval (*xp_get_partition_rsvd_page_pa)(u64 buf, u64 *cookie,
+ u64 *paddr, size_t *len);
+
+enum xp_retval (*xp_change_memprotect)(u64 paddr, size_t len, int request,
+ u64 *nasid_array);
+void (*xp_change_memprotect_shub_wars_1_1)(int request);
+void (*xp_allow_IPI_ops)(void);
+void (*xp_disallow_IPI_ops)(void);
+
+int (*xp_cpu_to_nasid)(int cpuid);
+int (*xp_node_to_nasid)(int nid);
/*
* Initialize the XPC interface to indicate that XPC isn't loaded.
*/
-static enum xpc_retval xpc_notloaded(void) { return xpcNotLoaded; }
+static enum xp_retval xpc_notloaded(void) { return xpNotLoaded; }
struct xpc_interface xpc_interface = {
(void (*)(int)) xpc_notloaded,
(void (*)(int)) xpc_notloaded,
- (enum xpc_retval (*)(partid_t, int, u32, void **)) xpc_notloaded,
- (enum xpc_retval (*)(partid_t, int, void *)) xpc_notloaded,
- (enum xpc_retval (*)(partid_t, int, void *, xpc_notify_func, void *))
+ (enum xp_retval (*)(short, int, u32, void **)) xpc_notloaded,
+ (enum xp_retval (*)(short, int, void *)) xpc_notloaded,
+ (enum xp_retval (*)(short, int, void *, xpc_notify_func, void *))
xpc_notloaded,
- (void (*)(partid_t, int, void *)) xpc_notloaded,
- (enum xpc_retval (*)(partid_t, void *)) xpc_notloaded
+ (void (*)(short, int, void *)) xpc_notloaded,
+ (enum xp_retval (*)(short, void *)) xpc_notloaded
};
@@ -61,12 +97,12 @@ struct xpc_interface xpc_interface = {
void
xpc_set_interface(void (*connect)(int),
void (*disconnect)(int),
- enum xpc_retval (*allocate)(partid_t, int, u32, void **),
- enum xpc_retval (*send)(partid_t, int, void *),
- enum xpc_retval (*send_notify)(partid_t, int, void *,
+ enum xp_retval (*allocate)(short, int, u32, void **),
+ enum xp_retval (*send)(short, int, void *),
+ enum xp_retval (*send_notify)(short, int, void *,
xpc_notify_func, void *),
- void (*received)(partid_t, int, void *),
- enum xpc_retval (*partid_to_nasids)(partid_t, void *))
+ void (*received)(short, int, void *),
+ enum xp_retval (*partid_to_nasids)(short, void *))
{
xpc_interface.connect = connect;
xpc_interface.disconnect = disconnect;
@@ -86,20 +122,27 @@ xpc_clear_interface(void)
{
xpc_interface.connect = (void (*)(int)) xpc_notloaded;
xpc_interface.disconnect = (void (*)(int)) xpc_notloaded;
- xpc_interface.allocate = (enum xpc_retval (*)(partid_t, int, u32,
+ xpc_interface.allocate = (enum xp_retval (*)(short, int, u32,
void **)) xpc_notloaded;
- xpc_interface.send = (enum xpc_retval (*)(partid_t, int, void *))
+ xpc_interface.send = (enum xp_retval (*)(short, int, void *))
xpc_notloaded;
- xpc_interface.send_notify = (enum xpc_retval (*)(partid_t, int, void *,
+ xpc_interface.send_notify = (enum xp_retval (*)(short, int, void *,
xpc_notify_func, void *)) xpc_notloaded;
- xpc_interface.received = (void (*)(partid_t, int, void *))
+ xpc_interface.received = (void (*)(short, int, void *))
xpc_notloaded;
- xpc_interface.partid_to_nasids = (enum xpc_retval (*)(partid_t, void *))
+ xpc_interface.partid_to_nasids = (enum xp_retval (*)(short, void *))
xpc_notloaded;
}
/*
+ * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
+ * users of XPC.
+ */
+struct xpc_registration xpc_registrations[XPC_NCHANNELS];
+
+
+/*
* Register for automatic establishment of a channel connection whenever
* a partition comes up.
*
@@ -116,14 +159,14 @@ xpc_clear_interface(void)
* this large enough to hold their largest message.
* nentries - max #of XPC message entries a message queue can contain.
* The actual number, which is determined when a connection
- * is established and may be less then requested, will be
- * passed to the user via the xpcConnected callout.
+ * is established and may be less then requested, will be
+ * passed to the user via the xpConnected callout.
* assigned_limit - max number of kthreads allowed to be processing
- * messages (per connection) at any given instant.
+ * messages (per connection) at any given instant.
* idle_limit - max number of kthreads allowed to be idle at any given
- * instant.
+ * instant.
*/
-enum xpc_retval
+enum xp_retval
xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
u16 nentries, u32 assigned_limit, u32 idle_limit)
{
@@ -138,13 +181,13 @@ xpc_connect(int ch_number, xpc_channel_f
registration = &xpc_registrations[ch_number];
if (mutex_lock_interruptible(®istration->mutex) != 0) {
- return xpcInterrupted;
+ return xpInterrupted;
}
/* if XPC_CHANNEL_REGISTERED(ch_number) */
if (registration->func != NULL) {
mutex_unlock(®istration->mutex);
- return xpcAlreadyRegistered;
+ return xpAlreadyRegistered;
}
/* register the channel for connection */
@@ -159,7 +202,7 @@ xpc_connect(int ch_number, xpc_channel_f
xpc_interface.connect(ch_number);
- return xpcSuccess;
+ return xpSuccess;
}
@@ -214,43 +257,26 @@ xpc_disconnect(int ch_number)
return;
}
+extern enum xp_retval xp_init_sn2(void);
+extern enum xp_retval xp_init_uv(void);
int __init
xp_init(void)
{
- int ret, ch_number;
- u64 func_addr = *(u64 *) xp_nofault_PIOR;
- u64 err_func_addr = *(u64 *) xp_error_PIOR;
+ enum xp_retval ret;
+ int ch_number;
+ if (is_shub())
+ ret = xp_init_sn2();
+ else if (is_uv())
+ ret = xp_init_uv();
+ else
+ ret = xpUnsupported;
- if (!ia64_platform_is("sn2")) {
+ if (ret != xpSuccess) {
return -ENODEV;
}
- /*
- * Register a nofault code region which performs a cross-partition
- * PIO read. If the PIO read times out, the MCA handler will consume
- * the error and return to a kernel-provided instruction to indicate
- * an error. This PIO read exists because it is guaranteed to timeout
- * if the destination is down (AMO operations do not timeout on at
- * least some CPUs on Shubs <= v1.2, which unfortunately we have to
- * work around).
- */
- if ((ret = sn_register_nofault_code(func_addr, err_func_addr,
- err_func_addr, 1, 1)) != 0) {
- printk(KERN_ERR "XP: can't register nofault code, error=%d\n",
- ret);
- }
- /*
- * Setup the nofault PIO read target. (There is no special reason why
- * SH_IPI_ACCESS was selected.)
- */
- if (is_shub2()) {
- xp_nofault_PIOR_target = SH2_IPI_ACCESS0;
- } else {
- xp_nofault_PIOR_target = SH1_IPI_ACCESS;
- }
-
/* initialize the connection registration mutex */
for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
mutex_init(&xpc_registrations[ch_number].mutex);
@@ -260,17 +286,16 @@ xp_init(void)
}
module_init(xp_init);
+extern void xp_exit_sn2(void);
+extern void xp_exit_uv(void);
void __exit
xp_exit(void)
{
- u64 func_addr = *(u64 *) xp_nofault_PIOR;
- u64 err_func_addr = *(u64 *) xp_error_PIOR;
-
-
- /* unregister the PIO read nofault code region */
- (void) sn_register_nofault_code(func_addr, err_func_addr,
- err_func_addr, 1, 0);
+ if (is_shub())
+ xp_exit_sn2();
+ else if (is_uv())
+ xp_exit_uv();
}
module_exit(xp_exit);
@@ -279,8 +304,26 @@ MODULE_AUTHOR("Silicon Graphics, Inc.");
MODULE_DESCRIPTION("Cross Partition (XP) base");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(xp_nofault_PIOR);
-EXPORT_SYMBOL(xp_nofault_PIOR_target);
+EXPORT_SYMBOL(xp_partition_id);
+EXPORT_SYMBOL(xp_region_size);
+EXPORT_SYMBOL(xp_rtc_cycles_per_second);
+EXPORT_SYMBOL(xp_remote_memcpy);
+EXPORT_SYMBOL(xp_register_remote_amos);
+EXPORT_SYMBOL(xp_unregister_remote_amos);
+EXPORT_SYMBOL(xp_sizeof_nasid_mask);
+EXPORT_SYMBOL(xp_sizeof_amo);
+EXPORT_SYMBOL(xp_alloc_amos);
+EXPORT_SYMBOL(xp_free_amos);
+EXPORT_SYMBOL(xp_set_amo);
+EXPORT_SYMBOL(xp_set_amo_with_interrupt);
+EXPORT_SYMBOL(xp_get_amo);
+EXPORT_SYMBOL(xp_get_partition_rsvd_page_pa);
+EXPORT_SYMBOL(xp_change_memprotect);
+EXPORT_SYMBOL(xp_change_memprotect_shub_wars_1_1);
+EXPORT_SYMBOL(xp_allow_IPI_ops);
+EXPORT_SYMBOL(xp_disallow_IPI_ops);
+EXPORT_SYMBOL(xp_cpu_to_nasid);
+EXPORT_SYMBOL(xp_node_to_nasid);
EXPORT_SYMBOL(xpc_registrations);
EXPORT_SYMBOL(xpc_interface);
EXPORT_SYMBOL(xpc_clear_interface);
Index: linux-2.6/drivers/misc/xp/xpc.h
===================================================================
--- linux-2.6.orig/drivers/misc/xp/xpc.h 2008-03-26 10:40:03.160341945 -0500
+++ linux-2.6/drivers/misc/xp/xpc.h 2008-03-26 10:41:38.940010397 -0500
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2004-2007 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
*/
@@ -11,8 +11,8 @@
* Cross Partition Communication (XPC) structures and macros.
*/
-#ifndef _ASM_IA64_SN_XPC_H
-#define _ASM_IA64_SN_XPC_H
+#ifndef _DRIVERS_MISC_XP_XPC_H
+#define _DRIVERS_MISC_XP_XPC_H
#include <linux/interrupt.h>
@@ -22,12 +22,15 @@
#include <linux/completion.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
-#include <asm/sn/bte.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/mspec.h>
-#include <asm/sn/shub_mmr.h>
-#include <asm/sn/xp.h>
+#if defined(CONFIG_IA64)
+#include <asm/sn/intr.h>
+#elif defined(CONFIG_X86_64)
+#define SGI_XPC_ACTIVATE 0x30
+#define SGI_XPC_NOTIFY 0xe7
+#else
+#error architecture is NOT supported
+#endif
+#include "xp.h"
/*
@@ -43,7 +46,7 @@
/*
* The next macros define word or bit representations for given
* C-brick nasid in either the SAL provided bit array representing
- * nasids in the partition/machine or the AMO_t array used for
+ * nasids in the partition/machine or the array of AMO variables used for
* inter-partition initiation communications.
*
* For SN2 machines, C-Bricks are alway even numbered NASIDs. As
@@ -51,11 +54,7 @@
* passed from SAL always be packed for C-Bricks and the
* cross-partition interrupts use the same packing scheme.
*/
-#define XPC_NASID_W_INDEX(_n) (((_n) / 64) / 2)
-#define XPC_NASID_B_INDEX(_n) (((_n) / 2) & (64 - 1))
-#define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[XPC_NASID_W_INDEX(_n)] & \
- (1UL << XPC_NASID_B_INDEX(_n)))
-#define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2)
+#define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[BIT_WORD((_n)/2)] & BIT_MASK((_n)/2))
#define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */
#define XPC_HB_CHECK_DEFAULT_INTERVAL 20 /* check HB every x secs */
@@ -80,8 +79,8 @@
* The first cacheline of the reserved page contains the header
* (struct xpc_rsvd_page). Before SAL initialization has completed,
* SAL has set up the following fields of the reserved page header:
- * SAL_signature, SAL_version, partid, and nasids_size. The other
- * fields are set up by XPC. (xpc_rsvd_page points to the local
+ * SAL_signature, SAL_version, SAL_partid, and SAL_nasids_size. The
+ * other fields are set up by XPC. (xpc_rsvd_page points to the local
* partition's reserved page.)
*
* part_nasids mask
@@ -112,16 +111,16 @@
struct xpc_rsvd_page {
u64 SAL_signature; /* SAL: unique signature */
u64 SAL_version; /* SAL: version */
- u8 partid; /* SAL: partition ID */
+ u8 SAL_partid; /* SAL: partition ID */
u8 version;
- u8 pad1[6]; /* align to next u64 in cacheline */
- volatile u64 vars_pa;
+ u8 pad[6];
+ volatile u64 vars_pa; /* physical address of struct xpc_vars */
struct timespec stamp; /* time when reserved page was setup by XPC */
u64 pad2[9]; /* align to last u64 in cacheline */
- u64 nasids_size; /* SAL: size of each nasid mask in bytes */
+ u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */
};
-#define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */
+#define XPC_RP_VERSION _XPC_VERSION(2,0) /* version 2.0 of the reserved page */
#define XPC_SUPPORTS_RP_STAMP(_version) \
(_version >= _XPC_VERSION(1,1))
@@ -162,65 +161,109 @@ xpc_compare_stamps(struct timespec *stam
*/
struct xpc_vars {
u8 version;
- u64 heartbeat;
- u64 heartbeating_to_mask;
- u64 heartbeat_offline; /* if 0, heartbeat should be changing */
+ short partid;
+ short npartitions; /* value of XPC_NPARTITIONS */
int act_nasid;
int act_phys_cpuid;
u64 vars_part_pa;
- u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */
- AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */
+ u64 amos_page_pa; /* paddr of first page of AMOs variables */
+ u64 *amos_page; /* vaddr of first page of AMOs variables */
+ u64 heartbeat;
+ u64 heartbeat_offline; /* if 0, heartbeat should be changing */
+ u64 heartbeating_to_mask[BITS_TO_LONGS(XP_MAX_NPARTITIONS)];
};
-#define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */
+#define XPC_V_VERSION _XPC_VERSION(4,0) /* version 4.0 of the cross vars */
#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \
(_version >= _XPC_VERSION(3,1))
static inline int
-xpc_hb_allowed(partid_t partid, struct xpc_vars *vars)
+xpc_hb_allowed(short partid, struct xpc_vars *vars)
{
- return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
+ return test_bit(partid, vars->heartbeating_to_mask);
+}
+
+static inline int
+xpc_any_hbs_allowed(struct xpc_vars *vars)
+{
+ return !bitmap_empty((unsigned long *)vars->heartbeating_to_mask,
+ vars->npartitions);
}
static inline void
-xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
+xpc_allow_hb(short partid, struct xpc_vars *vars)
{
- u64 old_mask, new_mask;
+ set_bit(partid, vars->heartbeating_to_mask);
+}
- do {
- old_mask = vars->heartbeating_to_mask;
- new_mask = (old_mask | (1UL << partid));
- } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
- old_mask);
+static inline void
+xpc_disallow_hb(short partid, struct xpc_vars *vars)
+{
+ clear_bit(partid, vars->heartbeating_to_mask);
}
static inline void
-xpc_disallow_hb(partid_t partid, struct xpc_vars *vars)
+xpc_disallow_all_hbs(struct xpc_vars *vars)
{
- u64 old_mask, new_mask;
+ int nlongs = BITS_TO_LONGS(vars->npartitions);
+ int i;
- do {
- old_mask = vars->heartbeating_to_mask;
- new_mask = (old_mask & ~(1UL << partid));
- } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
- old_mask);
+ for (i = 0; i < nlongs; i++)
+ vars->heartbeating_to_mask[i] = 0;
}
/*
- * The AMOs page consists of a number of AMO variables which are divided into
- * four groups, The first two groups are used to identify an IRQ's sender.
- * These two groups consist of 64 and 128 AMO variables respectively. The last
- * two groups, consisting of just one AMO variable each, are used to identify
- * the remote partitions that are currently engaged (from the viewpoint of
- * the XPC running on the remote partition).
+ * The AMOs page(s) consists of a number of AMO variables which are divided into
+ * four groups, The first group consists of one AMO per partition, each of which
+ * reflects state changes of up to eight channels and are accompanied by the
+ * receipt of a NOTIFY IRQ. The second group represents a bitmap of nasids by
+ * which to identify an ACTIVATE IRQ's sender. The last two groups, each
+ * representing a bitmap of partids, are used to identify the remote partitions
+ * that are currently engaged (from the viewpoint of the XPC running on the
+ * remote partition).
+ *
+ * The following #defines reflect an AMO index into these AMOS page(s).
*/
-#define XPC_NOTIFY_IRQ_AMOS 0
-#define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS)
-#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)
-#define XPC_DISENGAGE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1)
+
+/* get offset to beginning of notify IRQ AMOs */
+static inline int
+xpc_notify_irq_amos(void)
+{
+ return 0;
+}
+
+/* get offset to beginning of activate IRQ AMOs */
+static inline int
+xpc_activate_irq_amos(int npartitions)
+{
+ return xpc_notify_irq_amos() + npartitions;
+}
+
+/* get offset to beginning of engaged partitions AMOs */
+static inline int
+xpc_engaged_partitions_amos(int npartitions)
+{
+ return xpc_activate_irq_amos(npartitions) + xp_nasid_mask_words();
+}
+
+/* get offset to beginning of disengaged request AMOs */
+static inline int
+xpc_disengage_request_amos(int npartitions)
+{
+ return xpc_engaged_partitions_amos(npartitions) +
+ xp_partid_mask_words(npartitions);
+}
+
+/* get total number of AMOs */
+static inline int
+xpc_number_of_amos(int npartitions)
+{
+ return xpc_disengage_request_amos(npartitions) +
+ xp_partid_mask_words(npartitions);
+}
/*
@@ -239,7 +282,7 @@ struct xpc_vars_part {
u64 openclose_args_pa; /* physical address of open and close args */
u64 GPs_pa; /* physical address of Get/Put values */
- u64 IPI_amo_pa; /* physical address of IPI AMO_t structure */
+ u64 IPI_amo_pa; /* physical address of IPI AMO variable */
int IPI_nasid; /* nasid of where to send IPIs */
int IPI_phys_cpuid; /* physical CPU ID of where to send IPIs */
@@ -264,12 +307,14 @@ struct xpc_vars_part {
/* the reserved page sizes and offsets */
#define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
-#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars))
+#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars))
-#define XPC_RP_PART_NASIDS(_rp) (u64 *) ((u8 *) _rp + XPC_RP_HEADER_SIZE)
-#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words)
-#define XPC_RP_VARS(_rp) ((struct xpc_vars *) XPC_RP_MACH_NASIDS(_rp) + xp_nasid_mask_words)
-#define XPC_RP_VARS_PART(_rp) (struct xpc_vars_part *) ((u8 *) XPC_RP_VARS(rp) + XPC_RP_VARS_SIZE)
+#define XPC_RP_PART_NASIDS(_rp) (u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE)
+#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
+ xp_nasid_mask_words())
+#define XPC_RP_VARS(_rp) (struct xpc_vars *)(XPC_RP_MACH_NASIDS(_rp) + \
+ xp_nasid_mask_words())
+#define XPC_RP_VARS_PART(_rp) (struct xpc_vars_part *)((u8 *)XPC_RP_VARS(_rp) + XPC_RP_VARS_SIZE)
/*
@@ -428,11 +473,11 @@ struct xpc_notify {
* messages.
*/
struct xpc_channel {
- partid_t partid; /* ID of remote partition connected */
+ short partid; /* ID of remote partition connected */
spinlock_t lock; /* lock for updating this structure */
u32 flags; /* general flags */
- enum xpc_retval reason; /* reason why channel is disconnect'g */
+ enum xp_retval reason; /* reason why channel is disconnect'g */
int reason_line; /* line# disconnect initiated from */
u16 number; /* channel # */
@@ -481,16 +526,11 @@ struct xpc_channel {
/* kthread management related fields */
-// >>> rethink having kthreads_assigned_limit and kthreads_idle_limit; perhaps
-// >>> allow the assigned limit be unbounded and let the idle limit be dynamic
-// >>> dependent on activity over the last interval of time
atomic_t kthreads_assigned; /* #of kthreads assigned to channel */
- u32 kthreads_assigned_limit; /* limit on #of kthreads assigned */
+ u32 kthreads_assigned_limit; /* limit on #of kthreads assigned */
atomic_t kthreads_idle; /* #of kthreads idle waiting for work */
u32 kthreads_idle_limit; /* limit on #of kthreads idle */
atomic_t kthreads_active; /* #of kthreads actively working */
- // >>> following field is temporary
- u32 kthreads_created; /* total #of kthreads created */
wait_queue_head_t idle_wq; /* idle kthread wait queue */
@@ -538,6 +578,8 @@ struct xpc_partition {
/* XPC HB infrastructure */
u8 remote_rp_version; /* version# of partition's rsvd pg */
+ short remote_npartitions; /* value of XPC_NPARTITIONS */
+ u32 flags; /* general flags */
struct timespec remote_rp_stamp;/* time when rsvd pg was initialized */
u64 remote_rp_pa; /* phys addr of partition's rsvd pg */
u64 remote_vars_pa; /* phys addr of partition's vars */
@@ -547,10 +589,11 @@ struct xpc_partition {
int remote_act_nasid; /* active part's act/deact nasid */
int remote_act_phys_cpuid; /* active part's act/deact phys cpuid */
u32 act_IRQ_rcvd; /* IRQs since activation */
- spinlock_t act_lock; /* protect updating of act_state */
+ spinlock_t lock; /* protect updating of act_state and */
+ /* the general flags */
u8 act_state; /* from XPC HB viewpoint */
u8 remote_vars_version; /* version# of partition's vars */
- enum xpc_retval reason; /* reason partition is deactivating */
+ enum xp_retval reason; /* reason partition is deactivating */
int reason_line; /* line# deactivation initiated from */
int reactivate_nasid; /* nasid in partition to reactivate */
@@ -601,9 +644,9 @@ struct xpc_partition {
int remote_IPI_nasid; /* nasid of where to send IPIs */
int remote_IPI_phys_cpuid; /* phys CPU ID of where to send IPIs */
- AMO_t *remote_IPI_amo_va; /* address of remote IPI AMO_t structure */
+ u64 *remote_IPI_amo_va; /* address of remote IPI AMO variable */
- AMO_t *local_IPI_amo_va; /* address of IPI AMO_t structure */
+ u64 *local_IPI_amo_va; /* address of IPI AMO variable */
u64 local_IPI_amo; /* IPI amo flags yet to be handled */
char IPI_owner[8]; /* IPI owner's name */
struct timer_list dropped_IPI_timer; /* dropped IPI timer */
@@ -618,14 +661,17 @@ struct xpc_partition {
} ____cacheline_aligned;
+/* struct xpc_partition flags */
+
+#define XPC_P_RAMOSREGISTERED 0x00000001 /* remote AMOs were registered */
/* 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) \
@@ -634,10 +680,10 @@ struct xpc_partition {
/* 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 */
@@ -646,7 +692,7 @@ struct xpc_partition {
* dropped IPIs. These occur whenever an IPI amo write doesn't complete until
* after the IPI was received.
*/
-#define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ)
+#define XPC_DROPPED_IPI_WAIT_INTERVAL (0.25 * HZ)
/* number of seconds to wait for other partitions to disengage */
@@ -656,7 +702,7 @@ struct xpc_partition {
#define XPC_DISENGAGE_PRINTMSG_INTERVAL 10
-#define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0]))
+#define XPC_PARTID(_p) ((short) ((_p) - &xpc_partitions[0]))
@@ -682,41 +728,41 @@ extern int xpc_exiting;
extern struct xpc_vars *xpc_vars;
extern struct xpc_rsvd_page *xpc_rsvd_page;
extern struct xpc_vars_part *xpc_vars_part;
-extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
+extern struct xpc_partition xpc_partitions[XP_NPARTITIONS + 1];
extern char *xpc_remote_copy_buffer;
extern void *xpc_remote_copy_buffer_base;
extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
extern struct xpc_rsvd_page *xpc_rsvd_page_init(void);
-extern void xpc_allow_IPI_ops(void);
-extern void xpc_restrict_IPI_ops(void);
extern int xpc_identify_act_IRQ_sender(void);
extern int xpc_partition_disengaged(struct xpc_partition *);
-extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *);
+extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
+extern void xpc_deactivate_partition(const int, struct xpc_partition *,
+ enum xp_retval);
extern void xpc_mark_partition_inactive(struct xpc_partition *);
+extern enum xp_retval xpc_register_remote_amos(struct xpc_partition *);
+extern void xpc_unregister_remote_amos(struct xpc_partition *);
extern void xpc_discovery(void);
extern void xpc_check_remote_hb(void);
-extern void xpc_deactivate_partition(const int, struct xpc_partition *,
- enum xpc_retval);
-extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *);
+extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
/* found in xpc_channel.c */
extern void xpc_initiate_connect(int);
extern void xpc_initiate_disconnect(int);
-extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **);
-extern enum xpc_retval xpc_initiate_send(partid_t, int, void *);
-extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *,
+extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **);
+extern enum xp_retval xpc_initiate_send(short, int, void *);
+extern enum xp_retval xpc_initiate_send_notify(short, int, void *,
xpc_notify_func, void *);
-extern void xpc_initiate_received(partid_t, int, void *);
-extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *);
-extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *);
+extern void xpc_initiate_received(short, int, void *);
+extern enum xp_retval xpc_setup_infrastructure(struct xpc_partition *);
+extern enum xp_retval xpc_pull_remote_vars_part(struct xpc_partition *);
extern void xpc_process_channel_activity(struct xpc_partition *);
extern void xpc_connected_callout(struct xpc_channel *);
extern void xpc_deliver_msg(struct xpc_channel *);
extern void xpc_disconnect_channel(const int, struct xpc_channel *,
- enum xpc_retval, unsigned long *);
-extern void xpc_disconnect_callout(struct xpc_channel *, enum xpc_retval);
-extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
+ enum xp_retval, unsigned long *);
+extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
+extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
extern void xpc_teardown_infrastructure(struct xpc_partition *);
@@ -769,7 +815,7 @@ xpc_part_deref(struct xpc_partition *par
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);
}
}
@@ -781,7 +827,7 @@ xpc_part_ref(struct xpc_partition *part)
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);
}
@@ -811,145 +857,123 @@ xpc_part_ref(struct xpc_partition *part)
static inline void
xpc_mark_partition_engaged(struct xpc_partition *part)
{
- unsigned long irq_flags;
- AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
- (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t)));
-
-
- local_irq_save(irq_flags);
+ u64 *amo_va = __va(part->remote_amos_page_pa +
+ (xpc_engaged_partitions_amos(part->remote_npartitions) +
+ BIT_WORD(xp_partition_id)) * xp_sizeof_amo);
/* set bit corresponding to our partid in remote partition's AMO */
- FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR,
- (1UL << sn_partition_id));
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IPIs and AMOs to it until the heartbeat times out.
- */
- (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
- variable), xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
+ (void)xp_set_amo(amo_va, XP_AMO_OR, BIT_MASK(xp_partition_id), 1);
}
static inline void
xpc_mark_partition_disengaged(struct xpc_partition *part)
{
- unsigned long irq_flags;
- AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
- (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t)));
-
-
- local_irq_save(irq_flags);
+ u64 *amo_va = __va(part->remote_amos_page_pa +
+ (xpc_engaged_partitions_amos(part->remote_npartitions) +
+ BIT_WORD(xp_partition_id)) * xp_sizeof_amo);
/* clear bit corresponding to our partid in remote partition's AMO */
- FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
- ~(1UL << sn_partition_id));
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IPIs and AMOs to it until the heartbeat times out.
- */
- (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
- variable), xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
+ (void)xp_set_amo(amo_va, XP_AMO_AND, ~BIT_MASK(xp_partition_id), 1);
}
static inline void
xpc_request_partition_disengage(struct xpc_partition *part)
{
- unsigned long irq_flags;
- AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
- (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
-
-
- local_irq_save(irq_flags);
+ u64 *amo_va = __va(part->remote_amos_page_pa +
+ (xpc_disengage_request_amos(part->remote_npartitions) +
+ BIT_WORD(xp_partition_id)) * xp_sizeof_amo);
/* set bit corresponding to our partid in remote partition's AMO */
- FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR,
- (1UL << sn_partition_id));
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IPIs and AMOs to it until the heartbeat times out.
- */
- (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
- variable), xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
+ (void)xp_set_amo(amo_va, XP_AMO_OR, BIT_MASK(xp_partition_id), 1);
}
static inline void
xpc_cancel_partition_disengage_request(struct xpc_partition *part)
{
- unsigned long irq_flags;
- AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
- (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
-
-
- local_irq_save(irq_flags);
+ u64 *amo_va = __va(part->remote_amos_page_pa +
+ (xpc_disengage_request_amos(part->remote_npartitions) +
+ BIT_WORD(xp_partition_id)) * xp_sizeof_amo);
/* clear bit corresponding to our partid in remote partition's AMO */
- FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
- ~(1UL << sn_partition_id));
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IPIs and AMOs to it until the heartbeat times out.
- */
- (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
- variable), xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
+ (void)xp_set_amo(amo_va, XP_AMO_AND, ~BIT_MASK(xp_partition_id), 1);
}
-static inline u64
-xpc_partition_engaged(u64 partid_mask)
+static inline int
+xpc_any_partition_engaged(void)
{
- AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
+ enum xp_retval ret;
+ int w_index;
+ u64 *amo_va = (u64 *)((u64)xpc_vars->amos_page +
+ xpc_engaged_partitions_amos(xpc_vars->npartitions) *
+ xp_sizeof_amo);
+ u64 amo;
+
+ for (w_index = 0; w_index < xp_partid_mask_words(xpc_vars->npartitions);
+ w_index++) {
+ ret = xp_get_amo(amo_va, XP_AMO_LOAD, &amo);
+ BUG_ON(ret != xpSuccess); /* should never happen */
+ if (amo != 0)
+ return 1;
-
- /* return our partition's AMO variable ANDed with partid_mask */
- return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) &
- partid_mask);
+ amo_va = (u64 *)((u64)amo_va + xp_sizeof_amo);
+ }
+ return 0;
}
static inline u64
-xpc_partition_disengage_requested(u64 partid_mask)
+xpc_partition_engaged(short partid)
{
- AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
+ enum xp_retval ret;
+ u64 *amo_va = (u64 *)((u64)xpc_vars->amos_page +
+ (xpc_engaged_partitions_amos(xpc_vars->npartitions) +
+ BIT_WORD(partid)) * xp_sizeof_amo);
+ u64 amo;
+
+ /* return our partition's AMO variable ANDed with partid mask */
+ ret = xp_get_amo(amo_va, XP_AMO_LOAD, &amo);
+ BUG_ON(ret != xpSuccess); /* should never happen */
+ return (amo & BIT_MASK(partid));
+}
+static inline u64
+xpc_partition_disengage_requested(short partid)
+{
+ enum xp_retval ret;
+ u64 *amo_va = (u64 *)((u64)xpc_vars->amos_page +
+ (xpc_disengage_request_amos(xpc_vars->npartitions) +
+ BIT_WORD(partid)) * xp_sizeof_amo);
+ u64 amo;
- /* return our partition's AMO variable ANDed with partid_mask */
- return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) &
- partid_mask);
+ /* return our partition's AMO variable ANDed with partid mask */
+ ret = xp_get_amo(amo_va, XP_AMO_LOAD, &amo);
+ BUG_ON(ret != xpSuccess); /* should never happen */
+ return (amo & BIT_MASK(partid));
}
static inline void
-xpc_clear_partition_engaged(u64 partid_mask)
+xpc_clear_partition_engaged(short partid)
{
- AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
+ enum xp_retval ret;
+ u64 *amo_va = (u64 *)((u64)xpc_vars->amos_page +
+ (xpc_engaged_partitions_amos(xpc_vars->npartitions) +
+ BIT_WORD(partid)) * xp_sizeof_amo);
-
- /* clear bit(s) based on partid_mask in our partition's AMO */
- FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
- ~partid_mask);
+ /* clear bit corresponding to partid in our partition's AMO */
+ ret = xp_set_amo(amo_va, XP_AMO_AND, ~BIT_MASK(partid), 0);
+ BUG_ON(ret != xpSuccess); /* should never happen */
}
static inline void
-xpc_clear_partition_disengage_request(u64 partid_mask)
+xpc_clear_partition_disengage_request(short partid)
{
- AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
-
+ enum xp_retval ret;
+ u64 *amo_va = (u64 *)((u64)xpc_vars->amos_page +
+ (xpc_disengage_request_amos(xpc_vars->npartitions) +
+ BIT_WORD(partid)) * xp_sizeof_amo);
- /* clear bit(s) based on partid_mask in our partition's AMO */
- FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
- ~partid_mask);
+ /* clear bit corresponding to partid in our partition's AMO */
+ ret = xp_set_amo(amo_va, XP_AMO_AND, ~BIT_MASK(partid), 0);
+ BUG_ON(ret != xpSuccess); /* should never happen */
}
@@ -961,40 +985,6 @@ xpc_clear_partition_disengage_request(u6
* the other that is associated with channel activity (SGI_XPC_NOTIFY).
*/
-static inline u64
-xpc_IPI_receive(AMO_t *amo)
-{
- return FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_CLEAR);
-}
-
-
-static inline enum xpc_retval
-xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
-{
- int ret = 0;
- unsigned long irq_flags;
-
-
- local_irq_save(irq_flags);
-
- FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, flag);
- sn_send_IPI_phys(nasid, phys_cpuid, vector, 0);
-
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IPIs and AMOs to it until the heartbeat times out.
- */
- ret = xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->variable),
- xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
-
- return ((ret == 0) ? xpcSuccess : xpcPioReadError);
-}
-
-
/*
* IPIs associated with SGI_XPC_ACTIVATE IRQ.
*/
@@ -1004,44 +994,53 @@ xpc_IPI_send(AMO_t *amo, u64 flag, int n
*/
static inline void
xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid,
- int to_phys_cpuid)
+ int to_phys_cpuid, int remote_amo, int npartitions)
{
- int w_index = XPC_NASID_W_INDEX(from_nasid);
- int b_index = XPC_NASID_B_INDEX(from_nasid);
- AMO_t *amos = (AMO_t *) __va(amos_page_pa +
- (XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t)));
-
-
- (void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid,
- to_phys_cpuid, SGI_XPC_ACTIVATE);
+ enum xp_retval ret;
+ /* SN nodes are always even numbered nasids */
+ u64 *amo_va = (u64 *)__va(amos_page_pa +
+ (xpc_activate_irq_amos(npartitions) +
+ BIT_WORD(from_nasid/2)) * xp_sizeof_amo);
+
+ ret = xp_set_amo_with_interrupt(amo_va, XP_AMO_OR,
+ BIT_MASK(from_nasid/2),
+ remote_amo, to_nasid,
+ to_phys_cpuid, SGI_XPC_ACTIVA| Amit K. Arora | [RFC] Heads up on sys_fallocate() |
| Linus Torvalds | Linux 2.6.23-rc9 and a heads-up for the 2.6.24 series.. |
| Paul Jackson | Re: cpuset-remove-sched-domain-hooks-from-cpusets |
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
git: | |
| Linus Torvalds | Re: [GIT]: Networking |
| David Miller | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| Gerrit Renker | [PATCH 27/37] dccp: Integration of dynamic feature activation - part 2 (server side) |
| David Miller | Re: [klibc] [patch] import socket defines |
