aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-xp/xpc_main.c
diff options
context:
space:
mode:
authorDean Nelson <dcn@sgi.com>2008-07-30 01:34:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-30 12:41:49 -0400
commit33ba3c7724be79f7cdbfc611335572c056d9a05a (patch)
treedb0371c031b0bbab13ccb2aeaf015424633cf2d8 /drivers/misc/sgi-xp/xpc_main.c
parente17d416b1bc947df68499863f13b401fb42b48f6 (diff)
sgi-xp: isolate xpc_vars structure to sn2 only
Isolate the xpc_vars structure of XPC's reserved page to sn2 only. 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_main.c')
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c152
1 files changed, 101 insertions, 51 deletions
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index be3a48539307..10dac3652b23 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -148,12 +148,14 @@ static struct ctl_table_header *xpc_sysctl;
148int xpc_disengage_request_timedout; 148int xpc_disengage_request_timedout;
149 149
150/* #of IRQs received */ 150/* #of IRQs received */
151static atomic_t xpc_act_IRQ_rcvd; 151atomic_t xpc_act_IRQ_rcvd;
152 152
153/* IRQ handler notifies this wait queue on receipt of an IRQ */ 153/* IRQ handler notifies this wait queue on receipt of an IRQ */
154static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq); 154DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
155 155
156static unsigned long xpc_hb_check_timeout; 156static unsigned long xpc_hb_check_timeout;
157static struct timer_list xpc_hb_timer;
158void *xpc_heartbeating_to_mask;
157 159
158/* notification that the xpc_hb_checker thread has exited */ 160/* notification that the xpc_hb_checker thread has exited */
159static DECLARE_COMPLETION(xpc_hb_checker_exited); 161static DECLARE_COMPLETION(xpc_hb_checker_exited);
@@ -161,8 +163,6 @@ static DECLARE_COMPLETION(xpc_hb_checker_exited);
161/* notification that the xpc_discovery thread has exited */ 163/* notification that the xpc_discovery thread has exited */
162static DECLARE_COMPLETION(xpc_discovery_exited); 164static DECLARE_COMPLETION(xpc_discovery_exited);
163 165
164static struct timer_list xpc_hb_timer;
165
166static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *); 166static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *);
167 167
168static int xpc_system_reboot(struct notifier_block *, unsigned long, void *); 168static int xpc_system_reboot(struct notifier_block *, unsigned long, void *);
@@ -176,12 +176,54 @@ static struct notifier_block xpc_die_notifier = {
176}; 176};
177 177
178enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *rp); 178enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *rp);
179void (*xpc_heartbeat_init) (void);
180void (*xpc_heartbeat_exit) (void);
181void (*xpc_increment_heartbeat) (void);
182void (*xpc_offline_heartbeat) (void);
183void (*xpc_online_heartbeat) (void);
184void (*xpc_check_remote_hb) (void);
185
179enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part); 186enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part);
180u64 (*xpc_get_IPI_flags) (struct xpc_partition *part); 187u64 (*xpc_get_IPI_flags) (struct xpc_partition *part);
181struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *ch); 188struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *ch);
189
190void (*xpc_initiate_partition_activation) (struct xpc_rsvd_page *remote_rp,
191 u64 remote_rp_pa, int nasid);
192
193void (*xpc_process_act_IRQ_rcvd) (int n_IRQs_expected);
182enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *part); 194enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *part);
183void (*xpc_teardown_infrastructure) (struct xpc_partition *part); 195void (*xpc_teardown_infrastructure) (struct xpc_partition *part);
184 196
197void (*xpc_mark_partition_engaged) (struct xpc_partition *part);
198void (*xpc_mark_partition_disengaged) (struct xpc_partition *part);
199void (*xpc_request_partition_disengage) (struct xpc_partition *part);
200void (*xpc_cancel_partition_disengage_request) (struct xpc_partition *part);
201u64 (*xpc_partition_engaged) (u64 partid_mask);
202u64 (*xpc_partition_disengage_requested) (u64 partid_mask);
203void (*xpc_clear_partition_engaged) (u64 partid_mask);
204void (*xpc_clear_partition_disengage_request) (u64 partid_mask);
205
206void (*xpc_IPI_send_local_activate) (int from_nasid);
207void (*xpc_IPI_send_activated) (struct xpc_partition *part);
208void (*xpc_IPI_send_local_reactivate) (int from_nasid);
209void (*xpc_IPI_send_disengage) (struct xpc_partition *part);
210
211void (*xpc_IPI_send_closerequest) (struct xpc_channel *ch,
212 unsigned long *irq_flags);
213void (*xpc_IPI_send_closereply) (struct xpc_channel *ch,
214 unsigned long *irq_flags);
215void (*xpc_IPI_send_openrequest) (struct xpc_channel *ch,
216 unsigned long *irq_flags);
217void (*xpc_IPI_send_openreply) (struct xpc_channel *ch,
218 unsigned long *irq_flags);
219
220enum xp_retval (*xpc_allocate_msg) (struct xpc_channel *ch, u32 flags,
221 struct xpc_msg **address_of_msg);
222
223enum xp_retval (*xpc_send_msg) (struct xpc_channel *ch, struct xpc_msg *msg,
224 u8 notify_type, xpc_notify_func func,
225 void *key);
226void (*xpc_received_msg) (struct xpc_channel *ch, struct xpc_msg *msg);
185 227
186/* 228/*
187 * Timer function to enforce the timelimit on the partition disengage request. 229 * Timer function to enforce the timelimit on the partition disengage request.
@@ -218,7 +260,7 @@ xpc_act_IRQ_handler(int irq, void *dev_id)
218static void 260static void
219xpc_hb_beater(unsigned long dummy) 261xpc_hb_beater(unsigned long dummy)
220{ 262{
221 xpc_vars->heartbeat++; 263 xpc_increment_heartbeat();
222 264
223 if (time_after_eq(jiffies, xpc_hb_check_timeout)) 265 if (time_after_eq(jiffies, xpc_hb_check_timeout))
224 wake_up_interruptible(&xpc_act_IRQ_wq); 266 wake_up_interruptible(&xpc_act_IRQ_wq);
@@ -227,6 +269,22 @@ xpc_hb_beater(unsigned long dummy)
227 add_timer(&xpc_hb_timer); 269 add_timer(&xpc_hb_timer);
228} 270}
229 271
272static void
273xpc_start_hb_beater(void)
274{
275 xpc_heartbeat_init();
276 init_timer(&xpc_hb_timer);
277 xpc_hb_timer.function = xpc_hb_beater;
278 xpc_hb_beater(0);
279}
280
281static void
282xpc_stop_hb_beater(void)
283{
284 del_timer_sync(&xpc_hb_timer);
285 xpc_heartbeat_exit();
286}
287
230/* 288/*
231 * This thread is responsible for nearly all of the partition 289 * This thread is responsible for nearly all of the partition
232 * activation/deactivation. 290 * activation/deactivation.
@@ -244,7 +302,7 @@ xpc_hb_checker(void *ignore)
244 302
245 /* set our heartbeating to other partitions into motion */ 303 /* set our heartbeating to other partitions into motion */
246 xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ); 304 xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
247 xpc_hb_beater(0); 305 xpc_start_hb_beater();
248 306
249 while (!xpc_exiting) { 307 while (!xpc_exiting) {
250 308
@@ -274,11 +332,8 @@ xpc_hb_checker(void *ignore)
274 dev_dbg(xpc_part, "found an IRQ to process; will be " 332 dev_dbg(xpc_part, "found an IRQ to process; will be "
275 "resetting xpc_hb_check_timeout\n"); 333 "resetting xpc_hb_check_timeout\n");
276 334
277 last_IRQ_count += xpc_identify_act_IRQ_sender(); 335 xpc_process_act_IRQ_rcvd(new_IRQ_count -
278 if (last_IRQ_count < new_IRQ_count) { 336 last_IRQ_count);
279 /* retry once to help avoid missing AMO */
280 (void)xpc_identify_act_IRQ_sender();
281 }
282 last_IRQ_count = new_IRQ_count; 337 last_IRQ_count = new_IRQ_count;
283 338
284 xpc_hb_check_timeout = jiffies + 339 xpc_hb_check_timeout = jiffies +
@@ -294,6 +349,8 @@ xpc_hb_checker(void *ignore)
294 xpc_exiting)); 349 xpc_exiting));
295 } 350 }
296 351
352 xpc_stop_hb_beater();
353
297 dev_dbg(xpc_part, "heartbeat checker is exiting\n"); 354 dev_dbg(xpc_part, "heartbeat checker is exiting\n");
298 355
299 /* mark this thread as having exited */ 356 /* mark this thread as having exited */
@@ -401,31 +458,7 @@ xpc_activating(void *__partid)
401 458
402 dev_dbg(xpc_part, "activating partition %d\n", partid); 459 dev_dbg(xpc_part, "activating partition %d\n", partid);
403 460
404 /* 461 xpc_allow_hb(partid);
405 * Register the remote partition's AMOs with SAL so it can handle
406 * and cleanup errors within that address range should the remote
407 * partition go down. We don't unregister this range because it is
408 * difficult to tell when outstanding writes to the remote partition
409 * are finished and thus when it is safe to unregister. This should
410 * not result in wasted space in the SAL xp_addr_region table because
411 * we should get the same page for remote_amos_page_pa after module
412 * reloads and system reboots.
413 */
414 if (sn_register_xp_addr_region(part->remote_amos_page_pa,
415 PAGE_SIZE, 1) < 0) {
416 dev_warn(xpc_part, "xpc_activating(%d) failed to register "
417 "xp_addr region\n", partid);
418
419 spin_lock_irqsave(&part->act_lock, irq_flags);
420 part->act_state = XPC_P_INACTIVE;
421 XPC_SET_REASON(part, xpPhysAddrRegFailed, __LINE__);
422 spin_unlock_irqrestore(&part->act_lock, irq_flags);
423 part->remote_rp_pa = 0;
424 return 0;
425 }
426
427 xpc_allow_hb(partid, xpc_vars);
428 xpc_IPI_send_activated(part);
429 462
430 if (xpc_setup_infrastructure(part) == xpSuccess) { 463 if (xpc_setup_infrastructure(part) == xpSuccess) {
431 (void)xpc_part_ref(part); /* this will always succeed */ 464 (void)xpc_part_ref(part); /* this will always succeed */
@@ -440,12 +473,12 @@ xpc_activating(void *__partid)
440 xpc_teardown_infrastructure(part); 473 xpc_teardown_infrastructure(part);
441 } 474 }
442 475
443 xpc_disallow_hb(partid, xpc_vars); 476 xpc_disallow_hb(partid);
444 xpc_mark_partition_inactive(part); 477 xpc_mark_partition_inactive(part);
445 478
446 if (part->reason == xpReactivating) { 479 if (part->reason == xpReactivating) {
447 /* interrupting ourselves results in activating partition */ 480 /* interrupting ourselves results in activating partition */
448 xpc_IPI_send_reactivate(part); 481 xpc_IPI_send_local_reactivate(part->reactivate_nasid);
449 } 482 }
450 483
451 return 0; 484 return 0;
@@ -478,6 +511,32 @@ xpc_activate_partition(struct xpc_partition *part)
478} 511}
479 512
480/* 513/*
514 * Check to see if there is any channel activity to/from the specified
515 * partition.
516 */
517static void
518xpc_check_for_channel_activity(struct xpc_partition *part)
519{
520 u64 IPI_amo;
521 unsigned long irq_flags;
522
523/* this needs to be uncommented, but I'm thinking this function and the */
524/* ones that call it need to be moved into xpc_sn2.c... */
525 IPI_amo = 0; /* = xpc_IPI_receive(part->local_IPI_amo_va); */
526 if (IPI_amo == 0)
527 return;
528
529 spin_lock_irqsave(&part->IPI_lock, irq_flags);
530 part->local_IPI_amo |= IPI_amo;
531 spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
532
533 dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n",
534 XPC_PARTID(part), IPI_amo);
535
536 xpc_wakeup_channel_mgr(part);
537}
538
539/*
481 * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified 540 * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified
482 * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more 541 * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more
483 * than one partition, we use an AMO_t structure per partition to indicate 542 * than one partition, we use an AMO_t structure per partition to indicate
@@ -902,14 +961,11 @@ xpc_do_exit(enum xp_retval reason)
902 } while (1); 961 } while (1);
903 962
904 DBUG_ON(xpc_partition_engaged(-1UL)); 963 DBUG_ON(xpc_partition_engaged(-1UL));
964 DBUG_ON(xpc_any_hbs_allowed() != 0);
905 965
906 /* indicate to others that our reserved page is uninitialized */ 966 /* indicate to others that our reserved page is uninitialized */
907 xpc_rsvd_page->stamp = ZERO_STAMP; 967 xpc_rsvd_page->stamp = ZERO_STAMP;
908 968
909 /* now it's time to eliminate our heartbeat */
910 del_timer_sync(&xpc_hb_timer);
911 DBUG_ON(xpc_vars->heartbeating_to_mask != 0);
912
913 if (reason == xpUnloading) { 969 if (reason == xpUnloading) {
914 (void)unregister_die_notifier(&xpc_die_notifier); 970 (void)unregister_die_notifier(&xpc_die_notifier);
915 (void)unregister_reboot_notifier(&xpc_reboot_notifier); 971 (void)unregister_reboot_notifier(&xpc_reboot_notifier);
@@ -968,7 +1024,7 @@ xpc_die_disengage(void)
968 /* keep xpc_hb_checker thread from doing anything (just in case) */ 1024 /* keep xpc_hb_checker thread from doing anything (just in case) */
969 xpc_exiting = 1; 1025 xpc_exiting = 1;
970 1026
971 xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */ 1027 xpc_disallow_all_hbs(); /*indicate we're deactivated */
972 1028
973 for (partid = 0; partid < xp_max_npartitions; partid++) { 1029 for (partid = 0; partid < xp_max_npartitions; partid++) {
974 part = &xpc_partitions[partid]; 1030 part = &xpc_partitions[partid];
@@ -1054,8 +1110,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
1054 /* fall through */ 1110 /* fall through */
1055 case DIE_MCA_MONARCH_ENTER: 1111 case DIE_MCA_MONARCH_ENTER:
1056 case DIE_INIT_MONARCH_ENTER: 1112 case DIE_INIT_MONARCH_ENTER:
1057 xpc_vars->heartbeat++; 1113 xpc_offline_heartbeat();
1058 xpc_vars->heartbeat_offline = 1;
1059 break; 1114 break;
1060 1115
1061 case DIE_KDEBUG_LEAVE: 1116 case DIE_KDEBUG_LEAVE:
@@ -1066,8 +1121,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
1066 /* fall through */ 1121 /* fall through */
1067 case DIE_MCA_MONARCH_LEAVE: 1122 case DIE_MCA_MONARCH_LEAVE:
1068 case DIE_INIT_MONARCH_LEAVE: 1123 case DIE_INIT_MONARCH_LEAVE:
1069 xpc_vars->heartbeat++; 1124 xpc_online_heartbeat();
1070 xpc_vars->heartbeat_offline = 0;
1071 break; 1125 break;
1072 } 1126 }
1073 1127
@@ -1202,9 +1256,6 @@ xpc_init(void)
1202 if (ret != 0) 1256 if (ret != 0)
1203 dev_warn(xpc_part, "can't register die notifier\n"); 1257 dev_warn(xpc_part, "can't register die notifier\n");
1204 1258
1205 init_timer(&xpc_hb_timer);
1206 xpc_hb_timer.function = xpc_hb_beater;
1207
1208 /* 1259 /*
1209 * The real work-horse behind xpc. This processes incoming 1260 * The real work-horse behind xpc. This processes incoming
1210 * interrupts and monitors remote heartbeats. 1261 * interrupts and monitors remote heartbeats.
@@ -1246,7 +1297,6 @@ out_4:
1246 /* indicate to others that our reserved page is uninitialized */ 1297 /* indicate to others that our reserved page is uninitialized */
1247 xpc_rsvd_page->stamp = ZERO_STAMP; 1298 xpc_rsvd_page->stamp = ZERO_STAMP;
1248 1299
1249 del_timer_sync(&xpc_hb_timer);
1250 (void)unregister_die_notifier(&xpc_die_notifier); 1300 (void)unregister_die_notifier(&xpc_die_notifier);
1251 (void)unregister_reboot_notifier(&xpc_reboot_notifier); 1301 (void)unregister_reboot_notifier(&xpc_reboot_notifier);
1252out_3: 1302out_3: