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

sgi-xp: base xpc_rsvd_page's timestamp on jiffies

Change XPC's reserved page timestamp to be based on jiffies.
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 33ba3c77
...@@ -115,8 +115,8 @@ struct xpc_rsvd_page { ...@@ -115,8 +115,8 @@ struct xpc_rsvd_page {
u64 vars_pa; /* physical address of struct xpc_vars */ u64 vars_pa; /* physical address of struct xpc_vars */
u64 activate_mq_gpa; /* global phys address of activate_mq */ u64 activate_mq_gpa; /* global phys address of activate_mq */
} sn; } sn;
struct timespec stamp; /* time when reserved page was setup by XPC */ unsigned long stamp; /* time when reserved page was setup by XPC */
u64 pad2[9]; /* align to last u64 in 2nd 64-byte cacheline */ u64 pad2[10]; /* align to last u64 in 2nd 64-byte cacheline */
u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */ u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */
}; };
...@@ -125,26 +125,6 @@ struct xpc_rsvd_page { ...@@ -125,26 +125,6 @@ struct xpc_rsvd_page {
#define XPC_SUPPORTS_RP_STAMP(_version) \ #define XPC_SUPPORTS_RP_STAMP(_version) \
(_version >= _XPC_VERSION(1, 1)) (_version >= _XPC_VERSION(1, 1))
#define ZERO_STAMP ((struct timespec){0, 0})
/*
* compare stamps - the return value is:
*
* < 0, if stamp1 < stamp2
* = 0, if stamp1 == stamp2
* > 0, if stamp1 > stamp2
*/
static inline int
xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2)
{
int ret;
ret = stamp1->tv_sec - stamp2->tv_sec;
if (ret == 0)
ret = stamp1->tv_nsec - stamp2->tv_nsec;
return ret;
}
/* /*
* Define the structures by which XPC variables can be exported to other * Define the structures by which XPC variables can be exported to other
* partitions. (There are two: struct xpc_vars and struct xpc_vars_part) * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
...@@ -492,7 +472,7 @@ struct xpc_partition { ...@@ -492,7 +472,7 @@ struct xpc_partition {
/* XPC HB infrastructure */ /* XPC HB infrastructure */
u8 remote_rp_version; /* version# of partition's rsvd pg */ u8 remote_rp_version; /* version# of partition's rsvd pg */
struct timespec remote_rp_stamp; /* time when rsvd pg was initialized */ unsigned long remote_rp_stamp; /* time when rsvd pg was initialized */
u64 remote_rp_pa; /* phys addr of partition's rsvd pg */ u64 remote_rp_pa; /* phys addr of partition's rsvd pg */
u64 remote_vars_pa; /* phys addr of partition's vars */ u64 remote_vars_pa; /* phys addr of partition's vars */
u64 remote_vars_part_pa; /* phys addr of partition's vars part */ u64 remote_vars_part_pa; /* phys addr of partition's vars part */
......
...@@ -233,7 +233,7 @@ xpc_timeout_partition_disengage_request(unsigned long data) ...@@ -233,7 +233,7 @@ xpc_timeout_partition_disengage_request(unsigned long data)
{ {
struct xpc_partition *part = (struct xpc_partition *)data; struct xpc_partition *part = (struct xpc_partition *)data;
DBUG_ON(time_before(jiffies, part->disengage_request_timeout)); DBUG_ON(time_is_after_jiffies(part->disengage_request_timeout));
(void)xpc_partition_disengaged(part); (void)xpc_partition_disengaged(part);
...@@ -262,7 +262,7 @@ xpc_hb_beater(unsigned long dummy) ...@@ -262,7 +262,7 @@ xpc_hb_beater(unsigned long dummy)
{ {
xpc_increment_heartbeat(); xpc_increment_heartbeat();
if (time_after_eq(jiffies, xpc_hb_check_timeout)) if (time_is_before_eq_jiffies(xpc_hb_check_timeout))
wake_up_interruptible(&xpc_act_IRQ_wq); wake_up_interruptible(&xpc_act_IRQ_wq);
xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ); xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ);
...@@ -312,7 +312,7 @@ xpc_hb_checker(void *ignore) ...@@ -312,7 +312,7 @@ xpc_hb_checker(void *ignore)
atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count); atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count);
/* checking of remote heartbeats is skewed by IRQ handling */ /* checking of remote heartbeats is skewed by IRQ handling */
if (time_after_eq(jiffies, xpc_hb_check_timeout)) { if (time_is_before_eq_jiffies(xpc_hb_check_timeout)) {
dev_dbg(xpc_part, "checking remote heartbeats\n"); dev_dbg(xpc_part, "checking remote heartbeats\n");
xpc_check_remote_hb(); xpc_check_remote_hb();
...@@ -344,8 +344,8 @@ xpc_hb_checker(void *ignore) ...@@ -344,8 +344,8 @@ xpc_hb_checker(void *ignore)
(void)wait_event_interruptible(xpc_act_IRQ_wq, (void)wait_event_interruptible(xpc_act_IRQ_wq,
(last_IRQ_count < (last_IRQ_count <
atomic_read(&xpc_act_IRQ_rcvd) atomic_read(&xpc_act_IRQ_rcvd)
|| time_after_eq(jiffies, || time_is_before_eq_jiffies(
xpc_hb_check_timeout) || xpc_hb_check_timeout) ||
xpc_exiting)); xpc_exiting));
} }
...@@ -929,7 +929,7 @@ xpc_do_exit(enum xp_retval reason) ...@@ -929,7 +929,7 @@ xpc_do_exit(enum xp_retval reason)
} }
if (xpc_partition_engaged(-1UL)) { if (xpc_partition_engaged(-1UL)) {
if (time_after(jiffies, printmsg_time)) { if (time_is_before_jiffies(printmsg_time)) {
dev_info(xpc_part, "waiting for remote " dev_info(xpc_part, "waiting for remote "
"partitions to disengage, timeout in " "partitions to disengage, timeout in "
"%ld seconds\n", "%ld seconds\n",
...@@ -964,7 +964,7 @@ xpc_do_exit(enum xp_retval reason) ...@@ -964,7 +964,7 @@ xpc_do_exit(enum xp_retval reason)
DBUG_ON(xpc_any_hbs_allowed() != 0); DBUG_ON(xpc_any_hbs_allowed() != 0);
/* indicate to others that our reserved page is uninitialized */ /* indicate to others that our reserved page is uninitialized */
xpc_rsvd_page->stamp = ZERO_STAMP; xpc_rsvd_page->stamp = 0;
if (reason == xpUnloading) { if (reason == xpUnloading) {
(void)unregister_die_notifier(&xpc_die_notifier); (void)unregister_die_notifier(&xpc_die_notifier);
...@@ -1295,7 +1295,7 @@ xpc_init(void) ...@@ -1295,7 +1295,7 @@ xpc_init(void)
/* initialization was not successful */ /* initialization was not successful */
out_4: out_4:
/* indicate to others that our reserved page is uninitialized */ /* indicate to others that our reserved page is uninitialized */
xpc_rsvd_page->stamp = ZERO_STAMP; xpc_rsvd_page->stamp = 0;
(void)unregister_die_notifier(&xpc_die_notifier); (void)unregister_die_notifier(&xpc_die_notifier);
(void)unregister_reboot_notifier(&xpc_reboot_notifier); (void)unregister_reboot_notifier(&xpc_reboot_notifier);
......
...@@ -152,6 +152,7 @@ xpc_setup_rsvd_page(void) ...@@ -152,6 +152,7 @@ xpc_setup_rsvd_page(void)
{ {
struct xpc_rsvd_page *rp; struct xpc_rsvd_page *rp;
u64 rp_pa; u64 rp_pa;
unsigned long new_stamp;
/* get the local reserved page's address */ /* get the local reserved page's address */
...@@ -201,7 +202,10 @@ xpc_setup_rsvd_page(void) ...@@ -201,7 +202,10 @@ xpc_setup_rsvd_page(void)
* This signifies to the remote partition that our reserved * This signifies to the remote partition that our reserved
* page is initialized. * page is initialized.
*/ */
rp->stamp = CURRENT_TIME; new_stamp = jiffies;
if (new_stamp == 0 || new_stamp == rp->stamp)
new_stamp++;
rp->stamp = new_stamp;
return rp; return rp;
} }
...@@ -350,18 +354,8 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, ...@@ -350,18 +354,8 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
discovered_nasids[i] |= remote_part_nasids[i]; discovered_nasids[i] |= remote_part_nasids[i];
} }
/* check that the partid is valid and is for another partition */ /* see if the reserved page has been set up by XPC */
if (remote_rp->stamp == 0)
if (remote_rp->SAL_partid < 0 ||
remote_rp->SAL_partid >= xp_max_npartitions) {
return xpInvalidPartid;
}
if (remote_rp->SAL_partid == sn_partition_id)
return xpLocalPartid;
/* see if the rest of the reserved page has been set up by XPC */
if (timespec_equal(&remote_rp->stamp, &ZERO_STAMP))
return xpRsvdPageNotSet; return xpRsvdPageNotSet;
if (XPC_VERSION_MAJOR(remote_rp->version) != if (XPC_VERSION_MAJOR(remote_rp->version) !=
...@@ -369,8 +363,15 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, ...@@ -369,8 +363,15 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
return xpBadVersion; return xpBadVersion;
} }
if (remote_rp->max_npartitions <= sn_partition_id) /* check that both local and remote 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) {
return xpInvalidPartid; return xpInvalidPartid;
}
if (remote_rp->SAL_partid == sn_partition_id)
return xpLocalPartid;
return xpSuccess; return xpSuccess;
} }
...@@ -388,8 +389,8 @@ xpc_partition_disengaged(struct xpc_partition *part) ...@@ -388,8 +389,8 @@ xpc_partition_disengaged(struct xpc_partition *part)
disengaged = (xpc_partition_engaged(1UL << partid) == 0); disengaged = (xpc_partition_engaged(1UL << partid) == 0);
if (part->disengage_request_timeout) { if (part->disengage_request_timeout) {
if (!disengaged) { if (!disengaged) {
if (time_before(jiffies, if (time_is_after_jiffies(part->
part->disengage_request_timeout)) { disengage_request_timeout)) {
/* timelimit hasn't been reached yet */ /* timelimit hasn't been reached yet */
return 0; return 0;
} }
......
...@@ -597,8 +597,8 @@ xpc_initiate_partition_activation_sn2(struct xpc_rsvd_page *remote_rp, ...@@ -597,8 +597,8 @@ xpc_initiate_partition_activation_sn2(struct xpc_rsvd_page *remote_rp,
*/ */
static void static void
xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version, xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version,
struct timespec *remote_rp_stamp, unsigned long *remote_rp_stamp, u64 remote_rp_pa,
u64 remote_rp_pa, u64 remote_vars_pa, u64 remote_vars_pa,
struct xpc_vars_sn2 *remote_vars) struct xpc_vars_sn2 *remote_vars)
{ {
part->remote_rp_version = remote_rp_version; part->remote_rp_version = remote_rp_version;
...@@ -606,8 +606,8 @@ xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version, ...@@ -606,8 +606,8 @@ xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version,
part->remote_rp_version); part->remote_rp_version);
part->remote_rp_stamp = *remote_rp_stamp; part->remote_rp_stamp = *remote_rp_stamp;
dev_dbg(xpc_part, " remote_rp_stamp (tv_sec = 0x%lx tv_nsec = 0x%lx\n", dev_dbg(xpc_part, " remote_rp_stamp = 0x%016lx\n",
part->remote_rp_stamp.tv_sec, part->remote_rp_stamp.tv_nsec); part->remote_rp_stamp);
part->remote_rp_pa = remote_rp_pa; part->remote_rp_pa = remote_rp_pa;
dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n", part->remote_rp_pa); dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n", part->remote_rp_pa);
...@@ -664,8 +664,7 @@ xpc_identify_act_IRQ_req_sn2(int nasid) ...@@ -664,8 +664,7 @@ xpc_identify_act_IRQ_req_sn2(int nasid)
u64 remote_vars_pa; u64 remote_vars_pa;
int remote_rp_version; int remote_rp_version;
int reactivate = 0; int reactivate = 0;
int stamp_diff; unsigned long remote_rp_stamp = 0;
struct timespec remote_rp_stamp = { 0, 0 }; /*>>> ZERO_STAMP */
short partid; short partid;
struct xpc_partition *part; struct xpc_partition *part;
enum xp_retval ret; enum xp_retval ret;
...@@ -788,10 +787,7 @@ xpc_identify_act_IRQ_req_sn2(int nasid) ...@@ -788,10 +787,7 @@ xpc_identify_act_IRQ_req_sn2(int nasid)
} else { } else {
DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version)); DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version));
stamp_diff = xpc_compare_stamps(&part->remote_rp_stamp, if (remote_rp_stamp != part->remote_rp_stamp) {
&remote_rp_stamp);
if (stamp_diff != 0) {
DBUG_ON(stamp_diff >= 0);
/* /*
* Other side rebooted and the previous XPC did support * Other side rebooted and the previous XPC did support
......
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