[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>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user