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)
if (!(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))
......@@ -219,52 +219,6 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *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
* channel.
......@@ -275,6 +229,8 @@ xpc_notify_senders(struct xpc_channel *ch, enum xp_retval reason, s64 put)
static void
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(atomic_read(&ch->n_to_notify) != 0);
......@@ -287,15 +243,15 @@ xpc_free_msgqueues(struct xpc_channel *ch)
ch->kthreads_assigned_limit = 0;
ch->kthreads_idle_limit = 0;
ch->local_GP->get = 0;
ch->local_GP->put = 0;
ch->remote_GP.get = 0;
ch->remote_GP.put = 0;
ch->w_local_GP.get = 0;
ch->w_local_GP.put = 0;
ch->w_remote_GP.get = 0;
ch->w_remote_GP.put = 0;
ch->next_msg_to_pull = 0;
ch_sn2->local_GP->get = 0;
ch_sn2->local_GP->put = 0;
ch_sn2->remote_GP.get = 0;
ch_sn2->remote_GP.put = 0;
ch_sn2->w_local_GP.get = 0;
ch_sn2->w_local_GP.put = 0;
ch_sn2->w_remote_GP.get = 0;
ch_sn2->w_remote_GP.put = 0;
ch_sn2->next_msg_to_pull = 0;
if (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)
if (part->act_state == XPC_P_DEACTIVATING) {
/* can't proceed until the other side disengages from us */
if (xpc_partition_engaged(1UL << ch->partid))
if (xpc_partition_engaged(ch->partid))
return;
} else {
......@@ -351,7 +307,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
if (!(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))
......@@ -361,7 +317,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
/* wake those waiting for notify completion */
if (atomic_read(&ch->n_to_notify) > 0) {
/* >>> 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 */
......@@ -734,7 +690,7 @@ xpc_connect_channel(struct xpc_channel *ch)
/* initiate the connection */
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);
......@@ -743,142 +699,6 @@ xpc_connect_channel(struct xpc_channel *ch)
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
xpc_process_channel_activity(struct xpc_partition *part)
{
......@@ -1117,7 +937,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
XPC_C_CONNECTING | XPC_C_CONNECTED);
xpc_IPI_send_closerequest(ch, irq_flags);
xpc_send_channel_closerequest(ch, irq_flags);
if (channel_was_connected)
ch->flags |= XPC_C_WASCONNECTED;
......
This diff is collapsed.
......@@ -242,7 +242,7 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
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 ||
remote_rp->SAL_partid >= xp_max_npartitions ||
remote_rp->max_npartitions <= sn_partition_id) {
......@@ -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
* from us.
* See if the other side has responded to a partition deactivate request
* 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
xpc_partition_disengaged(struct xpc_partition *part)
......@@ -265,41 +266,37 @@ xpc_partition_disengaged(struct xpc_partition *part)
short partid = XPC_PARTID(part);
int disengaged;
disengaged = (xpc_partition_engaged(1UL << partid) == 0);
if (part->disengage_request_timeout) {
disengaged = !xpc_partition_engaged(partid);
if (part->disengage_timeout) {
if (!disengaged) {
if (time_is_after_jiffies(part->
disengage_request_timeout)) {
if (time_is_after_jiffies(part->disengage_timeout)) {
/* timelimit hasn't been reached yet */
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.
*/
dev_info(xpc_part, "disengage from remote partition %d "
"timed out\n", partid);
xpc_disengage_request_timedout = 1;
xpc_clear_partition_engaged(1UL << partid);
dev_info(xpc_part, "deactivate request to remote "
"partition %d timed out\n", partid);
xpc_disengage_timedout = 1;
xpc_assume_partition_disengaged(partid);
disengaged = 1;
}
part->disengage_request_timeout = 0;
part->disengage_timeout = 0;
/* cancel the timer function, provided it's not us */
if (!in_interrupt()) {
del_singleshot_timer_sync(&part->
disengage_request_timer);
}
if (!in_interrupt())
del_singleshot_timer_sync(&part->disengage_timer);
DBUG_ON(part->act_state != XPC_P_DEACTIVATING &&
part->act_state != XPC_P_INACTIVE);
if (part->act_state != XPC_P_INACTIVE)
xpc_wakeup_channel_mgr(part);
if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version))
xpc_cancel_partition_disengage_request(part);
xpc_cancel_partition_deactivation_request(part);
}
return disengaged;
}
......@@ -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
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);
if (reason == xpReactivating) {
/* we interrupt ourselves to reactivate partition */
xpc_IPI_send_local_reactivate(part->reactivate_nasid);
xpc_request_partition_reactivation(part);
}
return;
}
......@@ -362,17 +359,13 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
spin_unlock_irqrestore(&part->act_lock, irq_flags);
if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
xpc_request_partition_disengage(part);
xpc_IPI_send_disengage(part);
/* ask remote partition to deactivate with regard to us */
xpc_request_partition_deactivation(part);
/* set a timelimit on the disengage request */
part->disengage_request_timeout = jiffies +
(xpc_disengage_request_timelimit * HZ);
part->disengage_request_timer.expires =
part->disengage_request_timeout;
add_timer(&part->disengage_request_timer);
}
/* set a timelimit on the disengage phase of the deactivation request */
part->disengage_timeout = jiffies + (xpc_disengage_timelimit * HZ);
part->disengage_timer.expires = part->disengage_timeout;
add_timer(&part->disengage_timer);
dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n",
XPC_PARTID(part), reason);
......@@ -505,8 +498,8 @@ xpc_discovery(void)
continue;
}
xpc_initiate_partition_activation(remote_rp,
remote_rp_pa, nasid);
xpc_request_partition_activation(remote_rp,
remote_rp_pa, nasid);
}
}
......
This diff is collapsed.
......@@ -63,8 +63,8 @@ xpc_heartbeat_exit_uv(void)
}
static void
xpc_initiate_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
u64 remote_rp_pa, int nasid)
xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
u64 remote_rp_pa, int nasid)
{
short partid = remote_rp->SAL_partid;
struct xpc_partition *part = &xpc_partitions[partid];
......@@ -78,6 +78,12 @@ xpc_initiate_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
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
* between the specified remote partition and the local one.
......@@ -128,8 +134,9 @@ xpc_init_uv(void)
xpc_increment_heartbeat = xpc_increment_heartbeat_uv;
xpc_heartbeat_init = xpc_heartbeat_init_uv;
xpc_heartbeat_exit = xpc_heartbeat_exit_uv;
xpc_initiate_partition_activation =
xpc_initiate_partition_activation_uv;
xpc_request_partition_activation = xpc_request_partition_activation_uv;
xpc_request_partition_reactivation =
xpc_request_partition_reactivation_uv;
xpc_setup_infrastructure = xpc_setup_infrastructure_uv;
xpc_teardown_infrastructure = xpc_teardown_infrastructure_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