]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fuse: optimize over-io-uring request expiration check
authorJoanne Koong <joannelkoong@gmail.com>
Mon, 3 Feb 2025 19:30:22 +0000 (11:30 -0800)
committerMiklos Szeredi <mszeredi@redhat.com>
Tue, 15 Apr 2025 11:43:38 +0000 (13:43 +0200)
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
and ent_in_userspace.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/dev.c
fs/fuse/dev_uring.c
fs/fuse/fuse_dev_i.h

index c0b55bacecb1cd0e25690e913fad3c9e2396b91d..155bb6aeaef57f74687d5c3f4872bd284eb2533b 100644 (file)
@@ -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;
 
index cece9698fd6800f1e7b8492825050ffd19c4ff6c..249b210becb1cc2b40ae7b2fdf3a57dc57eaac42 100644 (file)
@@ -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;
+
+       ent = list_first_entry_or_null(list, struct fuse_ring_ent, list);
+       if (!ent)
+               return false;
+
+       req = ent->fuse_req;
+
+       return time_is_before_jiffies(req->create_time +
+                                     fc->timeout.req_timeout);
+}
+
 bool fuse_uring_request_expired(struct fuse_conn *fc)
 {
        struct fuse_ring *ring = fc->ring;
@@ -157,7 +172,8 @@ 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)) {
                        spin_unlock(&queue->lock);
                        return true;
                }
@@ -494,7 +510,7 @@ static void fuse_uring_cancel(struct io_uring_cmd *cmd,
        spin_lock(&queue->lock);
        if (ent->state == FRRS_AVAILABLE) {
                ent->state = FRRS_USERSPACE;
-               list_move(&ent->list, &queue->ent_in_userspace);
+               list_move_tail(&ent->list, &queue->ent_in_userspace);
                need_cmd_done = true;
                ent->cmd = NULL;
        }
@@ -714,7 +730,7 @@ static int fuse_uring_send_next_to_ring(struct fuse_ring_ent *ent,
        cmd = ent->cmd;
        ent->cmd = NULL;
        ent->state = FRRS_USERSPACE;
-       list_move(&ent->list, &queue->ent_in_userspace);
+       list_move_tail(&ent->list, &queue->ent_in_userspace);
        spin_unlock(&queue->lock);
 
        io_uring_cmd_done(cmd, 0, 0, issue_flags);
@@ -764,7 +780,7 @@ static void fuse_uring_add_req_to_ring_ent(struct fuse_ring_ent *ent,
        clear_bit(FR_PENDING, &req->flags);
        ent->fuse_req = req;
        ent->state = FRRS_FUSE_REQ;
-       list_move(&ent->list, &queue->ent_w_req_queue);
+       list_move_tail(&ent->list, &queue->ent_w_req_queue);
        fuse_uring_add_to_pq(ent, req);
 }
 
@@ -1180,7 +1196,7 @@ static void fuse_uring_send(struct fuse_ring_ent *ent, struct io_uring_cmd *cmd,
 
        spin_lock(&queue->lock);
        ent->state = FRRS_USERSPACE;
-       list_move(&ent->list, &queue->ent_in_userspace);
+       list_move_tail(&ent->list, &queue->ent_in_userspace);
        ent->cmd = NULL;
        spin_unlock(&queue->lock);
 
index d2e16f73ac99677ebfc9307f1b7693fe81b2b75c..db136e045925f1823e74f8e75c53676c781e5acb 100644 (file)
@@ -64,7 +64,6 @@ void fuse_dev_queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req);
 bool fuse_remove_pending_req(struct fuse_req *req, spinlock_t *lock);
 
 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