virtio_balloon: prevent uninitialized variable use
[pandora-kernel.git] / drivers / virtio / virtio_balloon.c
index 94fd738..bc7c26d 100644 (file)
@@ -142,6 +142,8 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)
        /* We can only do one array worth at a time. */
        num = min(num, ARRAY_SIZE(vb->pfns));
 
+       /* We can't release more pages than taken */
+       num = min(num, (size_t)vb->num_pages);
        for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
                page = list_first_entry(&vb->pages, struct page, lru);
                list_del(&page->lru);
@@ -178,12 +180,14 @@ static void update_balloon_stats(struct virtio_balloon *vb)
        all_vm_events(events);
        si_meminfo(&i);
 
+#ifdef CONFIG_VM_EVENT_COUNTERS
        update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN,
                                pages_to_bytes(events[PSWPIN]));
        update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_OUT,
                                pages_to_bytes(events[PSWPOUT]));
        update_stat(vb, idx++, VIRTIO_BALLOON_S_MAJFLT, events[PGMAJFAULT]);
        update_stat(vb, idx++, VIRTIO_BALLOON_S_MINFLT, events[PGFAULT]);
+#endif
        update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMFREE,
                                pages_to_bytes(i.freeram));
        update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMTOT,
@@ -271,6 +275,12 @@ static int balloon(void *_vballoon)
                else if (diff < 0)
                        leak_balloon(vb, -diff);
                update_balloon_size(vb);
+
+               /*
+                * For large balloon changes, we could spend a lot of time
+                * and always have work to do.  Be nice if preempt disabled.
+                */
+               cond_resched();
        }
        return 0;
 }
@@ -312,6 +322,8 @@ static int virtballoon_probe(struct virtio_device *vdev)
                 * Prime this virtqueue with one buffer so the hypervisor can
                 * use it to signal us later.
                 */
+               update_balloon_stats(vb);
+
                sg_init_one(&sg, vb->stats, sizeof vb->stats);
                if (virtqueue_add_buf(vb->stats_vq, &sg, 1, 0, vb) < 0)
                        BUG();