summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Rettberg2022-03-04 14:05:46 +0100
committerSimon Rettberg2022-03-04 14:05:46 +0100
commit9c0d227bbaf261888280da649ddc63fc750cac22 (patch)
treee60c0895c148a81df9b03f4fca12aa8b0df8a358 /src
parent[KERNEL] Fix copy&paste error (passing wrong sock) (diff)
downloaddnbd3-9c0d227bbaf261888280da649ddc63fc750cac22.tar.gz
dnbd3-9c0d227bbaf261888280da649ddc63fc750cac22.tar.xz
dnbd3-9c0d227bbaf261888280da649ddc63fc750cac22.zip
[KERNEL] Fix possible stall when switching server
If we switch to a different server when we only have something in the send list but nothing in the recv list, the send worker would not have gotten invoked. Now we unconditionally trigger the send worker when asked to re-queue any pending requests.
Diffstat (limited to 'src')
-rw-r--r--src/kernel/blk.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index 5795c03..bc18c44 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -536,8 +536,16 @@ void dnbd3_blk_requeue_all_requests(dnbd3_device_t *dev)
while (!list_empty(&local_copy)) {
blk_request = list_entry(local_copy.next, struct request, queuelist);
list_del_init(&blk_request->queuelist);
- dnbd3_add_queue(dev, blk_request);
+ spin_lock_irqsave(&dev->send_queue_lock, flags);
+ list_add_tail(&blk_request->queuelist, &dev->send_queue);
+ spin_unlock_irqrestore(&dev->send_queue_lock, flags);
}
+ // Do this even if we didn't move anything from the recv list to the send
+ // list. It might have already contained something, which needs to be
+ // re-requested anyways if this was called because of a server switch.
+ spin_lock_irqsave(&dev->blk_lock, flags);
+ queue_work(dev->send_wq, &dev->send_work);
+ spin_unlock_irqrestore(&dev->blk_lock, flags);
}
void dnbd3_blk_fail_all_requests(dnbd3_device_t *dev)