diff options
| -rw-r--r-- | drivers/virtio/virtio_balloon.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 22caf808bfab..7f38ae687b08 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
| @@ -104,12 +104,6 @@ static u32 page_to_balloon_pfn(struct page *page) | |||
| 104 | return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE; | 104 | return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | static struct page *balloon_pfn_to_page(u32 pfn) | ||
| 108 | { | ||
| 109 | BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE); | ||
| 110 | return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE); | ||
| 111 | } | ||
| 112 | |||
| 113 | static void balloon_ack(struct virtqueue *vq) | 107 | static void balloon_ack(struct virtqueue *vq) |
| 114 | { | 108 | { |
| 115 | struct virtio_balloon *vb = vq->vdev->priv; | 109 | struct virtio_balloon *vb = vq->vdev->priv; |
| @@ -182,18 +176,16 @@ static unsigned fill_balloon(struct virtio_balloon *vb, size_t num) | |||
| 182 | return num_allocated_pages; | 176 | return num_allocated_pages; |
| 183 | } | 177 | } |
| 184 | 178 | ||
| 185 | static void release_pages_balloon(struct virtio_balloon *vb) | 179 | static void release_pages_balloon(struct virtio_balloon *vb, |
| 180 | struct list_head *pages) | ||
| 186 | { | 181 | { |
| 187 | unsigned int i; | 182 | struct page *page, *next; |
| 188 | struct page *page; | ||
| 189 | 183 | ||
| 190 | /* Find pfns pointing at start of each page, get pages and free them. */ | 184 | list_for_each_entry_safe(page, next, pages, lru) { |
| 191 | for (i = 0; i < vb->num_pfns; i += VIRTIO_BALLOON_PAGES_PER_PAGE) { | ||
| 192 | page = balloon_pfn_to_page(virtio32_to_cpu(vb->vdev, | ||
| 193 | vb->pfns[i])); | ||
| 194 | if (!virtio_has_feature(vb->vdev, | 185 | if (!virtio_has_feature(vb->vdev, |
| 195 | VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) | 186 | VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) |
| 196 | adjust_managed_page_count(page, 1); | 187 | adjust_managed_page_count(page, 1); |
| 188 | list_del(&page->lru); | ||
| 197 | put_page(page); /* balloon reference */ | 189 | put_page(page); /* balloon reference */ |
| 198 | } | 190 | } |
| 199 | } | 191 | } |
| @@ -203,6 +195,7 @@ static unsigned leak_balloon(struct virtio_balloon *vb, size_t num) | |||
| 203 | unsigned num_freed_pages; | 195 | unsigned num_freed_pages; |
| 204 | struct page *page; | 196 | struct page *page; |
| 205 | struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; | 197 | struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; |
| 198 | LIST_HEAD(pages); | ||
| 206 | 199 | ||
| 207 | /* We can only do one array worth at a time. */ | 200 | /* We can only do one array worth at a time. */ |
| 208 | num = min(num, ARRAY_SIZE(vb->pfns)); | 201 | num = min(num, ARRAY_SIZE(vb->pfns)); |
| @@ -216,6 +209,7 @@ static unsigned leak_balloon(struct virtio_balloon *vb, size_t num) | |||
| 216 | if (!page) | 209 | if (!page) |
| 217 | break; | 210 | break; |
| 218 | set_page_pfns(vb, vb->pfns + vb->num_pfns, page); | 211 | set_page_pfns(vb, vb->pfns + vb->num_pfns, page); |
| 212 | list_add(&page->lru, &pages); | ||
| 219 | vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; | 213 | vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; |
| 220 | } | 214 | } |
| 221 | 215 | ||
| @@ -227,7 +221,7 @@ static unsigned leak_balloon(struct virtio_balloon *vb, size_t num) | |||
| 227 | */ | 221 | */ |
| 228 | if (vb->num_pfns != 0) | 222 | if (vb->num_pfns != 0) |
| 229 | tell_host(vb, vb->deflate_vq); | 223 | tell_host(vb, vb->deflate_vq); |
| 230 | release_pages_balloon(vb); | 224 | release_pages_balloon(vb, &pages); |
| 231 | mutex_unlock(&vb->balloon_lock); | 225 | mutex_unlock(&vb->balloon_lock); |
| 232 | return num_freed_pages; | 226 | return num_freed_pages; |
| 233 | } | 227 | } |
