mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 20:22:46 +00:00
HV: bug fix in operating softirq
Current code is missing to handle the following race condition: Before: sti | V handle softirq with a while loop | <----- if a new softirq generated at this point, V it will be missed to be handled. cli | V return with unclear softirq bitmap After: again: sti | V handle softirq with a while loop | V cli | V check if a new softirq generated, if yes, jump back to above again lable point, and do a while loop again. | V return with clear softirq bitmap Signed-off-by: Zheng, Gen <gen.zheng@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
8f3b36b224
commit
a06f2d68dc
@ -40,27 +40,24 @@ void raise_softirq(int softirq_id)
|
|||||||
void exec_softirq(void)
|
void exec_softirq(void)
|
||||||
{
|
{
|
||||||
int cpu_id = get_cpu_id();
|
int cpu_id = get_cpu_id();
|
||||||
uint64_t *bitmap = &per_cpu(softirq_pending, cpu_id);
|
volatile uint64_t *bitmap = &per_cpu(softirq_pending, cpu_id);
|
||||||
|
|
||||||
uint64_t rflag;
|
|
||||||
int softirq_id;
|
int softirq_id;
|
||||||
|
|
||||||
if (cpu_id >= phy_cpu_num)
|
if (cpu_id >= phy_cpu_num)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (((*bitmap) & SOFTIRQ_MASK) == 0UL)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Disable softirq
|
/* Disable softirq
|
||||||
* SOFTIRQ_ATOMIC bit = 0 means softirq already in execution
|
* SOFTIRQ_ATOMIC bit = 0 means softirq already in execution
|
||||||
*/
|
*/
|
||||||
if (!bitmap_test_and_clear(SOFTIRQ_ATOMIC, bitmap))
|
if (!bitmap_test_and_clear(SOFTIRQ_ATOMIC, bitmap))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (((*bitmap) & SOFTIRQ_MASK) == 0UL)
|
again:
|
||||||
goto ENABLE_AND_EXIT;
|
CPU_IRQ_ENABLE();
|
||||||
|
|
||||||
/* check if we are in interrupt context */
|
|
||||||
CPU_RFLAGS_SAVE(&rflag);
|
|
||||||
if (!(rflag & (1<<9)))
|
|
||||||
goto ENABLE_AND_EXIT;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
softirq_id = ffs64(*bitmap);
|
softirq_id = ffs64(*bitmap);
|
||||||
@ -82,7 +79,11 @@ void exec_softirq(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ENABLE_AND_EXIT:
|
CPU_IRQ_DISABLE();
|
||||||
|
|
||||||
|
if (((*bitmap) & SOFTIRQ_MASK))
|
||||||
|
goto again;
|
||||||
|
|
||||||
enable_softirq(cpu_id);
|
enable_softirq(cpu_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,9 +32,7 @@ void vcpu_thread(struct vcpu *vcpu)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
/* handling pending softirq */
|
/* handling pending softirq */
|
||||||
CPU_IRQ_ENABLE();
|
|
||||||
exec_softirq();
|
exec_softirq();
|
||||||
CPU_IRQ_DISABLE();
|
|
||||||
|
|
||||||
/* Check and process pending requests(including interrupt) */
|
/* Check and process pending requests(including interrupt) */
|
||||||
ret = acrn_handle_pending_request(vcpu);
|
ret = acrn_handle_pending_request(vcpu);
|
||||||
|
Loading…
Reference in New Issue
Block a user