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

Commit bd912ef3 authored by Dongli Zhang's avatar Dongli Zhang Committed by Konrad Rzeszutek Wilk
Browse files

xen/blkfront: always allocate grants first from per-queue persistent grants



This patch partially reverts 3df0e505 ("xen/blkfront: pseudo support for
multi hardware queues/rings"). The xen-blkfront queue/ring might hang due
to grants allocation failure in the situation when gnttab_free_head is
almost empty while many persistent grants are reserved for this queue/ring.

As persistent grants management was per-queue since 73716df7 ("xen/blkfront:
make persistent grants pool per-queue"), we should always allocate from
persistent grants first.

Acked-by: default avatarRoger Pau Monné <roger.pau@citrix.com>
Signed-off-by: default avatarDongli Zhang <dongli.zhang@oracle.com>
Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
parent 4b422cb9
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -708,6 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
	 * existing persistent grants, or if we have to get new grants,
	 * as there are not sufficiently many free.
	 */
	bool new_persistent_gnts = false;
	struct scatterlist *sg;
	int num_sg, max_grefs, num_grant;

@@ -719,19 +720,21 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
		 */
		max_grefs += INDIRECT_GREFS(max_grefs);

	/*
	 * We have to reserve 'max_grefs' grants because persistent
	 * grants are shared by all rings.
	 */
	if (max_grefs > 0)
		if (gnttab_alloc_grant_references(max_grefs, &setup.gref_head) < 0) {
	/* Check if we have enough persistent grants to allocate a requests */
	if (rinfo->persistent_gnts_c < max_grefs) {
		new_persistent_gnts = true;

		if (gnttab_alloc_grant_references(
		    max_grefs - rinfo->persistent_gnts_c,
		    &setup.gref_head) < 0) {
			gnttab_request_free_callback(
				&rinfo->callback,
				blkif_restart_queue_callback,
				rinfo,
				max_grefs);
				max_grefs - rinfo->persistent_gnts_c);
			return 1;
		}
	}

	/* Fill out a communications ring structure. */
	id = blkif_ring_get_request(rinfo, req, &ring_req);
@@ -832,7 +835,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
	if (unlikely(require_extra_req))
		rinfo->shadow[extra_id].req = *extra_ring_req;

	if (max_grefs > 0)
	if (new_persistent_gnts)
		gnttab_free_grant_references(setup.gref_head);

	return 0;