cregit-Linux how code gets into the kernel

Release 4.11 arch/x86/xen/smp.c

Directory: arch/x86/xen
/*
 * Xen SMP support
 *
 * This file implements the Xen versions of smp_ops.  SMP under Xen is
 * very straightforward.  Bringing a CPU up is simply a matter of
 * loading its initial context and setting it running.
 *
 * IPIs are handled through the Xen event mechanism.
 *
 * Because virtual CPUs can be scheduled onto any real CPU, there's no
 * useful topology information for the kernel to make use of.  As a
 * result, all CPUs are treated as if they're single-core and
 * single-threaded.
 */
#include <linux/sched.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/irq_work.h>
#include <linux/tick.h>
#include <linux/nmi.h>

#include <asm/paravirt.h>
#include <asm/desc.h>
#include <asm/pgtable.h>
#include <asm/cpu.h>

#include <xen/interface/xen.h>
#include <xen/interface/vcpu.h>
#include <xen/interface/xenpmu.h>

#include <asm/xen/interface.h>
#include <asm/xen/hypercall.h>

#include <xen/xen.h>
#include <xen/page.h>
#include <xen/events.h>

#include <xen/hvc-console.h>
#include "xen-ops.h"
#include "mmu.h"
#include "smp.h"
#include "pmu.h"


cpumask_var_t xen_cpu_initialized_map;


struct xen_common_irq {
	
int irq;
	
char *name;
};
static DEFINE_PER_CPU(struct xen_common_irq, xen_resched_irq) = { .irq = -1 };
static DEFINE_PER_CPU(struct xen_common_irq, xen_callfunc_irq) = { .irq = -1 };
static DEFINE_PER_CPU(struct xen_common_irq, xen_callfuncsingle_irq) = { .irq = -1 };
static DEFINE_PER_CPU(struct xen_common_irq, xen_irq_work) = { .irq = -1 };
static DEFINE_PER_CPU(struct xen_common_irq, xen_debug_irq) = { .irq = -1 };
static DEFINE_PER_CPU(struct xen_common_irq, xen_pmu_irq) = { .irq = -1 };

static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id);
static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id);
static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id);

/*
 * Reschedule call back.
 */

static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) { inc_irq_stat(irq_resched_count); scheduler_ipi(); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge2083.33%250.00%
Peter Zijlstra312.50%125.00%
Brian Gerst14.17%125.00%
Total24100.00%4100.00%


static void cpu_bringup(void) { int cpu; cpu_init(); touch_softlockup_watchdog(); preempt_disable(); /* PVH runs in ring 0 and allows us to do native syscalls. Yay! */ if (!xen_feature(XENFEAT_supervisor_mode_kernel)) { xen_enable_sysenter(); xen_enable_syscall(); } cpu = smp_processor_id(); smp_store_cpu_info(cpu); cpu_data(cpu).x86_max_cores = 1; set_cpu_sibling_map(cpu); xen_setup_cpu_clockevents(); notify_cpu_starting(cpu); set_cpu_online(cpu, true); cpu_set_state_online(cpu); /* Implies full memory barrier. */ /* We can take interrupts now: we're officially "up". */ local_irq_enable(); }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge6069.77%444.44%
Mukesh Rathor1112.79%111.11%
Alex Nixon55.81%111.11%
Konrad Rzeszutek Wilk55.81%111.11%
Paul E. McKenney33.49%111.11%
Rusty Russell22.33%111.11%
Total86100.00%9100.00%


asmlinkage __visible void cpu_bringup_and_idle(void) { cpu_bringup(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); }

Contributors

PersonTokensPropCommitsCommitProp
Alex Nixon847.06%116.67%
Thomas Gleixner423.53%233.33%
Jeremy Fitzhardinge211.76%116.67%
Mukesh Rathor211.76%116.67%
Boris Ostrovsky15.88%116.67%
Total17100.00%6100.00%


void xen_smp_intr_free(unsigned int cpu) { if (per_cpu(xen_resched_irq, cpu).irq >= 0) { unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu).irq, NULL); per_cpu(xen_resched_irq, cpu).irq = -1; kfree(per_cpu(xen_resched_irq, cpu).name); per_cpu(xen_resched_irq, cpu).name = NULL; } if (per_cpu(xen_callfunc_irq, cpu).irq >= 0) { unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu).irq, NULL); per_cpu(xen_callfunc_irq, cpu).irq = -1; kfree(per_cpu(xen_callfunc_irq, cpu).name); per_cpu(xen_callfunc_irq, cpu).name = NULL; } if (per_cpu(xen_debug_irq, cpu).irq >= 0) { unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu).irq, NULL); per_cpu(xen_debug_irq, cpu).irq = -1; kfree(per_cpu(xen_debug_irq, cpu).name); per_cpu(xen_debug_irq, cpu).name = NULL; } if (per_cpu(xen_callfuncsingle_irq, cpu).irq >= 0) { unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu).irq, NULL); per_cpu(xen_callfuncsingle_irq, cpu).irq = -1; kfree(per_cpu(xen_callfuncsingle_irq, cpu).name); per_cpu(xen_callfuncsingle_irq, cpu).name = NULL; } if (xen_hvm_domain()) return; if (per_cpu(xen_irq_work, cpu).irq >= 0) { unbind_from_irqhandler(per_cpu(xen_irq_work, cpu).irq, NULL); per_cpu(xen_irq_work, cpu).irq = -1; kfree(per_cpu(xen_irq_work, cpu).name); per_cpu(xen_irq_work, cpu).name = NULL; } if (per_cpu(xen_pmu_irq, cpu).irq >= 0) { unbind_from_irqhandler(per_cpu(xen_pmu_irq, cpu).irq, NULL); per_cpu(xen_pmu_irq, cpu).irq = -1; kfree(per_cpu(xen_pmu_irq, cpu).name); per_cpu(xen_pmu_irq, cpu).name = NULL; } }

Contributors

PersonTokensPropCommitsCommitProp
Konrad Rzeszutek Wilk33182.96%457.14%
Boris Ostrovsky6416.04%114.29%
Jeremy Fitzhardinge20.50%114.29%
Thomas Gleixner20.50%114.29%
Total399100.00%7100.00%

;
int xen_smp_intr_init(unsigned int cpu) { int rc; char *resched_name, *callfunc_name, *debug_name, *pmu_name; resched_name = kasprintf(GFP_KERNEL, "resched%d", cpu); rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR, cpu, xen_reschedule_interrupt, IRQF_PERCPU|IRQF_NOBALANCING, resched_name, NULL); if (rc < 0) goto fail; per_cpu(xen_resched_irq, cpu).irq = rc; per_cpu(xen_resched_irq, cpu).name = resched_name; callfunc_name = kasprintf(GFP_KERNEL, "callfunc%d", cpu); rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR, cpu, xen_call_function_interrupt, IRQF_PERCPU|IRQF_NOBALANCING, callfunc_name, NULL); if (rc < 0) goto fail; per_cpu(xen_callfunc_irq, cpu).irq = rc; per_cpu(xen_callfunc_irq, cpu).name = callfunc_name; debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu); rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, xen_debug_interrupt, IRQF_PERCPU | IRQF_NOBALANCING, debug_name, NULL); if (rc < 0) goto fail; per_cpu(xen_debug_irq, cpu).irq = rc; per_cpu(xen_debug_irq, cpu).name = debug_name; callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu); rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR, cpu, xen_call_function_single_interrupt, IRQF_PERCPU|IRQF_NOBALANCING, callfunc_name, NULL); if (rc < 0) goto fail; per_cpu(xen_callfuncsingle_irq, cpu).irq = rc; per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name; /* * The IRQ worker on PVHVM goes through the native path and uses the * IPI mechanism. */ if (xen_hvm_domain()) return 0; callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, cpu, xen_irq_work_interrupt, IRQF_PERCPU|IRQF_NOBALANCING, callfunc_name, NULL); if (rc < 0) goto fail; per_cpu(xen_irq_work, cpu).irq = rc; per_cpu(xen_irq_work, cpu).name = callfunc_name; if (is_xen_pmu(cpu)) { pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu); rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu, xen_pmu_irq_handler, IRQF_PERCPU|IRQF_NOBALANCING, pmu_name, NULL); if (rc < 0) goto fail; per_cpu(xen_pmu_irq, cpu).irq = rc; per_cpu(xen_pmu_irq, cpu).name = pmu_name; } return 0; fail: xen_smp_intr_free(cpu); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge16940.05%220.00%
Boris Ostrovsky7317.30%110.00%
Konrad Rzeszutek Wilk7016.59%440.00%
Jens Axboe5312.56%110.00%
Lin Ming5312.56%110.00%
Tejun Heo40.95%110.00%
Total422100.00%10100.00%


