diff options
| -rw-r--r-- | drivers/misc/sgi-xp/xpc.h | 100 | ||||
| -rw-r--r-- | drivers/misc/sgi-xp/xpc_main.c | 8 | ||||
| -rw-r--r-- | drivers/misc/sgi-xp/xpc_sn2.c | 44 | ||||
| -rw-r--r-- | drivers/misc/sgi-xp/xpc_uv.c | 123 |
4 files changed, 123 insertions, 152 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 | { |
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index 1ab9fda87fab..34b084cd63da 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | /* | 9 | /* |
| @@ -150,7 +150,6 @@ DECLARE_WAIT_QUEUE_HEAD(xpc_activate_IRQ_wq); | |||
| 150 | 150 | ||
| 151 | static unsigned long xpc_hb_check_timeout; | 151 | static unsigned long xpc_hb_check_timeout; |
| 152 | static struct timer_list xpc_hb_timer; | 152 | static struct timer_list xpc_hb_timer; |
| 153 | void *xpc_heartbeating_to_mask; | ||
| 154 | 153 | ||
| 155 | /* notification that the xpc_hb_checker thread has exited */ | 154 | /* notification that the xpc_hb_checker thread has exited */ |
| 156 | static DECLARE_COMPLETION(xpc_hb_checker_exited); | 155 | static DECLARE_COMPLETION(xpc_hb_checker_exited); |
| @@ -176,6 +175,10 @@ enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie, | |||
| 176 | unsigned long *rp_pa, | 175 | unsigned long *rp_pa, |
| 177 | size_t *len); | 176 | size_t *len); |
| 178 | int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *rp); | 177 | int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *rp); |
| 178 | |||
| 179 | void (*xpc_allow_hb) (short partid); | ||
| 180 | void (*xpc_disallow_hb) (short partid); | ||
| 181 | void (*xpc_disallow_all_hbs) (void); | ||
| 179 | void (*xpc_heartbeat_init) (void); | 182 | void (*xpc_heartbeat_init) (void); |
| 180 | void (*xpc_heartbeat_exit) (void); | 183 | void (*xpc_heartbeat_exit) (void); |
| 181 | void (*xpc_increment_heartbeat) (void); | 184 | void (*xpc_increment_heartbeat) (void); |
| @@ -1087,7 +1090,6 @@ xpc_do_exit(enum xp_retval reason) | |||
| 1087 | } while (1); | 1090 | } while (1); |
| 1088 | 1091 | ||
| 1089 | DBUG_ON(xpc_any_partition_engaged()); | 1092 | DBUG_ON(xpc_any_partition_engaged()); |
| 1090 | DBUG_ON(xpc_any_hbs_allowed() != 0); | ||
| 1091 | 1093 | ||
| 1092 | xpc_teardown_rsvd_page(); | 1094 | xpc_teardown_rsvd_page(); |
| 1093 | 1095 | ||
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index eaaa964942de..43ad2968daf5 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c +++ b/drivers/misc/sgi-xp/xpc_sn2.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | /* | 9 | /* |
| @@ -629,7 +629,7 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp) | |||
| 629 | 629 | ||
| 630 | xpc_vars_sn2 = XPC_RP_VARS(rp); | 630 | xpc_vars_sn2 = XPC_RP_VARS(rp); |
| 631 | 631 | ||
| 632 | rp->sn.vars_pa = xp_pa(xpc_vars_sn2); | 632 | rp->sn.sn2.vars_pa = xp_pa(xpc_vars_sn2); |
| 633 | 633 | ||
| 634 | /* vars_part array follows immediately after vars */ | 634 | /* vars_part array follows immediately after vars */ |
| 635 | xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) + | 635 | xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) + |
| @@ -693,6 +693,33 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp) | |||
| 693 | return 0; | 693 | return 0; |
| 694 | } | 694 | } |
| 695 | 695 | ||
| 696 | static int | ||
| 697 | xpc_hb_allowed_sn2(short partid, void *heartbeating_to_mask) | ||
| 698 | { | ||
| 699 | return test_bit(partid, heartbeating_to_mask); | ||
| 700 | } | ||
| 701 | |||
| 702 | static void | ||
| 703 | xpc_allow_hb_sn2(short partid) | ||
| 704 | { | ||
| 705 | DBUG_ON(xpc_vars_sn2 == NULL); | ||
| 706 | set_bit(partid, xpc_vars_sn2->heartbeating_to_mask); | ||
| 707 | } | ||
| 708 | |||
| 709 | static void | ||
| 710 | xpc_disallow_hb_sn2(short partid) | ||
| 711 | { | ||
| 712 | DBUG_ON(xpc_vars_sn2 == NULL); | ||
| 713 | clear_bit(partid, xpc_vars_sn2->heartbeating_to_mask); | ||
| 714 | } | ||
| 715 | |||
| 716 | static void | ||
| 717 | xpc_disallow_all_hbs_sn2(void) | ||
| 718 | { | ||
| 719 | DBUG_ON(xpc_vars_sn2 == NULL); | ||
| 720 | bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, xp_max_npartitions); | ||
| 721 | } | ||
| 722 | |||
| 696 | static void | 723 | static void |
| 697 | xpc_increment_heartbeat_sn2(void) | 724 | xpc_increment_heartbeat_sn2(void) |
| 698 | { | 725 | { |
| @@ -719,7 +746,6 @@ xpc_heartbeat_init_sn2(void) | |||
| 719 | DBUG_ON(xpc_vars_sn2 == NULL); | 746 | DBUG_ON(xpc_vars_sn2 == NULL); |
| 720 | 747 | ||
| 721 | bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2); | 748 | bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2); |
| 722 | xpc_heartbeating_to_mask = &xpc_vars_sn2->heartbeating_to_mask[0]; | ||
| 723 | xpc_online_heartbeat_sn2(); | 749 | xpc_online_heartbeat_sn2(); |
| 724 | } | 750 | } |
| 725 | 751 | ||
| @@ -751,9 +777,9 @@ xpc_get_remote_heartbeat_sn2(struct xpc_partition *part) | |||
| 751 | remote_vars->heartbeating_to_mask[0]); | 777 | remote_vars->heartbeating_to_mask[0]); |
| 752 | 778 | ||
| 753 | if ((remote_vars->heartbeat == part->last_heartbeat && | 779 | if ((remote_vars->heartbeat == part->last_heartbeat && |
| 754 | remote_vars->heartbeat_offline == 0) || | 780 | !remote_vars->heartbeat_offline) || |
| 755 | !xpc_hb_allowed(sn_partition_id, | 781 | !xpc_hb_allowed_sn2(sn_partition_id, |
| 756 | &remote_vars->heartbeating_to_mask)) { | 782 | remote_vars->heartbeating_to_mask)) { |
| 757 | ret = xpNoHeartbeat; | 783 | ret = xpNoHeartbeat; |
| 758 | } else { | 784 | } else { |
| 759 | part->last_heartbeat = remote_vars->heartbeat; | 785 | part->last_heartbeat = remote_vars->heartbeat; |
| @@ -972,7 +998,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid) | |||
| 972 | return; | 998 | return; |
| 973 | } | 999 | } |
| 974 | 1000 | ||
| 975 | remote_vars_pa = remote_rp->sn.vars_pa; | 1001 | remote_vars_pa = remote_rp->sn.sn2.vars_pa; |
| 976 | remote_rp_version = remote_rp->version; | 1002 | remote_rp_version = remote_rp->version; |
| 977 | remote_rp_ts_jiffies = remote_rp->ts_jiffies; | 1003 | remote_rp_ts_jiffies = remote_rp->ts_jiffies; |
| 978 | 1004 | ||
| @@ -2325,6 +2351,10 @@ xpc_init_sn2(void) | |||
| 2325 | xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_sn2; | 2351 | xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_sn2; |
| 2326 | xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2; | 2352 | xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2; |
| 2327 | xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_sn2; | 2353 | xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_sn2; |
| 2354 | |||
| 2355 | xpc_allow_hb = xpc_allow_hb_sn2; | ||
| 2356 | xpc_disallow_hb = xpc_disallow_hb_sn2; | ||
| 2357 | xpc_disallow_all_hbs = xpc_disallow_all_hbs_sn2; | ||
| 2328 | xpc_increment_heartbeat = xpc_increment_heartbeat_sn2; | 2358 | xpc_increment_heartbeat = xpc_increment_heartbeat_sn2; |
| 2329 | xpc_offline_heartbeat = xpc_offline_heartbeat_sn2; | 2359 | xpc_offline_heartbeat = xpc_offline_heartbeat_sn2; |
| 2330 | xpc_online_heartbeat = xpc_online_heartbeat_sn2; | 2360 | xpc_online_heartbeat = xpc_online_heartbeat_sn2; |
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index f7fff4727edb..97f7cb21a0a2 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
| @@ -46,8 +46,7 @@ struct uv_IO_APIC_route_entry { | |||
| 46 | }; | 46 | }; |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | static atomic64_t xpc_heartbeat_uv; | 49 | static struct xpc_heartbeat_uv *xpc_heartbeat_uv; |
| 50 | static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV); | ||
| 51 | 50 | ||
| 52 | #define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES) | 51 | #define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES) |
| 53 | #define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ | 52 | #define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ |
| @@ -423,41 +422,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, | |||
| 423 | /* syncing of remote_act_state was just done above */ | 422 | /* syncing of remote_act_state was just done above */ |
| 424 | break; | 423 | break; |
| 425 | 424 | ||
| 426 | case XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV: { | ||
| 427 | struct xpc_activate_mq_msg_heartbeat_req_uv *msg; | ||
| 428 | |||
| 429 | msg = container_of(msg_hdr, | ||
| 430 | struct xpc_activate_mq_msg_heartbeat_req_uv, | ||
| 431 | hdr); | ||
| 432 | part_uv->heartbeat = msg->heartbeat; | ||
| 433 | break; | ||
| 434 | } | ||
| 435 | case XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV: { | ||
| 436 | struct xpc_activate_mq_msg_heartbeat_req_uv *msg; | ||
| 437 | |||
| 438 | msg = container_of(msg_hdr, | ||
| 439 | struct xpc_activate_mq_msg_heartbeat_req_uv, | ||
| 440 | hdr); | ||
| 441 | part_uv->heartbeat = msg->heartbeat; | ||
| 442 | |||
| 443 | spin_lock_irqsave(&part_uv->flags_lock, irq_flags); | ||
| 444 | part_uv->flags |= XPC_P_HEARTBEAT_OFFLINE_UV; | ||
| 445 | spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); | ||
| 446 | break; | ||
| 447 | } | ||
| 448 | case XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV: { | ||
| 449 | struct xpc_activate_mq_msg_heartbeat_req_uv *msg; | ||
| 450 | |||
| 451 | msg = container_of(msg_hdr, | ||
| 452 | struct xpc_activate_mq_msg_heartbeat_req_uv, | ||
| 453 | hdr); | ||
| 454 | part_uv->heartbeat = msg->heartbeat; | ||
| 455 | |||
| 456 | spin_lock_irqsave(&part_uv->flags_lock, irq_flags); | ||
| 457 | part_uv->flags &= ~XPC_P_HEARTBEAT_OFFLINE_UV; | ||
| 458 | spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); | ||
| 459 | break; | ||
| 460 | } | ||
| 461 | case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: { | 425 | case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: { |
| 462 | struct xpc_activate_mq_msg_activate_req_uv *msg; | 426 | struct xpc_activate_mq_msg_activate_req_uv *msg; |
| 463 | 427 | ||
| @@ -475,6 +439,7 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, | |||
| 475 | part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV; | 439 | part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV; |
| 476 | part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */ | 440 | part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */ |
| 477 | part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies; | 441 | part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies; |
| 442 | part_uv->heartbeat_gpa = msg->heartbeat_gpa; | ||
| 478 | 443 | ||
| 479 | if (msg->activate_gru_mq_desc_gpa != | 444 | if (msg->activate_gru_mq_desc_gpa != |
| 480 | part_uv->activate_gru_mq_desc_gpa) { | 445 | part_uv->activate_gru_mq_desc_gpa) { |
| @@ -759,7 +724,7 @@ xpc_send_local_activate_IRQ_uv(struct xpc_partition *part, int act_state_req) | |||
| 759 | 724 | ||
| 760 | /* | 725 | /* |
| 761 | * !!! Make our side think that the remote partition sent an activate | 726 | * !!! Make our side think that the remote partition sent an activate |
| 762 | * !!! message our way by doing what the activate IRQ handler would | 727 | * !!! mq message our way by doing what the activate IRQ handler would |
| 763 | * !!! do had one really been sent. | 728 | * !!! do had one really been sent. |
| 764 | */ | 729 | */ |
| 765 | 730 | ||
| @@ -808,88 +773,80 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa, | |||
| 808 | static int | 773 | static int |
| 809 | xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp) | 774 | xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp) |
| 810 | { | 775 | { |
| 811 | rp->sn.activate_gru_mq_desc_gpa = | 776 | xpc_heartbeat_uv = |
| 777 | &xpc_partitions[sn_partition_id].sn.uv.cached_heartbeat; | ||
| 778 | rp->sn.uv.heartbeat_gpa = uv_gpa(xpc_heartbeat_uv); | ||
| 779 | rp->sn.uv.activate_gru_mq_desc_gpa = | ||
| 812 | uv_gpa(xpc_activate_mq_uv->gru_mq_desc); | 780 | uv_gpa(xpc_activate_mq_uv->gru_mq_desc); |
| 813 | return 0; | 781 | return 0; |
| 814 | } | 782 | } |
| 815 | 783 | ||
| 816 | static void | 784 | static void |
| 817 | xpc_send_heartbeat_uv(int msg_type) | 785 | xpc_allow_hb_uv(short partid) |
| 818 | { | 786 | { |
| 819 | short partid; | 787 | } |
| 820 | struct xpc_partition *part; | ||
| 821 | struct xpc_activate_mq_msg_heartbeat_req_uv msg; | ||
| 822 | |||
| 823 | /* | ||
| 824 | * !!! On uv we're broadcasting a heartbeat message every 5 seconds. | ||
| 825 | * !!! Whereas on sn2 we're bte_copy'ng the heartbeat info every 20 | ||
| 826 | * !!! seconds. This is an increase in numalink traffic. | ||
| 827 | * ??? Is this good? | ||
| 828 | */ | ||
| 829 | |||
| 830 | msg.heartbeat = atomic64_inc_return(&xpc_heartbeat_uv); | ||
| 831 | |||
| 832 | partid = find_first_bit(xpc_heartbeating_to_mask_uv, | ||
| 833 | XP_MAX_NPARTITIONS_UV); | ||
| 834 | |||
| 835 | while (partid < XP_MAX_NPARTITIONS_UV) { | ||
| 836 | part = &xpc_partitions[partid]; | ||
| 837 | 788 | ||
| 838 | xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), | 789 | static void |
| 839 | msg_type); | 790 | xpc_disallow_hb_uv(short partid) |
| 791 | { | ||
| 792 | } | ||
| 840 | 793 | ||
| 841 | partid = find_next_bit(xpc_heartbeating_to_mask_uv, | 794 | static void |
| 842 | XP_MAX_NPARTITIONS_UV, partid + 1); | 795 | xpc_disallow_all_hbs_uv(void) |
| 843 | } | 796 | { |
| 844 | } | 797 | } |
| 845 | 798 | ||
| 846 | static void | 799 | static void |
| 847 | xpc_increment_heartbeat_uv(void) | 800 | xpc_increment_heartbeat_uv(void) |
| 848 | { | 801 | { |
| 849 | xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV); | 802 | xpc_heartbeat_uv->value++; |
| 850 | } | 803 | } |
| 851 | 804 | ||
| 852 | static void | 805 | static void |
| 853 | xpc_offline_heartbeat_uv(void) | 806 | xpc_offline_heartbeat_uv(void) |
| 854 | { | 807 | { |
| 855 | xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV); | 808 | xpc_increment_heartbeat_uv(); |
| 809 | xpc_heartbeat_uv->offline = 1; | ||
| 856 | } | 810 | } |
| 857 | 811 | ||
| 858 | static void | 812 | static void |
| 859 | xpc_online_heartbeat_uv(void) | 813 | xpc_online_heartbeat_uv(void) |
| 860 | { | 814 | { |
| 861 | xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV); | 815 | xpc_increment_heartbeat_uv(); |
| 816 | xpc_heartbeat_uv->offline = 0; | ||
| 862 | } | 817 | } |
| 863 | 818 | ||
| 864 | static void | 819 | static void |
| 865 | xpc_heartbeat_init_uv(void) | 820 | xpc_heartbeat_init_uv(void) |
| 866 | { | 821 | { |
| 867 | atomic64_set(&xpc_heartbeat_uv, 0); | 822 | xpc_heartbeat_uv->value = 1; |
| 868 | bitmap_zero(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV); | 823 | xpc_heartbeat_uv->offline = 0; |
| 869 | xpc_heartbeating_to_mask = &xpc_heartbeating_to_mask_uv[0]; | ||
| 870 | } | 824 | } |
| 871 | 825 | ||
| 872 | static void | 826 | static void |
| 873 | xpc_heartbeat_exit_uv(void) | 827 | xpc_heartbeat_exit_uv(void) |
| 874 | { | 828 | { |
| 875 | xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV); | 829 | xpc_offline_heartbeat_uv(); |
| 876 | } | 830 | } |
| 877 | 831 | ||
| 878 | static enum xp_retval | 832 | static enum xp_retval |
| 879 | xpc_get_remote_heartbeat_uv(struct xpc_partition *part) | 833 | xpc_get_remote_heartbeat_uv(struct xpc_partition *part) |
| 880 | { | 834 | { |
| 881 | struct xpc_partition_uv *part_uv = &part->sn.uv; | 835 | struct xpc_partition_uv *part_uv = &part->sn.uv; |
| 882 | enum xp_retval ret = xpNoHeartbeat; | 836 | enum xp_retval ret; |
| 883 | 837 | ||
| 884 | if (part_uv->remote_act_state != XPC_P_AS_INACTIVE && | 838 | ret = xp_remote_memcpy(uv_gpa(&part_uv->cached_heartbeat), |
| 885 | part_uv->remote_act_state != XPC_P_AS_DEACTIVATING) { | 839 | part_uv->heartbeat_gpa, |
| 840 | sizeof(struct xpc_heartbeat_uv)); | ||
| 841 | if (ret != xpSuccess) | ||
| 842 | return ret; | ||
| 886 | 843 | ||
| 887 | if (part_uv->heartbeat != part->last_heartbeat || | 844 | if (part_uv->cached_heartbeat.value == part->last_heartbeat && |
| 888 | (part_uv->flags & XPC_P_HEARTBEAT_OFFLINE_UV)) { | 845 | !part_uv->cached_heartbeat.offline) { |
| 889 | 846 | ||
| 890 | part->last_heartbeat = part_uv->heartbeat; | 847 | ret = xpNoHeartbeat; |
| 891 | ret = xpSuccess; | 848 | } else { |
| 892 | } | 849 | part->last_heartbeat = part_uv->cached_heartbeat.value; |
| 893 | } | 850 | } |
| 894 | return ret; | 851 | return ret; |
| 895 | } | 852 | } |
| @@ -904,8 +861,9 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp, | |||
| 904 | 861 | ||
| 905 | part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */ | 862 | part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */ |
| 906 | part->remote_rp_ts_jiffies = remote_rp->ts_jiffies; | 863 | part->remote_rp_ts_jiffies = remote_rp->ts_jiffies; |
| 864 | part->sn.uv.heartbeat_gpa = remote_rp->sn.uv.heartbeat_gpa; | ||
| 907 | part->sn.uv.activate_gru_mq_desc_gpa = | 865 | part->sn.uv.activate_gru_mq_desc_gpa = |
| 908 | remote_rp->sn.activate_gru_mq_desc_gpa; | 866 | remote_rp->sn.uv.activate_gru_mq_desc_gpa; |
| 909 | 867 | ||
| 910 | /* | 868 | /* |
| 911 | * ??? Is it a good idea to make this conditional on what is | 869 | * ??? Is it a good idea to make this conditional on what is |
| @@ -913,8 +871,9 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp, | |||
| 913 | */ | 871 | */ |
| 914 | if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) { | 872 | if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) { |
| 915 | msg.rp_gpa = uv_gpa(xpc_rsvd_page); | 873 | msg.rp_gpa = uv_gpa(xpc_rsvd_page); |
| 874 | msg.heartbeat_gpa = xpc_rsvd_page->sn.uv.heartbeat_gpa; | ||
| 916 | msg.activate_gru_mq_desc_gpa = | 875 | msg.activate_gru_mq_desc_gpa = |
| 917 | xpc_rsvd_page->sn.activate_gru_mq_desc_gpa; | 876 | xpc_rsvd_page->sn.uv.activate_gru_mq_desc_gpa; |
| 918 | xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), | 877 | xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), |
| 919 | XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV); | 878 | XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV); |
| 920 | } | 879 | } |
| @@ -1677,6 +1636,10 @@ xpc_init_uv(void) | |||
| 1677 | xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv; | 1636 | xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv; |
| 1678 | xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv; | 1637 | xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv; |
| 1679 | xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_uv; | 1638 | xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_uv; |
| 1639 | |||
| 1640 | xpc_allow_hb = xpc_allow_hb_uv; | ||
| 1641 | xpc_disallow_hb = xpc_disallow_hb_uv; | ||
| 1642 | xpc_disallow_all_hbs = xpc_disallow_all_hbs_uv; | ||
| 1680 | xpc_increment_heartbeat = xpc_increment_heartbeat_uv; | 1643 | xpc_increment_heartbeat = xpc_increment_heartbeat_uv; |
| 1681 | xpc_offline_heartbeat = xpc_offline_heartbeat_uv; | 1644 | xpc_offline_heartbeat = xpc_offline_heartbeat_uv; |
| 1682 | xpc_online_heartbeat = xpc_online_heartbeat_uv; | 1645 | xpc_online_heartbeat = xpc_online_heartbeat_uv; |
