From: Akio T. <tak...@jp...> - 2008-01-10 07:14:20
|
Hi, Marcelo >+struct balloon_buf *alloc_balloon_buf(struct virtio_device *vdev, gfp_t >flags) >+{ >+ struct balloon_buf *buf; >+ >+ buf = kzalloc(sizeof(struct balloon_buf), flags); >+ if (!buf) >+ dev_printk(KERN_ERR, &vdev->dev, "%s: alloc fail\n", __func__); >+ >+ return buf; >+} >+ [snip..] >+static int kvm_balloon_inflate(struct virtballoon *v, int32_t npages) >+{ >+ LIST_HEAD(tmp_list); >+ struct page *page, *tmp; >+ struct balloon_buf *buf; >+ u32 *pfn; >+ int allocated = 0; >+ int i, r = -ENOMEM; >+ >+ buf = alloc_balloon_buf(v->vdev, GFP_KERNEL); When does balloon driver free the buf? >+ if (!buf) >+ return r; >+ >+ pfn = (u32 *)&buf->data; >+ *pfn++ = (u32)npages; >+ >+ for (i = 0; i < npages; i++) { >+ page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY); >+ if (!page) >+ goto out_free; >+ list_add(&page->lru, &tmp_list); >+ allocated++; >+ *pfn = page_to_pfn(page); >+ pfn++; >+ } >+ >+ r = send_balloon_buf(v, CMD_BALLOON_INFLATE, buf); >+ if (r) >+ goto out_free; >+ >+ spin_lock(&v->plist_lock); >+ list_splice(&tmp_list, &v->balloon_plist); >+ v->balloon_size += allocated; >+ totalram_pages -= allocated; >+ dprintk(&v->vdev->dev, "%s: current balloon size=%d\n", __func__, >+ v->balloon_size); >+ spin_unlock(&v->plist_lock); >+ return allocated; >+ >+out_free: >+ list_for_each_entry_safe(page, tmp, &tmp_list, lru) { >+ list_del(&page->lru); >+ __free_page(page); >+ } >+ return r; >+} >+ >+static int kvm_balloon_deflate(struct virtballoon *v, int32_t npages) >+{ >+ LIST_HEAD(tmp_list); >+ struct page *page, *tmp; >+ struct balloon_buf *buf; >+ u32 *pfn; >+ int deallocated = 0; >+ int r = 0; >+ >+ buf = alloc_balloon_buf(v->vdev, GFP_KERNEL); ditto. >+ if (!buf) >+ return r; >+ >+ spin_lock(&v->plist_lock); >+ >+ if (v->balloon_size < npages) { >+ dev_printk(KERN_INFO, &v->vdev->dev, >+ "%s: balloon=%d with deflate rq=%d\n", >+ __func__, v->balloon_size, npages); >+ npages = v->balloon_size; >+ if (!npages) >+ goto out; >+ } >+ >+ pfn = (u32 *)&buf->data; >+ *pfn++ = (u32)-npages; >+ >+ /* >+ * Move the balloon pages to tmp list before issuing >+ * the virtio buffer >+ */ >+ list_for_each_entry_safe(page, tmp, &v->balloon_plist, lru) { >+ *pfn++ = page_to_pfn(page); >+ list_move(&page->lru, &tmp_list); >+ if (++deallocated == npages) >+ break; >+ } >+ >+ r = send_balloon_buf(v, CMD_BALLOON_DEFLATE, buf); >+ if (r) >+ goto out; >+ >+ list_for_each_entry_safe(page, tmp, &tmp_list, lru) >+ list_del_init(&page->lru); >+ >+ v->balloon_size -= npages; >+ totalram_pages += npages; >+ dprintk(&v->vdev->dev, "%s: current balloon size=%d\n", __func__, >+ v->balloon_size); >+ >+ spin_unlock(&v->plist_lock); >+ return deallocated; >+ >+out: >+ list_splice(&tmp_list, &v->balloon_plist); >+ spin_unlock(&v->plist_lock); >+ return r; >+} >+ Best Regards, Akio Takebe |