static void __init xen_fill_possible_map(void) { int i, rc; if (xen_initial_domain()) return; for (i = 0; i < nr_cpu_ids; i++) { rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); if (rc >= 0) { num_processors++; set_cpu_possible(i, true); } } }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge5585.94%350.00%
Stefano Stabellini69.38%116.67%
Rusty Russell23.12%116.67%
Mike Travis11.56%116.67%
Total64100.00%6100.00%


static void __init xen_filter_cpu_maps(void) { int i, rc; unsigned int subtract = 0; if (!xen_initial_domain()) return; num_processors = 0; disabled_cpus = 0; for (i = 0; i < nr_cpu_ids; i++) { rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); if (rc >= 0) { num_processors++; set_cpu_possible(i, true); } else { set_cpu_possible(i, false); set_cpu_present(i, false); subtract++; } } #ifdef CONFIG_HOTPLUG_CPU /* This is akin to using 'nr_cpus' on the Linux command line. * Which is OK as when we use 'dom0_max_vcpus=X' we can only * have up to X, while nr_cpu_ids is greater than X. This * normally is not a problem, except when CPU hotplugging * is involved and then there might be more than X CPUs * in the guest - which will not work as there is no * hypercall to expand the max number of VCPUs an already * running guest has. So cap it up to X. */ if (subtract) nr_cpu_ids = nr_cpu_ids - subtract; #endif }

Contributors

PersonTokensPropCommitsCommitProp
Stefano Stabellini4539.13%228.57%
Jeremy Fitzhardinge4236.52%228.57%
Konrad Rzeszutek Wilk2521.74%114.29%
Rusty Russell21.74%114.29%
Mike Travis10.87%114.29%
Total115100.00%7100.00%


static void __init xen_smp_prepare_boot_cpu(void) { BUG_ON(smp_processor_id() != 0); native_smp_prepare_boot_cpu(); if (xen_pv_domain()) { if (!xen_feature(XENFEAT_writable_page_tables)) /* We've switched to the "real" per-cpu gdt, so make * sure the old memory can be recycled. */ make_lowmem_page_readwrite(xen_initial_gdt); #ifdef CONFIG_X86_32 /* * Xen starts us with XEN_FLAT_RING1_DS, but linux code * expects __USER_DS */ loadsegment(ds, __USER_DS); loadsegment(es, __USER_DS); #endif xen_filter_cpu_maps(); xen_setup_vcpu_info_placement(); } /* * Setup vcpu_info for boot CPU. */ if (xen_hvm_domain()) xen_vcpu_setup(0); /* * The alternative logic (which patches the unlock/lock) runs before * the smp bootup up code is activated. Hence we need to set this up * the core kernel is being patched. Otherwise we will have only * modules patched but not core code. */ xen_init_spinlocks(); }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge3137.80%550.00%
Frediano Ziglio2024.39%110.00%
Vitaly Kuznetsov1113.41%110.00%
Mukesh Rathor910.98%110.00%
Konrad Rzeszutek Wilk89.76%110.00%
Stefano Stabellini33.66%110.00%
Total82100.00%10100.00%


static void __init xen_smp_prepare_cpus(unsigned int max_cpus) { unsigned cpu; unsigned int i; if (skip_ioapic_setup) { char *m = (max_cpus == 0) ? "The nosmp parameter is incompatible with Xen; " \ "use Xen dom0_max_vcpus=1 parameter" : "The noapic parameter is incompatible with Xen"; xen_raw_printk(m); panic(m); } xen_init_lock_cpu(0); smp_store_boot_cpu_info(); cpu_data(0).x86_max_cores = 1; for_each_possible_cpu(i) { zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL); zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL); zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL); } set_cpu_sibling_map(0); xen_pmu_init(0); if (xen_smp_intr_init(0)) BUG(); if (!alloc_cpumask_var(&xen_cpu_initialized_map, GFP_KERNEL)) panic("could not allocate xen_cpu_initialized_map\n"); cpumask_copy(xen_cpu_initialized_map, cpumask_of(0)); /* Restrict the possible_map according to max_cpus. */ while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) { for (cpu = nr_cpu_ids - 1; !cpu_possible(cpu); cpu--) continue; set_cpu_possible(cpu, false); } for_each_possible_cpu(cpu) set_cpu_present(cpu, true); }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge9745.54%430.77%
Andrew Jones4923.00%17.69%
Konrad Rzeszutek Wilk3415.96%215.38%
Mike Travis2210.33%215.38%
Boris Ostrovsky52.35%17.69%
Rusty Russell41.88%17.69%
Akinobu Mita10.47%17.69%
Glauber de Oliveira Costa10.47%17.69%
Total213100.00%13100.00%


