Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 530c4cbb authored by Paolo Valente's avatar Paolo Valente Committed by Jens Axboe
Browse files

block, bfq: unconditionally plug I/O in asymmetric scenarios



bfq detects the creation of multiple bfq_queues shortly after each
other, namely a burst of queue creations in the terminology used in the
code. If the burst is large, then no queue in the burst is granted
- either I/O-dispatch plugging when the queue remains temporarily idle
  while in service;
- or weight raising, because it causes even longer plugging.

In fact, such a plugging tends to lower throughput, while these bursts
are typically due to applications or services that spawn multiple
processes, to reach a common goal as soon as possible. Examples are a
"git grep" or the booting of a system.

Unfortunately, disabling plugging may cause a loss of service guarantees
in asymmetric scenarios, i.e., if queue weights are differentiated or if
more than one group is active.

This commit addresses this issue by no longer disabling I/O-dispatch
plugging for queues in large bursts.

Signed-off-by: default avatarPaolo Valente <paolo.valente@linaro.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent ac8b0cb4
Loading
Loading
Loading
Loading
+165 −181
Original line number Original line Diff line number Diff line
@@ -3479,15 +3479,12 @@ static bool idling_boosts_thr_without_issues(struct bfq_data *bfqd,
		bfqd->wr_busy_queues == 0;
		bfqd->wr_busy_queues == 0;
}
}


static bool idling_needed_for_service_guarantees(struct bfq_data *bfqd,
						 struct bfq_queue *bfqq)
{
/*
/*
 * There is a case where idling must be performed not for
 * There is a case where idling must be performed not for
 * throughput concerns, but to preserve service guarantees.
 * throughput concerns, but to preserve service guarantees.
 *
 *
 * To introduce this case, we can note that allowing the drive
 * To introduce this case, we can note that allowing the drive
	 * to enqueue more than one request at a time, and thereby
 * to enqueue more than one request at a time, and hence
 * delegating de facto final scheduling decisions to the
 * delegating de facto final scheduling decisions to the
 * drive's internal scheduler, entails loss of control on the
 * drive's internal scheduler, entails loss of control on the
 * actual request service order. In particular, the critical
 * actual request service order. In particular, the critical
@@ -3644,26 +3641,13 @@ static bool idling_needed_for_service_guarantees(struct bfq_data *bfqd,
 * to let requests be served in the desired order until all
 * to let requests be served in the desired order until all
 * the requests already queued in the device have been served.
 * the requests already queued in the device have been served.
 */
 */
	bool asymmetric_scenario = (bfqq->wr_coeff > 1 &&
static bool idling_needed_for_service_guarantees(struct bfq_data *bfqd,
						 struct bfq_queue *bfqq)
{
	return (bfqq->wr_coeff > 1 &&
		bfqd->wr_busy_queues <
		bfqd->wr_busy_queues <
		bfq_tot_busy_queues(bfqd)) ||
		bfq_tot_busy_queues(bfqd)) ||
		!bfq_symmetric_scenario(bfqd);
		!bfq_symmetric_scenario(bfqd);

	/*
	 * Finally, there is a case where maximizing throughput is the
	 * best choice even if it may cause unfairness toward
	 * bfqq. Such a case is when bfqq became active in a burst of
	 * queue activations. Queues that became active during a large
	 * burst benefit only from throughput, as discussed in the
	 * comments on bfq_handle_burst. Thus, if bfqq became active
	 * in a burst and not idling the device maximizes throughput,
	 * then the device must no be idled, because not idling the
	 * device provides bfqq and all other queues in the burst with
	 * maximum benefit. Combining this and the above case, we can
	 * now establish when idling is actually needed to preserve
	 * service guarantees.
	 */
	return asymmetric_scenario && !bfq_bfqq_in_large_burst(bfqq);
}
}


/*
/*