Re: [PATCHv7 3/4] virtio_console: Merge struct buffer_token into struct port_buffer

2012-10-22 Thread Rusty Russell
sjur.brandel...@stericsson.com writes:
 From: Sjur Brændeland sjur.brandel...@stericsson.com

 Refactoring the splice functionality by unifying the approach for
 sending scatter-lists and regular buffers. This simplifies
 buffer handling and reduces code size. Splice will now allocate
 a port_buffer and send_buf() and free_buf() can always be used
 for any buffer.

 Signed-off-by: Sjur Brændeland sjur.brandel...@stericsson.com

This looks sensible; a couple of extra blank lines inserted though.

Amit?

 @@ -1033,6 +1008,8 @@ static const struct file_operations port_fops = {
  static int put_chars(u32 vtermno, const char *buf, int count)
  {
   struct port *port;
 + struct scatterlist sg[1];
 +
  
   if (unlikely(early_put_chars))
   return early_put_chars(vtermno, buf, count);
 @@ -1041,7 +1018,9 @@ static int put_chars(u32 vtermno, const char *buf, int 
 count)
   if (!port)
   return -EPIPE;
  
 - return send_buf(port, (void *)buf, count, false);
 + sg_init_one(sg, buf, count);
 + return __send_to_port(port, sg, 1, count, (void *)buf, false);
 +
  }
  
  /*

Cheers,
Rusty.
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCHv7 3/4] virtio_console: Merge struct buffer_token into struct port_buffer

2012-10-15 Thread sjur . brandeland
From: Sjur Brændeland sjur.brandel...@stericsson.com

Refactoring the splice functionality by unifying the approach for
sending scatter-lists and regular buffers. This simplifies
buffer handling and reduces code size. Splice will now allocate
a port_buffer and send_buf() and free_buf() can always be used
for any buffer.

Signed-off-by: Sjur Brændeland sjur.brandel...@stericsson.com
---
 drivers/char/virtio_console.c |  131 +
 1 files changed, 55 insertions(+), 76 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 301d17e..917cc830 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -111,6 +111,12 @@ struct port_buffer {
size_t len;
/* offset in the buf from which to consume data */
size_t offset;
+
+   /* If sgpages == 0 then buf is used */
+   unsigned int sgpages;
+
+   /* sg is used if spages  0. sg must be the last in is struct */
+   struct scatterlist sg[0];
 };
 
 /*
@@ -338,17 +344,39 @@ static inline bool use_multiport(struct ports_device 
*portdev)
 
 static void free_buf(struct port_buffer *buf)
 {
+   unsigned int i;
+
kfree(buf-buf);
+   for (i = 0; i  buf-sgpages; i++) {
+   struct page *page = sg_page(buf-sg[i]);
+   if (!page)
+   break;
+   put_page(page);
+   }
+
kfree(buf);
 }
 
-static struct port_buffer *alloc_buf(size_t buf_size)
+static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
+int pages)
 {
struct port_buffer *buf;
 
-   buf = kmalloc(sizeof(*buf), GFP_KERNEL);
+   /*
+* Allocate buffer and the sg list. The sg list array is allocated
+* directly after the port_buffer struct.
+*/
+   buf = kmalloc(sizeof(*buf) + sizeof(struct scatterlist) * pages,
+ GFP_KERNEL);
if (!buf)
goto fail;
+
+   buf-sgpages = pages;
+   if (pages  0) {
+   buf-buf = NULL;
+   return buf;
+   }
+
buf-buf = kmalloc(buf_size, GFP_KERNEL);
if (!buf-buf)
goto free_buf;
@@ -476,52 +504,26 @@ static ssize_t send_control_msg(struct port *port, 
unsigned int event,
return 0;
 }
 
-struct buffer_token {
-   union {
-   void *buf;
-   struct scatterlist *sg;
-   } u;
-   /* If sgpages == 0 then buf is used, else sg is used */
-   unsigned int sgpages;
-};
-
-static void reclaim_sg_pages(struct scatterlist *sg, unsigned int nrpages)
-{
-   int i;
-   struct page *page;
-
-   for (i = 0; i  nrpages; i++) {
-   page = sg_page(sg[i]);
-   if (!page)
-   break;
-   put_page(page);
-   }
-   kfree(sg);
-}
 
 /* Callers must take the port-outvq_lock */
 static void reclaim_consumed_buffers(struct port *port)
 {
-   struct buffer_token *tok;
+   struct port_buffer *buf;
unsigned int len;
 
if (!port-portdev) {
/* Device has been unplugged.  vqs are already gone. */
return;
}
-   while ((tok = virtqueue_get_buf(port-out_vq, len))) {
-   if (tok-sgpages)
-   reclaim_sg_pages(tok-u.sg, tok-sgpages);
-   else
-   kfree(tok-u.buf);
-   kfree(tok);
+   while ((buf = virtqueue_get_buf(port-out_vq, len))) {
+   free_buf(buf);
port-outvq_full = false;
}
 }
 
 static ssize_t __send_to_port(struct port *port, struct scatterlist *sg,
  int nents, size_t in_count,
- struct buffer_token *tok, bool nonblock)
+ void *data, bool nonblock)
 {
struct virtqueue *out_vq;
ssize_t ret;
@@ -534,7 +536,7 @@ static ssize_t __send_to_port(struct port *port, struct 
scatterlist *sg,
 
reclaim_consumed_buffers(port);
 
-   ret = virtqueue_add_buf(out_vq, sg, nents, 0, tok, GFP_ATOMIC);
+   ret = virtqueue_add_buf(out_vq, sg, nents, 0, data, GFP_ATOMIC);
 
/* Tell Host to go! */
virtqueue_kick(out_vq);
@@ -572,37 +574,6 @@ done:
return in_count;
 }
 
-static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
-   bool nonblock)
-{
-   struct scatterlist sg[1];
-   struct buffer_token *tok;
-
-   tok = kmalloc(sizeof(*tok), GFP_ATOMIC);
-   if (!tok)
-   return -ENOMEM;
-   tok-sgpages = 0;
-   tok-u.buf = in_buf;
-
-   sg_init_one(sg, in_buf, in_count);
-
-   return __send_to_port(port, sg, 1, in_count, tok, nonblock);
-}
-
-static ssize_t send_pages(struct port *port, struct scatterlist *sg, int nents,
- size_t in_count, bool nonblock)
-{
-   struct