aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Nelson <dcn@sgi.com>2005-09-01 15:01:37 -0400
committerTony Luck <tony.luck@intel.com>2005-09-06 19:15:38 -0400
commita607c38971fd078865fa9bef39e6c1d4435680c8 (patch)
treecb7853f0d74ee6a9cd92ccc721096b57367d0390
parent4706df3d3c42af802597d82c8b1542c3d52eab23 (diff)
[IA64-SGI] get XPC to cleanly disengage from remote memory references
When XPC is being shutdown (i.e., rmmod, reboot) it doesn't ensure that other partitions with whom it was connected have completely disengaged from any attempt at cross-partition memory references. This can lead to MCAs in any of these other partitions when the partition is reset. Signed-off-by: Dean Nelson <dcn@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--arch/ia64/sn/kernel/xpc.h288
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c216
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c242
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c304
-rw-r--r--include/asm-ia64/sn/xp.h10
5 files changed, 822 insertions, 238 deletions
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
index d0ee635daf2e..565822ab3d08 100644
--- a/arch/ia64/sn/kernel/xpc.h
+++ b/arch/ia64/sn/kernel/xpc.h
@@ -57,7 +57,7 @@
57#define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2) 57#define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2)
58 58
59#define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */ 59#define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */
60#define XPC_HB_CHECK_DEFAULT_TIMEOUT 20 /* check HB every x secs */ 60#define XPC_HB_CHECK_DEFAULT_INTERVAL 20 /* check HB every x secs */
61 61
62/* define the process name of HB checker and the CPU it is pinned to */ 62/* define the process name of HB checker and the CPU it is pinned to */
63#define XPC_HB_CHECK_THREAD_NAME "xpc_hb" 63#define XPC_HB_CHECK_THREAD_NAME "xpc_hb"
@@ -67,11 +67,6 @@
67#define XPC_DISCOVERY_THREAD_NAME "xpc_discovery" 67#define XPC_DISCOVERY_THREAD_NAME "xpc_discovery"
68 68
69 69
70#define XPC_HB_ALLOWED(_p, _v) ((_v)->heartbeating_to_mask & (1UL << (_p)))
71#define XPC_ALLOW_HB(_p, _v) (_v)->heartbeating_to_mask |= (1UL << (_p))
72#define XPC_DISALLOW_HB(_p, _v) (_v)->heartbeating_to_mask &= (~(1UL << (_p)))
73
74
75/* 70/*
76 * Reserved Page provided by SAL. 71 * Reserved Page provided by SAL.
77 * 72 *
@@ -88,14 +83,38 @@ struct xpc_rsvd_page {
88 u8 version; 83 u8 version;
89 u8 pad[6]; /* pad to u64 align */ 84 u8 pad[6]; /* pad to u64 align */
90 volatile u64 vars_pa; 85 volatile u64 vars_pa;
86 struct timespec stamp; /* time when reserved page was initialized */
91 u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; 87 u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
92 u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; 88 u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
93}; 89};
94#define XPC_RP_VERSION _XPC_VERSION(1,0) /* version 1.0 of the reserved page */
95 90
96#define XPC_RSVD_PAGE_ALIGNED_SIZE \ 91#define XPC_RSVD_PAGE_ALIGNED_SIZE \
97 (L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))) 92 (L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page)))
98 93
94#define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */
95
96#define XPC_SUPPORTS_RP_STAMP(_version) \
97 (_version >= _XPC_VERSION(1,1))
98
99/*
100 * compare stamps - the return value is:
101 *
102 * < 0, if stamp1 < stamp2
103 * = 0, if stamp1 == stamp2
104 * > 0, if stamp1 > stamp2
105 */
106static inline int
107xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2)
108{
109 int ret;
110
111
112 if ((ret = stamp1->tv_sec - stamp2->tv_sec) == 0) {
113 ret = stamp1->tv_nsec - stamp2->tv_nsec;
114 }
115 return ret;
116}
117
99 118
100/* 119/*
101 * Define the structures by which XPC variables can be exported to other 120 * Define the structures by which XPC variables can be exported to other
@@ -121,12 +140,61 @@ struct xpc_vars {
121 u64 vars_part_pa; 140 u64 vars_part_pa;
122 u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */ 141 u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */
123 AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */ 142 AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */
124 AMO_t *act_amos; /* pointer to the first activation AMO */
125}; 143};
126#define XPC_V_VERSION _XPC_VERSION(3,0) /* version 3.0 of the cross vars */
127 144
128#define XPC_VARS_ALIGNED_SIZE (L1_CACHE_ALIGN(sizeof(struct xpc_vars))) 145#define XPC_VARS_ALIGNED_SIZE (L1_CACHE_ALIGN(sizeof(struct xpc_vars)))
129 146
147#define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */
148
149#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \
150 (_version >= _XPC_VERSION(3,1))
151
152
153static inline int
154xpc_hb_allowed(partid_t partid, struct xpc_vars *vars)
155{
156 return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
157}
158
159static inline void
160xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
161{
162 u64 old_mask, new_mask;
163
164 do {
165 old_mask = vars->heartbeating_to_mask;
166 new_mask = (old_mask | (1UL << partid));
167 } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
168 old_mask);
169}
170
171static inline void
172xpc_disallow_hb(partid_t partid, struct xpc_vars *vars)
173{
174 u64 old_mask, new_mask;
175
176 do {
177 old_mask = vars->heartbeating_to_mask;
178 new_mask = (old_mask & ~(1UL << partid));
179 } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
180 old_mask);
181}
182
183
184/*
185 * The AMOs page consists of a number of AMO variables which are divided into
186 * four groups, The first two groups are used to identify an IRQ's sender.
187 * These two groups consist of 64 and 16 AMO variables respectively. The last
188 * two groups, consisting of just one AMO variable each, are used to identify
189 * the remote partitions that are currently engaged (from the viewpoint of
190 * the XPC running on the remote partition).
191 */
192#define XPC_NOTIFY_IRQ_AMOS 0
193#define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS)
194#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)
195#define XPC_DISENGAGE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1)
196
197
130/* 198/*
131 * The following structure describes the per partition specific variables. 199 * The following structure describes the per partition specific variables.
132 * 200 *
@@ -358,7 +426,7 @@ struct xpc_channel {
358 void *key; /* pointer to user's key */ 426 void *key; /* pointer to user's key */
359 427
360 struct semaphore msg_to_pull_sema; /* next msg to pull serialization */ 428 struct semaphore msg_to_pull_sema; /* next msg to pull serialization */
361 struct semaphore teardown_sema; /* wait for teardown completion */ 429 struct semaphore wdisconnect_sema; /* wait for channel disconnect */
362 430
363 struct xpc_openclose_args *local_openclose_args; /* args passed on */ 431 struct xpc_openclose_args *local_openclose_args; /* args passed on */
364 /* opening or closing of channel */ 432 /* opening or closing of channel */
@@ -410,6 +478,7 @@ struct xpc_channel {
410 478
411#define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */ 479#define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */
412#define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */ 480#define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */
481#define XPC_C_WDISCONNECT 0x00008000 /* waiting for channel disconnect */
413 482
414 483
415 484
@@ -422,6 +491,8 @@ struct xpc_partition {
422 491
423 /* XPC HB infrastructure */ 492 /* XPC HB infrastructure */
424 493
494 u8 remote_rp_version; /* version# of partition's rsvd pg */
495 struct timespec remote_rp_stamp;/* time when rsvd pg was initialized */
425 u64 remote_rp_pa; /* phys addr of partition's rsvd pg */ 496 u64 remote_rp_pa; /* phys addr of partition's rsvd pg */
426 u64 remote_vars_pa; /* phys addr of partition's vars */ 497 u64 remote_vars_pa; /* phys addr of partition's vars */
427 u64 remote_vars_part_pa; /* phys addr of partition's vars part */ 498 u64 remote_vars_part_pa; /* phys addr of partition's vars part */
@@ -432,10 +503,14 @@ struct xpc_partition {
432 u32 act_IRQ_rcvd; /* IRQs since activation */ 503 u32 act_IRQ_rcvd; /* IRQs since activation */
433 spinlock_t act_lock; /* protect updating of act_state */ 504 spinlock_t act_lock; /* protect updating of act_state */
434 u8 act_state; /* from XPC HB viewpoint */ 505 u8 act_state; /* from XPC HB viewpoint */
506 u8 remote_vars_version; /* version# of partition's vars */
435 enum xpc_retval reason; /* reason partition is deactivating */ 507 enum xpc_retval reason; /* reason partition is deactivating */
436 int reason_line; /* line# deactivation initiated from */ 508 int reason_line; /* line# deactivation initiated from */