diff options
author | Dongli Zhang <dongli.zhang@oracle.com> | 2017-06-28 08:57:28 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2017-07-25 11:31:09 -0400 |
commit | bd912ef3e46b6edb51bb8af4b73fd2be7817e305 (patch) | |
tree | 61b5281d5730da8d913a400b63182e64375bdc02 | |
parent | 4b422cb99836de3d261faec20a0329385bdec43d (diff) |
xen/blkfront: always allocate grants first from per-queue persistent 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>
-rw-r--r-- | drivers/block/xen-blkfront.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 04eeb540490f..98e34e4c62b8 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -708,6 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri | |||
708 | * existing persistent grants, or if we have to get new grants, | 708 | * existing persistent grants, or if we have to get new grants, |
709 | * as there are not sufficiently many free. | 709 | * as there are not sufficiently many free. |
710 | */ | 710 | */ |
711 | bool new_persistent_gnts = false; | ||
711 | struct scatterlist *sg; | 712 | struct scatterlist *sg; |
712 | int num_sg, max_grefs, num_grant; | 713 | int num_sg, max_grefs, num_grant; |
713 | 714 | ||
@@ -719,19 +720,21 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri | |||
719 | */ | 720 | */ |
720 | max_grefs += INDIRECT_GREFS(max_grefs); | 721 | max_grefs += INDIRECT_GREFS(max_grefs); |
721 | 722 | ||
722 | /* | 723 | /* Check if we have enough persistent grants to allocate a requests */ |
723 | * We have to reserve 'max_grefs' grants because persistent | 724 | if (rinfo->persistent_gnts_c < max_grefs) { |
724 | * grants are shared by all rings. | 725 | new_persistent_gnts = true; |
725 | */ | 726 | |
726 | if (max_grefs > 0) | 727 | if (gnttab_alloc_grant_references( |
727 | if (gnttab_alloc_grant_references(max_grefs, &setup.gref_head) < 0) { | 728 | max_grefs - rinfo->persistent_gnts_c, |
729 | &setup.gref_head) < 0) { | ||
728 | gnttab_request_free_callback( | 730 | gnttab_request_free_callback( |
729 | &rinfo->callback, | 731 | &rinfo->callback, |
730 | blkif_restart_queue_callback, | 732 | blkif_restart_queue_callback, |
731 | rinfo, | 733 | rinfo, |
732 | max_grefs); | 734 | max_grefs - rinfo->persistent_gnts_c); |
733 | return 1; | 735 | return 1; |
734 | } | 736 | } |
737 | } | ||
735 | 738 | ||
736 | /* Fill out a communications ring structure. */ | 739 | /* Fill out a communications ring structure. */ |
737 | id = blkif_ring_get_request(rinfo, req, &ring_req); | 740 | 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 | if (unlikely(require_extra_req)) | 835 | if (unlikely(require_extra_req)) |
833 | rinfo->shadow[extra_id].req = *extra_ring_req; | 836 | rinfo->shadow[extra_id].req = *extra_ring_req; |
834 | 837 | ||
835 | if (max_grefs > 0) | 838 | if (new_persistent_gnts) |
836 | gnttab_free_grant_references(setup.gref_head); | 839 | gnttab_free_grant_references(setup.gref_head); |
837 | 840 | ||
838 | return 0; | 841 | return 0; |