[IA64-SGI] ensure XPC disengage request is processed
authorDean Nelson <dcn@sgi.com>
Thu, 22 Dec 2005 20:32:56 +0000 (14:32 -0600)
committerTony Luck <tony.luck@intel.com>
Fri, 13 Jan 2006 18:16:36 +0000 (10:16 -0800)
This patch fixes a problem in XPC disengage processing whereby it was not
seeing the request to disengage from a remote partition, so the disengage
wasn't happening. The disengagement is suppose to transpire during the time
a XPC channel is disconnecting, and should be completed before the channel
is declared to be disconnected.

Signed-off-by: Dean Nelson <dcn@sgi.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
arch/ia64/sn/kernel/xpc.h
arch/ia64/sn/kernel/xpc_channel.c
arch/ia64/sn/kernel/xpc_main.c
arch/ia64/sn/kernel/xpc_partition.c
include/asm-ia64/sn/xp.h

index 5483a9f227d457bb2af4702b99e697cfed49b220..66b17b6aa81f4f9bf8c52cfc75675c88b5725b5b 100644 (file)
@@ -707,7 +707,7 @@ extern void xpc_connected_callout(struct xpc_channel *);
 extern void xpc_deliver_msg(struct xpc_channel *);
 extern void xpc_disconnect_channel(const int, struct xpc_channel *,
                                        enum xpc_retval, unsigned long *);
-extern void xpc_disconnecting_callout(struct xpc_channel *);
+extern void xpc_disconnect_callout(struct xpc_channel *, enum xpc_retval);
 extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
 extern void xpc_teardown_infrastructure(struct xpc_partition *);
 
index abf4fc2a87bba20e98014172412be96f84c92f91..272ab4deb573bf974d721e3e8f3c64f88995c689 100644 (file)
@@ -779,6 +779,12 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
 
        /* both sides are disconnected now */
 
+       if (ch->flags & XPC_C_CONNECTCALLOUT) {
+               spin_unlock_irqrestore(&ch->lock, *irq_flags);
+               xpc_disconnect_callout(ch, xpcDisconnected);
+               spin_lock_irqsave(&ch->lock, *irq_flags);
+       }
+
        /* it's now safe to free the channel's message queues */
        xpc_free_msgqueues(ch);
 
@@ -1645,7 +1651,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
 
 
 void
-xpc_disconnecting_callout(struct xpc_channel *ch)
+xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason)
 {
        /*
         * Let the channel's registerer know that the channel is being
@@ -1654,15 +1660,13 @@ xpc_disconnecting_callout(struct xpc_channel *ch)
         */
 
        if (ch->func != NULL) {
-               dev_dbg(xpc_chan, "ch->func() called, reason=xpcDisconnecting,"
-                       " partid=%d, channel=%d\n", ch->partid, ch->number);
+               dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, "
+                       "channel=%d\n", reason, ch->partid, ch->number);
 
-               ch->func(xpcDisconnecting, ch->partid, ch->number, NULL,
-                                                               ch->key);
+               ch->func(reason, ch->partid, ch->number, NULL, ch->key);
 
-               dev_dbg(xpc_chan, "ch->func() returned, reason="
-                       "xpcDisconnecting, partid=%d, channel=%d\n",
-                       ch->partid, ch->number);
+               dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, "
+                       "channel=%d\n", reason, ch->partid, ch->number);
        }
 }
 
index b617236524c690ea2eb95122e26b9ad133d30819..6708ef6e061845641cf2f20e74b1a90936276d86 100644 (file)
@@ -773,7 +773,7 @@ xpc_daemonize_kthread(void *args)
                        ch->flags |= XPC_C_DISCONNECTCALLOUT;
                        spin_unlock_irqrestore(&ch->lock, irq_flags);
 
-                       xpc_disconnecting_callout(ch);
+                       xpc_disconnect_callout(ch, xpcDisconnecting);
                } else {
                        spin_unlock_irqrestore(&ch->lock, irq_flags);
                }
index cdd6431853a1b4cc7cfaafa1d30612ed215b104e..cf02a9bcd24589bc574912c90dd0d2ad25733492 100644 (file)
@@ -771,7 +771,8 @@ xpc_identify_act_IRQ_req(int nasid)
                }
        }
 
-       if (!xpc_partition_disengaged(part)) {
+       if (part->disengage_request_timeout > 0 &&
+                                       !xpc_partition_disengaged(part)) {
                /* still waiting on other side to disengage from us */
                return;
        }
index 49faf8f26430806f6fa19fc39a6d8b65f914fe04..203945ae034e1c70e5a8aee672a6b40e22bbfdc1 100644 (file)
@@ -227,7 +227,9 @@ enum xpc_retval {
 
        xpcOpenCloseError,      /* 50: channel open/close protocol error */
 
-       xpcUnknownReason        /* 51: unknown reason -- must be last in list */
+       xpcDisconnected,        /* 51: channel disconnected (closed) */
+
+       xpcUnknownReason        /* 52: unknown reason -- must be last in list */
 };