static int cpu_initialize_context(unsigned int cpu, struct task_struct *idle) { struct vcpu_guest_context *ctxt; struct desc_struct *gdt; unsigned long gdt_mfn; /* used to tell cpu_init() that it can proceed with initialization */ cpumask_set_cpu(cpu, cpu_callout_mask); if (cpumask_test_and_set_cpu(cpu, xen_cpu_initialized_map)) return 0; ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); if (ctxt == NULL) return -ENOMEM; gdt = get_cpu_gdt_table(cpu); #ifdef CONFIG_X86_32 ctxt->user_regs.fs = __KERNEL_PERCPU; ctxt->user_regs.gs = __KERNEL_STACK_CANARY; #endif memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt)); ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle; ctxt->flags = VGCF_IN_KERNEL; ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */ ctxt->user_regs.ds = __USER_DS; ctxt->user_regs.es = __USER_DS; ctxt->user_regs.ss = __KERNEL_DS; xen_copy_trap_info(ctxt->trap_ctxt); ctxt->ldt_ents = 0; BUG_ON((unsigned long)gdt & ~PAGE_MASK); gdt_mfn = arbitrary_virt_to_mfn(gdt); make_lowmem_page_readonly(gdt); make_lowmem_page_readonly(mfn_to_virt(gdt_mfn)); ctxt->gdt_frames[0] = gdt_mfn; ctxt->gdt_ents = GDT_ENTRIES; ctxt->kernel_ss = __KERNEL_DS; ctxt->kernel_sp = idle->thread.sp0; #ifdef CONFIG_X86_32 ctxt->event_callback_cs = __KERNEL_CS; ctxt->failsafe_callback_cs = __KERNEL_CS; #else ctxt->gs_base_kernel = per_cpu_offset(cpu); #endif ctxt->event_callback_eip = (unsigned long)xen_hypervisor_callback; ctxt->failsafe_callback_eip = (unsigned long)xen_failsafe_callback; ctxt->user_regs.cs = __KERNEL_CS; per_cpu(xen_cr3, cpu) = __pa(swapper_pg_dir); ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs); ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_gfn(swapper_pg_dir)); if (HYPERVISOR_vcpu_op(VCPUOP_initialise, xen_vcpu_nr(cpu), ctxt)) BUG(); kfree(ctxt); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge25468.65%430.77%
Konrad Rzeszutek Wilk5113.78%17.69%
Mukesh Rathor5013.51%215.38%
Igor Mammedov82.16%17.69%
Vitaly Kuznetsov30.81%17.69%
Glauber de Oliveira Costa10.27%17.69%
H. Peter Anvin10.27%17.69%
Julien Grall10.27%17.69%
Mike Travis10.27%17.69%
Total370100.00%13100.00%


