Skip to content

Commit

Permalink
xen/blkfront: always allocate grants first from per-queue persistent …
Browse files Browse the repository at this point in the history
…grants

This patch partially reverts 3df0e50 ("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 73716df ("xen/blkfront:
make persistent grants pool per-queue"), we should always allocate from
persistent grants first.

Acked-by: Roger Pau Monné <roger.pau@citrix.com>
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
  • Loading branch information
Dongli Zhang authored and Konrad Rzeszutek Wilk committed Jul 25, 2017
1 parent 4b422cb commit bd912ef
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions drivers/block/xen-blkfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit bd912ef

Please sign in to comment.