forked from Minki/linux
sgi-xp: use standard bitops macros and functions
Change sgi-xp to use the standard bitops macros and functions instead of trying to invent its own mechanism. 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:
parent
ea57f80c8c
commit
04de741885
@ -21,9 +21,6 @@
|
|||||||
#include <asm/sn/arch.h>
|
#include <asm/sn/arch.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ??? Add this #define to some linux header file some day? */
|
|
||||||
#define BYTES_PER_WORD sizeof(void *)
|
|
||||||
|
|
||||||
#ifdef USE_DBUG_ON
|
#ifdef USE_DBUG_ON
|
||||||
#define DBUG_ON(condition) BUG_ON(condition)
|
#define DBUG_ON(condition) BUG_ON(condition)
|
||||||
#else
|
#else
|
||||||
|
@ -35,23 +35,7 @@
|
|||||||
#define XPC_VERSION_MAJOR(_v) ((_v) >> 4)
|
#define XPC_VERSION_MAJOR(_v) ((_v) >> 4)
|
||||||
#define XPC_VERSION_MINOR(_v) ((_v) & 0xf)
|
#define XPC_VERSION_MINOR(_v) ((_v) & 0xf)
|
||||||
|
|
||||||
/*
|
/* define frequency of the heartbeat and frequency how often it's checked */
|
||||||
* The next macros define word or bit representations for given
|
|
||||||
* C-brick nasid in either the SAL provided bit array representing
|
|
||||||
* nasids in the partition/machine or the array of amo structures used
|
|
||||||
* for inter-partition initiation communications.
|
|
||||||
*
|
|
||||||
* For SN2 machines, C-Bricks are alway even numbered NASIDs. As
|
|
||||||
* such, some space will be saved by insisting that nasid information
|
|
||||||
* passed from SAL always be packed for C-Bricks and the
|
|
||||||
* cross-partition interrupts use the same packing scheme.
|
|
||||||
*/
|
|
||||||
#define XPC_NASID_W_INDEX(_n) (((_n) / 64) / 2)
|
|
||||||
#define XPC_NASID_B_INDEX(_n) (((_n) / 2) & (64 - 1))
|
|
||||||
#define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[XPC_NASID_W_INDEX(_n)] & \
|
|
||||||
(1UL << XPC_NASID_B_INDEX(_n)))
|
|
||||||
#define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2)
|
|
||||||
|
|
||||||
#define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */
|
#define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */
|
||||||
#define XPC_HB_CHECK_DEFAULT_INTERVAL 20 /* check HB every x secs */
|
#define XPC_HB_CHECK_DEFAULT_INTERVAL 20 /* check HB every x secs */
|
||||||
|
|
||||||
@ -86,11 +70,13 @@
|
|||||||
* the actual nasids in the entire machine (mach_nasids). We're only
|
* the actual nasids in the entire machine (mach_nasids). We're only
|
||||||
* interested in the even numbered nasids (which contain the processors
|
* interested in the even numbered nasids (which contain the processors
|
||||||
* and/or memory), so we only need half as many bits to represent the
|
* and/or memory), so we only need half as many bits to represent the
|
||||||
* nasids. The part_nasids mask is located starting at the first cacheline
|
* nasids. When mapping nasid to bit in a mask (or bit to nasid) be sure
|
||||||
* following the reserved page header. The mach_nasids mask follows right
|
* to either divide or multiply by 2. The part_nasids mask is located
|
||||||
* after the part_nasids mask. The size in bytes of each mask is reflected
|
* starting at the first cacheline following the reserved page header. The
|
||||||
* by the reserved page header field 'SAL_nasids_size'. (Local partition's
|
* mach_nasids mask follows right after the part_nasids mask. The size in
|
||||||
* mask pointers are xpc_part_nasids and xpc_mach_nasids.)
|
* bytes of each mask is reflected by the reserved page header field
|
||||||
|
* 'SAL_nasids_size'. (Local partition's mask pointers are xpc_part_nasids
|
||||||
|
* and xpc_mach_nasids.)
|
||||||
*
|
*
|
||||||
* vars (ia64-sn2 only)
|
* vars (ia64-sn2 only)
|
||||||
* vars part (ia64-sn2 only)
|
* vars part (ia64-sn2 only)
|
||||||
@ -194,10 +180,11 @@ struct xpc_vars_part_sn2 {
|
|||||||
#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2))
|
#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2))
|
||||||
|
|
||||||
#define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE))
|
#define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE))
|
||||||
#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xpc_nasid_mask_words)
|
#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
|
||||||
|
xpc_nasid_mask_nlongs)
|
||||||
#define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *) \
|
#define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *) \
|
||||||
(XPC_RP_MACH_NASIDS(_rp) + \
|
(XPC_RP_MACH_NASIDS(_rp) + \
|
||||||
xpc_nasid_mask_words))
|
xpc_nasid_mask_nlongs))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions registered by add_timer() or called by kernel_thread() only
|
* Functions registered by add_timer() or called by kernel_thread() only
|
||||||
@ -695,9 +682,9 @@ extern void xpc_exit_uv(void);
|
|||||||
|
|
||||||
/* found in xpc_partition.c */
|
/* found in xpc_partition.c */
|
||||||
extern int xpc_exiting;
|
extern int xpc_exiting;
|
||||||
extern int xpc_nasid_mask_words;
|
extern int xpc_nasid_mask_nlongs;
|
||||||
extern struct xpc_rsvd_page *xpc_rsvd_page;
|
extern struct xpc_rsvd_page *xpc_rsvd_page;
|
||||||
extern u64 *xpc_mach_nasids;
|
extern unsigned long *xpc_mach_nasids;
|
||||||
extern struct xpc_partition *xpc_partitions;
|
extern struct xpc_partition *xpc_partitions;
|
||||||
extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
|
extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
|
||||||
extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void);
|
extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void);
|
||||||
@ -706,8 +693,8 @@ extern int xpc_partition_disengaged(struct xpc_partition *);
|
|||||||
extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
|
extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
|
||||||
extern void xpc_mark_partition_inactive(struct xpc_partition *);
|
extern void xpc_mark_partition_inactive(struct xpc_partition *);
|
||||||
extern void xpc_discovery(void);
|
extern void xpc_discovery(void);
|
||||||
extern enum xp_retval xpc_get_remote_rp(int, u64 *, struct xpc_rsvd_page *,
|
extern enum xp_retval xpc_get_remote_rp(int, unsigned long *,
|
||||||
u64 *);
|
struct xpc_rsvd_page *, u64 *);
|
||||||
extern void xpc_deactivate_partition(const int, struct xpc_partition *,
|
extern void xpc_deactivate_partition(const int, struct xpc_partition *,
|
||||||
enum xp_retval);
|
enum xp_retval);
|
||||||
extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
|
extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
|
||||||
|
@ -31,11 +31,11 @@ int xpc_exiting;
|
|||||||
|
|
||||||
/* this partition's reserved page pointers */
|
/* this partition's reserved page pointers */
|
||||||
struct xpc_rsvd_page *xpc_rsvd_page;
|
struct xpc_rsvd_page *xpc_rsvd_page;
|
||||||
static u64 *xpc_part_nasids;
|
static unsigned long *xpc_part_nasids;
|
||||||
u64 *xpc_mach_nasids;
|
unsigned long *xpc_mach_nasids;
|
||||||
|
|
||||||
static int xpc_sizeof_nasid_mask; /* actual size in bytes of nasid mask */
|
static int xpc_nasid_mask_nbytes; /* #of bytes in nasid mask */
|
||||||
int xpc_nasid_mask_words; /* actual size in words of nasid mask */
|
int xpc_nasid_mask_nlongs; /* #of longs in nasid mask */
|
||||||
|
|
||||||
struct xpc_partition *xpc_partitions;
|
struct xpc_partition *xpc_partitions;
|
||||||
|
|
||||||
@ -167,9 +167,9 @@ xpc_setup_rsvd_page(void)
|
|||||||
/* SAL_version 1 didn't set the nasids_size field */
|
/* SAL_version 1 didn't set the nasids_size field */
|
||||||
rp->SAL_nasids_size = 128;
|
rp->SAL_nasids_size = 128;
|
||||||
}
|
}
|
||||||
xpc_sizeof_nasid_mask = rp->SAL_nasids_size;
|
xpc_nasid_mask_nbytes = rp->SAL_nasids_size;
|
||||||
xpc_nasid_mask_words = DIV_ROUND_UP(xpc_sizeof_nasid_mask,
|
xpc_nasid_mask_nlongs = BITS_TO_LONGS(rp->SAL_nasids_size *
|
||||||
BYTES_PER_WORD);
|
BITS_PER_BYTE);
|
||||||
|
|
||||||
/* setup the pointers to the various items in the reserved page */
|
/* setup the pointers to the various items in the reserved page */
|
||||||
xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
|
xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
|
||||||
@ -199,10 +199,10 @@ xpc_setup_rsvd_page(void)
|
|||||||
* part_nasids mask.
|
* part_nasids mask.
|
||||||
*/
|
*/
|
||||||
enum xp_retval
|
enum xp_retval
|
||||||
xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
|
xpc_get_remote_rp(int nasid, unsigned long *discovered_nasids,
|
||||||
struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
|
struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
|
||||||
{
|
{
|
||||||
int i;
|
int l;
|
||||||
enum xp_retval ret;
|
enum xp_retval ret;
|
||||||
|
|
||||||
/* get the reserved page's physical address */
|
/* get the reserved page's physical address */
|
||||||
@ -213,15 +213,16 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
|
|||||||
|
|
||||||
/* pull over the reserved page header and part_nasids mask */
|
/* pull over the reserved page header and part_nasids mask */
|
||||||
ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa,
|
ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa,
|
||||||
XPC_RP_HEADER_SIZE + xpc_sizeof_nasid_mask);
|
XPC_RP_HEADER_SIZE + xpc_nasid_mask_nbytes);
|
||||||
if (ret != xpSuccess)
|
if (ret != xpSuccess)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (discovered_nasids != NULL) {
|
if (discovered_nasids != NULL) {
|
||||||
u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp);
|
unsigned long *remote_part_nasids =
|
||||||
|
XPC_RP_PART_NASIDS(remote_rp);
|
||||||
|
|
||||||
for (i = 0; i < xpc_nasid_mask_words; i++)
|
for (l = 0; l < xpc_nasid_mask_nlongs; l++)
|
||||||
discovered_nasids[i] |= remote_part_nasids[i];
|
discovered_nasids[l] |= remote_part_nasids[l];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if the reserved page has been set up by XPC */
|
/* see if the reserved page has been set up by XPC */
|
||||||
@ -401,16 +402,16 @@ xpc_discovery(void)
|
|||||||
int max_regions;
|
int max_regions;
|
||||||
int nasid;
|
int nasid;
|
||||||
struct xpc_rsvd_page *rp;
|
struct xpc_rsvd_page *rp;
|
||||||
u64 *discovered_nasids;
|
unsigned long *discovered_nasids;
|
||||||
enum xp_retval ret;
|
enum xp_retval ret;
|
||||||
|
|
||||||
remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
|
remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
|
||||||
xpc_sizeof_nasid_mask,
|
xpc_nasid_mask_nbytes,
|
||||||
GFP_KERNEL, &remote_rp_base);
|
GFP_KERNEL, &remote_rp_base);
|
||||||
if (remote_rp == NULL)
|
if (remote_rp == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
discovered_nasids = kzalloc(sizeof(u64) * xpc_nasid_mask_words,
|
discovered_nasids = kzalloc(sizeof(long) * xpc_nasid_mask_nlongs,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (discovered_nasids == NULL) {
|
if (discovered_nasids == NULL) {
|
||||||
kfree(remote_rp_base);
|
kfree(remote_rp_base);
|
||||||
@ -453,21 +454,21 @@ xpc_discovery(void)
|
|||||||
|
|
||||||
dev_dbg(xpc_part, "checking nasid %d\n", nasid);
|
dev_dbg(xpc_part, "checking nasid %d\n", nasid);
|
||||||
|
|
||||||
if (XPC_NASID_IN_ARRAY(nasid, xpc_part_nasids)) {
|
if (test_bit(nasid / 2, xpc_part_nasids)) {
|
||||||
dev_dbg(xpc_part, "PROM indicates Nasid %d is "
|
dev_dbg(xpc_part, "PROM indicates Nasid %d is "
|
||||||
"part of the local partition; skipping "
|
"part of the local partition; skipping "
|
||||||
"region\n", nasid);
|
"region\n", nasid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(XPC_NASID_IN_ARRAY(nasid, xpc_mach_nasids))) {
|
if (!(test_bit(nasid / 2, xpc_mach_nasids))) {
|
||||||
dev_dbg(xpc_part, "PROM indicates Nasid %d was "
|
dev_dbg(xpc_part, "PROM indicates Nasid %d was "
|
||||||
"not on Numa-Link network at reset\n",
|
"not on Numa-Link network at reset\n",
|
||||||
nasid);
|
nasid);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (XPC_NASID_IN_ARRAY(nasid, discovered_nasids)) {
|
if (test_bit(nasid / 2, discovered_nasids)) {
|
||||||
dev_dbg(xpc_part, "Nasid %d is part of a "
|
dev_dbg(xpc_part, "Nasid %d is part of a "
|
||||||
"partition which was previously "
|
"partition which was previously "
|
||||||
"discovered\n", nasid);
|
"discovered\n", nasid);
|
||||||
@ -512,10 +513,10 @@ xpc_initiate_partid_to_nasids(short partid, void *nasid_mask)
|
|||||||
if (part->remote_rp_pa == 0)
|
if (part->remote_rp_pa == 0)
|
||||||
return xpPartitionDown;
|
return xpPartitionDown;
|
||||||
|
|
||||||
memset(nasid_mask, 0, xpc_sizeof_nasid_mask);
|
memset(nasid_mask, 0, xpc_nasid_mask_nbytes);
|
||||||
|
|
||||||
part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa);
|
part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa);
|
||||||
|
|
||||||
return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa,
|
return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa,
|
||||||
xpc_sizeof_nasid_mask);
|
xpc_nasid_mask_nbytes);
|
||||||
}
|
}
|
||||||
|
@ -210,28 +210,26 @@ static void
|
|||||||
xpc_send_activate_IRQ_sn2(u64 amos_page_pa, int from_nasid, int to_nasid,
|
xpc_send_activate_IRQ_sn2(u64 amos_page_pa, int from_nasid, int to_nasid,
|
||||||
int to_phys_cpuid)
|
int to_phys_cpuid)
|
||||||
{
|
{
|
||||||
int w_index = XPC_NASID_W_INDEX(from_nasid);
|
|
||||||
int b_index = XPC_NASID_B_INDEX(from_nasid);
|
|
||||||
struct amo *amos = (struct amo *)__va(amos_page_pa +
|
struct amo *amos = (struct amo *)__va(amos_page_pa +
|
||||||
(XPC_ACTIVATE_IRQ_AMOS_SN2 *
|
(XPC_ACTIVATE_IRQ_AMOS_SN2 *
|
||||||
sizeof(struct amo)));
|
sizeof(struct amo)));
|
||||||
|
|
||||||
(void)xpc_send_IRQ_sn2(&amos[w_index], (1UL << b_index), to_nasid,
|
(void)xpc_send_IRQ_sn2(&amos[BIT_WORD(from_nasid / 2)],
|
||||||
|
BIT_MASK(from_nasid / 2), to_nasid,
|
||||||
to_phys_cpuid, SGI_XPC_ACTIVATE);
|
to_phys_cpuid, SGI_XPC_ACTIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xpc_send_local_activate_IRQ_sn2(int from_nasid)
|
xpc_send_local_activate_IRQ_sn2(int from_nasid)
|
||||||
{
|
{
|
||||||
int w_index = XPC_NASID_W_INDEX(from_nasid);
|
|
||||||
int b_index = XPC_NASID_B_INDEX(from_nasid);
|
|
||||||
struct amo *amos = (struct amo *)__va(xpc_vars_sn2->amos_page_pa +
|
struct amo *amos = (struct amo *)__va(xpc_vars_sn2->amos_page_pa +
|
||||||
(XPC_ACTIVATE_IRQ_AMOS_SN2 *
|
(XPC_ACTIVATE_IRQ_AMOS_SN2 *
|
||||||
sizeof(struct amo)));
|
sizeof(struct amo)));
|
||||||
|
|
||||||
/* fake the sending and receipt of an activate IRQ from remote nasid */
|
/* fake the sending and receipt of an activate IRQ from remote nasid */
|
||||||
FETCHOP_STORE_OP(TO_AMO((u64)&amos[w_index].variable), FETCHOP_OR,
|
FETCHOP_STORE_OP(TO_AMO((u64)&amos[BIT_WORD(from_nasid / 2)].variable),
|
||||||
(1UL << b_index));
|
FETCHOP_OR, BIT_MASK(from_nasid / 2));
|
||||||
|
|
||||||
atomic_inc(&xpc_activate_IRQ_rcvd);
|
atomic_inc(&xpc_activate_IRQ_rcvd);
|
||||||
wake_up_interruptible(&xpc_activate_IRQ_wq);
|
wake_up_interruptible(&xpc_activate_IRQ_wq);
|
||||||
}
|
}
|
||||||
@ -439,7 +437,8 @@ xpc_indicate_partition_engaged_sn2(struct xpc_partition *part)
|
|||||||
|
|
||||||
/* set bit corresponding to our partid in remote partition's amo */
|
/* set bit corresponding to our partid in remote partition's amo */
|
||||||
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
|
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
|
||||||
(1UL << sn_partition_id));
|
BIT(sn_partition_id));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must always use the nofault function regardless of whether we
|
* We must always use the nofault function regardless of whether we
|
||||||
* are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
|
* are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
|
||||||
@ -466,7 +465,8 @@ xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part)
|
|||||||
|
|
||||||
/* clear bit corresponding to our partid in remote partition's amo */
|
/* clear bit corresponding to our partid in remote partition's amo */
|
||||||
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
|
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
|
||||||
~(1UL << sn_partition_id));
|
~BIT(sn_partition_id));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must always use the nofault function regardless of whether we
|
* We must always use the nofault function regardless of whether we
|
||||||
* are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
|
* are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
|
||||||
@ -497,7 +497,7 @@ xpc_partition_engaged_sn2(short partid)
|
|||||||
|
|
||||||
/* our partition's amo variable ANDed with partid mask */
|
/* our partition's amo variable ANDed with partid mask */
|
||||||
return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
|
return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
|
||||||
(1UL << partid)) != 0;
|
BIT(partid)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -518,7 +518,7 @@ xpc_assume_partition_disengaged_sn2(short partid)
|
|||||||
|
|
||||||
/* clear bit(s) based on partid mask in our partition's amo */
|
/* clear bit(s) based on partid mask in our partition's amo */
|
||||||
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
|
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
|
||||||
~(1UL << partid));
|
~BIT(partid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* original protection values for each node */
|
/* original protection values for each node */
|
||||||
@ -639,7 +639,7 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_page *rp)
|
|||||||
xp_max_npartitions);
|
xp_max_npartitions);
|
||||||
|
|
||||||
/* initialize the activate IRQ related amo variables */
|
/* initialize the activate IRQ related amo variables */
|
||||||
for (i = 0; i < xpc_nasid_mask_words; i++)
|
for (i = 0; i < xpc_nasid_mask_nlongs; i++)
|
||||||
(void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS_SN2 + i);
|
(void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS_SN2 + i);
|
||||||
|
|
||||||
/* initialize the engaged remote partitions related amo variables */
|
/* initialize the engaged remote partitions related amo variables */
|
||||||
@ -796,7 +796,8 @@ xpc_request_partition_deactivation_sn2(struct xpc_partition *part)
|
|||||||
|
|
||||||
/* set bit corresponding to our partid in remote partition's amo */
|
/* set bit corresponding to our partid in remote partition's amo */
|
||||||
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
|
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
|
||||||
(1UL << sn_partition_id));
|
BIT(sn_partition_id));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must always use the nofault function regardless of whether we
|
* We must always use the nofault function regardless of whether we
|
||||||
* are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
|
* are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
|
||||||
@ -831,7 +832,8 @@ xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part)
|
|||||||
|
|
||||||
/* clear bit corresponding to our partid in remote partition's amo */
|
/* clear bit corresponding to our partid in remote partition's amo */
|
||||||
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
|
FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
|
||||||
~(1UL << sn_partition_id));
|
~BIT(sn_partition_id));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must always use the nofault function regardless of whether we
|
* We must always use the nofault function regardless of whether we
|
||||||
* are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
|
* are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
|
||||||
@ -853,7 +855,7 @@ xpc_partition_deactivation_requested_sn2(short partid)
|
|||||||
|
|
||||||
/* our partition's amo variable ANDed with partid mask */
|
/* our partition's amo variable ANDed with partid mask */
|
||||||
return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
|
return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
|
||||||
(1UL << partid)) != 0;
|
BIT(partid)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1031,28 +1033,31 @@ xpc_identify_activate_IRQ_req_sn2(int nasid)
|
|||||||
int
|
int
|
||||||
xpc_identify_activate_IRQ_sender_sn2(void)
|
xpc_identify_activate_IRQ_sender_sn2(void)
|
||||||
{
|
{
|
||||||
int word, bit;
|
int l;
|
||||||
u64 nasid_mask;
|
int b;
|
||||||
|
unsigned long nasid_mask_long;
|
||||||
u64 nasid; /* remote nasid */
|
u64 nasid; /* remote nasid */
|
||||||
int n_IRQs_detected = 0;
|
int n_IRQs_detected = 0;
|
||||||
struct amo *act_amos;
|
struct amo *act_amos;
|
||||||
|
|
||||||
act_amos = xpc_vars_sn2->amos_page + XPC_ACTIVATE_IRQ_AMOS_SN2;
|
act_amos = xpc_vars_sn2->amos_page + XPC_ACTIVATE_IRQ_AMOS_SN2;
|
||||||
|
|
||||||
/* scan through act amo variable looking for non-zero entries */
|
/* scan through activate amo variables looking for non-zero entries */
|
||||||
for (word = 0; word < xpc_nasid_mask_words; word++) {
|
for (l = 0; l < xpc_nasid_mask_nlongs; l++) {
|
||||||
|
|
||||||
if (xpc_exiting)
|
if (xpc_exiting)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nasid_mask = xpc_receive_IRQ_amo_sn2(&act_amos[word]);
|
nasid_mask_long = xpc_receive_IRQ_amo_sn2(&act_amos[l]);
|
||||||
if (nasid_mask == 0) {
|
|
||||||
/* no IRQs from nasids in this variable */
|
b = find_first_bit(&nasid_mask_long, BITS_PER_LONG);
|
||||||
|
if (b >= BITS_PER_LONG) {
|
||||||
|
/* no IRQs from nasids in this amo variable */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(xpc_part, "amo[%d] gave back 0x%lx\n", word,
|
dev_dbg(xpc_part, "amo[%d] gave back 0x%lx\n", l,
|
||||||
nasid_mask);
|
nasid_mask_long);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this nasid has been added to the machine since
|
* If this nasid has been added to the machine since
|
||||||
@ -1060,19 +1065,19 @@ xpc_identify_activate_IRQ_sender_sn2(void)
|
|||||||
* remote nasid in our reserved pages machine mask.
|
* remote nasid in our reserved pages machine mask.
|
||||||
* This is used in the event of module reload.
|
* This is used in the event of module reload.
|
||||||
*/
|
*/
|
||||||
xpc_mach_nasids[word] |= nasid_mask;
|
xpc_mach_nasids[l] |= nasid_mask_long;
|
||||||
|
|
||||||
/* locate the nasid(s) which sent interrupts */
|
/* locate the nasid(s) which sent interrupts */
|
||||||
|
|
||||||
for (bit = 0; bit < (8 * sizeof(u64)); bit++) {
|
do {
|
||||||
if (nasid_mask & (1UL << bit)) {
|
n_IRQs_detected++;
|
||||||
n_IRQs_detected++;
|
nasid = (l * BITS_PER_LONG + b) * 2;
|
||||||
nasid = XPC_NASID_FROM_W_B(word, bit);
|
dev_dbg(xpc_part, "interrupt from nasid %ld\n", nasid);
|
||||||
dev_dbg(xpc_part, "interrupt from nasid %ld\n",
|
xpc_identify_activate_IRQ_req_sn2(nasid);
|
||||||
nasid);
|
|
||||||
xpc_identify_activate_IRQ_req_sn2(nasid);
|
b = find_next_bit(&nasid_mask_long, BITS_PER_LONG,
|
||||||
}
|
b + 1);
|
||||||
}
|
} while (b < BITS_PER_LONG);
|
||||||
}
|
}
|
||||||
return n_IRQs_detected;
|
return n_IRQs_detected;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user