support for dynamically toggling time sharing when CPU is oversubscribed
This commit is contained in:
@@ -39,6 +39,7 @@
|
|||||||
#define LAPIC_ICR0 0x300
|
#define LAPIC_ICR0 0x300
|
||||||
#define LAPIC_ICR2 0x310
|
#define LAPIC_ICR2 0x310
|
||||||
#define LAPIC_ESR 0x280
|
#define LAPIC_ESR 0x280
|
||||||
|
#define LOCAL_TIMER_VECTOR 0xef
|
||||||
|
|
||||||
#define APIC_INT_LEVELTRIG 0x08000
|
#define APIC_INT_LEVELTRIG 0x08000
|
||||||
#define APIC_INT_ASSERT 0x04000
|
#define APIC_INT_ASSERT 0x04000
|
||||||
@@ -48,6 +49,8 @@
|
|||||||
#define APIC_DM_NMI 0x00400
|
#define APIC_DM_NMI 0x00400
|
||||||
#define APIC_DM_INIT 0x00500
|
#define APIC_DM_INIT 0x00500
|
||||||
#define APIC_DM_STARTUP 0x00600
|
#define APIC_DM_STARTUP 0x00600
|
||||||
|
#define APIC_DIVISOR 16
|
||||||
|
#define APIC_LVT_TIMER_PERIODIC (1 << 17)
|
||||||
|
|
||||||
|
|
||||||
//#define DEBUG_PRINT_CPU
|
//#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)
|
void print_msr(int idx)
|
||||||
{
|
{
|
||||||
int bit;
|
int bit;
|
||||||
@@ -673,6 +693,12 @@ void handle_interrupt(int vector, struct x86_user_context *regs)
|
|||||||
panic("Unhandled exception");
|
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 &&
|
else if (vector >= IHK_TLB_FLUSH_IRQ_VECTOR_START &&
|
||||||
vector < IHK_TLB_FLUSH_IRQ_VECTOR_END) {
|
vector < IHK_TLB_FLUSH_IRQ_VECTOR_END) {
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ struct cpu_local_var {
|
|||||||
struct list_head migq;
|
struct list_head migq;
|
||||||
int in_interrupt;
|
int in_interrupt;
|
||||||
int no_preempt;
|
int no_preempt;
|
||||||
|
int timer_enabled;
|
||||||
} __attribute__((aligned(64)));
|
} __attribute__((aligned(64)));
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ extern void restore_fp_regs(struct process *proc);
|
|||||||
void settid(struct process *proc, int mode, int newcpuid, int oldcpuid);
|
void settid(struct process *proc, int mode, int newcpuid, int oldcpuid);
|
||||||
extern void __runq_add_proc(struct process *proc, int cpu_id);
|
extern void __runq_add_proc(struct process *proc, int cpu_id);
|
||||||
extern void terminate_host(int pid);
|
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)
|
int refcount_fork_tree_node(struct fork_tree_node *ftn)
|
||||||
{
|
{
|
||||||
@@ -2264,6 +2266,23 @@ redo:
|
|||||||
list_add_tail(&prev->sched_list, &(v->runq));
|
list_add_tail(&prev->sched_list, &(v->runq));
|
||||||
++v->runq_len;
|
++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) {
|
if (v->flags & CPU_FLAG_NEED_MIGRATE) {
|
||||||
|
|||||||
Reference in New Issue
Block a user