sgi-xp: isolate xpc_vars structure to sn2 only
Isolate the xpc_vars structure of XPC's reserved page to sn2 only. Signed-off-by: Dean Nelson <dcn@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
e17d416b1b
commit
33ba3c7724
@ -148,12 +148,14 @@ static struct ctl_table_header *xpc_sysctl;
|
||||
int xpc_disengage_request_timedout;
|
||||
|
||||
/* #of IRQs received */
|
||||
static atomic_t xpc_act_IRQ_rcvd;
|
||||
atomic_t xpc_act_IRQ_rcvd;
|
||||
|
||||
/* IRQ handler notifies this wait queue on receipt of an IRQ */
|
||||
static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
|
||||
DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
|
||||
|
||||
static unsigned long xpc_hb_check_timeout;
|
||||
static struct timer_list xpc_hb_timer;
|
||||
void *xpc_heartbeating_to_mask;
|
||||
|
||||
/* notification that the xpc_hb_checker thread has exited */
|
||||
static DECLARE_COMPLETION(xpc_hb_checker_exited);
|
||||
@ -161,8 +163,6 @@ static DECLARE_COMPLETION(xpc_hb_checker_exited);
|
||||
/* notification that the xpc_discovery thread has exited */
|
||||
static DECLARE_COMPLETION(xpc_discovery_exited);
|
||||
|
||||
static struct timer_list xpc_hb_timer;
|
||||
|
||||
static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *);
|
||||
|
||||
static int xpc_system_reboot(struct notifier_block *, unsigned long, void *);
|
||||
@ -176,12 +176,54 @@ static struct notifier_block xpc_die_notifier = {
|
||||
};
|
||||
|
||||
enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *rp);
|
||||
void (*xpc_heartbeat_init) (void);
|
||||
void (*xpc_heartbeat_exit) (void);
|
||||
void (*xpc_increment_heartbeat) (void);
|
||||
void (*xpc_offline_heartbeat) (void);
|
||||
void (*xpc_online_heartbeat) (void);
|
||||
void (*xpc_check_remote_hb) (void);
|
||||
|
||||
enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part);
|
||||
u64 (*xpc_get_IPI_flags) (struct xpc_partition *part);
|
||||
struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *ch);
|
||||
|
||||
void (*xpc_initiate_partition_activation) (struct xpc_rsvd_page *remote_rp,
|
||||
u64 remote_rp_pa, int nasid);
|
||||
|
||||
void (*xpc_process_act_IRQ_rcvd) (int n_IRQs_expected);
|
||||
enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *part);
|
||||
void (*xpc_teardown_infrastructure) (struct xpc_partition *part);
|
||||
|
||||
void (*xpc_mark_partition_engaged) (struct xpc_partition *part);
|
||||
void (*xpc_mark_partition_disengaged) (struct xpc_partition *part);
|
||||
void (*xpc_request_partition_disengage) (struct xpc_partition *part);
|
||||
void (*xpc_cancel_partition_disengage_request) (struct xpc_partition *part);
|
||||
u64 (*xpc_partition_engaged) (u64 partid_mask);
|
||||
u64 (*xpc_partition_disengage_requested) (u64 partid_mask);
|
||||
void (*xpc_clear_partition_engaged) (u64 partid_mask);
|
||||
void (*xpc_clear_partition_disengage_request) (u64 partid_mask);
|
||||
|
||||
void (*xpc_IPI_send_local_activate) (int from_nasid);
|
||||
void (*xpc_IPI_send_activated) (struct xpc_partition *part);
|
||||
void (*xpc_IPI_send_local_reactivate) (int from_nasid);
|
||||
void (*xpc_IPI_send_disengage) (struct xpc_partition *part);
|
||||
|
||||
void (*xpc_IPI_send_closerequest) (struct xpc_channel *ch,
|
||||
unsigned long *irq_flags);
|
||||
void (*xpc_IPI_send_closereply) (struct xpc_channel *ch,
|
||||
unsigned long *irq_flags);
|
||||
void (*xpc_IPI_send_openrequest) (struct xpc_channel *ch,
|
||||
unsigned long *irq_flags);
|
||||
void (*xpc_IPI_send_openreply) (struct xpc_channel *ch,
|
||||
unsigned long *irq_flags);
|
||||
|
||||
enum xp_retval (*xpc_allocate_msg) (struct xpc_channel *ch, u32 flags,
|
||||
struct xpc_msg **address_of_msg);
|
||||
|
||||
enum xp_retval (*xpc_send_msg) (struct xpc_channel *ch, struct xpc_msg *msg,
|
||||
u8 notify_type, xpc_notify_func func,
|
||||
void *key);
|
||||
void (*xpc_received_msg) (struct xpc_channel *ch, struct xpc_msg *msg);
|
||||
|
||||
/*
|
||||
* Timer function to enforce the timelimit on the partition disengage request.
|
||||
@ -218,7 +260,7 @@ xpc_act_IRQ_handler(int irq, void *dev_id)
|
||||
static void
|
||||
xpc_hb_beater(unsigned long dummy)
|
||||
{
|
||||
xpc_vars->heartbeat++;
|
||||
xpc_increment_heartbeat();
|
||||
|
||||
if (time_after_eq(jiffies, xpc_hb_check_timeout))
|
||||
wake_up_interruptible(&xpc_act_IRQ_wq);
|
||||
@ -227,6 +269,22 @@ xpc_hb_beater(unsigned long dummy)
|
||||
add_timer(&xpc_hb_timer);
|
||||
}
|
||||
|
||||
static void
|
||||
xpc_start_hb_beater(void)
|
||||
{
|
||||
xpc_heartbeat_init();
|
||||
init_timer(&xpc_hb_timer);
|
||||
xpc_hb_timer.function = xpc_hb_beater;
|
||||
xpc_hb_beater(0);
|
||||
}
|
||||
|
||||
static void
|
||||
xpc_stop_hb_beater(void)
|
||||
{
|
||||
del_timer_sync(&xpc_hb_timer);
|
||||
xpc_heartbeat_exit();
|
||||
}
|
||||
|
||||
/*
|
||||
* This thread is responsible for nearly all of the partition
|
||||
* activation/deactivation.
|
||||
@ -244,7 +302,7 @@ xpc_hb_checker(void *ignore)
|
||||
|
||||
/* set our heartbeating to other partitions into motion */
|
||||
xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
|
||||
xpc_hb_beater(0);
|
||||
xpc_start_hb_beater();
|
||||
|
||||
while (!xpc_exiting) {
|
||||
|
||||
@ -274,11 +332,8 @@ xpc_hb_checker(void *ignore)
|
||||
dev_dbg(xpc_part, "found an IRQ to process; will be "
|
||||
"resetting xpc_hb_check_timeout\n");
|
||||
|
||||
last_IRQ_count += xpc_identify_act_IRQ_sender();
|
||||
if (last_IRQ_count < new_IRQ_count) {
|
||||
/* retry once to help avoid missing AMO */
|
||||
(void)xpc_identify_act_IRQ_sender();
|
||||
}
|
||||
xpc_process_act_IRQ_rcvd(new_IRQ_count -
|
||||
last_IRQ_count);
|
||||
last_IRQ_count = new_IRQ_count;
|
||||
|
||||
xpc_hb_check_timeout = jiffies +
|
||||
@ -294,6 +349,8 @@ xpc_hb_checker(void *ignore)
|
||||
xpc_exiting));
|
||||
}
|
||||
|
||||
xpc_stop_hb_beater();
|
||||
|
||||
dev_dbg(xpc_part, "heartbeat checker is exiting\n");
|
||||
|
||||
/* mark this thread as having exited */
|
||||
@ -401,31 +458,7 @@ xpc_activating(void *__partid)
|
||||
|
||||
dev_dbg(xpc_part, "activating partition %d\n", partid);
|
||||
|
||||
/*
|
||||
* Register the remote partition's AMOs with SAL so it can handle
|
||||
* and cleanup errors within that address range should the remote
|
||||
* partition go down. We don't unregister this range because it is
|
||||
* difficult to tell when outstanding writes to the remote partition
|
||||
* are finished and thus when it is safe to unregister. This should
|
||||
* not result in wasted space in the SAL xp_addr_region table because
|
||||
* we should get the same page for remote_amos_page_pa after module
|
||||
* reloads and system reboots.
|
||||
*/
|
||||
if (sn_register_xp_addr_region(part->remote_amos_page_pa,
|
||||
PAGE_SIZE, 1) < 0) {
|
||||
dev_warn(xpc_part, "xpc_activating(%d) failed to register "
|
||||
"xp_addr region\n", partid);
|
||||
|
||||
spin_lock_irqsave(&part->act_lock, irq_flags);
|
||||
part->act_state = XPC_P_INACTIVE;
|
||||
XPC_SET_REASON(part, xpPhysAddrRegFailed, __LINE__);
|
||||
spin_unlock_irqrestore(&part->act_lock, irq_flags);
|
||||
part->remote_rp_pa = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
xpc_allow_hb(partid, xpc_vars);
|
||||
xpc_IPI_send_activated(part);
|
||||
xpc_allow_hb(partid);
|
||||
|
||||
if (xpc_setup_infrastructure(part) == xpSuccess) {
|
||||
(void)xpc_part_ref(part); /* this will always succeed */
|
||||
@ -440,12 +473,12 @@ xpc_activating(void *__partid)
|
||||
xpc_teardown_infrastructure(part);
|
||||
}
|
||||
|
||||
xpc_disallow_hb(partid, xpc_vars);
|
||||
xpc_disallow_hb(partid);
|
||||
xpc_mark_partition_inactive(part);
|
||||
|
||||
if (part->reason == xpReactivating) {
|
||||
/* interrupting ourselves results in activating partition */
|
||||
xpc_IPI_send_reactivate(part);
|
||||
xpc_IPI_send_local_reactivate(part->reactivate_nasid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -477,6 +510,32 @@ xpc_activate_partition(struct xpc_partition *part)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if there is any channel activity to/from the specified
|
||||
* partition.
|
||||
*/
|
||||
static void
|
||||
xpc_check_for_channel_activity(struct xpc_partition *part)
|
||||
{
|
||||
u64 IPI_amo;
|
||||
unsigned long irq_flags;
|
||||
|
||||
/* this needs to be uncommented, but I'm thinking this function and the */
|
||||
/* ones that call it need to be moved into xpc_sn2.c... */
|
||||
IPI_amo = 0; /* = xpc_IPI_receive(part->local_IPI_amo_va); */
|
||||
if (IPI_amo == 0)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&part->IPI_lock, irq_flags);
|
||||
part->local_IPI_amo |= IPI_amo;
|
||||
spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
|
||||
|
||||
dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n",
|
||||
XPC_PARTID(part), IPI_amo);
|
||||
|
||||
xpc_wakeup_channel_mgr(part);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified
|
||||
* partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more
|
||||
@ -902,14 +961,11 @@ xpc_do_exit(enum xp_retval reason)
|
||||
} while (1);
|
||||
|
||||
DBUG_ON(xpc_partition_engaged(-1UL));
|
||||
DBUG_ON(xpc_any_hbs_allowed() != 0);
|
||||
|
||||
/* indicate to others that our reserved page is uninitialized */
|
||||
xpc_rsvd_page->stamp = ZERO_STAMP;
|
||||
|
||||
/* now it's time to eliminate our heartbeat */
|
||||
del_timer_sync(&xpc_hb_timer);
|
||||
DBUG_ON(xpc_vars->heartbeating_to_mask != 0);
|
||||
|
||||
if (reason == xpUnloading) {
|
||||
(void)unregister_die_notifier(&xpc_die_notifier);
|
||||
(void)unregister_reboot_notifier(&xpc_reboot_notifier);
|
||||
@ -968,7 +1024,7 @@ xpc_die_disengage(void)
|
||||
/* keep xpc_hb_checker thread from doing anything (just in case) */
|
||||
xpc_exiting = 1;
|
||||
|
||||
xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */
|
||||
xpc_disallow_all_hbs(); /*indicate we're deactivated */
|
||||
|
||||
for (partid = 0; partid < xp_max_npartitions; partid++) {
|
||||
part = &xpc_partitions[partid];
|
||||
@ -1054,8 +1110,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
|
||||
/* fall through */
|
||||
case DIE_MCA_MONARCH_ENTER:
|
||||
case DIE_INIT_MONARCH_ENTER:
|
||||
xpc_vars->heartbeat++;
|
||||
xpc_vars->heartbeat_offline = 1;
|
||||
xpc_offline_heartbeat();
|
||||
break;
|
||||
|
||||
case DIE_KDEBUG_LEAVE:
|
||||
@ -1066,8 +1121,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
|
||||
/* fall through */
|
||||
case DIE_MCA_MONARCH_LEAVE:
|
||||
case DIE_INIT_MONARCH_LEAVE:
|
||||
xpc_vars->heartbeat++;
|
||||
xpc_vars->heartbeat_offline = 0;
|
||||
xpc_online_heartbeat();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1202,9 +1256,6 @@ xpc_init(void)
|
||||
if (ret != 0)
|
||||
dev_warn(xpc_part, "can't register die notifier\n");
|
||||
|
||||
init_timer(&xpc_hb_timer);
|
||||
xpc_hb_timer.function = xpc_hb_beater;
|
||||
|
||||
/*
|
||||
* The real work-horse behind xpc. This processes incoming
|
||||
* interrupts and monitors remote heartbeats.
|
||||
@ -1246,7 +1297,6 @@ out_4:
|
||||
/* indicate to others that our reserved page is uninitialized */
|
||||
xpc_rsvd_page->stamp = ZERO_STAMP;
|
||||
|
||||
del_timer_sync(&xpc_hb_timer);
|
||||
(void)unregister_die_notifier(&xpc_die_notifier);
|
||||
(void)unregister_reboot_notifier(&xpc_reboot_notifier);
|
||||
out_3:
|
||||
|
Reference in New Issue
Block a user