diff options
author | Robin Holt <holt@sgi.com> | 2009-04-13 17:40:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-13 18:04:33 -0400 |
commit | a374c57b0764432a80303abee3d1afd1939b5a0a (patch) | |
tree | b3e15b590d5342e5de6c2b62da4dd61fb2ad0836 /drivers/misc/sgi-xp/xpc.h | |
parent | a06bba4643ae10ac6b202dade1cde38bc5e08b25 (diff) |
sgi-xpc: prevent false heartbeat failures
The heartbeat timeout functionality in sgi-xpc is currently not trained to
the connection time. If a connection is made and the code is in the last
polling window prior to doing a timeout, the next polling window will see
the heartbeat as unchanged and initiate a no-heartbeat disconnect.
Signed-off-by: Robin Holt <holt@sgi.com>
Signed-off-by: Dean Nelson <dcn@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-xp/xpc.h')
-rw-r--r-- | drivers/misc/sgi-xp/xpc.h | 100 |
1 files changed, 38 insertions, 62 deletions
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h index 114444cfd496..da32bbe8caaf 100644 --- a/drivers/misc/sgi-xp/xpc.h +++ b/drivers/misc/sgi-xp/xpc.h | |||
@@ -90,18 +90,21 @@ struct xpc_rsvd_page { | |||
90 | short max_npartitions; /* value of XPC_MAX_PARTITIONS */ | 90 | short max_npartitions; /* value of XPC_MAX_PARTITIONS */ |
91 | u8 version; | 91 | u8 version; |
92 | u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */ | 92 | u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */ |
93 | unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */ | ||
93 | union { | 94 | union { |
94 | unsigned long vars_pa; /* phys address of struct xpc_vars */ | 95 | struct { |
95 | unsigned long activate_gru_mq_desc_gpa; /* phys addr of */ | 96 | unsigned long vars_pa; /* phys addr */ |
96 | /* activate mq's */ | 97 | } sn2; |
97 | /* gru mq descriptor */ | 98 | struct { |
99 | unsigned long heartbeat_gpa; /* phys addr */ | ||
100 | unsigned long activate_gru_mq_desc_gpa; /* phys addr */ | ||
101 | } uv; | ||
98 | } sn; | 102 | } sn; |
99 | unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */ | 103 | u64 pad2[9]; /* align to last u64 in 2nd 64-byte cacheline */ |
100 | u64 pad2[10]; /* align to last u64 in 2nd 64-byte cacheline */ | ||
101 | u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */ | 104 | u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */ |
102 | }; | 105 | }; |
103 | 106 | ||
104 | #define XPC_RP_VERSION _XPC_VERSION(2, 0) /* version 2.0 of the reserved page */ | 107 | #define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */ |
105 | 108 | ||
106 | /* | 109 | /* |
107 | * Define the structures by which XPC variables can be exported to other | 110 | * Define the structures by which XPC variables can be exported to other |
@@ -182,6 +185,17 @@ struct xpc_vars_part_sn2 { | |||
182 | (XPC_RP_MACH_NASIDS(_rp) + \ | 185 | (XPC_RP_MACH_NASIDS(_rp) + \ |
183 | xpc_nasid_mask_nlongs)) | 186 | xpc_nasid_mask_nlongs)) |
184 | 187 | ||
188 | |||
189 | /* | ||
190 | * The following structure describes the partition's heartbeat info which | ||
191 | * will be periodically read by other partitions to determine whether this | ||
192 | * XPC is still 'alive'. | ||
193 | */ | ||
194 | struct xpc_heartbeat_uv { | ||
195 | unsigned long value; | ||
196 | unsigned long offline; /* if 0, heartbeat should be changing */ | ||
197 | }; | ||
198 | |||
185 | /* | 199 | /* |
186 | * Info pertinent to a GRU message queue using a watch list for irq generation. | 200 | * Info pertinent to a GRU message queue using a watch list for irq generation. |
187 | */ | 201 | */ |
@@ -198,7 +212,7 @@ struct xpc_gru_mq_uv { | |||
198 | 212 | ||
199 | /* | 213 | /* |
200 | * The activate_mq is used to send/receive GRU messages that affect XPC's | 214 | * The activate_mq is used to send/receive GRU messages that affect XPC's |
201 | * heartbeat, partition active state, and channel state. This is UV only. | 215 | * partition active state and channel state. This is uv only. |
202 | */ | 216 | */ |
203 | struct xpc_activate_mq_msghdr_uv { | 217 | struct xpc_activate_mq_msghdr_uv { |
204 | unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */ | 218 | unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */ |
@@ -210,33 +224,26 @@ struct xpc_activate_mq_msghdr_uv { | |||
210 | 224 | ||
211 | /* activate_mq defined message types */ | 225 | /* activate_mq defined message types */ |
212 | #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV 0 | 226 | #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV 0 |
213 | #define XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV 1 | ||
214 | #define XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV 2 | ||
215 | #define XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV 3 | ||
216 | 227 | ||
217 | #define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 4 | 228 | #define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 1 |
218 | #define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 5 | 229 | #define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 2 |
219 | 230 | ||
220 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 6 | 231 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 3 |
221 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 7 | 232 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 4 |
222 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 8 | 233 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 5 |
223 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 9 | 234 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 6 |
224 | 235 | ||
225 | #define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 10 | 236 | #define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 7 |
226 | #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 11 | 237 | #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 8 |
227 | 238 | ||
228 | struct xpc_activate_mq_msg_uv { | 239 | struct xpc_activate_mq_msg_uv { |
229 | struct xpc_activate_mq_msghdr_uv hdr; | 240 | struct xpc_activate_mq_msghdr_uv hdr; |
230 | }; | 241 | }; |
231 | 242 | ||
232 | struct xpc_activate_mq_msg_heartbeat_req_uv { | ||
233 | struct xpc_activate_mq_msghdr_uv hdr; | ||
234 | u64 heartbeat; | ||
235 | }; | ||
236 | |||
237 | struct xpc_activate_mq_msg_activate_req_uv { | 243 | struct xpc_activate_mq_msg_activate_req_uv { |
238 | struct xpc_activate_mq_msghdr_uv hdr; | 244 | struct xpc_activate_mq_msghdr_uv hdr; |
239 | unsigned long rp_gpa; | 245 | unsigned long rp_gpa; |
246 | unsigned long heartbeat_gpa; | ||
240 | unsigned long activate_gru_mq_desc_gpa; | 247 | unsigned long activate_gru_mq_desc_gpa; |
241 | }; | 248 | }; |
242 | 249 | ||
@@ -687,6 +694,9 @@ struct xpc_partition_sn2 { | |||
687 | }; | 694 | }; |
688 | 695 | ||
689 | struct xpc_partition_uv { | 696 | struct xpc_partition_uv { |
697 | unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */ | ||
698 | struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */ | ||
699 | /* partition's heartbeat */ | ||
690 | unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */ | 700 | unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */ |
691 | /* activate mq's gru mq */ | 701 | /* activate mq's gru mq */ |
692 | /* descriptor */ | 702 | /* descriptor */ |
@@ -698,14 +708,12 @@ struct xpc_partition_uv { | |||
698 | u8 remote_act_state; /* remote partition's act_state */ | 708 | u8 remote_act_state; /* remote partition's act_state */ |
699 | u8 act_state_req; /* act_state request from remote partition */ | 709 | u8 act_state_req; /* act_state request from remote partition */ |
700 | enum xp_retval reason; /* reason for deactivate act_state request */ | 710 | enum xp_retval reason; /* reason for deactivate act_state request */ |
701 | u64 heartbeat; /* incremented by remote partition */ | ||
702 | }; | 711 | }; |
703 | 712 | ||
704 | /* struct xpc_partition_uv flags */ | 713 | /* struct xpc_partition_uv flags */ |
705 | 714 | ||
706 | #define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001 | 715 | #define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000001 |
707 | #define XPC_P_ENGAGED_UV 0x00000002 | 716 | #define XPC_P_ENGAGED_UV 0x00000002 |
708 | #define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000004 | ||
709 | 717 | ||
710 | /* struct xpc_partition_uv act_state change requests */ | 718 | /* struct xpc_partition_uv act_state change requests */ |
711 | 719 | ||
@@ -807,7 +815,6 @@ extern int xpc_disengage_timedout; | |||
807 | extern int xpc_activate_IRQ_rcvd; | 815 | extern int xpc_activate_IRQ_rcvd; |
808 | extern spinlock_t xpc_activate_IRQ_rcvd_lock; | 816 | extern spinlock_t xpc_activate_IRQ_rcvd_lock; |
809 | extern wait_queue_head_t xpc_activate_IRQ_wq; | 817 | extern wait_queue_head_t xpc_activate_IRQ_wq; |
810 | extern void *xpc_heartbeating_to_mask; | ||
811 | extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **); | 818 | extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **); |
812 | extern void xpc_activate_partition(struct xpc_partition *); | 819 | extern void xpc_activate_partition(struct xpc_partition *); |
813 | extern void xpc_activate_kthreads(struct xpc_channel *, int); | 820 | extern void xpc_activate_kthreads(struct xpc_channel *, int); |
@@ -825,6 +832,9 @@ extern void (*xpc_increment_heartbeat) (void); | |||
825 | extern void (*xpc_offline_heartbeat) (void); | 832 | extern void (*xpc_offline_heartbeat) (void); |
826 | extern void (*xpc_online_heartbeat) (void); | 833 | extern void (*xpc_online_heartbeat) (void); |
827 | extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *); | 834 | extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *); |
835 | extern void (*xpc_allow_hb) (short); | ||
836 | extern void (*xpc_disallow_hb) (short); | ||
837 | extern void (*xpc_disallow_all_hbs) (void); | ||
828 | extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *); | 838 | extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *); |
829 | extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *); | 839 | extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *); |
830 | extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *); | 840 | extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *); |
@@ -909,40 +919,6 @@ extern void xpc_disconnect_channel(const int, struct xpc_channel *, | |||
909 | extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval); | 919 | extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval); |
910 | extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval); | 920 | extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval); |
911 | 921 | ||
912 | static inline int | ||
913 | xpc_hb_allowed(short partid, void *heartbeating_to_mask) | ||
914 | { | ||
915 | return test_bit(partid, heartbeating_to_mask); | ||
916 | } | ||
917 | |||
918 | static inline int | ||
919 | xpc_any_hbs_allowed(void) | ||
920 | { | ||
921 | DBUG_ON(xpc_heartbeating_to_mask == NULL); | ||
922 | return !bitmap_empty(xpc_heartbeating_to_mask, xp_max_npartitions); | ||
923 | } | ||
924 | |||
925 | static inline void | ||
926 | xpc_allow_hb(short partid) | ||
927 | { | ||
928 | DBUG_ON(xpc_heartbeating_to_mask == NULL); | ||
929 | set_bit(partid, xpc_heartbeating_to_mask); | ||
930 | } | ||
931 | |||
932 | static inline void | ||
933 | xpc_disallow_hb(short partid) | ||
934 | { | ||
935 | DBUG_ON(xpc_heartbeating_to_mask == NULL); | ||
936 | clear_bit(partid, xpc_heartbeating_to_mask); | ||
937 | } | ||
938 | |||
939 | static inline void | ||
940 | xpc_disallow_all_hbs(void) | ||
941 | { | ||
942 | DBUG_ON(xpc_heartbeating_to_mask == NULL); | ||
943 | bitmap_zero(xpc_heartbeating_to_mask, xp_max_npartitions); | ||
944 | } | ||
945 | |||
946 | static inline void | 922 | static inline void |
947 | xpc_wakeup_channel_mgr(struct xpc_partition *part) | 923 | xpc_wakeup_channel_mgr(struct xpc_partition *part) |
948 | { | 924 | { |