On Sat, 9 Jan 2010 05:05:06 am Gaurav Kukreja wrote:> Hi,
>
> I am doing working on enabling Transcendent Memory(OLS '09) support on
> lguest.
>
> For the same, I need ballooning support for lguest. Is there an
> implmentation of Virtio Balloon driver, that I can use for my purpose?
Here's a patch I had for testing. It's not a real implementation, but
it serves as a start point.
This patch probably won't apply now, but you can use the code:
Crappy lguest balloon testing code.
---
Documentation/lguest/lguest.c | 75 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff -r 62e37935e821 Documentation/lguest/lguest.c
--- a/Documentation/lguest/lguest.c Sun Jun 15 23:00:15 2008 +1000
+++ b/Documentation/lguest/lguest.c Sun Jun 15 23:00:54 2008 +1000
@@ -44,6 +44,7 @@
#include "linux/virtio_console.h"
#include "linux/virtio_rng.h"
#include "linux/virtio_ring.h"
+#include "linux/virtio_balloon.h"
#include "linux/vring.h"
#include "asm-x86/bootparam.h"
/*L:110 We can ignore the 39 include files we need for this program, but I do
@@ -2194,6 +2195,75 @@ static void setup_block_file(const char
verbose("device %u: virtblock %llu sectors\n",
devices.device_num, le64_to_cpu(conf.capacity));
}
+/*:*/
+
+static bool handle_balloon_cmd(int fd, struct device *dev)
+{
+ struct virtio_balloon_config conf;
+ int r, diff;
+ char cmd[80];
+
+ r = read(dev->fd, cmd, sizeof(cmd)-1);
+ if (r < 0)
+ err(1, "Reading balloon cmd fd");
+
+ /* Closed? Stop listening. */
+ if (r == 0)
+ return false;
+
+ cmd[r] = '\0';
+ diff = atol(cmd);
+ if (!diff)
+ errx(1, "Bad balloon target diff '%s'", cmd);
+
+ memcpy(&conf, device_config(dev), sizeof(conf));
+ conf.num_pages += diff;
+ printf("New balloon target: %u\n", conf.num_pages);
+ memcpy(device_config(dev), &conf, sizeof(conf));
+
+ /* Config change, so trigger the irq. */
+ dev->desc->config_change = 1;
+ trigger_irq(fd, dev->vq);
+ return true;
+}
+
+static void handle_virtballoon_output(int fd, struct virtqueue *vq)
+{
+ unsigned int head, out, in, i;
+ struct iovec iov[vq->vqi.vring.num];
+
+ head = get_vq_desc(&vq->vqi, iov, &out, &in);
+ if (head < 0)
+ return;
+
+ if (in)
+ errx(1, "Input buffers in output queue?");
+
+ if (out != 1 || (iov[0].iov_len % 4) != 0)
+ errx(1, "Surprising output num %i, len %u\n",
+ out, iov[0].iov_len);
+
+ for (i = 0; i < iov[0].iov_len/4; i++)
+ printf("Released page %u\n", ((u32 *)iov[0].iov_base)[i]);
+
+ add_used_and_trigger(fd, vq, head, iov[0].iov_len);
+}
+
+/*L:199 The balloon device: this is a hack for testing. */
+static void setup_balloon_file(const char *filename, unsigned int mempages)
+{
+ int fd;
+ struct device *dev;
+ struct virtio_balloon_config conf = { .num_pages = 0 };
+
+ fd = open_or_die(filename, O_RDWR);
+
+ dev = new_device("balloon", VIRTIO_ID_BALLOON, fd,
handle_balloon_cmd);
+
+ /* The device has one virtqueue, where the Guest places page numbers. */
+ add_virtqueue(dev, VIRTQUEUE_NUM, handle_virtballoon_output);
+ set_config(dev, sizeof(conf), &conf);
+}
/* Our random number generator device reads from /dev/random into the
Guest's
* input buffers. The usual case is that the Guest doesn't want random
numbers
@@ -2326,6 +2396,7 @@ static struct option opts[] = {
{ "block", 1, NULL, 'b' },
{ "rng", 0, NULL, 'r' },
{ "initrd", 1, NULL, 'i' },
+ { "balloon", 1, NULL, 'B' },
{ "sharenet", 1, NULL, 's' },
{ NULL },
};
@@ -2334,6 +2405,7 @@ static void usage(void)
errx(1, "Usage: lguest [--verbose] "
"[--tunnet=(<ipaddr>:<macaddr>|bridge:<bridgename>:<macaddr>)\n"
"|--sharenet=<controlfile>]\n"
+ "|--balloon=<filename>]\n"
"|--block=<filename>|--initrd=<filename>]...\n"
"<mem-in-mb> vmlinux [args...]");
}
@@ -2409,6 +2481,9 @@ int main(int argc, char *argv[])
break;
case 'i':
initrd_name = optarg;
+ break;
+ case 'B':
+ setup_balloon_file(optarg, mem/getpagesize());
break;
case 's':
setup_sharenet(optarg);