Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 44415
b: refs/heads/master
c: a460ef8
h: refs/heads/master
i:
  44413: 9de74f9
  44411: a427aa7
  44407: e98a507
  44399: 49d0ced
  44383: dee6255
  44351: a96b100
  44287: 39ae60f
v: v3
  • Loading branch information
Dean Nelson authored and Tony Luck committed Dec 12, 2006
1 parent 14ed771 commit a039822
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1cf24bdbbbd2eb5439796dc399ab1649d150ed1d
refs/heads/master: a460ef8d0a98ac9ef6b829ae292c9b6c13bc0120
15 changes: 10 additions & 5 deletions trunk/arch/ia64/sn/kernel/xpc_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
ch->number, ch->partid);

spin_unlock_irqrestore(&ch->lock, *irq_flags);
xpc_create_kthreads(ch, 1);
xpc_create_kthreads(ch, 1, 0);
spin_lock_irqsave(&ch->lock, *irq_flags);
}

Expand Down Expand Up @@ -754,12 +754,12 @@ 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 ||
((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
!(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE))) {
if (atomic_read(&ch->kthreads_assigned) > 0 ||
atomic_read(&ch->references) > 0) {
return;
}
DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
DBUG_ON((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
!(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE));

if (part->act_state == XPC_P_DEACTIVATING) {
/* can't proceed until the other side disengages from us */
Expand Down Expand Up @@ -1651,6 +1651,11 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
/* wake all idle kthreads so they can exit */
if (atomic_read(&ch->kthreads_idle) > 0) {
wake_up_all(&ch->idle_wq);

} else if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
!(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
/* start a kthread that will do the xpcDisconnecting callout */
xpc_create_kthreads(ch, 1, 1);
}

/* wake those waiting to allocate an entry from the local msg queue */
Expand Down
64 changes: 43 additions & 21 deletions trunk/arch/ia64/sn/kernel/xpc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ xpc_activate_kthreads(struct xpc_channel *ch, int needed)
dev_dbg(xpc_chan, "create %d new kthreads, partid=%d, channel=%d\n",
needed, ch->partid, ch->number);

xpc_create_kthreads(ch, needed);
xpc_create_kthreads(ch, needed, 0);
}


Expand Down Expand Up @@ -775,26 +775,28 @@ xpc_daemonize_kthread(void *args)
xpc_kthread_waitmsgs(part, ch);
}

if (atomic_dec_return(&ch->kthreads_assigned) == 0) {
spin_lock_irqsave(&ch->lock, irq_flags);
if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
!(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
ch->flags |= XPC_C_DISCONNECTINGCALLOUT;
spin_unlock_irqrestore(&ch->lock, irq_flags);
/* let registerer know that connection is disconnecting */

xpc_disconnect_callout(ch, xpcDisconnecting);

spin_lock_irqsave(&ch->lock, irq_flags);
ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
}
spin_lock_irqsave(&ch->lock, irq_flags);
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);

spin_lock_irqsave(&ch->lock, irq_flags);
ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
}
spin_unlock_irqrestore(&ch->lock, irq_flags);

if (atomic_dec_return(&ch->kthreads_assigned) == 0) {
if (atomic_dec_return(&part->nchannels_engaged) == 0) {
xpc_mark_partition_disengaged(part);
xpc_IPI_send_disengage(part);
}
}


xpc_msgqueue_deref(ch);

dev_dbg(xpc_chan, "kthread exiting, partid=%d, channel=%d\n",
Expand All @@ -818,7 +820,8 @@ xpc_daemonize_kthread(void *args)
* partition.
*/
void
xpc_create_kthreads(struct xpc_channel *ch, int needed)
xpc_create_kthreads(struct xpc_channel *ch, int needed,
int ignore_disconnecting)
{
unsigned long irq_flags;
pid_t pid;
Expand All @@ -833,16 +836,38 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed)
* kthread. That kthread is responsible for doing the
* counterpart to the following before it exits.
*/
if (ignore_disconnecting) {
if (!atomic_inc_not_zero(&ch->kthreads_assigned)) {
/* kthreads assigned had gone to zero */
BUG_ON(!(ch->flags &
XPC_C_DISCONNECTINGCALLOUT_MADE));
break;
}

} else if (ch->flags & XPC_C_DISCONNECTING) {
break;

} else if (atomic_inc_return(&ch->kthreads_assigned) == 1) {
if (atomic_inc_return(&part->nchannels_engaged) == 1)
xpc_mark_partition_engaged(part);
}
(void) xpc_part_ref(part);
xpc_msgqueue_ref(ch);
if (atomic_inc_return(&ch->kthreads_assigned) == 1 &&
atomic_inc_return(&part->nchannels_engaged) == 1) {
xpc_mark_partition_engaged(part);
}

pid = kernel_thread(xpc_daemonize_kthread, (void *) args, 0);
if (pid < 0) {
/* the fork failed */

/*
* NOTE: if (ignore_disconnecting &&
* !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) is true,
* then we'll deadlock if all other kthreads assigned
* to this channel are blocked in the channel's
* registerer, because the only thing that will unblock
* them is the xpcDisconnecting callout that this
* failed kernel_thread would have made.
*/

if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
atomic_dec_return(&part->nchannels_engaged) == 0) {
xpc_mark_partition_disengaged(part);
Expand All @@ -857,9 +882,6 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed)
* Flag this as an error only if we have an
* insufficient #of kthreads for the channel
* to function.
*
* No xpc_msgqueue_ref() is needed here since
* the channel mgr is doing this.
*/
spin_lock_irqsave(&ch->lock, irq_flags);
XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources,
Expand Down
2 changes: 1 addition & 1 deletion trunk/include/asm-ia64/sn/xpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ extern irqreturn_t xpc_notify_IRQ_handler(int, void *);
extern void xpc_dropped_IPI_check(struct xpc_partition *);
extern void xpc_activate_partition(struct xpc_partition *);
extern void xpc_activate_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int, int);
extern void xpc_disconnect_wait(int);


Expand Down

0 comments on commit a039822

Please sign in to comment.