Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 107059
b: refs/heads/master
c: 6e41017
h: refs/heads/master
i:
  107057: 813589d
  107055: 4a0d431
v: v3
  • Loading branch information
Dean Nelson authored and Linus Torvalds committed Jul 30, 2008
1 parent f73fdde commit 007639a
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 220 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 97bf1aa1e1bb18de9bb1987c6eb9ad751bf08aab
refs/heads/master: 6e41017aad9ed175ca51e4828eabc8c5cf5910be
14 changes: 8 additions & 6 deletions trunk/drivers/misc/sgi-xp/xpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ struct xpc_partition {
u64 remote_amos_page_pa; /* phys addr of partition's amos page */
int remote_act_nasid; /* active part's act/deact nasid */
int remote_act_phys_cpuid; /* active part's act/deact phys cpuid */
u32 act_IRQ_rcvd; /* IRQs since activation */
u32 activate_IRQ_rcvd; /* IRQs since activation */
spinlock_t act_lock; /* protect updating of act_state */
u8 act_state; /* from XPC HB viewpoint */
u8 remote_vars_version; /* version# of partition's vars */
Expand Down Expand Up @@ -580,8 +580,8 @@ extern struct device *xpc_part;
extern struct device *xpc_chan;
extern int xpc_disengage_request_timelimit;
extern int xpc_disengage_request_timedout;
extern atomic_t xpc_act_IRQ_rcvd;
extern wait_queue_head_t xpc_act_IRQ_wq;
extern atomic_t xpc_activate_IRQ_rcvd;
extern wait_queue_head_t xpc_activate_IRQ_wq;
extern void *xpc_heartbeating_to_mask;
extern irqreturn_t xpc_notify_IRQ_handler(int, void *);
extern void xpc_dropped_IPI_check(struct xpc_partition *);
Expand All @@ -601,7 +601,7 @@ extern u64 (*xpc_get_IPI_flags) (struct xpc_partition *);
extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *);
extern void (*xpc_initiate_partition_activation) (struct xpc_rsvd_page *, u64,
int);
extern void (*xpc_process_act_IRQ_rcvd) (int);
extern void (*xpc_process_activate_IRQ_rcvd) (int);
extern enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *);
extern void (*xpc_teardown_infrastructure) (struct xpc_partition *);
extern void (*xpc_mark_partition_engaged) (struct xpc_partition *);
Expand Down Expand Up @@ -629,10 +629,12 @@ extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, u32, void *, u16,
extern void (*xpc_received_msg) (struct xpc_channel *, struct xpc_msg *);

/* found in xpc_sn2.c */
extern void xpc_init_sn2(void);
extern int xpc_init_sn2(void);
extern void xpc_exit_sn2(void);

/* found in xpc_uv.c */
extern void xpc_init_uv(void);
extern void xpc_exit_uv(void);

/* found in xpc_partition.c */
extern int xpc_exiting;
Expand All @@ -646,7 +648,7 @@ extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void);
extern void xpc_allow_IPI_ops(void);
extern void xpc_restrict_IPI_ops(void);
extern int xpc_identify_act_IRQ_sender(void);
extern int xpc_identify_activate_IRQ_sender(void);
extern int xpc_partition_disengaged(struct xpc_partition *);
extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
extern void xpc_mark_partition_inactive(struct xpc_partition *);
Expand Down
96 changes: 31 additions & 65 deletions trunk/drivers/misc/sgi-xp/xpc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ static struct ctl_table_header *xpc_sysctl;
/* non-zero if any remote partition disengage request was timed out */
int xpc_disengage_request_timedout;

/* #of IRQs received */
atomic_t xpc_act_IRQ_rcvd;
/* #of activate IRQs received */
atomic_t xpc_activate_IRQ_rcvd = ATOMIC_INIT(0);

/* IRQ handler notifies this wait queue on receipt of an IRQ */
DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
DECLARE_WAIT_QUEUE_HEAD(xpc_activate_IRQ_wq);

static unsigned long xpc_hb_check_timeout;
static struct timer_list xpc_hb_timer;
Expand Down Expand Up @@ -190,7 +190,7 @@ 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);
void (*xpc_process_activate_IRQ_rcvd) (int n_IRQs_expected);
enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *part);
void (*xpc_teardown_infrastructure) (struct xpc_partition *part);

Expand Down Expand Up @@ -238,17 +238,6 @@ xpc_timeout_partition_disengage_request(unsigned long data)
DBUG_ON(xpc_partition_engaged(1UL << XPC_PARTID(part)) != 0);
}

/*
* Notify the heartbeat check thread that an IRQ has been received.
*/
static irqreturn_t
xpc_act_IRQ_handler(int irq, void *dev_id)
{
atomic_inc(&xpc_act_IRQ_rcvd);
wake_up_interruptible(&xpc_act_IRQ_wq);
return IRQ_HANDLED;
}

/*
* Timer to produce the heartbeat. The timer structures function is
* already set when this is initially called. A tunable is used to
Expand All @@ -260,7 +249,7 @@ xpc_hb_beater(unsigned long dummy)
xpc_increment_heartbeat();

if (time_is_before_eq_jiffies(xpc_hb_check_timeout))
wake_up_interruptible(&xpc_act_IRQ_wq);
wake_up_interruptible(&xpc_activate_IRQ_wq);

xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ);
add_timer(&xpc_hb_timer);
Expand Down Expand Up @@ -306,7 +295,7 @@ xpc_hb_checker(void *ignore)
dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have "
"been received\n",
(int)(xpc_hb_check_timeout - jiffies),
atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count);
atomic_read(&xpc_activate_IRQ_rcvd) - last_IRQ_count);

/* checking of remote heartbeats is skewed by IRQ handling */
if (time_is_before_eq_jiffies(xpc_hb_check_timeout)) {
Expand All @@ -322,25 +311,25 @@ xpc_hb_checker(void *ignore)
}

