Commit a47d5dac authored by Dean Nelson's avatar Dean Nelson Committed by Linus Torvalds

sgi-xp: isolate additional sn2 specific code

Move additional sn2 specific code into xpc_sn2.c.
Signed-off-by: default avatarDean Nelson <dcn@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6e41017a
This diff is collapsed.
...@@ -201,7 +201,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) ...@@ -201,7 +201,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
if (!(ch->flags & XPC_C_OPENREPLY)) { if (!(ch->flags & XPC_C_OPENREPLY)) {
ch->flags |= XPC_C_OPENREPLY; ch->flags |= XPC_C_OPENREPLY;
xpc_IPI_send_openreply(ch, irq_flags); xpc_send_channel_openreply(ch, irq_flags);
} }
if (!(ch->flags & XPC_C_ROPENREPLY)) if (!(ch->flags & XPC_C_ROPENREPLY))
...@@ -219,52 +219,6 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) ...@@ -219,52 +219,6 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
spin_lock_irqsave(&ch->lock, *irq_flags); spin_lock_irqsave(&ch->lock, *irq_flags);
} }
/*
* Notify those who wanted to be notified upon delivery of their message.
*/
static void
xpc_notify_senders(struct xpc_channel *ch, enum xp_retval reason, s64 put)
{
struct xpc_notify *notify;
u8 notify_type;
s64 get = ch->w_remote_GP.get - 1;
while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
notify = &ch->notify_queue[get % ch->local_nentries];
/*
* See if the notify entry indicates it was associated with
* a message who's sender wants to be notified. It is possible
* that it is, but someone else is doing or has done the
* notification.
*/
notify_type = notify->type;
if (notify_type == 0 ||
cmpxchg(&notify->type, notify_type, 0) != notify_type) {
continue;
}
DBUG_ON(notify_type != XPC_N_CALL);
atomic_dec(&ch->n_to_notify);
if (notify->func != NULL) {
dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, "
"msg_number=%ld, partid=%d, channel=%d\n",
(void *)notify, get, ch->partid, ch->number);
notify->func(reason, ch->partid, ch->number,
notify->key);
dev_dbg(xpc_chan, "notify->func() returned, "
"notify=0x%p, msg_number=%ld, partid=%d, "
"channel=%d\n", (void *)notify, get,
ch->partid, ch->number);
}
}
}
/* /*
* Free up message queues and other stuff that were allocated for the specified * Free up message queues and other stuff that were allocated for the specified
* channel. * channel.
...@@ -275,6 +229,8 @@ xpc_notify_senders(struct xpc_channel *ch, enum xp_retval reason, s64 put) ...@@ -275,6 +229,8 @@ xpc_notify_senders(struct xpc_channel *ch, enum xp_retval reason, s64 put)
static void static void
xpc_free_msgqueues(struct xpc_channel *ch) xpc_free_msgqueues(struct xpc_channel *ch)
{ {
struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
DBUG_ON(!spin_is_locked(&ch->lock)); DBUG_ON(!spin_is_locked(&ch->lock));
DBUG_ON(atomic_read(&ch->n_to_notify) != 0); DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
...@@ -287,15 +243,15 @@ xpc_free_msgqueues(struct xpc_channel *ch) ...@@ -287,15 +243,15 @@ xpc_free_msgqueues(struct xpc_channel *ch)
ch->kthreads_assigned_limit = 0; ch->kthreads_assigned_limit = 0;
ch->kthreads_idle_limit = 0; ch->kthreads_idle_limit = 0;
ch->local_GP->get = 0; ch_sn2->local_GP->get = 0;
ch->local_GP->put = 0; ch_sn2->local_GP->put = 0;
ch->remote_GP.get = 0; ch_sn2->remote_GP.get = 0;
ch->remote_GP.put = 0; ch_sn2->remote_GP.put = 0;
ch->w_local_GP.get = 0; ch_sn2->w_local_GP.get = 0;
ch->w_local_GP.put = 0; ch_sn2->w_local_GP.put = 0;
ch->w_remote_GP.get = 0; ch_sn2->w_remote_GP.get = 0;
ch->w_remote_GP.put = 0; ch_sn2->w_remote_GP.put = 0;
ch->next_msg_to_pull = 0; ch_sn2->next_msg_to_pull = 0;
if (ch->flags & XPC_C_SETUP) { if (ch->flags & XPC_C_SETUP) {
ch->flags &= ~XPC_C_SETUP; ch->flags &= ~XPC_C_SETUP;
...@@ -339,7 +295,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) ...@@ -339,7 +295,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
if (part->act_state == XPC_P_DEACTIVATING) { if (part->act_state == XPC_P_DEACTIVATING) {
/* can't proceed until the other side disengages from us */ /* can't proceed until the other side disengages from us */
if (xpc_partition_engaged(1UL << ch->partid)) if (xpc_partition_engaged(ch->partid))
return; return;
} else { } else {
...@@ -351,7 +307,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) ...@@ -351,7 +307,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
if (!(ch->flags & XPC_C_CLOSEREPLY)) { if (!(ch->flags & XPC_C_CLOSEREPLY)) {
ch->flags |= XPC_C_CLOSEREPLY; ch->flags |= XPC_C_CLOSEREPLY;
xpc_IPI_send_closereply(ch, irq_flags); xpc_send_channel_closereply(ch, irq_flags);
} }
if (!(ch->flags & XPC_C_RCLOSEREPLY)) if (!(ch->flags & XPC_C_RCLOSEREPLY))
...@@ -361,7 +317,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) ...@@ -361,7 +317,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
/* wake those waiting for notify completion */ /* wake those waiting for notify completion */
if (atomic_read(&ch->n_to_notify) > 0) { if (atomic_read(&ch->n_to_notify) > 0) {
/* >>> we do callout while holding ch->lock */ /* >>> we do callout while holding ch->lock */
xpc_notify_senders(ch, ch->reason, ch->w_local_GP.put); xpc_notify_senders_of_disconnect(ch);
} }
/* both sides are disconnected now */ /* both sides are disconnected now */
...@@ -734,7 +690,7 @@ xpc_connect_channel(struct xpc_channel *ch) ...@@ -734,7 +690,7 @@ xpc_connect_channel(struct xpc_channel *ch)
/* initiate the connection */ /* initiate the connection */
ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING); ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
xpc_IPI_send_openrequest(ch, &irq_flags); xpc_send_channel_openrequest(ch, &irq_flags);
xpc_process_connect(ch, &irq_flags); xpc_process_connect(ch, &irq_flags);
...@@ -743,142 +699,6 @@ xpc_connect_channel(struct xpc_channel *ch) ...@@ -743,142 +699,6 @@ xpc_connect_channel(struct xpc_channel *ch)
return xpSuccess; return xpSuccess;
} }
/*
* Clear some of the msg flags in the local message queue.
*/
static inline void
xpc_clear_local_msgqueue_flags(struct xpc_channel *ch)
{
struct xpc_msg *msg;
s64 get;
get = ch->w_remote_GP.get;
do {
msg = (struct xpc_msg *)((u64)ch->local_msgqueue +
(get % ch->local_nentries) *
ch->msg_size);
msg->flags = 0;
} while (++get < ch->remote_GP.get);
}
/*
* Clear some of the msg flags in the remote message queue.
*/
static inline void
xpc_clear_remote_msgqueue_flags(struct xpc_channel *ch)
{
struct xpc_msg *msg;
s64 put;
put = ch->w_remote_GP.put;
do {
msg = (struct xpc_msg *)((u64)ch->remote_msgqueue +
(put % ch->remote_nentries) *
ch->msg_size);
msg->flags = 0;
} while (++put < ch->remote_GP.put);
}
static void
xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
{
struct xpc_channel *ch = &part->channels[ch_number];
int nmsgs_sent;
ch->remote_GP = part->remote_GPs[ch_number];
/* See what, if anything, has changed for each connected channel */
xpc_msgqueue_ref(ch);
if (ch->w_remote_GP.get == ch->remote_GP.get &&
ch->w_remote_GP.put == ch->remote_GP.put) {
/* nothing changed since GPs were last pulled */
xpc_msgqueue_deref(ch);
return;
}
if (!(ch->flags & XPC_C_CONNECTED)) {
xpc_msgqueue_deref(ch);
return;
}
/*
* First check to see if messages recently sent by us have been
* received by the other side. (The remote GET value will have
* changed since we last looked at it.)
*/
if (ch->w_remote_GP.get != ch->remote_GP.get) {
/*
* We need to notify any senders that want to be notified
* that their sent messages have been received by their
* intended recipients. We need to do this before updating
* w_remote_GP.get so that we don't allocate the same message
* queue entries prematurely (see xpc_allocate_msg()).
*/
if (atomic_read(&ch->n_to_notify) > 0) {
/*
* Notify senders that messages sent have been
* received and delivered by the other side.
*/
xpc_notify_senders(ch, xpMsgDelivered,
ch->remote_GP.get);
}
/*
* Clear msg->flags in previously sent messages, so that
* they're ready for xpc_allocate_msg().
*/
xpc_clear_local_msgqueue_flags(ch);
ch->w_remote_GP.get = ch->remote_GP.get;
dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, "
"channel=%d\n", ch->w_remote_GP.get, ch->partid,
ch->number);
/*
* If anyone was waiting for message queue entries to become
* available, wake them up.
*/
if (atomic_read(&ch->n_on_msg_allocate_wq) > 0)
wake_up(&ch->msg_allocate_wq);
}
/*
* Now check for newly sent messages by the other side. (The remote
* PUT value will have changed since we last looked at it.)
*/
if (ch->w_remote_GP.put != ch->remote_GP.put) {
/*
* Clear msg->flags in previously received messages, so that
* they're ready for xpc_get_deliverable_msg().
*/
xpc_clear_remote_msgqueue_flags(ch);
ch->w_remote_GP.put = ch->remote_GP.put;
dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
"channel=%d\n", ch->w_remote_GP.put, ch->partid,
ch->number);
nmsgs_sent = ch->w_remote_GP.put - ch->w_local_GP.get;
if (nmsgs_sent > 0) {
dev_dbg(xpc_chan, "msgs waiting to be copied and "
"delivered=%d, partid=%d, channel=%d\n",
nmsgs_sent, ch->partid, ch->number);
if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)
xpc_activate_kthreads(ch, nmsgs_sent);
}
}
xpc_msgqueue_deref(ch);
}
void void
xpc_process_channel_activity(struct xpc_partition *part) xpc_process_channel_activity(struct xpc_partition *part)
{ {
...@@ -1117,7 +937,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch, ...@@ -1117,7 +937,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY | XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
XPC_C_CONNECTING | XPC_C_CONNECTED); XPC_C_CONNECTING | XPC_C_CONNECTED);
xpc_IPI_send_closerequest(ch, irq_flags); xpc_send_channel_closerequest(ch, irq_flags);
if (channel_was_connected) if (channel_was_connected)
ch->flags |= XPC_C_WASCONNECTED; ch->flags |= XPC_C_WASCONNECTED;
......
This diff is collapsed.
...@@ -242,7 +242,7 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, ...@@ -242,7 +242,7 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
return xpBadVersion; return xpBadVersion;
} }
/* check that both local and remote partids are valid for each side */ /* check that both remote and local partids are valid for each side */
if (remote_rp->SAL_partid < 0 || if (remote_rp->SAL_partid < 0 ||
remote_rp->SAL_partid >= xp_max_npartitions || remote_rp->SAL_partid >= xp_max_npartitions ||
remote_rp->max_npartitions <= sn_partition_id) { remote_rp->max_npartitions <= sn_partition_id) {
...@@ -256,8 +256,9 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, ...@@ -256,8 +256,9 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
} }
/* /*
* See if the other side has responded to a partition disengage request * See if the other side has responded to a partition deactivate request
* from us. * from us. Though we requested the remote partition to deactivate with regard
* to us, we really only need to wait for the other side to disengage from us.
*/ */
int int
xpc_partition_disengaged(struct xpc_partition *part) xpc_partition_disengaged(struct xpc_partition *part)
...@@ -265,41 +266,37 @@ xpc_partition_disengaged(struct xpc_partition *part) ...@@ -265,41 +266,37 @@ xpc_partition_disengaged(struct xpc_partition *part)
short partid = XPC_PARTID(part); short partid = XPC_PARTID(part);
int disengaged; int disengaged;
disengaged = (xpc_partition_engaged(1UL << partid) == 0); disengaged = !xpc_partition_engaged(partid);
if (part->disengage_request_timeout) { if (part->disengage_timeout) {
if (!disengaged) { if (!disengaged) {
if (time_is_after_jiffies(part-> if (time_is_after_jiffies(part->disengage_timeout)) {
disengage_request_timeout)) {
/* timelimit hasn't been reached yet */ /* timelimit hasn't been reached yet */
return 0; return 0;
} }
/* /*
* Other side hasn't responded to our disengage * Other side hasn't responded to our deactivate
* request in a timely fashion, so assume it's dead. * request in a timely fashion, so assume it's dead.
*/ */
dev_info(xpc_part, "disengage from remote partition %d " dev_info(xpc_part, "deactivate request to remote "
"timed out\n", partid); "partition %d timed out\n", partid);
xpc_disengage_request_timedout = 1; xpc_disengage_timedout = 1;
xpc_clear_partition_engaged(1UL << partid); xpc_assume_partition_disengaged(partid);
disengaged = 1; disengaged = 1;
} }
part->disengage_request_timeout = 0; part->disengage_timeout = 0;
/* cancel the timer function, provided it's not us */ /* cancel the timer function, provided it's not us */
if (!in_interrupt()) { if (!in_interrupt())
del_singleshot_timer_sync(&part-> del_singleshot_timer_sync(&part->disengage_timer);
disengage_request_timer);
}
DBUG_ON(part->act_state != XPC_P_DEACTIVATING && DBUG_ON(part->act_state != XPC_P_DEACTIVATING &&
part->act_state != XPC_P_INACTIVE); part->act_state != XPC_P_INACTIVE);
if (part->act_state != XPC_P_INACTIVE) if (part->act_state != XPC_P_INACTIVE)
xpc_wakeup_channel_mgr(part); xpc_wakeup_channel_mgr(part);
if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) xpc_cancel_partition_deactivation_request(part);
xpc_cancel_partition_disengage_request(part);
} }
return disengaged; return disengaged;
} }
...@@ -329,7 +326,7 @@ xpc_mark_partition_active(struct xpc_partition *part) ...@@ -329,7 +326,7 @@ xpc_mark_partition_active(struct xpc_partition *part)
} }
/* /*
* Notify XPC that the partition is down. * Start the process of deactivating the specified partition.
*/ */
void void
xpc_deactivate_partition(const int line, struct xpc_partition *part, xpc_deactivate_partition(const int line, struct xpc_partition *part,
...@@ -344,7 +341,7 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, ...@@ -344,7 +341,7 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
spin_unlock_irqrestore(&part->act_lock, irq_flags); spin_unlock_irqrestore(&part->act_lock, irq_flags);
if (reason == xpReactivating) { if (reason == xpReactivating) {
/* we interrupt ourselves to reactivate partition */ /* we interrupt ourselves to reactivate partition */
xpc_IPI_send_local_reactivate(part->reactivate_nasid); xpc_request_partition_reactivation(part);
} }
return; return;
} }
...@@ -362,17 +359,13 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, ...@@ -362,17 +359,13 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
spin_unlock_irqrestore(&part->act_lock, irq_flags); spin_unlock_irqrestore(&part->act_lock, irq_flags);
if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) { /* ask remote partition to deactivate with regard to us */
xpc_request_partition_disengage(part); xpc_request_partition_deactivation(part);
xpc_IPI_send_disengage(part);
/* set a timelimit on the disengage request */ /* set a timelimit on the disengage phase of the deactivation request */
part->disengage_request_timeout = jiffies + part->disengage_timeout = jiffies + (xpc_disengage_timelimit * HZ);
(xpc_disengage_request_timelimit * HZ); part->disengage_timer.expires = part->disengage_timeout;
part->disengage_request_timer.expires = add_timer(&part->disengage_timer);
part->disengage_request_timeout;
add_timer(&part->disengage_request_timer);
}
dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n",
XPC_PARTID(part), reason); XPC_PARTID(part), reason);
...@@ -505,7 +498,7 @@ xpc_discovery(void) ...@@ -505,7 +498,7 @@ xpc_discovery(void)
continue; continue;
} }
xpc_initiate_partition_activation(remote_rp, xpc_request_partition_activation(remote_rp,
remote_rp_pa, nasid); remote_rp_pa, nasid);
} }
} }
......
This diff is collapsed.
...@@ -63,7 +63,7 @@ xpc_heartbeat_exit_uv(void) ...@@ -63,7 +63,7 @@ xpc_heartbeat_exit_uv(void)
} }
static void static void
xpc_initiate_partition_activation_uv(struct xpc_rsvd_page *remote_rp, xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
u64 remote_rp_pa, int nasid) u64 remote_rp_pa, int nasid)
{ {
short partid = remote_rp->SAL_partid; short partid = remote_rp->SAL_partid;
...@@ -78,6 +78,12 @@ xpc_initiate_partition_activation_uv(struct xpc_rsvd_page *remote_rp, ...@@ -78,6 +78,12 @@ xpc_initiate_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
xpc_IPI_send_local_activate_uv(part); xpc_IPI_send_local_activate_uv(part);
} }
static void
xpc_request_partition_reactivation_uv(struct xpc_partition *part)
{
xpc_IPI_send_local_activate_uv(part);
}
/* /*
* Setup the infrastructure necessary to support XPartition Communication * Setup the infrastructure necessary to support XPartition Communication
* between the specified remote partition and the local one. * between the specified remote partition and the local one.
...@@ -128,8 +134,9 @@ xpc_init_uv(void) ...@@ -128,8 +134,9 @@ xpc_init_uv(void)
xpc_increment_heartbeat = xpc_increment_heartbeat_uv; xpc_increment_heartbeat = xpc_increment_heartbeat_uv;
xpc_heartbeat_init = xpc_heartbeat_init_uv; xpc_heartbeat_init = xpc_heartbeat_init_uv;
xpc_heartbeat_exit = xpc_heartbeat_exit_uv; xpc_heartbeat_exit = xpc_heartbeat_exit_uv;
xpc_initiate_partition_activation = xpc_request_partition_activation = xpc_request_partition_activation_uv;
xpc_initiate_partition_activation_uv; xpc_request_partition_reactivation =
xpc_request_partition_reactivation_uv;
xpc_setup_infrastructure = xpc_setup_infrastructure_uv; xpc_setup_infrastructure = xpc_setup_infrastructure_uv;
xpc_teardown_infrastructure = xpc_teardown_infrastructure_uv; xpc_teardown_infrastructure = xpc_teardown_infrastructure_uv;
xpc_make_first_contact = xpc_make_first_contact_uv; xpc_make_first_contact = xpc_make_first_contact_uv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment