Skip site navigation (1)Skip section navigation (2)
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>