Date: Tue, 24 Dec 2013 08:49:55 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r259818 - projects/sendfile/sys/kern Message-ID: <201312240849.rBO8ntSe097089@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Tue Dec 24 08:49:55 2013 New Revision: 259818 URL: http://svnweb.freebsd.org/changeset/base/259818 Log: Use macros to calculate offset and xfersize for given page, instead of allocating temporary memory for that. Modified: projects/sendfile/sys/kern/uipc_syscalls.c Modified: projects/sendfile/sys/kern/uipc_syscalls.c ============================================================================== --- projects/sendfile/sys/kern/uipc_syscalls.c Tue Dec 24 07:32:06 2013 (r259817) +++ projects/sendfile/sys/kern/uipc_syscalls.c Tue Dec 24 08:49:55 2013 (r259818) @@ -2089,52 +2089,44 @@ freebsd4_sendfile(struct thread *td, str } #endif /* COMPAT_FREEBSD4 */ -struct page_descr { - off_t off; - off_t xfsize; -}; - static void -sendfile_swapin(vm_object_t obj, vm_page_t *pa, struct page_descr *pd, - int npages, off_t off, off_t len) +sendfile_swapin(vm_object_t obj, vm_page_t *pa, int npages, off_t off, + off_t len) { int rv; - KASSERT(npages * PAGE_SIZE >= len, ("%s: npages %d len %ju", - __func__, npages, (uintmax_t)len)); + /* + * Macros to calculate size and offset for given (i) page, + * starting from offset (o) with maximum length of (l). + * Used in this function and vn_sendfile(). + */ +#define XFSIZE(i, o, l) ((i) == 0 ? \ + omin(PAGE_SIZE - ((o) & PAGE_MASK), (l)) : \ + ((i) == (npages - 1) ? \ + (((o) + (l)) & PAGE_MASK) : PAGE_SIZE)) +#define OFFSET(i, o) (vm_offset_t)((i) == 0 ? (o) : \ + trunc_page((o) + i * PAGE_SIZE)) VM_OBJECT_WLOCK(obj); - for (int i = 0; i < npages; i++) { - vm_offset_t pgoff; - off_t xfsize; - - pgoff = (vm_offset_t)(off & PAGE_MASK); - xfsize = omin(PAGE_SIZE - pgoff, len); - - pd[i].off = off; - pd[i].xfsize = xfsize; - pa[i] = vm_page_grab(obj, OFF_TO_IDX(off), + for (int i = 0; i < npages; i++) + pa[i] = vm_page_grab(obj, OFF_TO_IDX(OFFSET(i, off)), VM_ALLOC_WIRED | VM_ALLOC_NORMAL); - off += xfsize; - len -= xfsize; - } - for (int i = 0; i < npages; i++) { int j, a; - if (vm_page_is_valid(pa[i], pd[i].off & PAGE_MASK, - pd[i].xfsize)) { + if (vm_page_is_valid(pa[i], OFFSET(i, off) & PAGE_MASK, + XFSIZE(i, off, len))) { vm_page_xunbusy(pa[i]); continue; } for (j = i + 1; j < npages; j++) - if (vm_page_is_valid(pa[j], pd[j].off & PAGE_MASK, - pd[j].xfsize)) + if (vm_page_is_valid(pa[j], OFFSET(j, off) & PAGE_MASK, + XFSIZE(j, off, len))) break; - while (!vm_pager_has_page(obj, OFF_TO_IDX(pd[i].off), + while (!vm_pager_has_page(obj, OFF_TO_IDX(OFFSET(i, off)), NULL, &a) && i < j) { pmap_zero_page(pa[i]); pa[i]->valid = VM_PAGE_BITS_ALL; @@ -2152,21 +2144,20 @@ sendfile_swapin(vm_object_t obj, vm_page vm_page_xunbusy(pa[i]); SFSTAT_INC(sf_iocnt); - for (; a > 0 && i < npages; a--, i++) { - vm_page_t p; - - p = pa[i]; - pa[i] = vm_page_lookup(obj, OFF_TO_IDX(pd[i].off)); - if (p != pa[i]) - printf("p %p pa[i] %p\n", p, pa[i]); - } + i += a; + for (j = i - a; a > 0 && j < npages; a--, j++) + KASSERT(pa[j] == vm_page_lookup(obj, + OFF_TO_IDX(OFFSET(j, off))), + ("pa[j] %p lookup %p\n", pa[j], + vm_page_lookup(obj, OFF_TO_IDX(OFFSET(j, off))))); } for (int i = 0; i < npages; i++) KASSERT((pa[i]->wire_count > 0 && vm_page_is_valid(pa[i], - pd[i].off & PAGE_MASK, pd[i].xfsize)), + OFFSET(i, off) & PAGE_MASK, XFSIZE(i, off, len))), ("wrong page %p state off 0x%jx len 0x%jx", - pa[i], (uintmax_t)pd[i].off, (uintmax_t)pd[i].xfsize)); + pa[i], (uintmax_t)OFFSET(i, off), + (uintmax_t)XFSIZE(i, off, len))); VM_OBJECT_WUNLOCK(obj); } @@ -2365,10 +2356,8 @@ vn_sendfile(struct file *fp, int sockfd, */ for (off = offset; rem > 0; ) { vm_page_t *pa; - struct page_descr *pd; - u_int npages; struct mbuf *mtail; - int space; + int space, npages; mtail = NULL; /* @@ -2458,22 +2447,17 @@ retry_space: if (space > rem) space = rem; - npages = howmany(space - (PAGE_SIZE - off & PAGE_MASK), - PAGE_SIZE); if (off & PAGE_MASK) - npages++; + npages = 1 + howmany(space - + (PAGE_SIZE - (off & PAGE_MASK)), PAGE_SIZE); + else + npages = howmany(space, PAGE_SIZE); pa = malloc(npages * sizeof(vm_page_t), M_TEMP, mwait); if (pa == NULL) { error = merror; goto done; } - pd = malloc(npages * sizeof(*pd), M_TEMP, mwait); - if (pd == NULL) { - free(pa, M_TEMP); - error = merror; - goto done; - } - sendfile_swapin(obj, pa, pd, npages, off, space); + sendfile_swapin(obj, pa, npages, off, space); /* * Loop and construct maximum sized mbuf chain to be bulk @@ -2529,8 +2513,8 @@ retry_space: break; } m0->m_data = (char *)sf_buf_kva(sf) + - (pd[i].off & PAGE_MASK); - m0->m_len = pd[i].xfsize; + (OFFSET(i, off) & PAGE_MASK); + m0->m_len = XFSIZE(i, off, space); /* Append to mbuf chain. */ if (mtail != NULL) @@ -2539,10 +2523,6 @@ retry_space: m = m0; mtail = m0; - /* Keep track of bytes processed. */ - off += pd[i].xfsize; - rem -= pd[i].xfsize; - /* * XXX eventually this should be a sfsync * method call! @@ -2551,11 +2531,14 @@ retry_space: sf_sync_ref(sfs); } + /* Keep track of bytes processed. */ + off += space; + rem -= space; + if (vp != NULL) VOP_UNLOCK(vp, 0); free(pa, M_TEMP); - free(pd, M_TEMP); /* Prepend header, if any. */ if (hdrlen) { @@ -2563,6 +2546,9 @@ retry_space: m = mh; } + if (error) + break; + /* Add the buffer chain to the socket buffer. */ KASSERT(m_length(m, NULL) == space + hdrlen, ("%s: mlen %u space %d hdrlen %d",
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312240849.rBO8ntSe097089>