aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorDean Nelson <dcn@sgi.com>2006-02-15 09:02:21 -0500
committerTony Luck <tony.luck@intel.com>2006-02-15 16:35:03 -0500
commit4c2cd96696ae0896ce4bcf725b9f0eaffafeb640 (patch)
tree12b7d967d677e8e8ea154b0b4ae957df6cc43e39 /arch/ia64
parentc2a4969ba14e852bf4ee92c7db3b0cf82405a0c9 (diff)
[IA64-SGI] enforce proper ordering of callouts by XPC
Fix XPC so that it does not deliver any messages until the connected callout has returned, as well as, prevent the disconnected callout to occur before the disconnecting callout has returned. Signed-off-by: Dean Nelson <dcn@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c8
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c20
2 files changed, 18 insertions, 10 deletions
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 36e5437a0fb6..cdf6856ce089 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -738,7 +738,9 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
738 738
739 /* make sure all activity has settled down first */ 739 /* make sure all activity has settled down first */
740 740
741 if (atomic_read(&ch->references) > 0) { 741 if (atomic_read(&ch->references) > 0 ||
742 ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
743 !(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE))) {
742 return; 744 return;
743 } 745 }
744 DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0); 746 DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
@@ -775,7 +777,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
775 777
776 /* both sides are disconnected now */ 778 /* both sides are disconnected now */
777 779
778 if (ch->flags & XPC_C_CONNECTCALLOUT) { 780 if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) {
779 spin_unlock_irqrestore(&ch->lock, *irq_flags); 781 spin_unlock_irqrestore(&ch->lock, *irq_flags);
780 xpc_disconnect_callout(ch, xpcDisconnected); 782 xpc_disconnect_callout(ch, xpcDisconnected);
781 spin_lock_irqsave(&ch->lock, *irq_flags); 783 spin_lock_irqsave(&ch->lock, *irq_flags);
@@ -1300,7 +1302,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
1300 "delivered=%d, partid=%d, channel=%d\n", 1302 "delivered=%d, partid=%d, channel=%d\n",
1301 nmsgs_sent, ch->partid, ch->number); 1303 nmsgs_sent, ch->partid, ch->number);
1302 1304
1303 if (ch->flags & XPC_C_CONNECTCALLOUT) { 1305 if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) {
1304 xpc_activate_kthreads(ch, nmsgs_sent); 1306 xpc_activate_kthreads(ch, nmsgs_sent);
1305 } 1307 }
1306 } 1308 }
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index 9cd460dfe27e..8cbf16432570 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -750,12 +750,16 @@ xpc_daemonize_kthread(void *args)
750 /* let registerer know that connection has been established */ 750 /* let registerer know that connection has been established */
751 751
752 spin_lock_irqsave(&ch->lock, irq_flags); 752 spin_lock_irqsave(&ch->lock, irq_flags);
753 if (!(ch->flags & XPC_C_CONNECTCALLOUT)) { 753 if (!(ch->flags & XPC_C_CONNECTEDCALLOUT)) {
754 ch->flags |= XPC_C_CONNECTCALLOUT; 754 ch->flags |= XPC_C_CONNECTEDCALLOUT;
755 spin_unlock_irqrestore(&ch->lock, irq_flags); 755 spin_unlock_irqrestore(&ch->lock, irq_flags);
756 756
757 xpc_connected_callout(ch); 757 xpc_connected_callout(ch);
758 758
759 spin_lock_irqsave(&ch->lock, irq_flags);
760 ch->flags |= XPC_C_CONNECTEDCALLOUT_MADE;
761 spin_unlock_irqrestore(&ch->lock, irq_flags);
762
759 /* 763 /*
760 * It is possible that while the callout was being 764 * It is possible that while the callout was being
761 * made that the remote partition sent some messages. 765 * made that the remote partition sent some messages.
@@ -777,15 +781,17 @@ xpc_daemonize_kthread(void *args)
777 781
778 if (atomic_dec_return(&ch->kthreads_assigned) == 0) { 782 if (atomic_dec_return(&ch->kthreads_assigned) == 0) {
779 spin_lock_irqsave(&ch->lock, irq_flags); 783 spin_lock_irqsave(&ch->lock, irq_flags);
780 if ((ch->flags & XPC_C_CONNECTCALLOUT) && 784 if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
781 !(ch->flags & XPC_C_DISCONNECTCALLOUT)) { 785 !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
782 ch->flags |= XPC_C_DISCONNECTCALLOUT; 786 ch->flags |= XPC_C_DISCONNECTINGCALLOUT;
783 spin_unlock_irqrestore(&ch->lock, irq_flags); 787 spin_unlock_irqrestore(&ch->lock, irq_flags);
784 788
785 xpc_disconnect_callout(ch, xpcDisconnecting); 789 xpc_disconnect_callout(ch, xpcDisconnecting);
786 } else { 790
787 spin_unlock_irqrestore(&ch->lock, irq_flags); 791 spin_lock_irqsave(&ch->lock, irq_flags);
792 ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
788 } 793 }
794 spin_unlock_irqrestore(&ch->lock, irq_flags);
789 if (atomic_dec_return(&part->nchannels_engaged) == 0) { 795 if (atomic_dec_return(&part->nchannels_engaged) == 0) {
790 xpc_mark_partition_disengaged(part); 796 xpc_mark_partition_disengaged(part);
791 xpc_IPI_send_disengage(part); 797 xpc_IPI_send_disengage(part);