diff options
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 | } |