support for dynamically toggling time sharing when CPU is oversubscribed

This commit is contained in:
Balazs Gerofi
2015-08-07 08:51:50 +09:00
parent aa191b87d3
commit 0a0e2c04a0
3 changed files with 46 additions and 0 deletions

View File

@ -39,6 +39,7 @@
#define LAPIC_ICR0 0x300
#define LAPIC_ICR2 0x310
#define LAPIC_ESR 0x280
#define LOCAL_TIMER_VECTOR 0xef
#define APIC_INT_LEVELTRIG 0x08000
#define APIC_INT_ASSERT 0x04000
@ -48,6 +49,8 @@
#define APIC_DM_NMI 0x00400
#define APIC_DM_INIT 0x00500
#define APIC_DM_STARTUP 0x00600
#define APIC_DIVISOR 16
#define APIC_LVT_TIMER_PERIODIC (1 << 17)
//#define DEBUG_PRINT_CPU
@ -252,6 +255,23 @@ void lapic_icr_write(unsigned int h, unsigned int l)
}
void lapic_timer_enable(unsigned int clocks)
{
unsigned int lvtt_value;
lapic_write(LAPIC_TIMER_INITIAL, clocks / APIC_DIVISOR);
lapic_write(LAPIC_TIMER_DIVIDE, 3);
/* initialize periodic timer */
lvtt_value = LOCAL_TIMER_VECTOR | APIC_LVT_TIMER_PERIODIC;
lapic_write(LAPIC_TIMER, lvtt_value);
}
void lapic_timer_disable()
{
lapic_write(LAPIC_TIMER_INITIAL, 0);
}
void print_msr(int idx)
{
int bit;
@ -673,6 +693,12 @@ void handle_interrupt(int vector, struct x86_user_context *regs)
panic("Unhandled exception");
}
}
else if (vector == LOCAL_TIMER_VECTOR) {
/* Timer interrupt, enabled only on oversubscribed CPU cores,
* request reschedule */
v->flags |= CPU_FLAG_NEED_RESCHED;
dkprintf("timer[%lu]: CPU_FLAG_NEED_RESCHED \n", rdtsc());
}
else if (vector >= IHK_TLB_FLUSH_IRQ_VECTOR_START &&
vector < IHK_TLB_FLUSH_IRQ_VECTOR_END) {

View File

@ -69,6 +69,7 @@ struct cpu_local_var {
struct list_head migq;
int in_interrupt;
int no_preempt;
int timer_enabled;
} __attribute__((aligned(64)));

View File

@ -57,6 +57,8 @@ extern void restore_fp_regs(struct process *proc);
void settid(struct process *proc, int mode, int newcpuid, int oldcpuid);
extern void __runq_add_proc(struct process *proc, int cpu_id);
extern void terminate_host(int pid);
extern void lapic_timer_enable(unsigned int clocks);
extern void lapic_timer_disable();
int refcount_fork_tree_node(struct fork_tree_node *ftn)
{
@ -2264,6 +2266,23 @@ redo:
list_add_tail(&prev->sched_list, &(v->runq));
++v->runq_len;
}
/* Toggle timesharing if CPU core is oversubscribed
* (on last CPU core only for now) */
if (ihk_mc_get_processor_id() == num_processors - 1) {
if (v->runq_len > 1) {
if (!cpu_local_var(timer_enabled)) {
lapic_timer_enable(10000000);
cpu_local_var(timer_enabled) = 1;
}
}
else {
if (cpu_local_var(timer_enabled)) {
lapic_timer_disable();
cpu_local_var(timer_enabled) = 0;
}
}
}
}
if (v->flags & CPU_FLAG_NEED_MIGRATE) {