aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2012-08-09 08:31:20 -0400
committerRusty Russell <rusty@rustcorp.com.au>2012-09-28 01:35:12 -0400
commit8ca84a50e5b39487ea1de8809d0ee1c8474f6a5c (patch)
tree3e015a3c54606b1db785f9f1266f8d5133cc1982 /drivers/char
parentd55cb6cf143ae16eaa415baab520b8eaf4a1012f (diff)
virtio/console: Allocate scatterlist according to the current pipe size
Allocate scatterlist according to the current pipe size. This allows splicing bigger buffer if the pipe size has been changed by fcntl. Changes in v2: - Just a minor fix for avoiding a confliction with previous patch. Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Acked-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/virtio_console.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index b2fc2abedc79..e88f84390428 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -229,7 +229,6 @@ struct port {
229 bool guest_connected; 229 bool guest_connected;
230}; 230};
231 231
232#define MAX_SPLICE_PAGES 32
233/* This is the very early arch-specified put chars function. */ 232/* This is the very early arch-specified put chars function. */
234static int (*early_put_chars)(u32, const char *, int); 233static int (*early_put_chars)(u32, const char *, int);
235 234
@@ -482,15 +481,16 @@ struct buffer_token {
482 void *buf; 481 void *buf;
483 struct scatterlist *sg; 482 struct scatterlist *sg;
484 } u; 483 } u;
485 bool sgpages; 484 /* If sgpages == 0 then buf is used, else sg is used */
485 unsigned int sgpages;
486}; 486};
487 487
488static void reclaim_sg_pages(struct scatterlist *sg) 488static void reclaim_sg_pages(struct scatterlist *sg, unsigned int nrpages)
489{ 489{
490 int i; 490 int i;
491 struct page *page; 491 struct page *page;
492 492
493 for (i = 0; i < MAX_SPLICE_PAGES; i++) { 493 for (i = 0; i < nrpages; i++) {
494 page = sg_page(&sg[i]); 494 page = sg_page(&sg[i]);
495 if (!page) 495 if (!page)
496 break; 496 break;
@@ -511,7 +511,7 @@ static void reclaim_consumed_buffers(struct port *port)
511 } 511 }
512 while ((tok = virtqueue_get_buf(port->out_vq, &len))) { 512 while ((tok = virtqueue_get_buf(port->out_vq, &len))) {
513 if (tok->sgpages) 513 if (tok->sgpages)
514 reclaim_sg_pages(tok->u.sg); 514 reclaim_sg_pages(tok->u.sg, tok->sgpages);
515 else 515 else
516 kfree(tok->u.buf); 516 kfree(tok->u.buf);
517 kfree(tok); 517 kfree(tok);
@@ -581,7 +581,7 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
581 tok = kmalloc(sizeof(*tok), GFP_ATOMIC); 581 tok = kmalloc(sizeof(*tok), GFP_ATOMIC);
582 if (!tok) 582 if (!tok)
583 return -ENOMEM; 583 return -ENOMEM;
584 tok->sgpages = false; 584 tok->sgpages = 0;
585 tok->u.buf = in_buf; 585 tok->u.buf = in_buf;
586 586
587 sg_init_one(sg, in_buf, in_count); 587 sg_init_one(sg, in_buf, in_count);
@@ -597,7 +597,7 @@ static ssize_t send_pages(struct port *port, struct scatterlist *sg, int nents,
597 tok = kmalloc(sizeof(*tok), GFP_ATOMIC); 597 tok = kmalloc(sizeof(*tok), GFP_ATOMIC);
598 if (!tok) 598 if (!tok)
599 return -ENOMEM; 599 return -ENOMEM;
600 tok->sgpages = true; 600 tok->sgpages = nents;
601 tok->u.sg = sg; 601 tok->u.sg = sg;
602 602
603 return __send_to_port(port, sg, nents, in_count, tok, nonblock); 603 return __send_to_port(port, sg, nents, in_count, tok, nonblock);
@@ -797,6 +797,7 @@ out:
797 797
798struct sg_list { 798struct sg_list {
799 unsigned int n; 799 unsigned int n;
800 unsigned int size;
800 size_t len; 801 size_t len;
801 struct scatterlist *sg; 802 struct scatterlist *sg;
802}; 803};
@@ -807,7 +808,7 @@ static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
807 struct sg_list *sgl = sd->u.data; 808 struct sg_list *sgl = sd->u.data;
808 unsigned int offset, len; 809 unsigned int offset, len;
809 810
810 if (sgl->n == MAX_SPLICE_PAGES) 811 if (sgl->n == sgl->size)
811 return 0; 812 return 0;
812 813
813 /* Try lock this page */ 814 /* Try lock this page */
@@ -868,12 +869,12 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
868 869
869 sgl.n = 0; 870 sgl.n = 0;
870 sgl.len = 0; 871 sgl.len = 0;
871 sgl.sg = kmalloc(sizeof(struct scatterlist) * MAX_SPLICE_PAGES, 872 sgl.size = pipe->nrbufs;
872 GFP_KERNEL); 873 sgl.sg = kmalloc(sizeof(struct scatterlist) * sgl.size, GFP_KERNEL);
873 if (unlikely(!sgl.sg)) 874 if (unlikely(!sgl.sg))
874 return -ENOMEM; 875 return -ENOMEM;
875 876
876 sg_init_table(sgl.sg, MAX_SPLICE_PAGES); 877 sg_init_table(sgl.sg, sgl.size);
877 ret = __splice_from_pipe(pipe, &sd, pipe_to_sg); 878 ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
878 if (likely(ret > 0)) 879 if (likely(ret > 0))
879 ret = send_pages(port, sgl.sg, sgl.n, sgl.len, true); 880 ret = send_pages(port, sgl.sg, sgl.n, sgl.len, true);