diff options
author | Dean Nelson <dcn@sgi.com> | 2005-09-01 15:01:37 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-09-06 19:15:38 -0400 |
commit | a607c38971fd078865fa9bef39e6c1d4435680c8 (patch) | |
tree | cb7853f0d74ee6a9cd92ccc721096b57367d0390 /arch/ia64/sn/kernel/xpc_partition.c | |
parent | 4706df3d3c42af802597d82c8b1542c3d52eab23 (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>
Diffstat (limited to 'arch/ia64/sn/kernel/xpc_partition.c')
-rw-r--r-- | arch/ia64/sn/kernel/xpc_partition.c | 304 |
1 files changed, 254 insertions, 50 deletions
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 578265ea9e67..79a0fc4c860c 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c | |||
@@ -76,11 +76,6 @@ char ____cacheline_aligned | |||
76 | xpc_remote_copy_buffer[XPC_RSVD_PAGE_ALIGNED_SIZE]; | 76 | xpc_remote_copy_buffer[XPC_RSVD_PAGE_ALIGNED_SIZE]; |
77 | 77 | ||
78 | 78 | ||
79 | /* systune related variables */ | ||
80 | int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; | ||
81 | int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_TIMEOUT; | ||
82 | |||
83 | |||
84 | /* | 79 | /* |
85 | * Given a nasid, get the physical address of the partition's reserved page | 80 | * Given a nasid, get the physical address of the partition's reserved page |
86 | * for that nasid. This function returns 0 on any error. | 81 | * for that nasid. This function returns 0 on any error. |
@@ -239,16 +234,21 @@ xpc_rsvd_page_init(void) | |||
239 | xpc_vars->amos_page = amos_page; /* save for next load of XPC */ | 234 | xpc_vars->amos_page = amos_page; /* save for next load of XPC */ |
240 | 235 | ||
241 | 236 | ||
242 | /* | 237 | /* initialize the activate IRQ related AMO variables */ |
243 | * Initialize the activation related AMO variables. | 238 | for (i = 0; i < XP_NASID_MASK_WORDS; i++) { |
244 | */ | 239 | (void) xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i); |
245 | xpc_vars->act_amos = xpc_IPI_init(XP_MAX_PARTITIONS); | ||
246 | for (i = 1; i < XP_NASID_MASK_WORDS; i++) { | ||
247 | xpc_IPI_init(i + XP_MAX_PARTITIONS); | ||
248 | } | 240 | } |
241 | |||
242 | /* initialize the engaged remote partitions related AMO variables */ | ||
243 | (void) xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO); | ||
244 | (void) xpc_IPI_init(XPC_DISENGAGE_REQUEST_AMO); | ||
245 | |||
249 | /* export AMO page's physical address to other partitions */ | 246 | /* export AMO page's physical address to other partitions */ |
250 | xpc_vars->amos_page_pa = ia64_tpa((u64) xpc_vars->amos_page); | 247 | xpc_vars->amos_page_pa = ia64_tpa((u64) xpc_vars->amos_page); |
251 | 248 | ||
249 | /* timestamp of when reserved page was initialized */ | ||
250 | rp->stamp = CURRENT_TIME; | ||
251 | |||
252 | /* | 252 | /* |
253 | * This signifies to the remote partition that our reserved | 253 | * This signifies to the remote partition that our reserved |
254 | * page is initialized. | 254 | * page is initialized. |
@@ -387,6 +387,11 @@ xpc_check_remote_hb(void) | |||
387 | remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer; | 387 | remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer; |
388 | 388 | ||
389 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | 389 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { |
390 | |||
391 | if (xpc_exiting) { | ||
392 | break; | ||
393 | } | ||
394 | |||
390 | if (partid == sn_partition_id) { | 395 | if (partid == sn_partition_id) { |
391 | continue; | 396 | continue; |
392 | } | 397 | } |
@@ -417,7 +422,7 @@ xpc_check_remote_hb(void) | |||
417 | 422 | ||
418 | if (((remote_vars->heartbeat == part->last_heartbeat) && | 423 | if (((remote_vars->heartbeat == part->last_heartbeat) && |
419 | (remote_vars->kdb_status == 0)) || | 424 | (remote_vars->kdb_status == 0)) || |
420 | !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) { | 425 | !xpc_hb_allowed(sn_partition_id, remote_vars)) { |
421 | 426 | ||
422 | XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); | 427 | XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); |
423 | continue; | 428 | continue; |
@@ -436,23 +441,23 @@ xpc_check_remote_hb(void) | |||
436 | */ | 441 | */ |
437 | static enum xpc_retval | 442 | static enum xpc_retval |
438 | xpc_get_remote_rp(int nasid, u64 *discovered_nasids, | 443 | xpc_get_remote_rp(int nasid, u64 *discovered_nasids, |
439 | struct xpc_rsvd_page *remote_rp, u64 *remote_rsvd_page_pa) | 444 | struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa) |
440 | { | 445 | { |
441 | int bres, i; | 446 | int bres, i; |
442 | 447 | ||
443 | 448 | ||
444 | /* get the reserved page's physical address */ | 449 | /* get the reserved page's physical address */ |
445 | 450 | ||
446 | *remote_rsvd_page_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp, | 451 | *remote_rp_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp, |
447 | XPC_RSVD_PAGE_ALIGNED_SIZE); | 452 | XPC_RSVD_PAGE_ALIGNED_SIZE); |
448 | if (*remote_rsvd_page_pa == 0) { | 453 | if (*remote_rp_pa == 0) { |
449 | return xpcNoRsvdPageAddr; | 454 | return xpcNoRsvdPageAddr; |
450 | } | 455 | } |
451 | 456 | ||
452 | 457 | ||
453 | /* pull over the reserved page structure */ | 458 | /* pull over the reserved page structure */ |
454 | 459 | ||
455 | bres = xp_bte_copy(*remote_rsvd_page_pa, ia64_tpa((u64) remote_rp), | 460 | bres = xp_bte_copy(*remote_rp_pa, ia64_tpa((u64) remote_rp), |
456 | XPC_RSVD_PAGE_ALIGNED_SIZE, | 461 | XPC_RSVD_PAGE_ALIGNED_SIZE, |
457 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); | 462 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); |
458 | if (bres != BTE_SUCCESS) { | 463 | if (bres != BTE_SUCCESS) { |
@@ -524,6 +529,55 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars) | |||
524 | 529 | ||
525 | 530 | ||
526 | /* | 531 | /* |
532 | * Update the remote partition's info. | ||
533 | */ | ||
534 | static void | ||
535 | xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version, | ||
536 | struct timespec *remote_rp_stamp, u64 remote_rp_pa, | ||
537 | u64 remote_vars_pa, struct xpc_vars *remote_vars) | ||
538 | { | ||
539 | part->remote_rp_version = remote_rp_version; | ||
540 | dev_dbg(xpc_part, " remote_rp_version = 0x%016lx\n", | ||
541 | part->remote_rp_version); | ||
542 | |||
543 | part->remote_rp_stamp = *remote_rp_stamp; | ||
544 | dev_dbg(xpc_part, " remote_rp_stamp (tv_sec = 0x%lx tv_nsec = 0x%lx\n", | ||
545 | part->remote_rp_stamp.tv_sec, part->remote_rp_stamp.tv_nsec); | ||
546 | |||
547 | part->remote_rp_pa = remote_rp_pa; | ||
548 | dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n", part->remote_rp_pa); | ||
549 | |||
550 | part->remote_vars_pa = remote_vars_pa; | ||
551 | dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n", | ||
552 | part->remote_vars_pa); | ||
553 | |||
554 | part->last_heartbeat = remote_vars->heartbeat; | ||
555 | dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n", | ||
556 | part->last_heartbeat); | ||
557 | |||
558 | part->remote_vars_part_pa = remote_vars->vars_part_pa; | ||
559 | dev_dbg(xpc_part, " remote_vars_part_pa = 0x%016lx\n", | ||
560 | part->remote_vars_part_pa); | ||
561 | |||
562 | part->remote_act_nasid = remote_vars->act_nasid; | ||
563 | dev_dbg(xpc_part, " remote_act_nasid = 0x%x\n", | ||
564 | part->remote_act_nasid); | ||
565 | |||
566 | part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid; | ||
567 | dev_dbg(xpc_part, " remote_act_phys_cpuid = 0x%x\n", | ||
568 | part->remote_act_phys_cpuid); | ||
569 | |||
570 | part->remote_amos_page_pa = remote_vars->amos_page_pa; | ||
571 | dev_dbg(xpc_part, " remote_amos_page_pa = 0x%lx\n", | ||
572 | part->remote_amos_page_pa); | ||
573 | |||
574 | part->remote_vars_version = remote_vars->version; | ||
575 | dev_dbg(xpc_part, " remote_vars_version = 0x%x\n", | ||
576 | part->remote_vars_version); | ||
577 | } | ||
578 | |||
579 | |||
580 | /* | ||
527 | * Prior code has determine the nasid which generated an IPI. Inspect | 581 | * Prior code has determine the nasid which generated an IPI. Inspect |
528 | * that nasid to determine if its partition needs to be activated or | 582 | * that nasid to determine if its partition needs to be activated or |
529 | * deactivated. | 583 | * deactivated. |
@@ -542,8 +596,12 @@ xpc_identify_act_IRQ_req(int nasid) | |||
542 | { | 596 | { |
543 | struct xpc_rsvd_page *remote_rp; | 597 | struct xpc_rsvd_page *remote_rp; |
544 | struct xpc_vars *remote_vars; | 598 | struct xpc_vars *remote_vars; |
545 | u64 remote_rsvd_page_pa; | 599 | u64 remote_rp_pa; |
546 | u64 remote_vars_pa; | 600 | u64 remote_vars_pa; |
601 | int remote_rp_version; | ||
602 | int reactivate = 0; | ||
603 | int stamp_diff; | ||
604 | struct timespec remote_rp_stamp = { 0, 0 }; | ||
547 | partid_t partid; | 605 | partid_t partid; |
548 | struct xpc_partition *part; | 606 | struct xpc_partition *part; |
549 | enum xpc_retval ret; | 607 | enum xpc_retval ret; |
@@ -553,7 +611,7 @@ xpc_identify_act_IRQ_req(int nasid) | |||
553 | 611 | ||
554 | remote_rp = (struct xpc_rsvd_page *) xpc_remote_copy_buffer; | 612 | remote_rp = (struct xpc_rsvd_page *) xpc_remote_copy_buffer; |
555 | 613 | ||
556 | ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rsvd_page_pa); | 614 | ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa); |
557 | if (ret != xpcSuccess) { | 615 | if (ret != xpcSuccess) { |
558 | dev_warn(xpc_part, "unable to get reserved page from nasid %d, " | 616 | dev_warn(xpc_part, "unable to get reserved page from nasid %d, " |
559 | "which sent interrupt, reason=%d\n", nasid, ret); | 617 | "which sent interrupt, reason=%d\n", nasid, ret); |
@@ -561,6 +619,10 @@ xpc_identify_act_IRQ_req(int nasid) | |||
561 | } | 619 | } |
562 | 620 | ||
563 | remote_vars_pa = remote_rp->vars_pa; | 621 | remote_vars_pa = remote_rp->vars_pa; |
622 | remote_rp_version = remote_rp->version; | ||
623 | if (XPC_SUPPORTS_RP_STAMP(remote_rp_version)) { | ||
624 | remote_rp_stamp = remote_rp->stamp; | ||
625 | } | ||
564 | partid = remote_rp->partid; | 626 | partid = remote_rp->partid; |
565 | part = &xpc_partitions[partid]; | 627 | part = &xpc_partitions[partid]; |
566 | 628 | ||
@@ -586,44 +648,117 @@ xpc_identify_act_IRQ_req(int nasid) | |||
586 | "%ld:0x%lx\n", (int) nasid, (int) partid, part->act_IRQ_rcvd, | 648 | "%ld:0x%lx\n", (int) nasid, (int) partid, part->act_IRQ_rcvd, |
587 | remote_vars->heartbeat, remote_vars->heartbeating_to_mask); | 649 | remote_vars->heartbeat, remote_vars->heartbeating_to_mask); |
588 | 650 | ||
651 | if (xpc_partition_disengaged(part) && | ||
652 | part->act_state == XPC_P_INACTIVE) { | ||
589 | 653 | ||
590 | if (part->act_state == XPC_P_INACTIVE) { | 654 | xpc_update_partition_info(part, remote_rp_version, |
655 | &remote_rp_stamp, remote_rp_pa, | ||
656 | remote_vars_pa, remote_vars); | ||
591 | 657 | ||
592 | part->remote_rp_pa = remote_rsvd_page_pa; | 658 | if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) { |
593 | dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n", | 659 | if (xpc_partition_disengage_requested(1UL << partid)) { |
594 | part->remote_rp_pa); | 660 | /* |
661 | * Other side is waiting on us to disengage, | ||
662 | * even though we already have. | ||
663 | */ | ||
664 | return; | ||
665 | } | ||
666 | } else { | ||
667 | /* other side doesn't support disengage requests */ | ||
668 | xpc_clear_partition_disengage_request(1UL << partid); | ||
669 | } | ||
595 | 670 | ||
596 | part->remote_vars_pa = remote_vars_pa; | 671 | xpc_activate_partition(part); |
597 | dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n", | 672 | return; |
598 | part->remote_vars_pa); | 673 | } |
599 | 674 | ||
600 | part->last_heartbeat = remote_vars->heartbeat; | 675 | DBUG_ON(part->remote_rp_version == 0); |
601 | dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n", | 676 | DBUG_ON(part->remote_vars_version == 0); |
602 | part->last_heartbeat); | 677 | |
678 | if (!XPC_SUPPORTS_RP_STAMP(part->remote_rp_version)) { | ||
679 | DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(part-> | ||
680 | remote_vars_version)); | ||
681 | |||
682 | if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) { | ||
683 | DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars-> | ||
684 | version)); | ||
685 | /* see if the other side rebooted */ | ||
686 | if (part->remote_amos_page_pa == | ||
687 | remote_vars->amos_page_pa && | ||
688 | xpc_hb_allowed(sn_partition_id, | ||
689 | remote_vars)) { | ||
690 | /* doesn't look that way, so ignore the IPI */ | ||
691 | return; | ||
692 | } | ||
693 | } | ||
603 | 694 | ||
604 | part->remote_vars_part_pa = remote_vars->vars_part_pa; | 695 | /* |
605 | dev_dbg(xpc_part, " remote_vars_part_pa = 0x%016lx\n", | 696 | * Other side rebooted and previous XPC didn't support the |
606 | part->remote_vars_part_pa); | 697 | * disengage request, so we don't need to do anything special. |
698 | */ | ||
607 | 699 | ||
608 | part->remote_act_nasid = remote_vars->act_nasid; | 700 | xpc_update_partition_info(part, remote_rp_version, |
609 | dev_dbg(xpc_part, " remote_act_nasid = 0x%x\n", | 701 | &remote_rp_stamp, remote_rp_pa, |
610 | part->remote_act_nasid); | 702 | remote_vars_pa, remote_vars); |
703 | part->reactivate_nasid = nasid; | ||
704 | XPC_DEACTIVATE_PARTITION(part, xpcReactivating); | ||
705 | return; | ||
706 | } | ||
611 | 707 | ||
612 | part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid; | 708 | DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)); |
613 | dev_dbg(xpc_part, " remote_act_phys_cpuid = 0x%x\n", | ||
614 | part->remote_act_phys_cpuid); | ||
615 | 709 | ||
616 | part->remote_amos_page_pa = remote_vars->amos_page_pa; | 710 | if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) { |
617 | dev_dbg(xpc_part, " remote_amos_page_pa = 0x%lx\n", | 711 | DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version)); |
618 | part->remote_amos_page_pa); | ||
619 | 712 | ||
620 | xpc_activate_partition(part); | 713 | /* |
714 | * Other side rebooted and previous XPC did support the | ||
715 | * disengage request, but the new one doesn't. | ||
716 | */ | ||
621 | 717 | ||
622 | } else if (part->remote_amos_page_pa != remote_vars->amos_page_pa || | 718 | xpc_clear_partition_engaged(1UL << partid); |
623 | !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) { | 719 | xpc_clear_partition_disengage_request(1UL << partid); |
624 | 720 | ||
721 | xpc_update_partition_info(part, remote_rp_version, | ||
722 | &remote_rp_stamp, remote_rp_pa, | ||
723 | remote_vars_pa, remote_vars); | ||
724 | reactivate = 1; | ||
725 | |||
726 | } else { | ||
727 | DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version)); | ||
728 | |||
729 | stamp_diff = xpc_compare_stamps(&part->remote_rp_stamp, | ||
730 | &remote_rp_stamp); | ||
731 | if (stamp_diff != 0) { | ||
732 | DBUG_ON(stamp_diff >= 0); | ||
733 | |||
734 | /* | ||
735 | * Other side rebooted and the previous XPC did support | ||
736 | * the disengage request, as does the new one. | ||
737 | */ | ||
738 | |||
739 | DBUG_ON(xpc_partition_engaged(1UL << partid)); | ||
740 | DBUG_ON(xpc_partition_disengage_requested(1UL << | ||
741 | partid)); | ||
742 | |||
743 | xpc_update_partition_info(part, remote_rp_version, | ||
744 | &remote_rp_stamp, remote_rp_pa, | ||
745 | remote_vars_pa, remote_vars); | ||
746 | reactivate = 1; | ||
747 | } | ||
748 | } | ||
749 | |||
750 | if (!xpc_partition_disengaged(part)) { | ||
751 | /* still waiting on other side to disengage from us */ | ||
752 | return; | ||
753 | } | ||
754 | |||
755 | if (reactivate) { | ||
625 | part->reactivate_nasid = nasid; | 756 | part->reactivate_nasid = nasid; |
626 | XPC_DEACTIVATE_PARTITION(part, xpcReactivating); | 757 | XPC_DEACTIVATE_PARTITION(part, xpcReactivating); |
758 | |||
759 | } else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) && | ||
760 | xpc_partition_disengage_requested(1UL << partid)) { | ||
761 | XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown); | ||
627 | } | 762 | } |
628 | } | 763 | } |
629 | 764 | ||
@@ -646,12 +781,16 @@ xpc_identify_act_IRQ_sender(void) | |||
646 | struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page; | 781 | struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page; |
647 | 782 | ||
648 | 783 | ||
649 | act_amos = xpc_vars->act_amos; | 784 | act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS; |
650 | 785 | ||
651 | 786 | ||
652 | /* scan through act AMO variable looking for non-zero entries */ | 787 | /* scan through act AMO variable looking for non-zero entries */ |
653 | for (word = 0; word < XP_NASID_MASK_WORDS; word++) { | 788 | for (word = 0; word < XP_NASID_MASK_WORDS; word++) { |
654 | 789 | ||
790 | if (xpc_exiting) { | ||
791 | break; | ||
792 | } | ||
793 | |||
655 | nasid_mask = xpc_IPI_receive(&act_amos[word]); | 794 | nasid_mask = xpc_IPI_receive(&act_amos[word]); |
656 | if (nasid_mask == 0) { | 795 | if (nasid_mask == 0) { |
657 | /* no IRQs from nasids in this variable */ | 796 | /* no IRQs from nasids in this variable */ |
@@ -688,6 +827,55 @@ xpc_identify_act_IRQ_sender(void) | |||
688 | 827 | ||
689 | 828 | ||
690 | /* | 829 | /* |
830 | * See if the other side has responded to a partition disengage request | ||
831 | * from us. | ||
832 | */ | ||
833 | int | ||
834 | xpc_partition_disengaged(struct xpc_partition *part) | ||
835 | { | ||
836 | partid_t partid = XPC_PARTID(part); | ||
837 | int disengaged; | ||
838 | |||
839 | |||
840 | disengaged = (xpc_partition_engaged(1UL << partid) == 0); | ||
841 | if (part->disengage_request_timeout) { | ||
842 | if (!disengaged) { | ||
843 | if (jiffies < part->disengage_request_timeout) { | ||
844 | /* timelimit hasn't been reached yet */ | ||
845 | return 0; | ||
846 | } | ||
847 | |||
848 | /* | ||
849 | * Other side hasn't responded to our disengage | ||
850 | * request in a timely fashion, so assume it's dead. | ||
851 | */ | ||
852 | |||
853 | xpc_clear_partition_engaged(1UL << partid); | ||
854 | disengaged = 1; | ||
855 | } | ||
856 | part->disengage_request_timeout = 0; | ||
857 | |||
858 | /* cancel the timer function, provided it's not us */ | ||
859 | if (!in_interrupt()) { | ||
860 | del_singleshot_timer_sync(&part-> | ||
861 | disengage_request_timer); | ||
862 | } | ||
863 | |||
864 | DBUG_ON(part->act_state != XPC_P_DEACTIVATING && | ||
865 | part->act_state != XPC_P_INACTIVE); | ||
866 | if (part->act_state != XPC_P_INACTIVE) { | ||
867 | xpc_wakeup_channel_mgr(part); | ||
868 | } | ||
869 | |||
870 | if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) { | ||
871 | xpc_cancel_partition_disengage_request(part); | ||
872 | } | ||
873 | } | ||
874 | return disengaged; | ||
875 | } | ||
876 | |||
877 | |||
878 | /* | ||
691 | * Mark specified partition as active. | 879 | * Mark specified partition as active. |
692 | */ | 880 | */ |
693 | enum xpc_retval | 881 | enum xpc_retval |
@@ -721,7 +909,6 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, | |||
721 | enum xpc_retval reason) | 909 | enum xpc_retval reason) |
722 | { | 910 | { |
723 | unsigned long irq_flags; | 911 | unsigned long irq_flags; |
724 | partid_t partid = XPC_PARTID(part); | ||
725 | 912 | ||
726 | 913 | ||
727 | spin_lock_irqsave(&part->act_lock, irq_flags); | 914 | spin_lock_irqsave(&part->act_lock, irq_flags); |
@@ -749,17 +936,27 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, | |||
749 | 936 | ||
750 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | 937 | spin_unlock_irqrestore(&part->act_lock, irq_flags); |
751 | 938 | ||
752 | XPC_DISALLOW_HB(partid, xpc_vars); | 939 | if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) { |
940 | xpc_request_partition_disengage(part); | ||
941 | xpc_IPI_send_disengage(part); | ||
942 | |||
943 | /* set a timelimit on the disengage request */ | ||
944 | part->disengage_request_timeout = jiffies + | ||
945 | (XPC_DISENGAGE_REQUEST_TIMELIMIT * HZ); | ||
946 | part->disengage_request_timer.expires = | ||
947 | part->disengage_request_timeout; | ||
948 | add_timer(&part->disengage_request_timer); | ||
949 | } | ||
753 | 950 | ||
754 | dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", partid, | 951 | dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", partid, |
755 | reason); | 952 | reason); |
756 | 953 | ||
757 | xpc_partition_down(part, reason); | 954 | xpc_partition_going_down(part, reason); |
758 | } | 955 | } |
759 | 956 | ||
760 | 957 | ||
761 | /* | 958 | /* |
762 | * Mark specified partition as active. | 959 | * Mark specified partition as inactive. |
763 | */ | 960 | */ |
764 | void | 961 | void |
765 | xpc_mark_partition_inactive(struct xpc_partition *part) | 962 | xpc_mark_partition_inactive(struct xpc_partition *part) |
@@ -792,7 +989,7 @@ xpc_discovery(void) | |||
792 | void *remote_rp_base; | 989 | void *remote_rp_base; |
793 | struct xpc_rsvd_page *remote_rp; | 990 | struct xpc_rsvd_page *remote_rp; |
794 | struct xpc_vars *remote_vars; | 991 | struct xpc_vars *remote_vars; |
795 | u64 remote_rsvd_page_pa; | 992 | u64 remote_rp_pa; |
796 | u64 remote_vars_pa; | 993 | u64 remote_vars_pa; |
797 | int region; | 994 | int region; |
798 | int max_regions; | 995 | int max_regions; |
@@ -877,7 +1074,7 @@ xpc_discovery(void) | |||
877 | /* pull over the reserved page structure */ | 1074 | /* pull over the reserved page structure */ |
878 | 1075 | ||
879 | ret = xpc_get_remote_rp(nasid, discovered_nasids, | 1076 | ret = xpc_get_remote_rp(nasid, discovered_nasids, |
880 | remote_rp, &remote_rsvd_page_pa); | 1077 | remote_rp, &remote_rp_pa); |
881 | if (ret != xpcSuccess) { | 1078 | if (ret != xpcSuccess) { |
882 | dev_dbg(xpc_part, "unable to get reserved page " | 1079 | dev_dbg(xpc_part, "unable to get reserved page " |
883 | "from nasid %d, reason=%d\n", nasid, | 1080 | "from nasid %d, reason=%d\n", nasid, |
@@ -948,6 +1145,13 @@ xpc_discovery(void) | |||
948 | remote_vars->act_nasid, | 1145 | remote_vars->act_nasid, |
949 | remote_vars->act_phys_cpuid); | 1146 | remote_vars->act_phys_cpuid); |
950 | 1147 | ||
1148 | if (XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars-> | ||
1149 | version)) { | ||
1150 | part->remote_amos_page_pa = | ||
1151 | remote_vars->amos_page_pa; | ||
1152 | xpc_mark_partition_disengaged(part); | ||
1153 | xpc_cancel_partition_disengage_request(part); | ||
1154 | } | ||
951 | xpc_IPI_send_activate(remote_vars); | 1155 | xpc_IPI_send_activate(remote_vars); |
952 | } | 1156 | } |
953 | } | 1157 | } |