Skip to content

Commit 8ca84a5

Browse files
mhiramathitachirustyrussell
authored andcommitted
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 <[email protected]> Acked-by: Amit Shah <[email protected]> Signed-off-by: Rusty Russell <[email protected]>
1 parent d55cb6c commit 8ca84a5

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

drivers/char/virtio_console.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ struct port {
229229
bool guest_connected;
230230
};
231231

232-
#define MAX_SPLICE_PAGES 32
233232
/* This is the very early arch-specified put chars function. */
234233
static int (*early_put_chars)(u32, const char *, int);
235234

@@ -482,15 +481,16 @@ struct buffer_token {
482481
void *buf;
483482
struct scatterlist *sg;
484483
} u;
485-
bool sgpages;
484+
/* If sgpages == 0 then buf is used, else sg is used */
485+
unsigned int sgpages;
486486
};
487487

488-
static void reclaim_sg_pages(struct scatterlist *sg)
488+
static void reclaim_sg_pages(struct scatterlist *sg, unsigned int nrpages)
489489
{
490490
int i;
491491
struct page *page;
492492

493-
for (i = 0; i < MAX_SPLICE_PAGES; i++) {
493+
for (i = 0; i < nrpages; i++) {
494494
page = sg_page(&sg[i]);
495495
if (!page)
496496
break;
@@ -511,7 +511,7 @@ static void reclaim_consumed_buffers(struct port *port)
511511
}
512512
while ((tok = virtqueue_get_buf(port->out_vq, &len))) {
513513
if (tok->sgpages)
514-
reclaim_sg_pages(tok->u.sg);
514+
reclaim_sg_pages(tok->u.sg, tok->sgpages);
515515
else
516516
kfree(tok->u.buf);
517517
kfree(tok);
@@ -581,7 +581,7 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
581581
tok = kmalloc(sizeof(*tok), GFP_ATOMIC);
582582
if (!tok)
583583
return -ENOMEM;
584-
tok->sgpages = false;
584+
tok->sgpages = 0;
585585
tok->u.buf = in_buf;
586586

587587
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,
597597
tok = kmalloc(sizeof(*tok), GFP_ATOMIC);
598598
if (!tok)
599599
return -ENOMEM;
600-
tok->sgpages = true;
600+
tok->sgpages = nents;
601601
tok->u.sg = sg;
602602

603603
return __send_to_port(port, sg, nents, in_count, tok, nonblock);
@@ -797,6 +797,7 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
797797

798798
struct sg_list {
799799
unsigned int n;
800+
unsigned int size;
800801
size_t len;
801802
struct scatterlist *sg;
802803
};
@@ -807,7 +808,7 @@ static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
807808
struct sg_list *sgl = sd->u.data;
808809
unsigned int offset, len;
809810

810-
if (sgl->n == MAX_SPLICE_PAGES)
811+
if (sgl->n == sgl->size)
811812
return 0;
812813

813814
/* Try lock this page */
@@ -868,12 +869,12 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
868869

869870
sgl.n = 0;
870871
sgl.len = 0;
871-
sgl.sg = kmalloc(sizeof(struct scatterlist) * MAX_SPLICE_PAGES,
872-
GFP_KERNEL);
872+
sgl.size = pipe->nrbufs;
873+
sgl.sg = kmalloc(sizeof(struct scatterlist) * sgl.size, GFP_KERNEL);
873874
if (unlikely(!sgl.sg))
874875
return -ENOMEM;
875876

876-
sg_init_table(sgl.sg, MAX_SPLICE_PAGES);
877+
sg_init_table(sgl.sg, sgl.size);
877878
ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
878879
if (likely(ret > 0))
879880
ret = send_pages(port, sgl.sg, sgl.n, sgl.len, true);

0 commit comments

Comments
 (0)