Message ID | 20250205202641.646812-2-axboe@kernel.dk (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Cancelation cleanups | expand |
> -----Original Message----- > From: Jens Axboe <axboe@kernel.dk> > Sent: Thursday, February 6, 2025 4:26 AM > To: io-uring@vger.kernel.org > Cc: Jens Axboe <axboe@kernel.dk> > Subject: [PATCH 1/6] io_uring/cancel: add generic remove_all helper > > Any opcode that is cancelable ends up defining its own remove all helper, which > iterates the pending list and cancels matches. Add a generic helper for it, which > can be used by them. > > Signed-off-by: Jens Axboe <axboe@kernel.dk> > --- > io_uring/cancel.c | 20 ++++++++++++++++++++ io_uring/cancel.h | 4 ++++ > 2 files changed, 24 insertions(+) > > diff --git a/io_uring/cancel.c b/io_uring/cancel.c index > 484193567839..0565dc0d7611 100644 > --- a/io_uring/cancel.c > +++ b/io_uring/cancel.c > @@ -341,3 +341,23 @@ int io_sync_cancel(struct io_ring_ctx *ctx, void __user > *arg) > fput(file); > return ret; > } > + > +bool io_cancel_remove_all(struct io_ring_ctx *ctx, struct io_uring_task *tctx, > + struct hlist_head *list, bool cancel_all, > + bool (*cancel)(struct io_kiocb *)) { > + struct hlist_node *tmp; > + struct io_kiocb *req; > + bool found = false; > + > + lockdep_assert_held(&ctx->uring_lock); > + > + hlist_for_each_entry_safe(req, tmp, list, hash_node) { > + if (!io_match_task_safe(req, tctx, cancel_all)) > + continue; Should call hlist_del_init(&req->hash_node) here, just like the original code logic. > + if (cancel(req)) > + found = true; > + } > + > + return found; > +} > diff --git a/io_uring/cancel.h b/io_uring/cancel.h index > bbfea2cd00ea..80734a0a2b26 100644 > --- a/io_uring/cancel.h > +++ b/io_uring/cancel.h > @@ -24,6 +24,10 @@ int io_try_cancel(struct io_uring_task *tctx, struct > io_cancel_data *cd, int io_sync_cancel(struct io_ring_ctx *ctx, void __user > *arg); bool io_cancel_req_match(struct io_kiocb *req, struct io_cancel_data > *cd); > > +bool io_cancel_remove_all(struct io_ring_ctx *ctx, struct io_uring_task *tctx, > + struct hlist_head *list, bool cancel_all, > + bool (*cancel)(struct io_kiocb *)); > + > static inline bool io_cancel_match_sequence(struct io_kiocb *req, int sequence) > { > if (req->cancel_seq_set && sequence == req->work.cancel_seq) > -- > 2.47.2 > --- Li Zetao
On 2/6/25 5:46 AM, lizetao wrote: > > >> -----Original Message----- >> From: Jens Axboe <axboe@kernel.dk> >> Sent: Thursday, February 6, 2025 4:26 AM >> To: io-uring@vger.kernel.org >> Cc: Jens Axboe <axboe@kernel.dk> >> Subject: [PATCH 1/6] io_uring/cancel: add generic remove_all helper >> >> Any opcode that is cancelable ends up defining its own remove all helper, which >> iterates the pending list and cancels matches. Add a generic helper for it, which >> can be used by them. >> >> Signed-off-by: Jens Axboe <axboe@kernel.dk> >> --- >> io_uring/cancel.c | 20 ++++++++++++++++++++ io_uring/cancel.h | 4 ++++ >> 2 files changed, 24 insertions(+) >> >> diff --git a/io_uring/cancel.c b/io_uring/cancel.c index >> 484193567839..0565dc0d7611 100644 >> --- a/io_uring/cancel.c >> +++ b/io_uring/cancel.c >> @@ -341,3 +341,23 @@ int io_sync_cancel(struct io_ring_ctx *ctx, void __user >> *arg) >> fput(file); >> return ret; >> } >> + >> +bool io_cancel_remove_all(struct io_ring_ctx *ctx, struct io_uring_task *tctx, >> + struct hlist_head *list, bool cancel_all, >> + bool (*cancel)(struct io_kiocb *)) { >> + struct hlist_node *tmp; >> + struct io_kiocb *req; >> + bool found = false; >> + >> + lockdep_assert_held(&ctx->uring_lock); >> + >> + hlist_for_each_entry_safe(req, tmp, list, hash_node) { >> + if (!io_match_task_safe(req, tctx, cancel_all)) >> + continue; > > Should call hlist_del_init(&req->hash_node) here, just like the > original code logic. Indeed, good catch! I'll make the change.
diff --git a/io_uring/cancel.c b/io_uring/cancel.c index 484193567839..0565dc0d7611 100644 --- a/io_uring/cancel.c +++ b/io_uring/cancel.c @@ -341,3 +341,23 @@ int io_sync_cancel(struct io_ring_ctx *ctx, void __user *arg) fput(file); return ret; } + +bool io_cancel_remove_all(struct io_ring_ctx *ctx, struct io_uring_task *tctx, + struct hlist_head *list, bool cancel_all, + bool (*cancel)(struct io_kiocb *)) +{ + struct hlist_node *tmp; + struct io_kiocb *req; + bool found = false; + + lockdep_assert_held(&ctx->uring_lock); + + hlist_for_each_entry_safe(req, tmp, list, hash_node) { + if (!io_match_task_safe(req, tctx, cancel_all)) + continue; + if (cancel(req)) + found = true; + } + + return found; +} diff --git a/io_uring/cancel.h b/io_uring/cancel.h index bbfea2cd00ea..80734a0a2b26 100644 --- a/io_uring/cancel.h +++ b/io_uring/cancel.h @@ -24,6 +24,10 @@ int io_try_cancel(struct io_uring_task *tctx, struct io_cancel_data *cd, int io_sync_cancel(struct io_ring_ctx *ctx, void __user *arg); bool io_cancel_req_match(struct io_kiocb *req, struct io_cancel_data *cd); +bool io_cancel_remove_all(struct io_ring_ctx *ctx, struct io_uring_task *tctx, + struct hlist_head *list, bool cancel_all, + bool (*cancel)(struct io_kiocb *)); + static inline bool io_cancel_match_sequence(struct io_kiocb *req, int sequence) { if (req->cancel_seq_set && sequence == req->work.cancel_seq)
Any opcode that is cancelable ends up defining its own remove all helper, which iterates the pending list and cancels matches. Add a generic helper for it, which can be used by them. Signed-off-by: Jens Axboe <axboe@kernel.dk> --- io_uring/cancel.c | 20 ++++++++++++++++++++ io_uring/cancel.h | 4 ++++ 2 files changed, 24 insertions(+)