diff options
author | Johannes Berg <johannes.berg@intel.com> | 2020-09-08 23:06:02 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2020-09-14 13:10:54 +0200 |
commit | ca7bdb1b511e9fd887b7710bfec756f21c4e83c4 (patch) | |
tree | e91b640b233abfc994c654c043b52e024504aa67 | |
parent | 6e9ad48d7c56cf22e6a29c6775c3e37dcd2bb88d (diff) | |
download | um-ca7bdb1b511e9fd887b7710bfec756f21c4e83c4.tar.gz |
um: time-travel: fix IRQ handling in time_travel_handle_message()
As the comment here indicates, we need to do the polling in the
idle loop without blocking interrupts, since interrupts can be
vhost-user messages that we must process even while in our idle
loop.
I don't know why I explained one thing and implemented another,
but we have indeed observed random hangs due to this, depending
on the timing of the messages.
Fixes: 88ce64249233 ("um: Implement time-travel=ext")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | arch/um/kernel/time.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 25eaa6a0c6583f..c07436e89e599e 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -70,13 +70,17 @@ static void time_travel_handle_message(struct um_timetravel_msg *msg, * read of the message and write of the ACK. */ if (mode != TTMH_READ) { + bool disabled = irqs_disabled(); + + BUG_ON(mode == TTMH_IDLE && !disabled); + + if (disabled) + local_irq_enable(); while (os_poll(1, &time_travel_ext_fd) != 0) { - if (mode == TTMH_IDLE) { - BUG_ON(!irqs_disabled()); - local_irq_enable(); - local_irq_disable(); - } + /* nothing */ } + if (disabled) + local_irq_disable(); } ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg)); |