Skip to content

Commit fea0f31

Browse files
committed
avoid busy waiting if the cpu feature mwait is missing
1 parent b4cb878 commit fea0f31

4 files changed

Lines changed: 41 additions & 2 deletions

File tree

arch/x86/kernel/apic.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,24 @@ int apic_send_ipi(uint64_t dest, uint8_t irq)
10331033
return 0;
10341034
}
10351035

1036+
void wakeup_core(uint32_t core_id)
1037+
{
1038+
// if mwait is available, an IPI isn't required to wakeup the core
1039+
if (has_mwait())
1040+
return;
1041+
1042+
// no self IPI required
1043+
if (core_id == CORE_ID)
1044+
return;
1045+
1046+
// no IPI required if core is offline
1047+
if (!online[core_id])
1048+
return;
1049+
1050+
LOG_DEBUG("wakeup core %d\n", core_id);
1051+
apic_send_ipi(core_id, 82+32);
1052+
}
1053+
10361054
static void apic_err_handler(struct state *s)
10371055
{
10381056
LOG_ERROR("Got APIC error 0x%x\n", lapic_read(APIC_ESR));
@@ -1091,6 +1109,11 @@ static void apic_shutdown(struct state * s)
10911109
LOG_DEBUG("Receive shutdown interrupt\n");
10921110
}
10931111

1112+
static void apic_wakeup_handler(struct state * s)
1113+
{
1114+
LOG_DEBUG("Receive wakeup interrupt\n");
1115+
}
1116+
10941117
int apic_init(void)
10951118
{
10961119
int ret;
@@ -1105,6 +1128,7 @@ int apic_init(void)
11051128
irq_install_handler(80+32, apic_tlb_handler);
11061129
#endif
11071130
irq_install_handler(81+32, apic_shutdown);
1131+
irq_install_handler(82+32, apic_wakeup_handler);
11081132
if (apic_processors[boot_processor])
11091133
LOG_INFO("Boot processor %u (ID %u)\n", boot_processor, apic_processors[boot_processor]->id);
11101134
else

arch/x86/kernel/tasks.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor
196196
void wait_for_task(void)
197197
{
198198
if (!has_mwait()) {
199-
PAUSE;
199+
HALT;
200200
} else {
201201
void* queue = get_readyqueue();
202202

include/hermit/tasks.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ void reschedule(void);
166166
*/
167167
int wakeup_task(tid_t);
168168

169+
/** @brief Wake up a core_id
170+
*
171+
* Wakeup core to be sure that
172+
* the core isn't in halt state
173+
*
174+
* @param core_id Specifies the core
175+
*/
176+
void wakeup_core(uint32_t core_id);
169177

170178
/** @brief Block current task
171179
*

kernel/tasks.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ static void readyqueues_push_back(uint32_t core_id, task_t* task)
176176

177177
// increase the number of ready tasks
178178
readyqueues[core_id].nr_tasks++;
179+
180+
// should we wakeup the core?
181+
if (readyqueues[core_id].nr_tasks == 1)
182+
wakeup_core(core_id);
179183
}
180184

181185

@@ -483,7 +487,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
483487
task_table[i].stack = stack;
484488
task_table[i].prio = prio;
485489
task_table[i].heap = curr_task->heap;
486-
task_table[i].start_tick = get_clock_tick();
490+
task_table[i].start_tick = get_clock_tick();
487491
task_table[i].last_tsc = 0;
488492
task_table[i].parent = curr_task->id;
489493
task_table[i].tls_addr = curr_task->tls_addr;
@@ -513,6 +517,9 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
513517
readyqueues[core_id].queue[prio-1].last->next = task_table+i;
514518
readyqueues[core_id].queue[prio-1].last = task_table+i;
515519
}
520+
// should we wakeup the core?
521+
if (readyqueues[core_id].nr_tasks == 1)
522+
wakeup_core(core_id);
516523
spinlock_irqsave_unlock(&readyqueues[core_id].lock);
517524
break;
518525
}

0 commit comments

Comments
 (0)