Re: [PATCH 1/6] block: Add blk_completion
From: Christoph Hellwig
Date: Tue Oct 27 2020 - 14:30:44 EST
On Thu, Oct 22, 2020 at 10:22:23PM +0100, Matthew Wilcox (Oracle) wrote:
> This new data structure allows a task to wait for N things to complete.
> Usually the submitting task will handle cleanup, but if it is killed,
> the last completer will take care of it.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx>
> ---
> block/blk-core.c | 61 +++++++++++++++++++++++++++++++++++++++++++++
> include/linux/bio.h | 11 ++++++++
> 2 files changed, 72 insertions(+)
>
> diff --git a/block/blk-core.c b/block/blk-core.c
> index 10c08ac50697..2892246f2176 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -1900,6 +1900,67 @@ void blk_io_schedule(void)
> }
> EXPORT_SYMBOL_GPL(blk_io_schedule);
>
> +void blk_completion_init(struct blk_completion *cmpl, int n)
> +{
> + spin_lock_init(&cmpl->cmpl_lock);
> + cmpl->cmpl_count = n;
> + cmpl->cmpl_task = current;
> + cmpl->cmpl_status = BLK_STS_OK;
> +}
> +
> +int blk_completion_sub(struct blk_completion *cmpl, blk_status_t status, int n)
This needs documentation. e.g. to explain what 'n' is.
> +int blk_completion_wait_killable(struct blk_completion *cmpl)
> +{
> + int err = 0;
> +
> + for (;;) {
> + set_current_state(TASK_KILLABLE);
> + spin_lock_bh(&cmpl->cmpl_lock);
> + if (cmpl->cmpl_count == 0)
> + break;
> + spin_unlock_bh(&cmpl->cmpl_lock);
> + blk_io_schedule();
> + if (fatal_signal_pending(current)) {
> + spin_lock_bh(&cmpl->cmpl_lock);
> + cmpl->cmpl_task = NULL;
> + if (cmpl->cmpl_count != 0) {
> + spin_unlock_bh(&cmpl->cmpl_lock);
> + cmpl = NULL;
> + }
> + err = -ERESTARTSYS;
> + break;
> + }
> + }
> + set_current_state(TASK_RUNNING);
> + if (cmpl) {
> + spin_unlock_bh(&cmpl->cmpl_lock);
> + err = blk_status_to_errno(cmpl->cmpl_status);
> + kfree(cmpl);
> + }
> +
> + return err;
> +}
What are the life time rules for cmpl? Who frees it in the case
of a fatal signal?