On 1/24/25 00:52, Joanne Koong wrote: > 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); > } > Oh, this is actually a fix, it should be always set with the lock being held. > /* 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; > +} Hmm, would only need to check head? Oh I see it, we need to use list_move_tail(). > + > 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 >