diff options
author | Jens Axboe <axboe@fb.com> | 2016-06-09 11:49:55 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2016-06-09 11:49:55 -0400 |
commit | 1decabc1a70b97ef7412224df3dcb59d1227e3af (patch) | |
tree | 3e235b7bc0b1a2edc027f90b8cab5c1a590728a8 | |
parent | d366a0ff1cf73f93796f2377e7b0361a94c41c35 (diff) | |
parent | 2a6f71ad99cabe436e70c3f5fcf58072cb3bc07f (diff) |
Merge branch 'stable/for-jens-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen into for-linus
Konrad writes:
Thishas two fixes for a guest migrating from host that
has multi-queue to one without it (and vice-versa).
-rw-r--r-- | drivers/block/xen-blkfront.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index ca13df854639..2e6d1e9c3345 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -874,8 +874,12 @@ static int blkif_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
874 | const struct blk_mq_queue_data *qd) | 874 | const struct blk_mq_queue_data *qd) |
875 | { | 875 | { |
876 | unsigned long flags; | 876 | unsigned long flags; |
877 | struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)hctx->driver_data; | 877 | int qid = hctx->queue_num; |
878 | struct blkfront_info *info = hctx->queue->queuedata; | ||
879 | struct blkfront_ring_info *rinfo = NULL; | ||
878 | 880 | ||
881 | BUG_ON(info->nr_rings <= qid); | ||
882 | rinfo = &info->rinfo[qid]; | ||
879 | blk_mq_start_request(qd->rq); | 883 | blk_mq_start_request(qd->rq); |
880 | spin_lock_irqsave(&rinfo->ring_lock, flags); | 884 | spin_lock_irqsave(&rinfo->ring_lock, flags); |
881 | if (RING_FULL(&rinfo->ring)) | 885 | if (RING_FULL(&rinfo->ring)) |
@@ -901,20 +905,9 @@ out_busy: | |||
901 | return BLK_MQ_RQ_QUEUE_BUSY; | 905 | return BLK_MQ_RQ_QUEUE_BUSY; |
902 | } | 906 | } |
903 | 907 | ||
904 | static int blk_mq_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, | ||
905 | unsigned int index) | ||
906 | { | ||
907 | struct blkfront_info *info = (struct blkfront_info *)data; | ||
908 | |||
909 | BUG_ON(info->nr_rings <= index); | ||
910 | hctx->driver_data = &info->rinfo[index]; | ||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | static struct blk_mq_ops blkfront_mq_ops = { | 908 | static struct blk_mq_ops blkfront_mq_ops = { |
915 | .queue_rq = blkif_queue_rq, | 909 | .queue_rq = blkif_queue_rq, |
916 | .map_queue = blk_mq_map_queue, | 910 | .map_queue = blk_mq_map_queue, |
917 | .init_hctx = blk_mq_init_hctx, | ||
918 | }; | 911 | }; |
919 | 912 | ||
920 | static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, | 913 | static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, |
@@ -950,6 +943,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, | |||
950 | return PTR_ERR(rq); | 943 | return PTR_ERR(rq); |
951 | } | 944 | } |
952 | 945 | ||
946 | rq->queuedata = info; | ||
953 | queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq); | 947 | queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq); |
954 | 948 | ||
955 | if (info->feature_discard) { | 949 | if (info->feature_discard) { |
@@ -2149,6 +2143,8 @@ static int blkfront_resume(struct xenbus_device *dev) | |||
2149 | return err; | 2143 | return err; |
2150 | 2144 | ||
2151 | err = talk_to_blkback(dev, info); | 2145 | err = talk_to_blkback(dev, info); |
2146 | if (!err) | ||
2147 | blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings); | ||
2152 | 2148 | ||
2153 | /* | 2149 | /* |
2154 | * We have to wait for the backend to switch to | 2150 | * We have to wait for the backend to switch to |
@@ -2485,10 +2481,23 @@ static void blkback_changed(struct xenbus_device *dev, | |||
2485 | break; | 2481 | break; |
2486 | 2482 | ||
2487 | case XenbusStateConnected: | 2483 | case XenbusStateConnected: |
2488 | if (dev->state != XenbusStateInitialised) { | 2484 | /* |
2485 | * talk_to_blkback sets state to XenbusStateInitialised | ||
2486 | * and blkfront_connect sets it to XenbusStateConnected | ||
2487 | * (if connection went OK). | ||
2488 | * | ||
2489 | * If the backend (or toolstack) decides to poke at backend | ||
2490 | * state (and re-trigger the watch by setting the state repeatedly | ||
2491 | * to XenbusStateConnected (4)) we need to deal with this. | ||
2492 | * This is allowed as this is used to communicate to the guest | ||
2493 | * that the size of disk has changed! | ||
2494 | */ | ||
2495 | if ((dev->state != XenbusStateInitialised) && | ||
2496 | (dev->state != XenbusStateConnected)) { | ||
2489 | if (talk_to_blkback(dev, info)) | 2497 | if (talk_to_blkback(dev, info)) |
2490 | break; | 2498 | break; |
2491 | } | 2499 | } |
2500 | |||
2492 | blkfront_connect(info); | 2501 | blkfront_connect(info); |
2493 | break; | 2502 | break; |
2494 | 2503 | ||