diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 2c9a92f1e52570f45d558c9d3490fb955cb859ce..9057cc768ca534ee8ef65532bfd5c1f085fc28bd 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -49,7 +49,8 @@ struct virtio_balloon { struct virtqueue *inflate_vq, *deflate_vq, *stats_vq; /* The balloon servicing is delegated to a freezable workqueue. */ - struct work_struct work; + struct work_struct update_balloon_stats_work; + struct work_struct update_balloon_size_work; /* Prevent updating balloon when it is being canceled. */ spinlock_t stop_update_lock; @@ -76,7 +77,6 @@ struct virtio_balloon { u32 pfns[VIRTIO_BALLOON_ARRAY_PFNS_MAX]; /* Memory statistics */ - int need_stats_update; struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR]; /* To register callback in oom notifier call chain */ @@ -123,6 +123,7 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) /* When host has read buffer, this completes via balloon_ack */ wait_event(vb->acked, virtqueue_get_buf(vq, &len)); + } static void set_page_pfns(u32 pfns[], struct page *page) @@ -262,11 +263,9 @@ static void stats_request(struct virtqueue *vq) { struct virtio_balloon *vb = vq->vdev->priv; - vb->need_stats_update = 1; - spin_lock(&vb->stop_update_lock); if (!vb->stop_update) - queue_work(system_freezable_wq, &vb->work); + queue_work(system_freezable_wq, &vb->update_balloon_stats_work); spin_unlock(&vb->stop_update_lock); } @@ -276,7 +275,6 @@ static void stats_handle_request(struct virtio_balloon *vb) struct scatterlist sg; unsigned int len; - vb->need_stats_update = 0; update_balloon_stats(vb); vq = vb->stats_vq; @@ -294,7 +292,7 @@ static void virtballoon_changed(struct virtio_device *vdev) spin_lock_irqsave(&vb->stop_update_lock, flags); if (!vb->stop_update) - queue_work(system_freezable_wq, &vb->work); + queue_work(system_freezable_wq, &vb->update_balloon_size_work); spin_unlock_irqrestore(&vb->stop_update_lock, flags); } @@ -358,17 +356,24 @@ static int virtballoon_oom_notify(struct notifier_block *self, return NOTIFY_OK; } -static void balloon(struct work_struct *work) +static void update_balloon_stats_func(struct work_struct *work) +{ + struct virtio_balloon *vb; + + vb = container_of(work, struct virtio_balloon, + update_balloon_stats_work); + stats_handle_request(vb); +} + +static void update_balloon_size_func(struct work_struct *work) { struct virtio_balloon *vb; s64 diff; - vb = container_of(work, struct virtio_balloon, work); + vb = container_of(work, struct virtio_balloon, + update_balloon_size_work); diff = towards_target(vb); - if (vb->need_stats_update) - stats_handle_request(vb); - if (diff > 0) diff -= fill_balloon(vb, diff); else if (diff < 0) @@ -494,14 +499,14 @@ static int virtballoon_probe(struct virtio_device *vdev) goto out; } - INIT_WORK(&vb->work, balloon); + INIT_WORK(&vb->update_balloon_stats_work, update_balloon_stats_func); + INIT_WORK(&vb->update_balloon_size_work, update_balloon_size_func); spin_lock_init(&vb->stop_update_lock); vb->stop_update = false; vb->num_pages = 0; mutex_init(&vb->balloon_lock); init_waitqueue_head(&vb->acked); vb->vdev = vdev; - vb->need_stats_update = 0; balloon_devinfo_init(&vb->vb_dev_info); #ifdef CONFIG_BALLOON_COMPACTION @@ -552,7 +557,8 @@ static void virtballoon_remove(struct virtio_device *vdev) spin_lock_irq(&vb->stop_update_lock); vb->stop_update = true; spin_unlock_irq(&vb->stop_update_lock); - cancel_work_sync(&vb->work); + cancel_work_sync(&vb->update_balloon_size_work); + cancel_work_sync(&vb->update_balloon_stats_work); remove_common(vb); kfree(vb);