summaryrefslogtreecommitdiff
path: root/arch/ia64
diff options
context:
space:
mode:
authorDean Nelson <dcn@sgi.com>2006-02-15 08:02:21 -0600
committerTony Luck <tony.luck@intel.com>2006-02-15 13:35:03 -0800
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)
/* make sure all activity has settled down first */
- if (atomic_read(&ch->references) > 0) {
+ if (atomic_read(&ch->references) > 0 ||
+ ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
+ !(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE))) {
return;
}
DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
@@ -775,7 +777,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
/* both sides are disconnected now */
- if (ch->flags & XPC_C_CONNECTCALLOUT) {
+ if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) {
spin_unlock_irqrestore(&ch->lock, *irq_flags);
xpc_disconnect_callout(ch, xpcDisconnected);
spin_lock_irqsave(&ch->lock, *irq_flags);
@@ -1300,7 +1302,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
"delivered=%d, partid=%d, channel=%d\n",
nmsgs_sent, ch->partid, ch->number);
- if (ch->flags & XPC_C_CONNECTCALLOUT) {
+ if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) {
xpc_activate_kthreads(ch, nmsgs_sent);
}
}
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)
/* let registerer know that connection has been established */
spin_lock_irqsave(&ch->lock, irq_flags);
- if (!(ch->flags & XPC_C_CONNECTCALLOUT)) {
- ch->flags |= XPC_C_CONNECTCALLOUT;
+ if (!(ch->flags & XPC_C_CONNECTEDCALLOUT)) {
+ ch->flags |= XPC_C_CONNECTEDCALLOUT;
spin_unlock_irqrestore(&ch->lock, irq_flags);
xpc_connected_callout(ch);
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ ch->flags |= XPC_C_CONNECTEDCALLOUT_MADE;
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+
/*
* It is possible that while the callout was being
* made that the remote partition sent some messages.
@@ -777,15 +781,17 @@ xpc_daemonize_kthread(void *args)
if (atomic_dec_return(&ch->kthreads_assigned) == 0) {
spin_lock_irqsave(&ch->lock, irq_flags);
- if ((ch->flags & XPC_C_CONNECTCALLOUT) &&
- !(ch->flags & XPC_C_DISCONNECTCALLOUT)) {
- ch->flags |= XPC_C_DISCONNECTCALLOUT;
+ if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
+ !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
+ ch->flags |= XPC_C_DISCONNECTINGCALLOUT;
spin_unlock_irqrestore(&ch->lock, irq_flags);
xpc_disconnect_callout(ch, xpcDisconnecting);
- } else {
- spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
}
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
if (atomic_dec_return(&part->nchannels_engaged) == 0) {
xpc_mark_partition_disengaged(part);
xpc_IPI_send_disengage(part);