diff options
Diffstat (limited to '')
| -rw-r--r-- | drivers/misc/sgi-xp/xpc_main.c (renamed from arch/ia64/sn/kernel/xpc_main.c) | 432 |
1 files changed, 162 insertions, 270 deletions
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index 9e0b164da9c2..f673ba90eb0e 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -3,10 +3,9 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2004-2007 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. */ - /* * Cross Partition Communication (XPC) support - standard version. * @@ -44,23 +43,20 @@ * */ - #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> -#include <linux/sched.h> -#include <linux/syscalls.h> #include <linux/cache.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/reboot.h> #include <linux/completion.h> #include <linux/kdebug.h> +#include <linux/kthread.h> +#include <linux/uaccess.h> #include <asm/sn/intr.h> #include <asm/sn/sn_sal.h> -#include <asm/uaccess.h> -#include <asm/sn/xpc.h> - +#include "xpc.h" /* define two XPC debug device structures to be used with dev_dbg() et al */ @@ -81,10 +77,8 @@ struct device xpc_chan_dbg_subname = { struct device *xpc_part = &xpc_part_dbg_subname; struct device *xpc_chan = &xpc_chan_dbg_subname; - static int xpc_kdebug_ignore; - /* systune related variables for /proc/sys directories */ static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; @@ -96,61 +90,56 @@ static int xpc_hb_check_min_interval = 10; static int xpc_hb_check_max_interval = 120; int xpc_disengage_request_timelimit = XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT; -static int xpc_disengage_request_min_timelimit = 0; +static int xpc_disengage_request_min_timelimit; /* = 0 */ static int xpc_disengage_request_max_timelimit = 120; static ctl_table xpc_sys_xpc_hb_dir[] = { { - .ctl_name = CTL_UNNUMBERED, - .procname = "hb_interval", - .data = &xpc_hb_interval, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .strategy = &sysctl_intvec, - .extra1 = &xpc_hb_min_interval, - .extra2 = &xpc_hb_max_interval - }, + .ctl_name = CTL_UNNUMBERED, + .procname = "hb_interval", + .data = &xpc_hb_interval, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &xpc_hb_min_interval, + .extra2 = &xpc_hb_max_interval}, { - .ctl_name = CTL_UNNUMBERED, - .procname = "hb_check_interval", - .data = &xpc_hb_check_interval, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .strategy = &sysctl_intvec, - .extra1 = &xpc_hb_check_min_interval, - .extra2 = &xpc_hb_check_max_interval - }, + .ctl_name = CTL_UNNUMBERED, + .procname = "hb_check_interval", + .data = &xpc_hb_check_interval, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &xpc_hb_check_min_interval, + .extra2 = &xpc_hb_check_max_interval}, {} }; static ctl_table xpc_sys_xpc_dir[] = { { - .ctl_name = CTL_UNNUMBERED, - .procname = "hb", - .mode = 0555, - .child = xpc_sys_xpc_hb_dir - }, + .ctl_name = CTL_UNNUMBERED, + .procname = "hb", + .mode = 0555, + .child = xpc_sys_xpc_hb_dir}, { - .ctl_name = CTL_UNNUMBERED, - .procname = "disengage_request_timelimit", - .data = &xpc_disengage_request_timelimit, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .strategy = &sysctl_intvec, - .extra1 = &xpc_disengage_request_min_timelimit, - .extra2 = &xpc_disengage_request_max_timelimit - }, + .ctl_name = CTL_UNNUMBERED, + .procname = "disengage_request_timelimit", + .data = &xpc_disengage_request_timelimit, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &xpc_disengage_request_min_timelimit, + .extra2 = &xpc_disengage_request_max_timelimit}, {} }; static ctl_table xpc_sys_dir[] = { { - .ctl_name = CTL_UNNUMBERED, - .procname = "xpc", - .mode = 0555, - .child = xpc_sys_xpc_dir - }, + .ctl_name = CTL_UNNUMBERED, + .procname = "xpc", + .mode = 0555, + .child = xpc_sys_xpc_dir}, {} }; static struct ctl_table_header *xpc_sysctl; @@ -172,13 +161,10 @@ 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 *); static struct notifier_block xpc_reboot_notifier = { .notifier_call = xpc_system_reboot, @@ -189,25 +175,22 @@ static struct notifier_block xpc_die_notifier = { .notifier_call = xpc_system_die, }; - /* * Timer function to enforce the timelimit on the partition disengage request. */ static void 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)); - (void) xpc_partition_disengaged(part); + (void)xpc_partition_disengaged(part); DBUG_ON(part->disengage_request_timeout != 0); DBUG_ON(xpc_partition_engaged(1UL << XPC_PARTID(part)) != 0); } - /* * Notify the heartbeat check thread that an IRQ has been received. */ @@ -219,7 +202,6 @@ xpc_act_IRQ_handler(int irq, void *dev_id) 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 @@ -230,15 +212,13 @@ xpc_hb_beater(unsigned long dummy) { xpc_vars->heartbeat++; - if (time_after_eq(jiffies, xpc_hb_check_timeout)) { + if (time_after_eq(jiffies, xpc_hb_check_timeout)) wake_up_interruptible(&xpc_act_IRQ_wq); - } xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ); add_timer(&xpc_hb_timer); } - /* * This thread is responsible for nearly all of the partition * activation/deactivation. @@ -248,27 +228,23 @@ xpc_hb_checker(void *ignore) { int last_IRQ_count = 0; int new_IRQ_count; - int force_IRQ=0; - + int force_IRQ = 0; /* this thread was marked active by xpc_hb_init() */ - daemonize(XPC_HB_CHECK_THREAD_NAME); - set_cpus_allowed(current, cpumask_of_cpu(XPC_HB_CHECK_CPU)); /* set our heartbeating to other partitions into motion */ xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ); xpc_hb_beater(0); - while (!(volatile int) xpc_exiting) { + while (!xpc_exiting) { dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have " "been received\n", - (int) (xpc_hb_check_timeout - jiffies), + (int)(xpc_hb_check_timeout - jiffies), atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count); - /* checking of remote heartbeats is skewed by IRQ handling */ if (time_after_eq(jiffies, xpc_hb_check_timeout)) { dev_dbg(xpc_part, "checking remote heartbeats\n"); @@ -282,7 +258,6 @@ xpc_hb_checker(void *ignore) force_IRQ = 1; } - /* check for outstanding IRQs */ new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd); if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) { @@ -294,30 +269,30 @@ xpc_hb_checker(void *ignore) 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(); + (void)xpc_identify_act_IRQ_sender(); } last_IRQ_count = new_IRQ_count; xpc_hb_check_timeout = jiffies + - (xpc_hb_check_interval * HZ); + (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) || - time_after_eq(jiffies, xpc_hb_check_timeout) || - (volatile int) xpc_exiting)); + (void)wait_event_interruptible(xpc_act_IRQ_wq, + (last_IRQ_count < + atomic_read(&xpc_act_IRQ_rcvd) + || time_after_eq(jiffies, + xpc_hb_check_timeout) || + xpc_exiting)); } dev_dbg(xpc_part, "heartbeat checker is exiting\n"); - /* mark this thread as having exited */ complete(&xpc_hb_checker_exited); return 0; } - /* * This thread will attempt to discover other partitions to activate * based on info provided by SAL. This new thread is short lived and @@ -326,8 +301,6 @@ xpc_hb_checker(void *ignore) static int xpc_initiate_discovery(void *ignore) { - daemonize(XPC_DISCOVERY_THREAD_NAME); - xpc_discovery(); dev_dbg(xpc_part, "discovery thread is exiting\n"); @@ -337,7 +310,6 @@ xpc_initiate_discovery(void *ignore) return 0; } - /* * Establish first contact with the remote partititon. This involves pulling * the XPC per partition variables from the remote partition and waiting for @@ -348,7 +320,6 @@ xpc_make_first_contact(struct xpc_partition *part) { enum xpc_retval ret; - while ((ret = xpc_pull_remote_vars_part(part)) != xpcSuccess) { if (ret != xpcRetry) { XPC_DEACTIVATE_PARTITION(part, ret); @@ -359,17 +330,15 @@ xpc_make_first_contact(struct xpc_partition *part) "partition %d\n", XPC_PARTID(part)); /* wait a 1/4 of a second or so */ - (void) msleep_interruptible(250); + (void)msleep_interruptible(250); - if (part->act_state == XPC_P_DEACTIVATING) { + if (part->act_state == XPC_P_DEACTIVATING) return part->reason; - } } return xpc_mark_partition_active(part); } - /* * The first kthread assigned to a newly activated partition is the one * created by XPC HB with which it calls xpc_partition_up(). XPC hangs on to @@ -386,12 +355,11 @@ static void xpc_channel_mgr(struct xpc_partition *part) { while (part->act_state != XPC_P_DEACTIVATING || - atomic_read(&part->nchannels_active) > 0 || - !xpc_partition_disengaged(part)) { + atomic_read(&part->nchannels_active) > 0 || + !xpc_partition_disengaged(part)) { xpc_process_channel_activity(part); - /* * Wait until we've been requested to activate kthreads or * all of the channel's message queues have been torn down or @@ -406,21 +374,16 @@ xpc_channel_mgr(struct xpc_partition *part) * wake him up. */ atomic_dec(&part->channel_mgr_requests); - (void) wait_event_interruptible(part->channel_mgr_wq, + (void)wait_event_interruptible(part->channel_mgr_wq, (atomic_read(&part->channel_mgr_requests) > 0 || - (volatile u64) part->local_IPI_amo != 0 || - ((volatile u8) part->act_state == - XPC_P_DEACTIVATING && - atomic_read(&part->nchannels_active) == 0 && - xpc_partition_disengaged(part)))); + part->local_IPI_amo != 0 || + (part->act_state == XPC_P_DEACTIVATING && + atomic_read(&part->nchannels_active) == 0 && + xpc_partition_disengaged(part)))); atomic_set(&part->channel_mgr_requests, 1); - - // >>> Does it need to wakeup periodically as well? In case we - // >>> miscalculated the #of kthreads to wakeup or create? } } - /* * When XPC HB determines that a partition has come up, it will create a new * kthread and that kthread will call this function to attempt to set up the @@ -443,9 +406,8 @@ xpc_partition_up(struct xpc_partition *part) dev_dbg(xpc_chan, "activating partition %d\n", XPC_PARTID(part)); - if (xpc_setup_infrastructure(part) != xpcSuccess) { + if (xpc_setup_infrastructure(part) != xpcSuccess) return; - } /* * The kthread that XPC HB called us with will become the @@ -454,27 +416,22 @@ xpc_partition_up(struct xpc_partition *part) * has been dismantled. */ - (void) xpc_part_ref(part); /* this will always succeed */ + (void)xpc_part_ref(part); /* this will always succeed */ - if (xpc_make_first_contact(part) == xpcSuccess) { + if (xpc_make_first_contact(part) == xpcSuccess) xpc_channel_mgr(part); - } xpc_part_deref(part); xpc_teardown_infrastructure(part); } - static int xpc_activating(void *__partid) { - partid_t partid = (u64) __partid; + partid_t partid = (u64)__partid; struct xpc_partition *part = &xpc_partitions[partid]; unsigned long irq_flags; - struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; - int ret; - DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); @@ -496,21 +453,6 @@ xpc_activating(void *__partid) dev_dbg(xpc_part, "bringing partition %d up\n", partid); - daemonize("xpc%02d", partid); - - /* - * This thread needs to run at a realtime priority to prevent a - * significant performance degradation. - */ - ret = sched_setscheduler(current, SCHED_FIFO, ¶m); - if (ret != 0) { - dev_warn(xpc_part, "unable to set pid %d to a realtime " - "priority, ret=%d\n", current->pid, ret); - } - - /* allow this thread and its children to run on any CPU */ - set_cpus_allowed(current, CPU_MASK_ALL); - /* * Register the remote partition's AMOs with SAL so it can handle * and cleanup errors within that address range should the remote @@ -522,9 +464,9 @@ xpc_activating(void *__partid) * reloads and system reboots. */ if (sn_register_xp_addr_region(part->remote_amos_page_pa, - PAGE_SIZE, 1) < 0) { + PAGE_SIZE, 1) < 0) { dev_warn(xpc_part, "xpc_partition_up(%d) failed to register " - "xp_addr region\n", partid); + "xp_addr region\n", partid); spin_lock_irqsave(&part->act_lock, irq_flags); part->act_state = XPC_P_INACTIVE; @@ -537,12 +479,11 @@ xpc_activating(void *__partid) xpc_allow_hb(partid, xpc_vars); xpc_IPI_send_activated(part); - /* * xpc_partition_up() holds this thread and marks this partition as * XPC_P_ACTIVE by calling xpc_hb_mark_active(). */ - (void) xpc_partition_up(part); + (void)xpc_partition_up(part); xpc_disallow_hb(partid, xpc_vars); xpc_mark_partition_inactive(part); @@ -555,14 +496,12 @@ xpc_activating(void *__partid) return 0; } - void xpc_activate_partition(struct xpc_partition *part) { partid_t partid = XPC_PARTID(part); unsigned long irq_flags; - pid_t pid; - + struct task_struct *kthread; spin_lock_irqsave(&part->act_lock, irq_flags); @@ -573,9 +512,9 @@ xpc_activate_partition(struct xpc_partition *part) spin_unlock_irqrestore(&part->act_lock, irq_flags); - pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0); - - if (unlikely(pid <= 0)) { + kthread = kthread_run(xpc_activating, (void *)((u64)partid), "xpc%02d", + partid); + if (IS_ERR(kthread)) { spin_lock_irqsave(&part->act_lock, irq_flags); part->act_state = XPC_P_INACTIVE; XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__); @@ -583,12 +522,11 @@ xpc_activate_partition(struct xpc_partition *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 * than one partition, we use an AMO_t structure per partition to indicate - * whether a partition has sent an IPI or not. >>> If it has, then wake up the + * whether a partition has sent an IPI or not. If it has, then wake up the * associated kthread to handle it. * * All SGI_XPC_NOTIFY IRQs received by XPC are the result of IPIs sent by XPC @@ -603,10 +541,9 @@ xpc_activate_partition(struct xpc_partition *part) irqreturn_t xpc_notify_IRQ_handler(int irq, void *dev_id) { - partid_t partid = (partid_t) (u64) dev_id; + partid_t partid = (partid_t) (u64)dev_id; struct xpc_partition *part = &xpc_partitions[partid]; - DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); if (xpc_part_ref(part)) { @@ -617,7 +554,6 @@ xpc_notify_IRQ_handler(int irq, void *dev_id) return IRQ_HANDLED; } - /* * Check to see if xpc_notify_IRQ_handler() dropped any IPIs on the floor * because the write to their associated IPI amo completed after the IRQ/IPI @@ -630,13 +566,12 @@ xpc_dropped_IPI_check(struct xpc_partition *part) xpc_check_for_channel_activity(part); part->dropped_IPI_timer.expires = jiffies + - XPC_P_DROPPED_IPI_WAIT; + XPC_P_DROPPED_IPI_WAIT; add_timer(&part->dropped_IPI_timer); xpc_part_deref(part); } } - void xpc_activate_kthreads(struct xpc_channel *ch, int needed) { @@ -644,7 +579,6 @@ xpc_activate_kthreads(struct xpc_channel *ch, int needed) int assigned = atomic_read(&ch->kthreads_assigned); int wakeup; - DBUG_ON(needed <= 0); if (idle > 0) { @@ -658,16 +592,13 @@ xpc_activate_kthreads(struct xpc_channel *ch, int needed) wake_up_nr(&ch->idle_wq, wakeup); } - if (needed <= 0) { + if (needed <= 0) return; - } if (needed + assigned > ch->kthreads_assigned_limit) { needed = ch->kthreads_assigned_limit - assigned; - // >>>should never be less than 0 - if (needed <= 0) { + if (needed <= 0) return; - } } dev_dbg(xpc_chan, "create %d new kthreads, partid=%d, channel=%d\n", @@ -676,7 +607,6 @@ xpc_activate_kthreads(struct xpc_channel *ch, int needed) xpc_create_kthreads(ch, needed, 0); } - /* * This function is where XPC's kthreads wait for messages to deliver. */ @@ -686,15 +616,13 @@ xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch) do { /* deliver messages to their intended recipients */ - while ((volatile s64) ch->w_local_GP.get < - (volatile s64) ch->w_remote_GP.put && - !((volatile u32) ch->flags & - XPC_C_DISCONNECTING)) { + while (ch->w_local_GP.get < ch->w_remote_GP.put && + !(ch->flags & XPC_C_DISCONNECTING)) { xpc_deliver_msg(ch); } if (atomic_inc_return(&ch->kthreads_idle) > - ch->kthreads_idle_limit) { + ch->kthreads_idle_limit) { /* too many idle kthreads on this channel */ atomic_dec(&ch->kthreads_idle); break; @@ -703,20 +631,17 @@ xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch) dev_dbg(xpc_chan, "idle kthread calling " "wait_event_interruptible_exclusive()\n"); - (void) wait_event_interruptible_exclusive(ch->idle_wq, - ((volatile s64) ch->w_local_GP.get < - (volatile s64) ch->w_remote_GP.put || - ((volatile u32) ch->flags & - XPC_C_DISCONNECTING))); + (void)wait_event_interruptible_exclusive(ch->idle_wq, + (ch->w_local_GP.get < ch->w_remote_GP.put || + (ch->flags & XPC_C_DISCONNECTING))); atomic_dec(&ch->kthreads_idle); - } while (!((volatile u32) ch->flags & XPC_C_DISCONNECTING)); + } while (!(ch->flags & XPC_C_DISCONNECTING)); } - static int -xpc_daemonize_kthread(void *args) +xpc_kthread_start(void *args) { partid_t partid = XPC_UNPACK_ARG1(args); u16 ch_number = XPC_UNPACK_ARG2(args); @@ -725,9 +650,6 @@ xpc_daemonize_kthread(void *args) int n_needed; unsigned long irq_flags; - - daemonize("xpc%02dc%d", partid, ch_number); - dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n", partid, ch_number); @@ -756,10 +678,9 @@ xpc_daemonize_kthread(void *args) * need one less than total #of messages to deliver. */ n_needed = ch->w_remote_GP.put - ch->w_local_GP.get - 1; - if (n_needed > 0 && - !(ch->flags & XPC_C_DISCONNECTING)) { + if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING)) xpc_activate_kthreads(ch, n_needed); - } + } else { spin_unlock_irqrestore(&ch->lock, irq_flags); } @@ -771,7 +692,7 @@ xpc_daemonize_kthread(void *args) spin_lock_irqsave(&ch->lock, irq_flags); if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) && - !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) { + !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) { ch->flags |= XPC_C_DISCONNECTINGCALLOUT; spin_unlock_irqrestore(&ch->lock, irq_flags); @@ -798,7 +719,6 @@ xpc_daemonize_kthread(void *args) return 0; } - /* * For each partition that XPC has established communications with, there is * a minimum of one kernel thread assigned to perform any operation that @@ -813,13 +733,12 @@ xpc_daemonize_kthread(void *args) */ void xpc_create_kthreads(struct xpc_channel *ch, int needed, - int ignore_disconnecting) + int ignore_disconnecting) { unsigned long irq_flags; - pid_t pid; u64 args = XPC_PACK_ARGS(ch->partid, ch->number); struct xpc_partition *part = &xpc_partitions[ch->partid]; - + struct task_struct *kthread; while (needed-- > 0) { @@ -832,7 +751,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, if (!atomic_inc_not_zero(&ch->kthreads_assigned)) { /* kthreads assigned had gone to zero */ BUG_ON(!(ch->flags & - XPC_C_DISCONNECTINGCALLOUT_MADE)); + XPC_C_DISCONNECTINGCALLOUT_MADE)); break; } @@ -843,11 +762,12 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, if (atomic_inc_return(&part->nchannels_engaged) == 1) xpc_mark_partition_engaged(part); } - (void) xpc_part_ref(part); + (void)xpc_part_ref(part); xpc_msgqueue_ref(ch); - pid = kernel_thread(xpc_daemonize_kthread, (void *) args, 0); - if (pid < 0) { + kthread = kthread_run(xpc_kthread_start, (void *)args, + "xpc%02dc%d", ch->partid, ch->number); + if (IS_ERR(kthread)) { /* the fork failed */ /* @@ -857,7 +777,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, * to this channel are blocked in the channel's * registerer, because the only thing that will unblock * them is the xpcDisconnecting callout that this - * failed kernel_thread would have made. + * failed kthread_run() would have made. */ if (atomic_dec_return(&ch->kthreads_assigned) == 0 && @@ -869,7 +789,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, xpc_part_deref(part); if (atomic_read(&ch->kthreads_assigned) < - ch->kthreads_idle_limit) { + ch->kthreads_idle_limit) { /* * Flag this as an error only if we have an * insufficient #of kthreads for the channel @@ -877,17 +797,14 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, */ spin_lock_irqsave(&ch->lock, irq_flags); XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources, - &irq_flags); + &irq_flags); spin_unlock_irqrestore(&ch->lock, irq_flags); } break; } - - ch->kthreads_created++; // >>> temporary debug only!!! } } - void xpc_disconnect_wait(int ch_number) { @@ -897,14 +814,12 @@ xpc_disconnect_wait(int ch_number) struct xpc_channel *ch; int wakeup_channel_mgr; - /* now wait for all callouts to the caller's function to cease */ for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { part = &xpc_partitions[partid]; - if (!xpc_part_ref(part)) { + if (!xpc_part_ref(part)) continue; - } ch = &part->channels[ch_number]; @@ -923,7 +838,8 @@ xpc_disconnect_wait(int ch_number) if (part->act_state != XPC_P_DEACTIVATING) { spin_lock(&part->IPI_lock); XPC_SET_IPI_FLAGS(part->local_IPI_amo, - ch->number, ch->delayed_IPI_flags); + ch->number, + ch->delayed_IPI_flags); spin_unlock(&part->IPI_lock); wakeup_channel_mgr = 1; } @@ -933,15 +849,13 @@ xpc_disconnect_wait(int ch_number) ch->flags &= ~XPC_C_WDISCONNECT; spin_unlock_irqrestore(&ch->lock, irq_flags); - if (wakeup_channel_mgr) { + if (wakeup_channel_mgr) xpc_wakeup_channel_mgr(part); - } xpc_part_deref(part); } } - static void xpc_do_exit(enum xpc_retval reason) { @@ -950,7 +864,6 @@ xpc_do_exit(enum xpc_retval reason) struct xpc_partition *part; unsigned long printmsg_time, disengage_request_timeout = 0; - /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */ DBUG_ON(xpc_exiting == 1); @@ -971,10 +884,8 @@ xpc_do_exit(enum xpc_retval reason) /* wait for the heartbeat checker thread to exit */ wait_for_completion(&xpc_hb_checker_exited); - /* sleep for a 1/3 of a second or so */ - (void) msleep_interruptible(300); - + (void)msleep_interruptible(300); /* wait for all partitions to become inactive */ @@ -988,7 +899,7 @@ xpc_do_exit(enum xpc_retval reason) part = &xpc_partitions[partid]; if (xpc_partition_disengaged(part) && - part->act_state == XPC_P_INACTIVE) { + part->act_state == XPC_P_INACTIVE) { continue; } @@ -997,47 +908,46 @@ xpc_do_exit(enum xpc_retval reason) XPC_DEACTIVATE_PARTITION(part, reason); if (part->disengage_request_timeout > - disengage_request_timeout) { + disengage_request_timeout) { disengage_request_timeout = - part->disengage_request_timeout; + part->disengage_request_timeout; } } if (xpc_partition_engaged(-1UL)) { if (time_after(jiffies, printmsg_time)) { dev_info(xpc_part, "waiting for remote " - "partitions to disengage, timeout in " - "%ld seconds\n", - (disengage_request_timeout - jiffies) - / HZ); + "partitions to disengage, timeout in " + "%ld seconds\n", + (disengage_request_timeout - jiffies) + / HZ); printmsg_time = jiffies + - (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); + (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); printed_waiting_msg = 1; } } else if (active_part_count > 0) { if (printed_waiting_msg) { dev_info(xpc_part, "waiting for local partition" - " to disengage\n"); + " to disengage\n"); printed_waiting_msg = 0; } } else { if (!xpc_disengage_request_timedout) { dev_info(xpc_part, "all partitions have " - "disengaged\n"); + "disengaged\n"); } break; } /* sleep for a 1/3 of a second or so */ - (void) msleep_interruptible(300); + (void)msleep_interruptible(300); } while (1); DBUG_ON(xpc_partition_engaged(-1UL)); - /* indicate to others that our reserved page is uninitialized */ xpc_rsvd_page->vars_pa = 0; @@ -1047,27 +957,24 @@ xpc_do_exit(enum xpc_retval reason) if (reason == xpcUnloading) { /* take ourselves off of the reboot_notifier_list */ - (void) unregister_reboot_notifier(&xpc_reboot_notifier); + (void)unregister_reboot_notifier(&xpc_reboot_notifier); /* take ourselves off of the die_notifier list */ - (void) unregister_die_notifier(&xpc_die_notifier); + (void)unregister_die_notifier(&xpc_die_notifier); } /* close down protections for IPI operations */ xpc_restrict_IPI_ops(); - /* clear the interface to XPC's functions */ xpc_clear_interface(); - if (xpc_sysctl) { + if (xpc_sysctl) unregister_sysctl_table(xpc_sysctl); - } kfree(xpc_remote_copy_buffer_base); } - /* * This function is called when the system is being rebooted. */ @@ -1076,7 +983,6 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) { enum xpc_retval reason; - switch (event) { case SYS_RESTART: reason = xpcSystemReboot; @@ -1095,7 +1001,6 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) return NOTIFY_DONE; } - /* * Notify other partitions to disengage from all references to our memory. */ @@ -1107,17 +1012,16 @@ xpc_die_disengage(void) unsigned long engaged; long time, printmsg_time, disengage_request_timeout; - /* 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_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */ for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { part = &xpc_partitions[partid]; if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part-> - remote_vars_version)) { + remote_vars_version)) { /* just in case it was left set by an earlier XPC */ xpc_clear_partition_engaged(1UL << partid); @@ -1125,7 +1029,7 @@ xpc_die_disengage(void) } if (xpc_partition_engaged(1UL << partid) || - part->act_state != XPC_P_INACTIVE) { + part->act_state != XPC_P_INACTIVE) { xpc_request_partition_disengage(part); xpc_mark_partition_disengaged(part); xpc_IPI_send_disengage(part); @@ -1134,9 +1038,9 @@ xpc_die_disengage(void) time = rtc_time(); printmsg_time = time + - (XPC_DISENGAGE_PRINTMSG_INTERVAL * sn_rtc_cycles_per_second); + (XPC_DISENGAGE_PRINTMSG_INTERVAL * sn_rtc_cycles_per_second); disengage_request_timeout = time + - (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); + (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); /* wait for all other partitions to disengage from us */ @@ -1152,8 +1056,8 @@ xpc_die_disengage(void) for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { if (engaged & (1UL << partid)) { dev_info(xpc_part, "disengage from " - "remote partition %d timed " - "out\n", partid); + "remote partition %d timed " + "out\n", partid); } } break; @@ -1161,17 +1065,16 @@ xpc_die_disengage(void) if (time >= printmsg_time) { dev_info(xpc_part, "waiting for remote partitions to " - "disengage, timeout in %ld seconds\n", - (disengage_request_timeout - time) / - sn_rtc_cycles_per_second); + "disengage, timeout in %ld seconds\n", + (disengage_request_timeout - time) / + sn_rtc_cycles_per_second); printmsg_time = time + - (XPC_DISENGAGE_PRINTMSG_INTERVAL * - sn_rtc_cycles_per_second); + (XPC_DISENGAGE_PRINTMSG_INTERVAL * + sn_rtc_cycles_per_second); } } } - /* * This function is called when the system is being restarted or halted due * to some sort of system failure. If this is the case we need to notify the @@ -1191,9 +1094,9 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) case DIE_KDEBUG_ENTER: /* Should lack of heartbeat be ignored by other partitions? */ - if (!xpc_kdebug_ignore) { + if (!xpc_kdebug_ignore) break; - } + /* fall through */ case DIE_MCA_MONARCH_ENTER: case DIE_INIT_MONARCH_ENTER: @@ -1203,9 +1106,9 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) case DIE_KDEBUG_LEAVE: /* Is lack of heartbeat being ignored by other partitions? */ - if (!xpc_kdebug_ignore) { + if (!xpc_kdebug_ignore) break; - } + /* fall through */ case DIE_MCA_MONARCH_LEAVE: case DIE_INIT_MONARCH_LEAVE: @@ -1217,26 +1120,23 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) return NOTIFY_DONE; } - int __init xpc_init(void) { int ret; partid_t partid; struct xpc_partition *part; - pid_t pid; + struct task_struct *kthread; size_t buf_size; - - if (!ia64_platform_is("sn2")) { + if (!ia64_platform_is("sn2")) return -ENODEV; - } - buf_size = max(XPC_RP_VARS_SIZE, - XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES); + XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES); xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size, - GFP_KERNEL, &xpc_remote_copy_buffer_base); + GFP_KERNEL, + &xpc_remote_copy_buffer_base); if (xpc_remote_copy_buffer == NULL) return -ENOMEM; @@ -1256,7 +1156,7 @@ xpc_init(void) for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { part = &xpc_partitions[partid]; - DBUG_ON((u64) part != L1_CACHE_ALIGN((u64) part)); + DBUG_ON((u64)part != L1_CACHE_ALIGN((u64)part)); part->act_IRQ_rcvd = 0; spin_lock_init(&part->act_lock); @@ -1265,8 +1165,8 @@ xpc_init(void) init_timer(&part->disengage_request_timer); part->disengage_request_timer.function = - xpc_timeout_partition_disengage_request; - part->disengage_request_timer.data = (unsigned long) part; + xpc_timeout_partition_disengage_request; + part->disengage_request_timer.data = (unsigned long)part; part->setup_state = XPC_P_UNSET; init_waitqueue_head(&part->teardown_wq); @@ -1292,16 +1192,15 @@ xpc_init(void) * but rather immediately process the interrupt. */ ret = request_irq(SGI_XPC_ACTIVATE, xpc_act_IRQ_handler, 0, - "xpc hb", NULL); + "xpc hb", NULL); if (ret != 0) { dev_err(xpc_part, "can't register ACTIVATE IRQ handler, " "errno=%d\n", -ret); xpc_restrict_IPI_ops(); - if (xpc_sysctl) { + if (xpc_sysctl) unregister_sysctl_table(xpc_sysctl); - } kfree(xpc_remote_copy_buffer_base); return -EBUSY; @@ -1319,26 +1218,22 @@ xpc_init(void) free_irq(SGI_XPC_ACTIVATE, NULL); xpc_restrict_IPI_ops(); - if (xpc_sysctl) { + if (xpc_sysctl) unregister_sysctl_table(xpc_sysctl); - } kfree(xpc_remote_copy_buffer_base); return -EBUSY; } - /* add ourselves to the reboot_notifier_list */ ret = register_reboot_notifier(&xpc_reboot_notifier); - if (ret != 0) { + if (ret != 0) dev_warn(xpc_part, "can't register reboot notifier\n"); - } /* add ourselves to the die_notifier list */ ret = register_die_notifier(&xpc_die_notifier); - if (ret != 0) { + 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; @@ -1347,39 +1242,38 @@ xpc_init(void) * The real work-horse behind xpc. This processes incoming * interrupts and monitors remote heartbeats. */ - pid = kernel_thread(xpc_hb_checker, NULL, 0); - if (pid < 0) { + kthread = kthread_run(xpc_hb_checker, NULL, XPC_HB_CHECK_THREAD_NAME); + if (IS_ERR(kthread)) { dev_err(xpc_part, "failed while forking hb check thread\n"); /* indicate to others that our reserved page is uninitialized */ xpc_rsvd_page->vars_pa = 0; /* take ourselves off of the reboot_notifier_list */ - (void) unregister_reboot_notifier(&xpc_reboot_notifier); + (void)unregister_reboot_notifier(&xpc_reboot_notifier); /* take ourselves off of the die_notifier list */ - (void) unregister_die_notifier(&xpc_die_notifier); + (void)unregister_die_notifier(&xpc_die_notifier); del_timer_sync(&xpc_hb_timer); free_irq(SGI_XPC_ACTIVATE, NULL); xpc_restrict_IPI_ops(); - if (xpc_sysctl) { + if (xpc_sysctl) unregister_sysctl_table(xpc_sysctl); - } kfree(xpc_remote_copy_buffer_base); return -EBUSY; } - /* * Startup a thread that will attempt to discover other partitions to * activate based on info provided by SAL. This new thread is short * lived and will exit once discovery is complete. */ - pid = kernel_thread(xpc_initiate_discovery, NULL, 0); - if (pid < 0) { + kthread = kthread_run(xpc_initiate_discovery, NULL, + XPC_DISCOVERY_THREAD_NAME); + if (IS_ERR(kthread)) { dev_err(xpc_part, "failed while forking discovery thread\n"); /* mark this new thread as a non-starter */ @@ -1389,7 +1283,6 @@ xpc_init(void) return -EBUSY; } - /* set the interface to point at XPC's functions */ xpc_set_interface(xpc_initiate_connect, xpc_initiate_disconnect, xpc_initiate_allocate, xpc_initiate_send, @@ -1398,16 +1291,16 @@ xpc_init(void) return 0; } -module_init(xpc_init); +module_init(xpc_init); void __exit xpc_exit(void) { xpc_do_exit(xpcUnloading); } -module_exit(xpc_exit); +module_exit(xpc_exit); MODULE_AUTHOR("Silicon Graphics, Inc."); MODULE_DESCRIPTION("Cross Partition Communication (XPC) support"); @@ -1415,17 +1308,16 @@ MODULE_LICENSE("GPL"); module_param(xpc_hb_interval, int, 0); MODULE_PARM_DESC(xpc_hb_interval, "Number of seconds between " - "heartbeat increments."); + "heartbeat increments."); module_param(xpc_hb_check_interval, int, 0); MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between " - "heartbeat checks."); + "heartbeat checks."); module_param(xpc_disengage_request_timelimit, int, 0); MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait " - "for disengage request to complete."); + "for disengage request to complete."); module_param(xpc_kdebug_ignore, int, 0); MODULE_PARM_DESC(xpc_kdebug_ignore, "Should lack of heartbeat be ignored by " - "other partitions when dropping into kdebug."); - + "other partitions when dropping into kdebug."); |