static int xen_cpu_up(unsigned int cpu, struct task_struct *idle) { int rc; common_cpu_up(cpu, idle); xen_setup_runstate_info(cpu); /* * PV VCPUs are always successfully taken down (see 'while' loop * in xen_cpu_die()), so -EBUSY is an error. */ rc = cpu_check_up_prepare(cpu); if (rc) return rc; /* make sure interrupts start blocked */ per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1; rc = cpu_initialize_context(cpu, idle); if (rc) return rc; xen_pmu_init(cpu); rc = HYPERVISOR_vcpu_op(VCPUOP_up, xen_vcpu_nr(cpu), NULL); BUG_ON(rc); while (cpu_report_state(cpu) != CPU_ONLINE) HYPERVISOR_sched_op(SCHEDOP_yield, NULL); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge8371.55%325.00%
Paul E. McKenney1210.34%18.33%
Boris Ostrovsky65.17%216.67%
Ian Campbell54.31%18.33%
Thomas Gleixner54.31%216.67%
Vitaly Kuznetsov32.59%18.33%
Mukesh Rathor10.86%18.33%
Hannes Eder10.86%18.33%
Total116100.00%12100.00%


static void xen_smp_cpus_done(unsigned int max_cpus) { }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge9100.00%2100.00%
Total9100.00%2100.00%

#ifdef CONFIG_HOTPLUG_CPU
static int xen_cpu_disable(void) { unsigned int cpu = smp_processor_id(); if (cpu == 0) return -EBUSY; cpu_disable_common(); load_cr3(swapper_pg_dir); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Alex Nixon36100.00%2100.00%
Total36100.00%2100.00%


static void xen_cpu_die(unsigned int cpu) { while (xen_pv_domain() && HYPERVISOR_vcpu_op(VCPUOP_is_up, xen_vcpu_nr(cpu), NULL)) { __set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); } if (common_cpu_die(cpu) == 0) { xen_smp_intr_free(cpu); xen_uninit_lock_cpu(cpu); xen_teardown_timer(cpu); xen_pmu_finish(cpu); } }

Contributors

PersonTokensPropCommitsCommitProp
Alex Nixon4258.33%220.00%
Boris Ostrovsky811.11%220.00%
Paul E. McKenney811.11%110.00%
Konrad Rzeszutek Wilk811.11%330.00%
Vitaly Kuznetsov34.17%110.00%
Davidlohr Bueso A34.17%110.00%
Total72100.00%10100.00%


static void xen_play_dead(void) /* used only with HOTPLUG_CPU */ { play_dead_common(); HYPERVISOR_vcpu_op(VCPUOP_down, xen_vcpu_nr(smp_processor_id()), NULL); cpu_bringup(); /* * commit 4b0c0f294 (tick: Cleanup NOHZ per cpu data on cpu down) * clears certain data that the cpu_idle loop (which called us * and that we return from) expects. The only way to get that * data back is to call: */ tick_nohz_idle_enter(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); }

Contributors

PersonTokensPropCommitsCommitProp
Alex Nixon2464.86%233.33%
Boris Ostrovsky513.51%116.67%
Konrad Rzeszutek Wilk410.81%116.67%
Vitaly Kuznetsov38.11%116.67%
Robert P. J. Day12.70%116.67%
Total37100.00%6100.00%

#else /* !CONFIG_HOTPLUG_CPU */
static int xen_cpu_disable(void) { return -ENOSYS; }

Contributors

PersonTokensPropCommitsCommitProp
Alex Nixon12100.00%2100.00%
Total12100.00%2100.00%


static void xen_cpu_die(unsigned int cpu) { BUG(); }

Contributors

PersonTokensPropCommitsCommitProp
Alex Nixon13100.00%2100.00%
Total13100.00%2100.00%


static void xen_play_dead(void) { BUG(); }

Contributors

PersonTokensPropCommitsCommitProp
Alex Nixon11100.00%2100.00%
Total11100.00%2100.00%

#endif
static void stop_self(void *v) { int cpu = smp_processor_id(); /* make sure we're not pinning something down */ load_cr3(swapper_pg_dir); /* should set up a minimal gdt */ set_cpu_online(cpu, false); HYPERVISOR_vcpu_op(VCPUOP_down, xen_vcpu_nr(cpu), NULL); BUG(); }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge3577.78%133.33%
Ian Campbell715.56%133.33%
Vitaly Kuznetsov36.67%133.33%
Total45100.00%3100.00%


static void xen_stop_other_cpus(int wait) { smp_call_function(stop_self, NULL, wait); }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge1477.78%375.00%
Alok N Kataria422.22%125.00%
Total18100.00%4100.00%


static void xen_smp_send_reschedule(int cpu) { xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR); }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge16100.00%2100.00%
Total16100.00%2100.00%


