Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/*
 * This thread is responsible for nearly all of the partition
 * activation/deactivation.
 */
static int
xpc_hb_checker(void *ignore)
{
    int last_IRQ_count = 0;
    int new_IRQ_count;
    int force_IRQ = 0;

    /* this thread was marked active by xpc_hb_init() */

    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 (!xpc_exiting) {

        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);

        /* 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");
            xpc_check_remote_hb();

            /*
             * We need to periodically recheck to ensure no
             * IPI/AMO pairs have been missed.  That check
             * must always reset xpc_hb_check_timeout.
             */
            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) {
            force_IRQ = 0;

            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();
            }
            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)
                                        || 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;
}