On Fri, Jun 09, 2017 at 06:41:38PM +0800, Wei Wang wrote:
Add a new feature, VIRTIO_BALLOON_F_PAGE_CHUNKS, which enablesso now these chunks are just s/g list entry.
the transfer of the ballooned (i.e. inflated/deflated) pages in
chunks to the host.
So let's rename this VIRTIO_BALLOON_F_SG with a comment:
* Use standard virtio s/g instead of PFN lists *
It is the number of page bitmap being kept throughout the whole+/*It's not by default, it's at probe time, right?
+ * Callulates how many pfns can a page_bmap record. A bit corresponds to a
+ * page of PAGE_SIZE.
+ */
+#define VIRTIO_BALLOON_PFNS_PER_PAGE_BMAP \
+ (VIRTIO_BALLOON_PAGE_BMAP_SIZE * BITS_PER_BYTE)
+
+/* The number of page_bmap to allocate by default. */
+#define VIRTIO_BALLOON_PAGE_BMAP_DEFAULT_NUM 1
+/* The maximum number of page_bmap that can be allocated. */Not really, this is the size of the array we use to keep them.
+#define VIRTIO_BALLOON_PAGE_BMAP_MAX_NUM 32So you still have a home-grown bitmap. I'd like to know why
+
isn't xbitmap suggested for this purpose by Matthew Wilcox
appropriate. Please add a comment explaining the requirements
from the data structure.
+/*I think it doesn't, the issue is probably that you add a header
+ * QEMU virtio implementation requires the desc table size less than
+ * VIRTQUEUE_MAX_SIZE, so minus 1 here.
as a separate s/g. In any case see below.
+ */This is wrong, virtio spec says s/g size should not exceed VQ size.
+#define VIRTIO_BALLOON_MAX_PAGE_CHUNKS (VIRTQUEUE_MAX_SIZE - 1)
If you want to support huge VQ sizes, you can add a fallback to
smaller sizes until it fits in 1 page.
+static unsigned int extend_page_bmap_size(struct virtio_balloon *vb,OK, I will add some comments here. This is the function to extend
+ unsigned long pfn_num)
what's this API doing? Pls add comments. this seems to assume
it will only be called once.
it would be better to avoid makingActually it's not an assumption. The rule here is that we always keep
this assumption, just look at what has been allocated
and extend it.
+}OK, thanks.
+
+/* Add a chunk to the buffer. */
+static void add_one_chunk(struct virtio_balloon *vb, struct virtqueue *vq,
+ u64 base_addr, u32 size)
+{
+ unsigned int *num = &vb->balloon_page_chunk.chunk_num;
+ struct vring_desc *desc = &vb->balloon_page_chunk.desc_table[*num];
+
+ desc->addr = cpu_to_virtio64(vb->vdev, base_addr);
+ desc->len = cpu_to_virtio32(vb->vdev, size);
+ *num += 1;
+ if (*num == VIRTIO_BALLOON_MAX_PAGE_CHUNKS)
+ send_page_chunks(vb, vq);
+}
+
Poking at virtio internals like this is not nice. Pls move to virtio
code. Also, pages must be read descriptors as host might modify them.
This also lacks viommu support but this is not mandatory as
that is borken atm anyway. I'll send a patch to at least fail cleanly.
+static void convert_bmap_to_chunks(struct virtio_balloon *vb,This looks wrong. add_one_chunk assumes size in bytes. So should be just
+ struct virtqueue *vq,
+ unsigned long *bmap,
+ unsigned long pfn_start,
+ unsigned long size)
+{
+ unsigned long next_one, next_zero, pos = 0;
+ u64 chunk_base_addr;
+ u32 chunk_size;
+
+ while (pos < size) {
+ next_one = find_next_bit(bmap, size, pos);
+ /*
+ * No "1" bit found, which means that there is no pfn
+ * recorded in the rest of this bmap.
+ */
+ if (next_one == size)
+ break;
+ next_zero = find_next_zero_bit(bmap, size, next_one + 1);
+ /*
+ * A bit in page_bmap corresponds to a page of PAGE_SIZE.
+ * Convert it to be pages of 4KB balloon page size when
+ * adding it to a chunk.
PAGE_SIZE.
+ */How do you know this won't overflow a 32 bit integer? Needs a comment.
+ chunk_size = (next_zero - next_one) *
+ VIRTIO_BALLOON_PAGES_PER_PAGE;
+
+static int balloon_page_chunk_init(struct virtio_balloon *vb)
+{
+ int i;
+
+ vb->balloon_page_chunk.desc_table = alloc_indirect(vb->vdev,
+ VIRTIO_BALLOON_MAX_PAGE_CHUNKS,
+ GFP_KERNEL);
This one's problematic, you aren't supposed to use APIs when device
is not inited yet. Seems to work by luck here. I suggest moving
this to probe, that's where we do a bunch of inits.
And then you can move private init back to allocate too.