static void __xen_send_IPI_mask(const struct cpumask *mask, int vector) { unsigned cpu; for_each_cpu_and(cpu, mask, cpu_online_mask) xen_send_IPI_one(cpu, vector); }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge2472.73%125.00%
Mike Travis721.21%250.00%
Ben Guthro26.06%125.00%
Total33100.00%4100.00%


static void xen_smp_send_call_function_ipi(const struct cpumask *mask) { int cpu; __xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR); /* Make sure other vcpus get a chance to run if they need to. */ for_each_cpu(cpu, mask) { if (xen_vcpu_stolen(cpu)) { HYPERVISOR_sched_op(SCHEDOP_yield, NULL); break; } } }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe3981.25%116.67%
Mike Travis612.50%233.33%
Jeremy Fitzhardinge12.08%116.67%
Hannes Eder12.08%116.67%
Ben Guthro12.08%116.67%
Total48100.00%6100.00%


static void xen_smp_send_call_function_single_ipi(int cpu) { __xen_send_IPI_mask(cpumask_of(cpu), XEN_CALL_FUNCTION_SINGLE_VECTOR); }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe1684.21%125.00%
Jeremy Fitzhardinge15.26%125.00%
Ben Guthro15.26%125.00%
Mike Travis15.26%125.00%
Total19100.00%4100.00%


