Commit bb7ac03a authored by Pavel Emelyanov's avatar Pavel Emelyanov

iov: Add iov_grow_page() helper

Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 997f08ea
...@@ -8,6 +8,17 @@ ...@@ -8,6 +8,17 @@
#include "util.h" #include "util.h"
#include "page-pipe.h" #include "page-pipe.h"
/* can existing iov accumulate the page? */
static inline bool iov_grow_page(struct iovec *iov, unsigned long addr)
{
if ((unsigned long)iov->iov_base + iov->iov_len == addr) {
iov->iov_len += PAGE_SIZE;
return true;
}
return false;
}
static int page_pipe_grow(struct page_pipe *pp) static int page_pipe_grow(struct page_pipe *pp)
{ {
struct page_pipe_buf *ppb; struct page_pipe_buf *ppb;
...@@ -110,8 +121,6 @@ void page_pipe_reinit(struct page_pipe *pp) ...@@ -110,8 +121,6 @@ void page_pipe_reinit(struct page_pipe *pp)
static inline int try_add_page_to(struct page_pipe *pp, struct page_pipe_buf *ppb, static inline int try_add_page_to(struct page_pipe *pp, struct page_pipe_buf *ppb,
unsigned long addr) unsigned long addr)
{ {
struct iovec *iov;
if (ppb->pages_in == ppb->pipe_size) { if (ppb->pages_in == ppb->pipe_size) {
unsigned long new_size = ppb->pipe_size << 1; unsigned long new_size = ppb->pipe_size << 1;
int ret; int ret;
...@@ -131,12 +140,8 @@ static inline int try_add_page_to(struct page_pipe *pp, struct page_pipe_buf *pp ...@@ -131,12 +140,8 @@ static inline int try_add_page_to(struct page_pipe *pp, struct page_pipe_buf *pp
} }
if (ppb->nr_segs) { if (ppb->nr_segs) {
/* can existing iov accumulate the page? */ if (iov_grow_page(&ppb->iov[ppb->nr_segs - 1], addr))
iov = &ppb->iov[ppb->nr_segs - 1];
if ((unsigned long)iov->iov_base + iov->iov_len == addr) {
iov->iov_len += PAGE_SIZE;
goto out; goto out;
}
if (ppb->nr_segs == UIO_MAXIOV) if (ppb->nr_segs == UIO_MAXIOV)
/* XXX -- shrink pipe back? */ /* XXX -- shrink pipe back? */
...@@ -193,13 +198,9 @@ int page_pipe_add_hole(struct page_pipe *pp, unsigned long addr) ...@@ -193,13 +198,9 @@ int page_pipe_add_hole(struct page_pipe *pp, unsigned long addr)
pp->nr_holes += PP_HOLES_BATCH; pp->nr_holes += PP_HOLES_BATCH;
} }
if (pp->free_hole) { if (pp->free_hole &&
iov = &pp->holes[pp->free_hole - 1]; iov_grow_page(&pp->holes[pp->free_hole - 1], addr))
if ((unsigned long)iov->iov_base + iov->iov_len == addr) { goto out;
iov->iov_len += PAGE_SIZE;
goto out;
}
}
iov = &pp->holes[pp->free_hole]; iov = &pp->holes[pp->free_hole];
iov->iov_base = (void *)addr; iov->iov_base = (void *)addr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment