Re: [PATCH V9 4/8] block, bfq: turn bfqq_data into an array in bfq_io_cq

From: Damien Le Moal
Date: Thu Dec 08 2022 - 20:30:39 EST


On 12/8/22 19:43, Paolo Valente wrote:
> When a bfq_queue Q is merged with another queue, several pieces of
> information are saved about Q. These pieces are stored in the
> bfqq_data field in the bfq_io_cq data structure of the process
> associated with Q.
>
> Yet, with a multi-actuator drive, a process may get associated with
> multiple bfq_queues: one queue for each of the N actuators. Each of
> these queues may undergo a merge. So, the bfq_io_cq data structure
> must be able to accommodate the above information for N queues.
>
> This commit solves this problem by turning the bfqq_data scalar field
> into an array of N elements (and by changing code so as to handle
> this array).
>
> This solution is written under the assumption that bfq_queues
> associated with different actuators cannot be cross-merged. This
> assumption holds naturally with basic queue merging: the latter is
> triggered by spatial locality, and sectors for different actuators are
> not close to each other (apart from the corner case of the last
> sectors served by a given actuator and the first sectors served by the
> next actuator). As for stable cross-merging, the assumption here is
> that it is disabled.
>
> Signed-off-by: Gabriele Felici <felicigb@xxxxxxxxx>
> Signed-off-by: Gianmarco Lusvardi <glusvardi@xxxxxxxxxx>
> Signed-off-by: Giulio Barabino <giuliobarabino99@xxxxxxxxx>
> Signed-off-by: Emiliano Maccaferri <inbox@xxxxxxxxxxxxxxxxxxxxxx>
> Signed-off-by: Paolo Valente <paolo.valente@xxxxxxxxxx>
> ---
> block/bfq-iosched.c | 95 +++++++++++++++++++++++++++------------------
> block/bfq-iosched.h | 12 ++++--
> 2 files changed, 65 insertions(+), 42 deletions(-)
>
> diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
> index 0d6b35ef3d3f..18e2b8f75435 100644
> --- a/block/bfq-iosched.c
> +++ b/block/bfq-iosched.c
> @@ -406,7 +406,7 @@ void bic_set_bfqq(struct bfq_io_cq *bic,
> * we cancel the stable merge if
> * bic->stable_merge_bfqq == bfqq.
> */
> - struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data;
> + struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data[actuator_idx];
>
> if (is_sync)
> bic->bfqq[1][actuator_idx] = bfqq;
> @@ -1181,9 +1181,10 @@ static void
> bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
> struct bfq_io_cq *bic, bool bfq_already_existing)
> {
> - struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data;
> unsigned int old_wr_coeff = 1;
> bool busy = bfq_already_existing && bfq_bfqq_busy(bfqq);
> + unsigned int a_idx = bfqq->actuator_idx;
> + struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data[a_idx];
>
> if (bfqq_data->saved_has_short_ttime)
> bfq_mark_bfqq_has_short_ttime(bfqq);
> @@ -1899,7 +1900,9 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
> wr_or_deserves_wr = bfqd->low_latency &&
> (bfqq->wr_coeff > 1 ||
> (bfq_bfqq_sync(bfqq) &&
> - (bfqq->bic || RQ_BIC(rq)->bfqq_data.stably_merged) &&
> + (bfqq->bic ||
> + RQ_BIC(rq)->bfqq_data[bfq_actuator_index(bfqd, rq->bio)]
> + .stably_merged) &&

very weird line split here...

> (*interactive || soft_rt)));
>
> /*
> @@ -2888,6 +2891,35 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq,
> static bool idling_boosts_thr_without_issues(struct bfq_data *bfqd,
> struct bfq_queue *bfqq);
>
> +static struct bfq_queue *
> +bfq_setup_stable_merge(struct bfq_data *bfqd, struct bfq_queue *bfqq,
> + struct bfq_queue *stable_merge_bfqq,
> + struct bfq_iocq_bfqq_data *bfqq_data)
> +{
> + int proc_ref = min(bfqq_process_refs(bfqq),
> + bfqq_process_refs(stable_merge_bfqq));
> +
> + if (!idling_boosts_thr_without_issues(bfqd, bfqq) &&
> + proc_ref > 0) {

If you reverse the if condition and return NULL here you can save one tab
indent level for the hunk below (no need for an else after a return).

> + /* next function will take at least one ref */
> + struct bfq_queue *new_bfqq =
> + bfq_setup_merge(bfqq, stable_merge_bfqq);
> +
> + if (new_bfqq) {
> + bfqq_data->stably_merged = true;
> + if (new_bfqq->bic) {
> + unsigned int new_a_idx = new_bfqq->actuator_idx;
> + struct bfq_iocq_bfqq_data *new_bfqq_data =
> + &new_bfqq->bic->bfqq_data[new_a_idx];
> +
> + new_bfqq_data->stably_merged = true;
> + }
> + }
> + return new_bfqq;
> + } else
> + return NULL;
> +}

Otherwise, looks OK.

Reviewed-by: Damien Le Moal <damien.lemoal@xxxxxxxxxxxxxxxxxx>

--
Damien Le Moal
Western Digital Research