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

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
...@@ -708,6 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri ...@@ -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, * existing persistent grants, or if we have to get new grants,
* as there are not sufficiently many free. * as there are not sufficiently many free.
*/ */
bool new_persistent_gnts = false;
struct scatterlist *sg; struct scatterlist *sg;
int num_sg, max_grefs, num_grant; 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 ...@@ -719,19 +720,21 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
*/ */
max_grefs += INDIRECT_GREFS(max_grefs); max_grefs += INDIRECT_GREFS(max_grefs);
/* /* Check if we have enough persistent grants to allocate a requests */
* We have to reserve 'max_grefs' grants because persistent if (rinfo->persistent_gnts_c < max_grefs) {
* grants are shared by all rings. new_persistent_gnts = true;
*/
if (max_grefs > 0) if (gnttab_alloc_grant_references(
if (gnttab_alloc_grant_references(max_grefs, &setup.gref_head) < 0) { max_grefs - rinfo->persistent_gnts_c,
&setup.gref_head) < 0) {
gnttab_request_free_callback( gnttab_request_free_callback(
&rinfo->callback, &rinfo->callback,
blkif_restart_queue_callback, blkif_restart_queue_callback,
rinfo, rinfo,
max_grefs); max_grefs - rinfo->persistent_gnts_c);
return 1; return 1;
} }
}
/* Fill out a communications ring structure. */ /* Fill out a communications ring structure. */
id = blkif_ring_get_request(rinfo, req, &ring_req); 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 ...@@ -832,7 +835,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
if (unlikely(require_extra_req)) if (unlikely(require_extra_req))
rinfo->shadow[extra_id].req = *extra_ring_req; rinfo->shadow[extra_id].req = *extra_ring_req;
if (max_grefs > 0) if (new_persistent_gnts)
gnttab_free_grant_references(setup.gref_head); gnttab_free_grant_references(setup.gref_head);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment