Currently, when checking whether a request has timed out, we check fpq processing, but fuse-over-io-uring has one fpq per core and 256 entries in the processing table. For systems where there are a large number of cores, this may be too much overhead. Instead of checking the fpq processing list, check ent_w_req_queue, ent_in_userspace, and ent_commit_queue. Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx> --- fs/fuse/dev.c | 2 +- fs/fuse/dev_uring.c | 23 ++++++++++++++++++++--- fs/fuse/fuse_dev_i.h | 1 - 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 3c03aac480a4..80a11ef4b69a 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -45,7 +45,7 @@ bool fuse_request_expired(struct fuse_conn *fc, struct list_head *list) return time_is_before_jiffies(req->create_time + fc->timeout.req_timeout); } -bool fuse_fpq_processing_expired(struct fuse_conn *fc, struct list_head *processing) +static bool fuse_fpq_processing_expired(struct fuse_conn *fc, struct list_head *processing) { int i; diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c index 5c9b5a5fb7f7..dfa6c5337bbf 100644 --- a/fs/fuse/dev_uring.c +++ b/fs/fuse/dev_uring.c @@ -90,6 +90,7 @@ static void fuse_uring_req_end(struct fuse_ring_ent *ent, int error) fuse_uring_flush_bg(queue); spin_unlock(&fc->bg_lock); } + ent->fuse_req = NULL; spin_unlock(&queue->lock); @@ -97,8 +98,7 @@ static void fuse_uring_req_end(struct fuse_ring_ent *ent, int error) req->out.h.error = error; clear_bit(FR_SENT, &req->flags); - fuse_request_end(ent->fuse_req); - ent->fuse_req = NULL; + fuse_request_end(req); } /* Abort all list queued request on the given ring queue */ @@ -140,6 +140,21 @@ void fuse_uring_abort_end_requests(struct fuse_ring *ring) } } +static bool ent_list_request_expired(struct fuse_conn *fc, struct list_head *list) +{ + struct fuse_ring_ent *ent; + struct fuse_req *req; + + list_for_each_entry(ent, list, list) { + req = ent->fuse_req; + if (req) + return time_is_before_jiffies(req->create_time + + fc->timeout.req_timeout); + } + + return false; +} + bool fuse_uring_request_expired(struct fuse_conn *fc) { struct fuse_ring *ring = fc->ring; @@ -157,7 +172,9 @@ bool fuse_uring_request_expired(struct fuse_conn *fc) spin_lock(&queue->lock); if (fuse_request_expired(fc, &queue->fuse_req_queue) || fuse_request_expired(fc, &queue->fuse_req_bg_queue) || - fuse_fpq_processing_expired(fc, queue->fpq.processing)) { + ent_list_request_expired(fc, &queue->ent_w_req_queue) || + ent_list_request_expired(fc, &queue->ent_in_userspace) || + ent_list_request_expired(fc, &queue->ent_commit_queue)) { spin_unlock(&queue->lock); return true; } diff --git a/fs/fuse/fuse_dev_i.h b/fs/fuse/fuse_dev_i.h index 3c4ae4d52b6f..19c29c6000a7 100644 --- a/fs/fuse/fuse_dev_i.h +++ b/fs/fuse/fuse_dev_i.h @@ -63,7 +63,6 @@ void fuse_dev_queue_forget(struct fuse_iqueue *fiq, void fuse_dev_queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req); bool fuse_request_expired(struct fuse_conn *fc, struct list_head *list); -bool fuse_fpq_processing_expired(struct fuse_conn *fc, struct list_head *processing); #endif -- 2.43.5