aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2020-09-08 23:06:02 +0200
committerJohannes Berg <johannes.berg@intel.com>2020-09-14 13:10:54 +0200
commitca7bdb1b511e9fd887b7710bfec756f21c4e83c4 (patch)
treee91b640b233abfc994c654c043b52e024504aa67
parent6e9ad48d7c56cf22e6a29c6775c3e37dcd2bb88d (diff)
downloadum-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.c14
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));