forked from Minki/linux
misc/sgi-xp: remove SGI SN2 support
Note this also marks xp broken on ia64 now, as the UV support, which
was disable in generic kernels before actually never compiled due to
undefined uv_gpa_to_soc_phys_ram and uv_gpa_in_mmr_space symbols since
at least commit c2c9f11574
("x86: uv: update XPC to handle updated
BIOS interface").
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lkml.kernel.org/r/20190813072514.23299-11-hch@lst.de
Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
parent
0fef2532d2
commit
9726bfcdb9
@ -19,12 +19,8 @@ EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
|
||||
|
||||
#ifdef CONFIG_IA64_SGI_UV
|
||||
int sn_prom_type;
|
||||
long sn_partition_id;
|
||||
EXPORT_SYMBOL(sn_partition_id);
|
||||
long sn_coherency_id;
|
||||
EXPORT_SYMBOL_GPL(sn_coherency_id);
|
||||
long sn_region_size;
|
||||
EXPORT_SYMBOL(sn_region_size);
|
||||
#endif
|
||||
|
||||
struct redir_addr {
|
||||
|
@ -200,9 +200,8 @@ config ENCLOSURE_SERVICES
|
||||
config SGI_XP
|
||||
tristate "Support communication between SGI SSIs"
|
||||
depends on NET
|
||||
depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_UV) && SMP
|
||||
select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
|
||||
select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
|
||||
depends on (IA64_GENERIC || IA64_SGI_UV || X86_UV) && SMP
|
||||
depends on X86_64 || BROKEN
|
||||
select SGI_GRU if X86_64 && SMP
|
||||
---help---
|
||||
An SGI machine can be divided into multiple Single System
|
||||
|
@ -4,17 +4,10 @@
|
||||
#
|
||||
|
||||
obj-$(CONFIG_SGI_XP) += xp.o
|
||||
xp-y := xp_main.o
|
||||
xp-$(CONFIG_IA64_SGI_SN2) += xp_sn2.o xp_nofault.o
|
||||
xp-$(CONFIG_IA64_GENERIC) += xp_sn2.o xp_nofault.o
|
||||
xp-$(CONFIG_IA64_SGI_UV) += xp_uv.o
|
||||
xp-$(CONFIG_X86_64) += xp_uv.o
|
||||
xp-y := xp_main.o xp_uv.o
|
||||
|
||||
obj-$(CONFIG_SGI_XP) += xpc.o
|
||||
xpc-y := xpc_main.o xpc_channel.o xpc_partition.o
|
||||
xpc-$(CONFIG_IA64_SGI_SN2) += xpc_sn2.o
|
||||
xpc-$(CONFIG_IA64_GENERIC) += xpc_sn2.o
|
||||
xpc-$(CONFIG_IA64_SGI_UV) += xpc_uv.o
|
||||
xpc-$(CONFIG_X86_64) += xpc_uv.o
|
||||
xpc-y := xpc_main.o xpc_channel.o xpc_partition.o \
|
||||
xpc_uv.o
|
||||
|
||||
obj-$(CONFIG_SGI_XP) += xpnet.o
|
||||
|
@ -24,23 +24,6 @@
|
||||
#define is_uv() 0
|
||||
#endif
|
||||
|
||||
#if defined CONFIG_IA64
|
||||
#include <asm/sn/arch.h> /* defines is_shub1() and is_shub2() */
|
||||
#define is_shub() ia64_platform_is("sn2")
|
||||
#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
|
||||
|
||||
#ifdef USE_DBUG_ON
|
||||
#define DBUG_ON(condition) BUG_ON(condition)
|
||||
#else
|
||||
@ -360,9 +343,7 @@ extern int xp_nofault_PIOR(void *);
|
||||
extern int xp_error_PIOR(void);
|
||||
|
||||
extern struct device *xp;
|
||||
extern enum xp_retval xp_init_sn2(void);
|
||||
extern enum xp_retval xp_init_uv(void);
|
||||
extern void xp_exit_sn2(void);
|
||||
extern void xp_exit_uv(void);
|
||||
|
||||
#endif /* _DRIVERS_MISC_SGIXP_XP_H */
|
||||
|
@ -233,9 +233,7 @@ xp_init(void)
|
||||
for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++)
|
||||
mutex_init(&xpc_registrations[ch_number].mutex);
|
||||
|
||||
if (is_shub())
|
||||
ret = xp_init_sn2();
|
||||
else if (is_uv())
|
||||
if (is_uv())
|
||||
ret = xp_init_uv();
|
||||
else
|
||||
ret = 0;
|
||||
@ -251,9 +249,7 @@ module_init(xp_init);
|
||||
void __exit
|
||||
xp_exit(void)
|
||||
{
|
||||
if (is_shub())
|
||||
xp_exit_sn2();
|
||||
else if (is_uv())
|
||||
if (is_uv())
|
||||
xp_exit_uv();
|
||||
}
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The xp_nofault_PIOR function takes a pointer to a remote PIO register
|
||||
* and attempts to load and consume a value from it. This function
|
||||
* will be registered as a nofault code block. In the event that the
|
||||
* PIO read fails, the MCA handler will force the error to look
|
||||
* corrected and vector to the xp_error_PIOR which will return an error.
|
||||
*
|
||||
* The definition of "consumption" and the time it takes for an MCA
|
||||
* to surface is processor implementation specific. This code
|
||||
* is sufficient on Itanium through the Montvale processor family.
|
||||
* It may need to be adjusted for future processor implementations.
|
||||
*
|
||||
* extern int xp_nofault_PIOR(void *remote_register);
|
||||
*/
|
||||
|
||||
.global xp_nofault_PIOR
|
||||
xp_nofault_PIOR:
|
||||
mov r8=r0 // Stage a success return value
|
||||
ld8.acq r9=[r32];; // PIO Read the specified register
|
||||
adds r9=1,r9;; // Add to force consumption
|
||||
srlz.i;; // Allow time for MCA to surface
|
||||
br.ret.sptk.many b0;; // Return success
|
||||
|
||||
.global xp_error_PIOR
|
||||
xp_error_PIOR:
|
||||
mov r8=1 // Return value of 1
|
||||
br.ret.sptk.many b0;; // Return failure
|
@ -1,190 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Cross Partition (XP) sn2-based functions.
|
||||
*
|
||||
* Architecture specific implementation of common functions.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <asm/sn/bte.h>
|
||||
#include <asm/sn/sn_sal.h>
|
||||
#include "xp.h"
|
||||
|
||||
/*
|
||||
* The export of xp_nofault_PIOR needs to happen here since it is defined
|
||||
* in drivers/misc/sgi-xp/xp_nofault.S. The target of the nofault read is
|
||||
* defined here.
|
||||
*/
|
||||
EXPORT_SYMBOL_GPL(xp_nofault_PIOR);
|
||||
|
||||
u64 xp_nofault_PIOR_target;
|
||||
EXPORT_SYMBOL_GPL(xp_nofault_PIOR_target);
|
||||
|
||||
/*
|
||||
* 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).
|
||||
*/
|
||||
static enum xp_retval
|
||||
xp_register_nofault_code_sn2(void)
|
||||
{
|
||||
int ret;
|
||||
u64 func_addr;
|
||||
u64 err_func_addr;
|
||||
|
||||
func_addr = *(u64 *)xp_nofault_PIOR;
|
||||
err_func_addr = *(u64 *)xp_error_PIOR;
|
||||
ret = sn_register_nofault_code(func_addr, err_func_addr, err_func_addr,
|
||||
1, 1);
|
||||
if (ret != 0) {
|
||||
dev_err(xp, "can't register nofault code, error=%d\n", ret);
|
||||
return xpSalError;
|
||||
}
|
||||
/*
|
||||
* Setup the nofault PIO read target. (There is no special reason why
|
||||
* SH_IPI_ACCESS was selected.)
|
||||
*/
|
||||
if (is_shub1())
|
||||
xp_nofault_PIOR_target = SH1_IPI_ACCESS;
|
||||
else if (is_shub2())
|
||||
xp_nofault_PIOR_target = SH2_IPI_ACCESS0;
|
||||
|
||||
return xpSuccess;
|
||||
}
|
||||
|
||||
static void
|
||||
xp_unregister_nofault_code_sn2(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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a virtual memory address to a physical memory address.
|
||||
*/
|
||||
static unsigned long
|
||||
xp_pa_sn2(void *addr)
|
||||
{
|
||||
return __pa(addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a global physical to a socket physical address.
|
||||
*/
|
||||
static unsigned long
|
||||
xp_socket_pa_sn2(unsigned long gpa)
|
||||
{
|
||||
return gpa;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for bte_copy().
|
||||
*
|
||||
* dst_pa - physical address of the destination of the transfer.
|
||||
* src_pa - physical address of the source of the transfer.
|
||||
* len - number of bytes to transfer from source to destination.
|
||||
*
|
||||
* Note: xp_remote_memcpy_sn2() should never be called while holding a spinlock.
|
||||
*/
|
||||
static enum xp_retval
|
||||
xp_remote_memcpy_sn2(unsigned long dst_pa, const unsigned long src_pa,
|
||||
size_t len)
|
||||
{
|
||||
bte_result_t ret;
|
||||
|
||||
ret = bte_copy(src_pa, dst_pa, len, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
|
||||
if (ret == BTE_SUCCESS)
|
||||
return xpSuccess;
|
||||
|
||||
if (is_shub2()) {
|
||||
dev_err(xp, "bte_copy() on shub2 failed, error=0x%x dst_pa="
|
||||
"0x%016lx src_pa=0x%016lx len=%ld\\n", ret, dst_pa,
|
||||
src_pa, len);
|
||||
} else {
|
||||
dev_err(xp, "bte_copy() failed, error=%d dst_pa=0x%016lx "
|
||||
"src_pa=0x%016lx len=%ld\\n", ret, dst_pa, src_pa, len);
|
||||
}
|
||||
|
||||
return xpBteCopyError;
|
||||
}
|
||||
|
||||
static int
|
||||
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)
|
||||
{
|
||||
BUG_ON(!is_shub());
|
||||
|
||||
xp_max_npartitions = XP_MAX_NPARTITIONS_SN2;
|
||||
xp_partition_id = sn_partition_id;
|
||||
xp_region_size = sn_region_size;
|
||||
|
||||
xp_pa = xp_pa_sn2;
|
||||
xp_socket_pa = xp_socket_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();
|
||||
}
|
||||
|
||||
void
|
||||
xp_exit_sn2(void)
|
||||
{
|
||||
BUG_ON(!is_shub());
|
||||
|
||||
xp_unregister_nofault_code_sn2();
|
||||
}
|
||||
|
@ -151,9 +151,10 @@ xp_init_uv(void)
|
||||
BUG_ON(!is_uv());
|
||||
|
||||
xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
|
||||
#ifdef CONFIG_X86
|
||||
xp_partition_id = sn_partition_id;
|
||||
xp_region_size = sn_region_size;
|
||||
|
||||
#endif
|
||||
xp_pa = xp_pa_uv;
|
||||
xp_socket_pa = xp_socket_pa_uv;
|
||||
xp_remote_memcpy = xp_remote_memcpy_uv;
|
||||
|
@ -71,14 +71,10 @@
|
||||
* 'SAL_nasids_size'. (Local partition's mask pointers are xpc_part_nasids
|
||||
* and xpc_mach_nasids.)
|
||||
*
|
||||
* vars (ia64-sn2 only)
|
||||
* vars part (ia64-sn2 only)
|
||||
*
|
||||
* Immediately following the mach_nasids mask are the XPC variables
|
||||
* required by other partitions. First are those that are generic to all
|
||||
* partitions (vars), followed on the next available cacheline by those
|
||||
* which are partition specific (vars part). These are setup by XPC.
|
||||
* (Local partition's vars pointers are xpc_vars and xpc_vars_part.)
|
||||
*
|
||||
* Note: Until 'ts_jiffies' is set non-zero, the partition XPC code has not been
|
||||
* initialized.
|
||||
@ -92,9 +88,6 @@ struct xpc_rsvd_page {
|
||||
u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */
|
||||
unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
|
||||
union {
|
||||
struct {
|
||||
unsigned long vars_pa; /* phys addr */
|
||||
} sn2;
|
||||
struct {
|
||||
unsigned long heartbeat_gpa; /* phys addr */
|
||||
unsigned long activate_gru_mq_desc_gpa; /* phys addr */
|
||||
@ -106,84 +99,14 @@ struct xpc_rsvd_page {
|
||||
|
||||
#define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */
|
||||
|
||||
/*
|
||||
* Define the structures by which XPC variables can be exported to other
|
||||
* partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following structure describes the partition generic variables
|
||||
* needed by other partitions in order to properly initialize.
|
||||
*
|
||||
* struct xpc_vars version number also applies to struct xpc_vars_part.
|
||||
* Changes to either structure and/or related functionality should be
|
||||
* reflected by incrementing either the major or minor version numbers
|
||||
* of struct xpc_vars.
|
||||
*/
|
||||
struct xpc_vars_sn2 {
|
||||
u8 version;
|
||||
u64 heartbeat;
|
||||
DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
|
||||
u64 heartbeat_offline; /* if 0, heartbeat should be changing */
|
||||
int activate_IRQ_nasid;
|
||||
int activate_IRQ_phys_cpuid;
|
||||
unsigned long vars_part_pa;
|
||||
unsigned long amos_page_pa;/* paddr of page of amos from MSPEC driver */
|
||||
struct amo *amos_page; /* vaddr of page of amos from MSPEC driver */
|
||||
};
|
||||
|
||||
#define XPC_V_VERSION _XPC_VERSION(3, 1) /* version 3.1 of the cross vars */
|
||||
|
||||
/*
|
||||
* The following structure describes the per partition specific variables.
|
||||
*
|
||||
* An array of these structures, one per partition, will be defined. As a
|
||||
* partition becomes active XPC will copy the array entry corresponding to
|
||||
* itself from that partition. It is desirable that the size of this structure
|
||||
* evenly divides into a 128-byte cacheline, such that none of the entries in
|
||||
* this array crosses a 128-byte cacheline boundary. As it is now, each entry
|
||||
* occupies 64-bytes.
|
||||
*/
|
||||
struct xpc_vars_part_sn2 {
|
||||
u64 magic;
|
||||
|
||||
unsigned long openclose_args_pa; /* phys addr of open and close args */
|
||||
unsigned long GPs_pa; /* physical address of Get/Put values */
|
||||
|
||||
unsigned long chctl_amo_pa; /* physical address of chctl flags' amo */
|
||||
|
||||
int notify_IRQ_nasid; /* nasid of where to send notify IRQs */
|
||||
int notify_IRQ_phys_cpuid; /* CPUID of where to send notify IRQs */
|
||||
|
||||
u8 nchannels; /* #of defined channels supported */
|
||||
|
||||
u8 reserved[23]; /* pad to a full 64 bytes */
|
||||
};
|
||||
|
||||
/*
|
||||
* The vars_part MAGIC numbers play a part in the first contact protocol.
|
||||
*
|
||||
* MAGIC1 indicates that the per partition specific variables for a remote
|
||||
* partition have been initialized by this partition.
|
||||
*
|
||||
* MAGIC2 indicates that this partition has pulled the remote partititions
|
||||
* per partition variables that pertain to this partition.
|
||||
*/
|
||||
#define XPC_VP_MAGIC1_SN2 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */
|
||||
#define XPC_VP_MAGIC2_SN2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */
|
||||
|
||||
/* 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_sn2))
|
||||
|
||||
#define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
|
||||
XPC_RP_HEADER_SIZE))
|
||||
#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
|
||||
xpc_nasid_mask_nlongs)
|
||||
#define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *) \
|
||||
(XPC_RP_MACH_NASIDS(_rp) + \
|
||||
xpc_nasid_mask_nlongs))
|
||||
|
||||
|
||||
/*
|
||||
@ -297,17 +220,6 @@ struct xpc_activate_mq_msg_chctl_opencomplete_uv {
|
||||
#define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff)
|
||||
#define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)
|
||||
|
||||
/*
|
||||
* Define a Get/Put value pair (pointers) used with a message queue.
|
||||
*/
|
||||
struct xpc_gp_sn2 {
|
||||
s64 get; /* Get value */
|
||||
s64 put; /* Put value */
|
||||
};
|
||||
|
||||
#define XPC_GP_SIZE \
|
||||
L1_CACHE_ALIGN(sizeof(struct xpc_gp_sn2) * XPC_MAX_NCHANNELS)
|
||||
|
||||
/*
|
||||
* Define a structure that contains arguments associated with opening and
|
||||
* closing a channel.
|
||||
@ -340,30 +252,6 @@ struct xpc_fifo_head_uv {
|
||||
int n_entries;
|
||||
};
|
||||
|
||||
/*
|
||||
* Define a sn2 styled message.
|
||||
*
|
||||
* A user-defined message resides in the payload area. The max size of the
|
||||
* payload is defined by the user via xpc_connect().
|
||||
*
|
||||
* The size of a message entry (within a message queue) must be a 128-byte
|
||||
* cacheline sized multiple in order to facilitate the BTE transfer of messages
|
||||
* from one message queue to another.
|
||||
*/
|
||||
struct xpc_msg_sn2 {
|
||||
u8 flags; /* FOR XPC INTERNAL USE ONLY */
|
||||
u8 reserved[7]; /* FOR XPC INTERNAL USE ONLY */
|
||||
s64 number; /* FOR XPC INTERNAL USE ONLY */
|
||||
|
||||
u64 payload; /* user defined portion of message */
|
||||
};
|
||||
|
||||
/* struct xpc_msg_sn2 flags */
|
||||
|
||||
#define XPC_M_SN2_DONE 0x01 /* msg has been received/consumed */
|
||||
#define XPC_M_SN2_READY 0x02 /* msg is ready to be sent */
|
||||
#define XPC_M_SN2_INTERRUPT 0x04 /* send interrupt when msg consumed */
|
||||
|
||||
/*
|
||||
* The format of a uv XPC notify_mq GRU message is as follows:
|
||||
*
|
||||
@ -390,20 +278,6 @@ struct xpc_notify_mq_msg_uv {
|
||||
unsigned long payload;
|
||||
};
|
||||
|
||||
/*
|
||||
* Define sn2's notify entry.
|
||||
*
|
||||
* This is used to notify a message's sender that their message was received
|
||||
* and consumed by the intended recipient.
|
||||
*/
|
||||
struct xpc_notify_sn2 {
|
||||
u8 type; /* type of notification */
|
||||
|
||||
/* the following two fields are only used if type == XPC_N_CALL */
|
||||
xpc_notify_func func; /* user's notify function */
|
||||
void *key; /* pointer to user's key */
|
||||
};
|
||||
|
||||
/* struct xpc_notify_sn2 type of notification */
|
||||
|
||||
#define XPC_N_CALL 0x01 /* notify function provided by user */
|
||||
@ -431,102 +305,6 @@ struct xpc_send_msg_slot_uv {
|
||||
* of these structures for each potential channel connection to that partition.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following is sn2 only.
|
||||
*
|
||||
* Each channel structure manages two message queues (circular buffers).
|
||||
* They are allocated at the time a channel connection is made. One of
|
||||
* these message queues (local_msgqueue) holds the locally created messages
|
||||
* that are destined for the remote partition. The other of these message
|
||||
* queues (remote_msgqueue) is a locally cached copy of the remote partition's
|
||||
* own local_msgqueue.
|
||||
*
|
||||
* The following is a description of the Get/Put pointers used to manage these
|
||||
* two message queues. Consider the local_msgqueue to be on one partition
|
||||
* and the remote_msgqueue to be its cached copy on another partition. A
|
||||
* description of what each of the lettered areas contains is included.
|
||||
*
|
||||
*
|
||||
* local_msgqueue remote_msgqueue
|
||||
*
|
||||
* |/////////| |/////////|
|
||||
* w_remote_GP.get --> +---------+ |/////////|
|
||||
* | F | |/////////|
|
||||
* remote_GP.get --> +---------+ +---------+ <-- local_GP->get
|
||||
* | | | |
|
||||
* | | | E |
|
||||
* | | | |
|
||||
* | | +---------+ <-- w_local_GP.get
|
||||
* | B | |/////////|
|
||||
* | | |////D////|
|
||||
* | | |/////////|
|
||||
* | | +---------+ <-- w_remote_GP.put
|
||||
* | | |////C////|
|
||||
* local_GP->put --> +---------+ +---------+ <-- remote_GP.put
|
||||
* | | |/////////|
|
||||
* | A | |/////////|
|
||||
* | | |/////////|
|
||||
* w_local_GP.put --> +---------+ |/////////|
|
||||
* |/////////| |/////////|
|
||||
*
|
||||
*
|
||||
* ( remote_GP.[get|put] are cached copies of the remote
|
||||
* partition's local_GP->[get|put], and thus their values can
|
||||
* lag behind their counterparts on the remote partition. )
|
||||
*
|
||||
*
|
||||
* A - Messages that have been allocated, but have not yet been sent to the
|
||||
* remote partition.
|
||||
*
|
||||
* B - Messages that have been sent, but have not yet been acknowledged by the
|
||||
* remote partition as having been received.
|
||||
*
|
||||
* C - Area that needs to be prepared for the copying of sent messages, by
|
||||
* the clearing of the message flags of any previously received messages.
|
||||
*
|
||||
* D - Area into which sent messages are to be copied from the remote
|
||||
* partition's local_msgqueue and then delivered to their intended
|
||||
* recipients. [ To allow for a multi-message copy, another pointer
|
||||
* (next_msg_to_pull) has been added to keep track of the next message
|
||||
* number needing to be copied (pulled). It chases after w_remote_GP.put.
|
||||
* Any messages lying between w_local_GP.get and next_msg_to_pull have
|
||||
* been copied and are ready to be delivered. ]
|
||||
*
|
||||
* E - Messages that have been copied and delivered, but have not yet been
|
||||
* acknowledged by the recipient as having been received.
|
||||
*
|
||||
* F - Messages that have been acknowledged, but XPC has not yet notified the
|
||||
* sender that the message was received by its intended recipient.
|
||||
* This is also an area that needs to be prepared for the allocating of
|
||||
* new messages, by the clearing of the message flags of the acknowledged
|
||||
* messages.
|
||||
*/
|
||||
|
||||
struct xpc_channel_sn2 {
|
||||
struct xpc_openclose_args *local_openclose_args; /* args passed on */
|
||||
/* opening or closing of channel */
|
||||
|
||||
void *local_msgqueue_base; /* base address of kmalloc'd space */
|
||||
struct xpc_msg_sn2 *local_msgqueue; /* local message queue */
|
||||
void *remote_msgqueue_base; /* base address of kmalloc'd space */
|
||||
struct xpc_msg_sn2 *remote_msgqueue; /* cached copy of remote */
|
||||
/* partition's local message queue */
|
||||
unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */
|
||||
/* local message queue */
|
||||
|
||||
struct xpc_notify_sn2 *notify_queue;/* notify queue for messages sent */
|
||||
|
||||
/* various flavors of local and remote Get/Put values */
|
||||
|
||||
struct xpc_gp_sn2 *local_GP; /* local Get/Put values */
|
||||
struct xpc_gp_sn2 remote_GP; /* remote Get/Put values */
|
||||
struct xpc_gp_sn2 w_local_GP; /* working local Get/Put values */
|
||||
struct xpc_gp_sn2 w_remote_GP; /* working remote Get/Put values */
|
||||
s64 next_msg_to_pull; /* Put value of next msg to pull */
|
||||
|
||||
struct mutex msg_to_pull_mutex; /* next msg to pull serialization */
|
||||
};
|
||||
|
||||
struct xpc_channel_uv {
|
||||
void *cached_notify_gru_mq_desc; /* remote partition's notify mq's */
|
||||
/* gru mq descriptor */
|
||||
@ -579,7 +357,6 @@ struct xpc_channel {
|
||||
wait_queue_head_t idle_wq; /* idle kthread wait queue */
|
||||
|
||||
union {
|
||||
struct xpc_channel_sn2 sn2;
|
||||
struct xpc_channel_uv uv;
|
||||
} sn;
|
||||
|
||||
@ -666,43 +443,6 @@ xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Manage channels on a partition basis. There is one of these structures
|
||||
* for each partition (a partition will never utilize the structure that
|
||||
* represents itself).
|
||||
*/
|
||||
|
||||
struct xpc_partition_sn2 {
|
||||
unsigned long remote_amos_page_pa; /* paddr of partition's amos page */
|
||||
int activate_IRQ_nasid; /* active partition's act/deact nasid */
|
||||
int activate_IRQ_phys_cpuid; /* active part's act/deact phys cpuid */
|
||||
|
||||
unsigned long remote_vars_pa; /* phys addr of partition's vars */
|
||||
unsigned long remote_vars_part_pa; /* paddr of partition's vars part */
|
||||
u8 remote_vars_version; /* version# of partition's vars */
|
||||
|
||||
void *local_GPs_base; /* base address of kmalloc'd space */
|
||||
struct xpc_gp_sn2 *local_GPs; /* local Get/Put values */
|
||||
void *remote_GPs_base; /* base address of kmalloc'd space */
|
||||
struct xpc_gp_sn2 *remote_GPs; /* copy of remote partition's local */
|
||||
/* Get/Put values */
|
||||
unsigned long remote_GPs_pa; /* phys addr of remote partition's local */
|
||||
/* Get/Put values */
|
||||
|
||||
void *local_openclose_args_base; /* base address of kmalloc'd space */
|
||||
struct xpc_openclose_args *local_openclose_args; /* local's args */
|
||||
unsigned long remote_openclose_args_pa; /* phys addr of remote's args */
|
||||
|
||||
int notify_IRQ_nasid; /* nasid of where to send notify IRQs */
|
||||
int notify_IRQ_phys_cpuid; /* CPUID of where to send notify IRQs */
|
||||
char notify_IRQ_owner[8]; /* notify IRQ's owner's name */
|
||||
|
||||
struct amo *remote_chctl_amo_va; /* addr of remote chctl flags' amo */
|
||||
struct amo *local_chctl_amo_va; /* address of chctl flags' amo */
|
||||
|
||||
struct timer_list dropped_notify_IRQ_timer; /* dropped IRQ timer */
|
||||
};
|
||||
|
||||
struct xpc_partition_uv {
|
||||
unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */
|
||||
struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */
|
||||
@ -774,7 +514,6 @@ struct xpc_partition {
|
||||
wait_queue_head_t channel_mgr_wq; /* channel mgr's wait queue */
|
||||
|
||||
union {
|
||||
struct xpc_partition_sn2 sn2;
|
||||
struct xpc_partition_uv uv;
|
||||
} sn;
|
||||
|
||||
@ -854,14 +593,6 @@ struct xpc_arch_operations {
|
||||
#define XPC_P_SS_WTEARDOWN 0x02 /* waiting to teardown infrastructure */
|
||||
#define XPC_P_SS_TORNDOWN 0x03 /* infrastructure is torndown */
|
||||
|
||||
/*
|
||||
* struct xpc_partition_sn2's dropped notify IRQ timer is set to wait the
|
||||
* following interval #of seconds before checking for dropped notify IRQs.
|
||||
* These can occur whenever an IRQ's associated amo write doesn't complete
|
||||
* until after the IRQ was received.
|
||||
*/
|
||||
#define XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL (0.25 * HZ)
|
||||
|
||||
/* number of seconds to wait for other partitions to disengage */
|
||||
#define XPC_DISENGAGE_DEFAULT_TIMELIMIT 90
|
||||
|
||||
@ -888,10 +619,6 @@ extern void xpc_activate_kthreads(struct xpc_channel *, int);
|
||||
extern void xpc_create_kthreads(struct xpc_channel *, int, int);
|
||||
extern void xpc_disconnect_wait(int);
|
||||
|
||||
/* found in xpc_sn2.c */
|
||||
extern int xpc_init_sn2(void);
|
||||
extern void xpc_exit_sn2(void);
|
||||
|
||||
/* found in xpc_uv.c */
|
||||
extern int xpc_init_uv(void);
|
||||
extern void xpc_exit_uv(void);
|
||||
|
@ -279,13 +279,6 @@ xpc_hb_checker(void *ignore)
|
||||
|
||||
dev_dbg(xpc_part, "checking remote heartbeats\n");
|
||||
xpc_check_remote_hb();
|
||||
|
||||
/*
|
||||
* On sn2 we need to periodically recheck to ensure no
|
||||
* IRQ/amo pairs have been missed.
|
||||
*/
|
||||
if (is_shub())
|
||||
force_IRQ = 1;
|
||||
}
|
||||
|
||||
/* check for outstanding IRQs */
|
||||
@ -1050,9 +1043,7 @@ xpc_do_exit(enum xp_retval reason)
|
||||
|
||||
xpc_teardown_partitions();
|
||||
|
||||
if (is_shub())
|
||||
xpc_exit_sn2();
|
||||
else if (is_uv())
|
||||
if (is_uv())
|
||||
xpc_exit_uv();
|
||||
}
|
||||
|
||||
@ -1235,21 +1226,7 @@ xpc_init(void)
|
||||
dev_set_name(xpc_part, "part");
|
||||
dev_set_name(xpc_chan, "chan");
|
||||
|
||||
if (is_shub()) {
|
||||
/*
|
||||
* The ia64-sn2 architecture supports at most 64 partitions.
|
||||
* And the inability to unregister remote amos restricts us
|
||||
* further to only support exactly 64 partitions on this
|
||||
* architecture, no less.
|
||||
*/
|
||||
if (xp_max_npartitions != 64) {
|
||||
dev_err(xpc_part, "max #of partitions not set to 64\n");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
ret = xpc_init_sn2();
|
||||
}
|
||||
|
||||
} else if (is_uv()) {
|
||||
if (is_uv()) {
|
||||
ret = xpc_init_uv();
|
||||
|
||||
} else {
|
||||
@ -1335,9 +1312,7 @@ out_2:
|
||||
|
||||
xpc_teardown_partitions();
|
||||
out_1:
|
||||
if (is_shub())
|
||||
xpc_exit_sn2();
|
||||
else if (is_uv())
|
||||
if (is_uv())
|
||||
xpc_exit_uv();
|
||||
return ret;
|
||||
}
|
||||
|
@ -93,10 +93,6 @@ xpc_get_rsvd_page_pa(int nasid)
|
||||
if (ret != xpNeedMoreInfo)
|
||||
break;
|
||||
|
||||
/* !!! L1_CACHE_ALIGN() is only a sn2-bte_copy requirement */
|
||||
if (is_shub())
|
||||
len = L1_CACHE_ALIGN(len);
|
||||
|
||||
if (len > buf_len) {
|
||||
kfree(buf_base);
|
||||
buf_len = L1_CACHE_ALIGN(len);
|
||||
@ -452,7 +448,6 @@ xpc_discovery(void)
|
||||
case 32:
|
||||
max_regions *= 2;
|
||||
region_size = 16;
|
||||
DBUG_ON(!is_shub2());
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -48,6 +48,8 @@ struct uv_IO_APIC_route_entry {
|
||||
__reserved_2 : 15,
|
||||
dest : 32;
|
||||
};
|
||||
|
||||
#define sn_partition_id 0
|
||||
#endif
|
||||
|
||||
static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
|
||||
|
@ -515,7 +515,7 @@ xpnet_init(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!is_shub() && !is_uv())
|
||||
if (!is_uv())
|
||||
return -ENODEV;
|
||||
|
||||
dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
|
||||
|
Loading…
Reference in New Issue
Block a user