static inline int xen_map_vector(int vector) { int xen_vector; switch (vector) { case RESCHEDULE_VECTOR: xen_vector = XEN_RESCHEDULE_VECTOR; break; case CALL_FUNCTION_VECTOR: xen_vector = XEN_CALL_FUNCTION_VECTOR; break; case CALL_FUNCTION_SINGLE_VECTOR: xen_vector = XEN_CALL_FUNCTION_SINGLE_VECTOR; break; case IRQ_WORK_VECTOR: xen_vector = XEN_IRQ_WORK_VECTOR; break; #ifdef CONFIG_X86_64 case NMI_VECTOR: case APIC_DM_NMI: /* Some use that instead of NMI_VECTOR */ xen_vector = XEN_NMI_VECTOR; break; #endif default: xen_vector = -1; printk(KERN_ERR "xen: vector 0x%x is not implemented\n", vector); } return xen_vector; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Guthro6070.59%133.33%
Konrad Rzeszutek Wilk1720.00%133.33%
Lin Ming89.41%133.33%
Total85100.00%3100.00%


void xen_send_IPI_mask(const struct cpumask *mask, int vector) { int xen_vector = xen_map_vector(vector); if (xen_vector >= 0) __xen_send_IPI_mask(mask, xen_vector); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Guthro35100.00%1100.00%
Total35100.00%1100.00%


void xen_send_IPI_all(int vector) { int xen_vector = xen_map_vector(vector); if (xen_vector >= 0) __xen_send_IPI_mask(cpu_online_mask, xen_vector); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Guthro29100.00%1100.00%
Total29100.00%1100.00%


void xen_send_IPI_self(int vector) { int xen_vector = xen_map_vector(vector); if (xen_vector >= 0) xen_send_IPI_one(smp_processor_id(), xen_vector); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Guthro30100.00%1100.00%
Total30100.00%1100.00%


void xen_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) { unsigned cpu; unsigned int this_cpu = smp_processor_id(); int xen_vector = xen_map_vector(vector); if (!(num_online_cpus() > 1) || (xen_vector < 0)) return; for_each_cpu_and(cpu, mask, cpu_online_mask) { if (this_cpu == cpu) continue; xen_send_IPI_one(cpu, xen_vector); } }

Contributors

PersonTokensPropCommitsCommitProp
Ben Guthro5676.71%150.00%
Stefan Bader1723.29%150.00%
Total73100.00%2100.00%


void xen_send_IPI_allbutself(int vector) { xen_send_IPI_mask_allbutself(cpu_online_mask, vector); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Guthro1493.33%150.00%
Stefan Bader16.67%150.00%
Total15100.00%2100.00%


static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) { irq_enter(); generic_smp_call_function_interrupt(); inc_irq_stat(irq_call_count); irq_exit(); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge2583.33%240.00%
Joe Korty26.67%120.00%
Jens Axboe26.67%120.00%
Brian Gerst13.33%120.00%
Total30100.00%5100.00%


static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id) { irq_enter(); generic_smp_call_function_single_interrupt(); inc_irq_stat(irq_call_count); irq_exit(); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge1963.33%250.00%
Jens Axboe1033.33%125.00%
Brian Gerst13.33%125.00%
Total30100.00%4100.00%


static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id) { irq_enter(); irq_work_run(); inc_irq_stat(apic_irq_work_irqs); irq_exit(); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Lin Ming30100.00%1100.00%
Total30100.00%1100.00%

static const struct smp_ops xen_smp_ops __initconst = { .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu, .smp_prepare_cpus = xen_smp_prepare_cpus, .smp_cpus_done = xen_smp_cpus_done, .cpu_up = xen_cpu_up, .cpu_die = xen_cpu_die, .cpu_disable = xen_cpu_disable, .play_dead = xen_play_dead, .stop_other_cpus = xen_stop_other_cpus, .smp_send_reschedule = xen_smp_send_reschedule, .send_call_func_ipi = xen_smp_send_call_function_ipi, .send_call_func_single_ipi = xen_smp_send_call_function_single_ipi, };
void __init xen_smp_init(void) { smp_ops = xen_smp_ops; xen_fill_possible_map(); }

Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge15100.00%2100.00%
Total15100.00%2100.00%


static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) { native_smp_prepare_cpus(max_cpus); WARN_ON(xen_smp_intr_init(0)); xen_init_lock_cpu(0); }

Contributors

PersonTokensPropCommitsCommitProp
Stefano Stabellini29100.00%1100.00%
Total29100.00%1100.00%


void __init xen_hvm_smp_init(void) { smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; smp_ops.smp_send_reschedule = xen_smp_send_reschedule; smp_ops.cpu_die = xen_cpu_die; smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi; smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi; smp_ops.smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu; }

Contributors

PersonTokensPropCommitsCommitProp
Stefano Stabellini3784.09%133.33%
Konrad Rzeszutek Wilk613.64%133.33%
Paul E. McKenney12.27%133.33%
Total44100.00%3100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Jeremy Fitzhardinge110236.47%1518.99%
Konrad Rzeszutek Wilk62520.68%1518.99%
Ben Guthro2287.54%11.27%
Boris Ostrovsky1856.12%56.33%
Alex Nixon1775.86%33.80%
Jens Axboe1334.40%11.27%
Stefano Stabellini1234.07%33.80%
Lin Ming1133.74%11.27%
Mukesh Rathor762.51%22.53%
Andrew Jones491.62%11.27%
Mike Travis401.32%33.80%
Vitaly Kuznetsov260.86%22.53%
Paul E. McKenney240.79%11.27%
Frediano Ziglio200.66%11.27%
Stefan Bader180.60%11.27%
Ian Campbell120.40%22.53%
Tejun Heo110.36%22.53%
Thomas Gleixner110.36%45.06%
Rusty Russell100.33%22.53%
Igor Mammedov80.26%11.27%
Alok N Kataria60.20%11.27%
Peter Zijlstra40.13%11.27%
Brian Gerst30.10%11.27%
Glauber de Oliveira Costa30.10%11.27%
Davidlohr Bueso A30.10%11.27%
Ingo Molnar30.10%11.27%
Joe Korty20.07%11.27%
Hannes Eder20.07%11.27%
H. Peter Anvin10.03%11.27%
Daniel Kiper10.03%11.27%
Robert P. J. Day10.03%11.27%
Julien Grall10.03%11.27%
Akinobu Mita10.03%11.27%
Total3022100.00%79100.00%
Directory: arch/x86/xen
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.