/* check for outstanding IRQs */
new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd);
new_IRQ_count = atomic_read(&xpc_activate_IRQ_rcvd);
if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) {
force_IRQ = 0;

dev_dbg(xpc_part, "found an IRQ to process; will be "
"resetting xpc_hb_check_timeout\n");

xpc_process_act_IRQ_rcvd(new_IRQ_count -
last_IRQ_count);
xpc_process_activate_IRQ_rcvd(new_IRQ_count -
last_IRQ_count);
last_IRQ_count = new_IRQ_count;

xpc_hb_check_timeout = jiffies +
(xpc_hb_check_interval * HZ);
}

/* wait for IRQ or timeout */
(void)wait_event_interruptible(xpc_act_IRQ_wq,
(last_IRQ_count <
atomic_read(&xpc_act_IRQ_rcvd)
(void)wait_event_interruptible(xpc_activate_IRQ_wq,
(last_IRQ_count < atomic_read(
&xpc_activate_IRQ_rcvd)
|| time_is_before_eq_jiffies(
xpc_hb_check_timeout) ||
xpc_exiting));
Expand Down Expand Up @@ -884,10 +873,7 @@ xpc_do_exit(enum xp_retval reason)
* the heartbeat checker thread in case it's sleeping.
*/
xpc_exiting = 1;
wake_up_interruptible(&xpc_act_IRQ_wq);

/* ignore all incoming interrupts */
free_irq(SGI_XPC_ACTIVATE, NULL);
wake_up_interruptible(&xpc_activate_IRQ_wq);

/* wait for the discovery thread to exit */
wait_for_completion(&xpc_discovery_exited);
Expand Down Expand Up @@ -968,9 +954,6 @@ xpc_do_exit(enum xp_retval reason)
(void)unregister_reboot_notifier(&xpc_reboot_notifier);
}

/* close down protections for IPI operations */
xpc_restrict_IPI_ops();

/* clear the interface to XPC's functions */
xpc_clear_interface();

Expand All @@ -979,6 +962,11 @@ xpc_do_exit(enum xp_retval reason)

kfree(xpc_partitions);
kfree(xpc_remote_copy_buffer_base);

if (is_shub())
xpc_exit_sn2();
else
xpc_exit_uv();
}

/*
Expand Down Expand Up @@ -1144,7 +1132,9 @@ xpc_init(void)
if (xp_max_npartitions != 64)
return -EINVAL;

xpc_init_sn2();
ret = xpc_init_sn2();
if (ret != 0)
return ret;

} else if (is_uv()) {
xpc_init_uv();
Expand All @@ -1163,15 +1153,16 @@ xpc_init(void)
&xpc_remote_copy_buffer_base);
if (xpc_remote_copy_buffer == NULL) {
dev_err(xpc_part, "can't get memory for remote copy buffer\n");
return -ENOMEM;
ret = -ENOMEM;
goto out_1;
}

xpc_partitions = kzalloc(sizeof(struct xpc_partition) *
xp_max_npartitions, GFP_KERNEL);
if (xpc_partitions == NULL) {
dev_err(xpc_part, "can't get memory for partition structure\n");
ret = -ENOMEM;
goto out_1;
goto out_2;
}

/*
Expand All @@ -1187,7 +1178,7 @@ xpc_init(void)

DBUG_ON((u64)part != L1_CACHE_ALIGN((u64)part));

part->act_IRQ_rcvd = 0;
part->activate_IRQ_rcvd = 0;
spin_lock_init(&part->act_lock);
part->act_state = XPC_P_INACTIVE;
XPC_SET_REASON(part, 0, 0);
Expand All @@ -1204,33 +1195,6 @@ xpc_init(void)

xpc_sysctl = register_sysctl_table(xpc_sys_dir);

/*
* Open up protections for IPI operations (and AMO operations on
* Shub 1.1 systems).
*/
xpc_allow_IPI_ops();

/*
* Interrupts being processed will increment this atomic variable and
* awaken the heartbeat thread which will process the interrupts.
*/
atomic_set(&xpc_act_IRQ_rcvd, 0);

/*
* This is safe to do before the xpc_hb_checker thread has started
* because the handler releases a wait queue. If an interrupt is
* received before the thread is waiting, it will not go to sleep,
* but rather immediately process the interrupt.
*/
ret = request_irq(SGI_XPC_ACTIVATE, xpc_act_IRQ_handler, 0,
"xpc hb", NULL);
if (ret != 0) {
dev_err(xpc_part, "can't register ACTIVATE IRQ handler, "
"errno=%d\n", -ret);
ret = -EBUSY;
goto out_2;
}

/*
* Fill the partition reserved page with the information needed by
* other partitions to discover we are alive and establish initial
Expand Down Expand Up @@ -1296,14 +1260,16 @@ xpc_init(void)
(void)unregister_die_notifier(&xpc_die_notifier);
(void)unregister_reboot_notifier(&xpc_reboot_notifier);
out_3:
free_irq(SGI_XPC_ACTIVATE, NULL);
out_2:
xpc_restrict_IPI_ops();
if (xpc_sysctl)
unregister_sysctl_table(xpc_sysctl);
kfree(xpc_partitions);
out_1:
out_2:
kfree(xpc_remote_copy_buffer_base);
out_1:
if (is_shub())
xpc_exit_sn2();
else
xpc_exit_uv();
return ret;
}

Expand Down
Loading

0 comments on commit 007639a

Please sign in to comment.