virtio-balloon: tweak config_changed implementation

virtio-ccw has deadlock issues with reading the config space inside the
interrupt context, so we tweak the virtballoon_changed implementation
by moving the config read operations into the related workqueue contexts.
The config_read_bitmap is used as a flag to the workqueue callbacks
about the related config fields that need to be read.

The cmd_id_received is also renamed to cmd_id_received_cache, and
the value should be obtained via virtio_balloon_cmd_id_received.

Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Cc: stable@vger.kernel.org
Fixes: 86a559787e6f ("virtio-balloon: VIRTIO_BALLOON_F_FREE_PAGE_HINT")
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>

authored by Wei Wang and committed by Michael S. Tsirkin bf4dc0b2 a229989d

+65 -33
+65 -33
drivers/virtio/virtio_balloon.c
··· 61 61 VIRTIO_BALLOON_VQ_MAX 62 62 }; 63 63 64 + enum virtio_balloon_config_read { 65 + VIRTIO_BALLOON_CONFIG_READ_CMD_ID = 0, 66 + }; 67 + 64 68 struct virtio_balloon { 65 69 struct virtio_device *vdev; 66 70 struct virtqueue *inflate_vq, *deflate_vq, *stats_vq, *free_page_vq; ··· 81 77 /* Prevent updating balloon when it is being canceled. */ 82 78 spinlock_t stop_update_lock; 83 79 bool stop_update; 80 + /* Bitmap to indicate if reading the related config fields are needed */ 81 + unsigned long config_read_bitmap; 84 82 85 83 /* The list of allocated free pages, waiting to be given back to mm */ 86 84 struct list_head free_page_list; 87 85 spinlock_t free_page_list_lock; 88 86 /* The number of free page blocks on the above list */ 89 87 unsigned long num_free_page_blocks; 90 - /* The cmd id received from host */ 91 - u32 cmd_id_received; 88 + /* 89 + * The cmd id received from host. 90 + * Read it via virtio_balloon_cmd_id_received to get the latest value 91 + * sent from host. 92 + */ 93 + u32 cmd_id_received_cache; 92 94 /* The cmd id that is actively in use */ 93 95 __virtio32 cmd_id_active; 94 96 /* Buffer to store the stop sign */ ··· 400 390 return num_returned; 401 391 } 402 392 393 + static void virtio_balloon_queue_free_page_work(struct virtio_balloon *vb) 394 + { 395 + if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) 396 + return; 397 + 398 + /* No need to queue the work if the bit was already set. */ 399 + if (test_and_set_bit(VIRTIO_BALLOON_CONFIG_READ_CMD_ID, 400 + &vb->config_read_bitmap)) 401 + return; 402 + 403 + queue_work(vb->balloon_wq, &vb->report_free_page_work); 404 + } 405 + 403 406 static void virtballoon_changed(struct virtio_device *vdev) 404 407 { 405 408 struct virtio_balloon *vb = vdev->priv; 406 409 unsigned long flags; 407 - s64 diff = towards_target(vb); 408 410 409 - if (diff) { 410 - spin_lock_irqsave(&vb->stop_update_lock, flags); 411 - if (!vb->stop_update) 412 - queue_work(system_freezable_wq, 413 - &vb->update_balloon_size_work); 414 - spin_unlock_irqrestore(&vb->stop_update_lock, flags); 411 + spin_lock_irqsave(&vb->stop_update_lock, flags); 412 + if (!vb->stop_update) { 413 + queue_work(system_freezable_wq, 414 + &vb->update_balloon_size_work); 415 + virtio_balloon_queue_free_page_work(vb); 415 416 } 416 - 417 - if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { 418 - virtio_cread(vdev, struct virtio_balloon_config, 419 - free_page_report_cmd_id, &vb->cmd_id_received); 420 - if (vb->cmd_id_received == VIRTIO_BALLOON_CMD_ID_DONE) { 421 - /* Pass ULONG_MAX to give back all the free pages */ 422 - return_free_pages_to_mm(vb, ULONG_MAX); 423 - } else if (vb->cmd_id_received != VIRTIO_BALLOON_CMD_ID_STOP && 424 - vb->cmd_id_received != 425 - virtio32_to_cpu(vdev, vb->cmd_id_active)) { 426 - spin_lock_irqsave(&vb->stop_update_lock, flags); 427 - if (!vb->stop_update) { 428 - queue_work(vb->balloon_wq, 429 - &vb->report_free_page_work); 430 - } 431 - spin_unlock_irqrestore(&vb->stop_update_lock, flags); 432 - } 433 - } 417 + spin_unlock_irqrestore(&vb->stop_update_lock, flags); 434 418 } 435 419 436 420 static void update_balloon_size(struct virtio_balloon *vb) ··· 531 527 return 0; 532 528 } 533 529 530 + static u32 virtio_balloon_cmd_id_received(struct virtio_balloon *vb) 531 + { 532 + if (test_and_clear_bit(VIRTIO_BALLOON_CONFIG_READ_CMD_ID, 533 + &vb->config_read_bitmap)) 534 + virtio_cread(vb->vdev, struct virtio_balloon_config, 535 + free_page_report_cmd_id, 536 + &vb->cmd_id_received_cache); 537 + 538 + return vb->cmd_id_received_cache; 539 + } 540 + 534 541 static int send_cmd_id_start(struct virtio_balloon *vb) 535 542 { 536 543 struct scatterlist sg; ··· 552 537 while (virtqueue_get_buf(vq, &unused)) 553 538 ; 554 539 555 - vb->cmd_id_active = cpu_to_virtio32(vb->vdev, vb->cmd_id_received); 540 + vb->cmd_id_active = virtio32_to_cpu(vb->vdev, 541 + virtio_balloon_cmd_id_received(vb)); 556 542 sg_init_one(&sg, &vb->cmd_id_active, sizeof(vb->cmd_id_active)); 557 543 err = virtqueue_add_outbuf(vq, &sg, 1, &vb->cmd_id_active, GFP_KERNEL); 558 544 if (!err) ··· 636 620 * stop the reporting. 637 621 */ 638 622 cmd_id_active = virtio32_to_cpu(vb->vdev, vb->cmd_id_active); 639 - if (cmd_id_active != vb->cmd_id_received) 623 + if (unlikely(cmd_id_active != 624 + virtio_balloon_cmd_id_received(vb))) 640 625 break; 641 626 642 627 /* ··· 654 637 return 0; 655 638 } 656 639 657 - static void report_free_page_func(struct work_struct *work) 640 + static void virtio_balloon_report_free_page(struct virtio_balloon *vb) 658 641 { 659 642 int err; 660 - struct virtio_balloon *vb = container_of(work, struct virtio_balloon, 661 - report_free_page_work); 662 643 struct device *dev = &vb->vdev->dev; 663 644 664 645 /* Start by sending the received cmd id to host with an outbuf. */ ··· 672 657 err = send_cmd_id_stop(vb); 673 658 if (unlikely(err)) 674 659 dev_err(dev, "Failed to send a stop id, err = %d\n", err); 660 + } 661 + 662 + static void report_free_page_func(struct work_struct *work) 663 + { 664 + struct virtio_balloon *vb = container_of(work, struct virtio_balloon, 665 + report_free_page_work); 666 + u32 cmd_id_received; 667 + 668 + cmd_id_received = virtio_balloon_cmd_id_received(vb); 669 + if (cmd_id_received == VIRTIO_BALLOON_CMD_ID_DONE) { 670 + /* Pass ULONG_MAX to give back all the free pages */ 671 + return_free_pages_to_mm(vb, ULONG_MAX); 672 + } else if (cmd_id_received != VIRTIO_BALLOON_CMD_ID_STOP && 673 + cmd_id_received != 674 + virtio32_to_cpu(vb->vdev, vb->cmd_id_active)) { 675 + virtio_balloon_report_free_page(vb); 676 + } 675 677 } 676 678 677 679 #ifdef CONFIG_BALLOON_COMPACTION ··· 917 885 goto out_del_vqs; 918 886 } 919 887 INIT_WORK(&vb->report_free_page_work, report_free_page_func); 920 - vb->cmd_id_received = VIRTIO_BALLOON_CMD_ID_STOP; 888 + vb->cmd_id_received_cache = VIRTIO_BALLOON_CMD_ID_STOP; 921 889 vb->cmd_id_active = cpu_to_virtio32(vb->vdev, 922 890 VIRTIO_BALLOON_CMD_ID_STOP); 923 891 vb->cmd_id_stop = cpu_to_virtio32(vb->vdev,