Lines Matching +full:wake +full:- +full:on +full:- +full:motion

7  * Copyright (c) 2004-2009 Silicon Graphics, Inc.  All Rights Reserved.
11 * Cross Partition Communication (XPC) support - standard version.
29 * . Currently on sn2, we have no way to determine which nasid an IRQ
139 /* non-zero if any remote partition disengage was timed out */
146 /* IRQ handler notifies this wait queue on receipt of an IRQ */
173 * Timer function to enforce the timelimit on the partition disengage.
180 DBUG_ON(time_is_after_jiffies(part->disengage_timeout)); in xpc_timeout_partition_disengage()
184 DBUG_ON(part->disengage_timeout != 0); in xpc_timeout_partition_disengage()
241 if (part->act_state == XPC_P_AS_INACTIVE || in xpc_check_remote_hb()
242 part->act_state == XPC_P_AS_DEACTIVATING) { in xpc_check_remote_hb()
265 /* set our heartbeating to other partitions into motion */ in xpc_hb_checker()
273 (int)(xpc_hb_check_timeout - jiffies), in xpc_hb_checker()
312 * based on info provided by SAL. This new thread is short lived and
329 * created by XPC HB with which it calls xpc_activating(). XPC hangs on to
342 while (part->act_state != XPC_P_AS_DEACTIVATING || in xpc_channel_mgr()
343 atomic_read(&part->nchannels_active) > 0 || in xpc_channel_mgr()
359 * wake him up. in xpc_channel_mgr()
361 atomic_dec(&part->channel_mgr_requests); in xpc_channel_mgr()
362 (void)wait_event_interruptible(part->channel_mgr_wq, in xpc_channel_mgr()
363 (atomic_read(&part->channel_mgr_requests) > 0 || in xpc_channel_mgr()
364 part->chctl.all_flags != 0 || in xpc_channel_mgr()
365 (part->act_state == XPC_P_AS_DEACTIVATING && in xpc_channel_mgr()
366 atomic_read(&part->nchannels_active) == 0 && in xpc_channel_mgr()
368 atomic_set(&part->channel_mgr_requests, 1); in xpc_channel_mgr()
412 DBUG_ON(part->channels != NULL); in xpc_setup_ch_structures()
413 part->channels = kcalloc(XPC_MAX_NCHANNELS, in xpc_setup_ch_structures()
416 if (part->channels == NULL) { in xpc_setup_ch_structures()
423 part->remote_openclose_args = in xpc_setup_ch_structures()
425 GFP_KERNEL, &part-> in xpc_setup_ch_structures()
427 if (part->remote_openclose_args == NULL) { in xpc_setup_ch_structures()
433 part->chctl.all_flags = 0; in xpc_setup_ch_structures()
434 spin_lock_init(&part->chctl_lock); in xpc_setup_ch_structures()
436 atomic_set(&part->channel_mgr_requests, 1); in xpc_setup_ch_structures()
437 init_waitqueue_head(&part->channel_mgr_wq); in xpc_setup_ch_structures()
439 part->nchannels = XPC_MAX_NCHANNELS; in xpc_setup_ch_structures()
441 atomic_set(&part->nchannels_active, 0); in xpc_setup_ch_structures()
442 atomic_set(&part->nchannels_engaged, 0); in xpc_setup_ch_structures()
444 for (ch_number = 0; ch_number < part->nchannels; ch_number++) { in xpc_setup_ch_structures()
445 ch = &part->channels[ch_number]; in xpc_setup_ch_structures()
447 ch->partid = partid; in xpc_setup_ch_structures()
448 ch->number = ch_number; in xpc_setup_ch_structures()
449 ch->flags = XPC_C_DISCONNECTED; in xpc_setup_ch_structures()
451 atomic_set(&ch->kthreads_assigned, 0); in xpc_setup_ch_structures()
452 atomic_set(&ch->kthreads_idle, 0); in xpc_setup_ch_structures()
453 atomic_set(&ch->kthreads_active, 0); in xpc_setup_ch_structures()
455 atomic_set(&ch->references, 0); in xpc_setup_ch_structures()
456 atomic_set(&ch->n_to_notify, 0); in xpc_setup_ch_structures()
458 spin_lock_init(&ch->lock); in xpc_setup_ch_structures()
459 init_completion(&ch->wdisconnect_wait); in xpc_setup_ch_structures()
461 atomic_set(&ch->n_on_msg_allocate_wq, 0); in xpc_setup_ch_structures()
462 init_waitqueue_head(&ch->msg_allocate_wq); in xpc_setup_ch_structures()
463 init_waitqueue_head(&ch->idle_wq); in xpc_setup_ch_structures()
474 part->setup_state = XPC_P_SS_SETUP; in xpc_setup_ch_structures()
480 kfree(part->remote_openclose_args_base); in xpc_setup_ch_structures()
481 part->remote_openclose_args = NULL; in xpc_setup_ch_structures()
483 kfree(part->channels); in xpc_setup_ch_structures()
484 part->channels = NULL; in xpc_setup_ch_structures()
495 DBUG_ON(atomic_read(&part->nchannels_engaged) != 0); in xpc_teardown_ch_structures()
496 DBUG_ON(atomic_read(&part->nchannels_active) != 0); in xpc_teardown_ch_structures()
503 DBUG_ON(part->setup_state != XPC_P_SS_SETUP); in xpc_teardown_ch_structures()
504 part->setup_state = XPC_P_SS_WTEARDOWN; in xpc_teardown_ch_structures()
506 wait_event(part->teardown_wq, (atomic_read(&part->references) == 0)); in xpc_teardown_ch_structures()
512 kfree(part->remote_openclose_args_base); in xpc_teardown_ch_structures()
513 part->remote_openclose_args = NULL; in xpc_teardown_ch_structures()
514 kfree(part->channels); in xpc_teardown_ch_structures()
515 part->channels = NULL; in xpc_teardown_ch_structures()
517 part->setup_state = XPC_P_SS_TORNDOWN; in xpc_teardown_ch_structures()
540 spin_lock_irqsave(&part->act_lock, irq_flags); in xpc_activating()
542 if (part->act_state == XPC_P_AS_DEACTIVATING) { in xpc_activating()
543 part->act_state = XPC_P_AS_INACTIVE; in xpc_activating()
544 spin_unlock_irqrestore(&part->act_lock, irq_flags); in xpc_activating()
545 part->remote_rp_pa = 0; in xpc_activating()
550 DBUG_ON(part->act_state != XPC_P_AS_ACTIVATION_REQ); in xpc_activating()
551 part->act_state = XPC_P_AS_ACTIVATING; in xpc_activating()
554 spin_unlock_irqrestore(&part->act_lock, irq_flags); in xpc_activating()
576 if (part->reason == xpReactivating) { in xpc_activating()
591 spin_lock_irqsave(&part->act_lock, irq_flags); in xpc_activate_partition()
593 DBUG_ON(part->act_state != XPC_P_AS_INACTIVE); in xpc_activate_partition()
595 part->act_state = XPC_P_AS_ACTIVATION_REQ; in xpc_activate_partition()
598 spin_unlock_irqrestore(&part->act_lock, irq_flags); in xpc_activate_partition()
603 spin_lock_irqsave(&part->act_lock, irq_flags); in xpc_activate_partition()
604 part->act_state = XPC_P_AS_INACTIVE; in xpc_activate_partition()
606 spin_unlock_irqrestore(&part->act_lock, irq_flags); in xpc_activate_partition()
613 int idle = atomic_read(&ch->kthreads_idle); in xpc_activate_kthreads()
614 int assigned = atomic_read(&ch->kthreads_assigned); in xpc_activate_kthreads()
621 needed -= wakeup; in xpc_activate_kthreads()
624 "channel=%d\n", wakeup, ch->partid, ch->number); in xpc_activate_kthreads()
627 wake_up_nr(&ch->idle_wq, wakeup); in xpc_activate_kthreads()
633 if (needed + assigned > ch->kthreads_assigned_limit) { in xpc_activate_kthreads()
634 needed = ch->kthreads_assigned_limit - assigned; in xpc_activate_kthreads()
640 needed, ch->partid, ch->number); in xpc_activate_kthreads()
658 !(ch->flags & XPC_C_DISCONNECTING)) { in xpc_kthread_waitmsgs()
662 if (atomic_inc_return(&ch->kthreads_idle) > in xpc_kthread_waitmsgs()
663 ch->kthreads_idle_limit) { in xpc_kthread_waitmsgs()
664 /* too many idle kthreads on this channel */ in xpc_kthread_waitmsgs()
665 atomic_dec(&ch->kthreads_idle); in xpc_kthread_waitmsgs()
672 (void)wait_event_interruptible_exclusive(ch->idle_wq, in xpc_kthread_waitmsgs()
674 (ch->flags & XPC_C_DISCONNECTING))); in xpc_kthread_waitmsgs()
676 atomic_dec(&ch->kthreads_idle); in xpc_kthread_waitmsgs()
678 } while (!(ch->flags & XPC_C_DISCONNECTING)); in xpc_kthread_waitmsgs()
696 ch = &part->channels[ch_number]; in xpc_kthread_start()
698 if (!(ch->flags & XPC_C_DISCONNECTING)) { in xpc_kthread_start()
702 spin_lock_irqsave(&ch->lock, irq_flags); in xpc_kthread_start()
703 if (!(ch->flags & XPC_C_CONNECTEDCALLOUT)) { in xpc_kthread_start()
704 ch->flags |= XPC_C_CONNECTEDCALLOUT; in xpc_kthread_start()
705 spin_unlock_irqrestore(&ch->lock, irq_flags); in xpc_kthread_start()
709 spin_lock_irqsave(&ch->lock, irq_flags); in xpc_kthread_start()
710 ch->flags |= XPC_C_CONNECTEDCALLOUT_MADE; in xpc_kthread_start()
711 spin_unlock_irqrestore(&ch->lock, irq_flags); in xpc_kthread_start()
720 n_needed = n_of_deliverable_payloads(ch) - 1; in xpc_kthread_start()
721 if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING)) in xpc_kthread_start()
725 spin_unlock_irqrestore(&ch->lock, irq_flags); in xpc_kthread_start()
733 spin_lock_irqsave(&ch->lock, irq_flags); in xpc_kthread_start()
734 if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) && in xpc_kthread_start()
735 !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) { in xpc_kthread_start()
736 ch->flags |= XPC_C_DISCONNECTINGCALLOUT; in xpc_kthread_start()
737 spin_unlock_irqrestore(&ch->lock, irq_flags); in xpc_kthread_start()
741 spin_lock_irqsave(&ch->lock, irq_flags); in xpc_kthread_start()
742 ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE; in xpc_kthread_start()
744 spin_unlock_irqrestore(&ch->lock, irq_flags); in xpc_kthread_start()
746 if (atomic_dec_return(&ch->kthreads_assigned) == 0 && in xpc_kthread_start()
747 atomic_dec_return(&part->nchannels_engaged) == 0) { in xpc_kthread_start()
777 u64 args = XPC_PACK_ARGS(ch->partid, ch->number); in xpc_create_kthreads()
778 struct xpc_partition *part = &xpc_partitions[ch->partid]; in xpc_create_kthreads()
783 while (needed-- > 0) { in xpc_create_kthreads()
786 * The following is done on behalf of the newly created in xpc_create_kthreads()
791 if (!atomic_inc_not_zero(&ch->kthreads_assigned)) { in xpc_create_kthreads()
793 BUG_ON(!(ch->flags & in xpc_create_kthreads()
798 } else if (ch->flags & XPC_C_DISCONNECTING) { in xpc_create_kthreads()
801 } else if (atomic_inc_return(&ch->kthreads_assigned) == 1 && in xpc_create_kthreads()
802 atomic_inc_return(&part->nchannels_engaged) == 1) { in xpc_create_kthreads()
809 "xpc%02dc%d", ch->partid, ch->number); in xpc_create_kthreads()
815 * !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) is true, in xpc_create_kthreads()
823 if (atomic_dec_return(&ch->kthreads_assigned) == 0 && in xpc_create_kthreads()
824 atomic_dec_return(&part->nchannels_engaged) == 0) { in xpc_create_kthreads()
830 if (atomic_read(&ch->kthreads_assigned) < in xpc_create_kthreads()
831 ch->kthreads_idle_limit) { in xpc_create_kthreads()
837 spin_lock_irqsave(&ch->lock, irq_flags); in xpc_create_kthreads()
840 spin_unlock_irqrestore(&ch->lock, irq_flags); in xpc_create_kthreads()
863 ch = &part->channels[ch_number]; in xpc_disconnect_wait()
865 if (!(ch->flags & XPC_C_WDISCONNECT)) { in xpc_disconnect_wait()
870 wait_for_completion(&ch->wdisconnect_wait); in xpc_disconnect_wait()
872 spin_lock_irqsave(&ch->lock, irq_flags); in xpc_disconnect_wait()
873 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED)); in xpc_disconnect_wait()
876 if (ch->delayed_chctl_flags) { in xpc_disconnect_wait()
877 if (part->act_state != XPC_P_AS_DEACTIVATING) { in xpc_disconnect_wait()
878 spin_lock(&part->chctl_lock); in xpc_disconnect_wait()
879 part->chctl.flags[ch->number] |= in xpc_disconnect_wait()
880 ch->delayed_chctl_flags; in xpc_disconnect_wait()
881 spin_unlock(&part->chctl_lock); in xpc_disconnect_wait()
884 ch->delayed_chctl_flags = 0; in xpc_disconnect_wait()
887 ch->flags &= ~XPC_C_WDISCONNECT; in xpc_disconnect_wait()
888 spin_unlock_irqrestore(&ch->lock, irq_flags); in xpc_disconnect_wait()
908 return -ENOMEM; in xpc_setup_partitions()
924 part->activate_IRQ_rcvd = 0; in xpc_setup_partitions()
925 spin_lock_init(&part->act_lock); in xpc_setup_partitions()
926 part->act_state = XPC_P_AS_INACTIVE; in xpc_setup_partitions()
929 timer_setup(&part->disengage_timer, in xpc_setup_partitions()
932 part->setup_state = XPC_P_SS_UNSET; in xpc_setup_partitions()
933 init_waitqueue_head(&part->teardown_wq); in xpc_setup_partitions()
934 atomic_set(&part->references, 0); in xpc_setup_partitions()
960 * (if one is running) know that they should exit. Also wake up in xpc_do_exit()
987 part->act_state == XPC_P_AS_INACTIVE) { in xpc_do_exit()
995 if (part->disengage_timeout > disengage_timeout) in xpc_do_exit()
996 disengage_timeout = part->disengage_timeout; in xpc_do_exit()
1003 "%ld seconds\n", (disengage_timeout - in xpc_do_exit()
1105 part->act_state != XPC_P_AS_INACTIVE) { in xpc_die_deactivate()
1116 * Given that one iteration through the following while-loop takes in xpc_die_deactivate()
1130 if (!keep_waiting--) { in xpc_die_deactivate()
1142 if (!wait_to_print--) { in xpc_die_deactivate()
1199 if (die_args->trapnr == X86_TRAP_DF) in xpc_system_die()
1202 if (((die_args->trapnr == X86_TRAP_MF) || in xpc_system_die()
1203 (die_args->trapnr == X86_TRAP_XF)) && in xpc_system_die()
1204 !user_mode(die_args->regs)) in xpc_system_die()
1234 ret = -ENODEV; in xpc_init()
1270 * The real work-horse behind xpc. This processes incoming in xpc_init()
1276 ret = -EBUSY; in xpc_init()
1282 * activate based on info provided by SAL. This new thread is short in xpc_init()
1290 /* mark this new thread as a non-starter */ in xpc_init()
1294 return -EBUSY; in xpc_init()