[Virtio-fs] [PATCH] virtiofs: reduce lock contention on fpq->lock
Liu Bo
bo.liu at linux.alibaba.com
Tue Jul 30 05:51:12 UTC 2019
Right now within virtio_fs_requests_done_work(), virtqueue is protected by
both fsvq->lock and fpq->lock for processing both virtqueue and
fpq->processing_list, however, it is fine for them to be protected
separately.
Also since %req has been removed from fpq->processing_list, no one except
request_wait_answer() is looking at this %req and request_wait_answer()
waits only on FINISH flag, it's OK to remove fpq->lock after %req is
dropped from the list.
Signed-off-by: Liu Bo <bo.liu at linux.alibaba.com>
---
fs/fuse/virtio_fs.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index 9b3f2e9..d88bb6c 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -347,21 +347,22 @@ static void virtio_fs_requests_done_work(struct work_struct *work)
/* Collect completed requests off the virtqueue */
spin_lock(&fsvq->lock);
- /* grab fpq->lock as req is on fpq->processing list */
- spin_lock(&fpq->lock);
do {
unsigned len;
virtqueue_disable_cb(vq);
while ((req = virtqueue_get_buf(vq, &len)) != NULL) {
+ /* grab fpq->lock as req is on fpq->processing list */
+ spin_lock(&fpq->lock);
+
/* If !connected, req is freed by fuse_abort_conn. */
- if (fpq->connected) {
+ if (fpq->connected)
list_move_tail(&req->list, &reqs);
- }
+
+ spin_unlock(&fpq->lock);
}
} while (!virtqueue_enable_cb(vq) && likely(!virtqueue_is_broken(vq)));
- spin_unlock(&fpq->lock);
spin_unlock(&fsvq->lock);
/* End requests */
@@ -373,10 +374,8 @@ static void virtio_fs_requests_done_work(struct work_struct *work)
/* TODO zeroing? */
- spin_lock(&fpq->lock);
clear_bit(FR_SENT, &req->flags);
list_del_init(&req->list);
- spin_unlock(&fpq->lock);
fuse_request_end(fc, req);
}
--
1.8.3.1
More information about the Virtio-fs
mailing list