svn commit: r292381 - in projects/sendfile: sys/kern sys/sys usr.bin/netstat

Gleb Smirnoff glebius at FreeBSD.org
Wed Dec 16 22:48:34 UTC 2015


Author: glebius
Date: Wed Dec 16 22:48:32 2015
New Revision: 292381
URL: https://svnweb.freebsd.org/changeset/base/292381

Log:
  Provide new behavior of SF_NODISKIO flag - abandon operation upon encounter
  of a busy page. A retry after a short period of time is adviced. This behavior
  is already documented in lib/libc/sys/sendfile.2 of this branch.

Modified:
  projects/sendfile/sys/kern/uipc_syscalls.c
  projects/sendfile/sys/sys/sf_buf.h
  projects/sendfile/usr.bin/netstat/mbuf.c

Modified: projects/sendfile/sys/kern/uipc_syscalls.c
==============================================================================
--- projects/sendfile/sys/kern/uipc_syscalls.c	Wed Dec 16 22:34:41 2015	(r292380)
+++ projects/sendfile/sys/kern/uipc_syscalls.c	Wed Dec 16 22:48:32 2015	(r292381)
@@ -2138,21 +2138,28 @@ sf_iodone(void *arg, vm_page_t *pg, int 
  */
 static int
 sendfile_swapin(vm_object_t obj, struct sf_io *sfio, off_t off, off_t len,
-    int npages, int rhpages)
+    int npages, int rhpages, int flags)
 {
 	vm_page_t *pa = sfio->pa;
 	int nios;
 
 	nios = 0;
-	VM_OBJECT_WLOCK(obj);
+	flags = (flags & SF_NODISKIO) ? VM_ALLOC_NOWAIT : 0;
 
 	/*
 	 * First grab all the pages and wire them.  Note that we grab
 	 * only required pages.  Readahead pages are dealt with later.
 	 */
-	for (int i = 0; i < npages; i++)
+	VM_OBJECT_WLOCK(obj);
+	for (int i = 0; i < npages; i++) {
 		pa[i] = vm_page_grab(obj, OFF_TO_IDX(vmoff(i, off)),
-		    VM_ALLOC_WIRED | VM_ALLOC_NORMAL);
+		    VM_ALLOC_WIRED | VM_ALLOC_NORMAL | flags);
+		if (pa[i] == NULL) {
+			npages = i;
+			rhpages = 0;
+			break;
+		}
+	}
 
 	for (int i = 0; i < npages;) {
 		int j, a, count, rv;
@@ -2552,7 +2559,8 @@ retry_space:
 		refcount_init(&sfio->nios, 1);
 		sfio->error = 0;
 
-		nios = sendfile_swapin(obj, sfio, off, space, npages, rhpages);
+		nios = sendfile_swapin(obj, sfio, off, space, npages, rhpages,
+		    flags);
 
 		/*
 		 * Loop and construct maximum sized mbuf chain to be bulk
@@ -2563,6 +2571,18 @@ retry_space:
 			struct mbuf *m0;
 
 			/*
+			 * If a page wasn't grabbed successfully, then
+			 * trim the array. Can happen only with SF_NODISKIO.
+			 */
+			if (pa[i] == NULL) {
+				SFSTAT_INC(sf_busy);
+				fixspace(npages, i, off, &space);
+				npages = i;
+				softerr = EBUSY;
+				break;
+			}
+
+			/*
 			 * Get a sendfile buf.  When allocating the
 			 * first buffer for mbuf chain, we usually
 			 * wait as long as necessary, but this wait

Modified: projects/sendfile/sys/sys/sf_buf.h
==============================================================================
--- projects/sendfile/sys/sys/sf_buf.h	Wed Dec 16 22:34:41 2015	(r292380)
+++ projects/sendfile/sys/sys/sf_buf.h	Wed Dec 16 22:48:32 2015	(r292381)
@@ -38,6 +38,7 @@ struct sfstat {				/* sendfile statistic
 	uint64_t	sf_pages_valid;	/* pages were valid for a request */
 	uint64_t	sf_rhpages_requested;	/* readahead pages requested */
 	uint64_t	sf_rhpages_read;	/* readahead pages read */
+	uint64_t	sf_busy;	/* times aborted on a busy page */
 	uint64_t	sf_allocfail;	/* times sfbuf allocation failed */
 	uint64_t	sf_allocwait;	/* times sfbuf allocation had to wait */
 };

Modified: projects/sendfile/usr.bin/netstat/mbuf.c
==============================================================================
--- projects/sendfile/usr.bin/netstat/mbuf.c	Wed Dec 16 22:34:41 2015	(r292380)
+++ projects/sendfile/usr.bin/netstat/mbuf.c	Wed Dec 16 22:48:32 2015	(r292381)
@@ -346,6 +346,9 @@ mbpr(void *kvmd, u_long mbaddr)
         xo_emit("{:sendfile-readahead/%ju} "
 	    "{N:pages were read ahead by sendfile}\n",
             (uintmax_t)sfstat.sf_rhpages_read);
+	xo_emit("{:sendfile-busy-encounters/%ju} "
+	    "{N:times sendfile encountered an already busy page}\n",
+	    (uintmax_t)sfstat.sf_busy);
 	xo_emit("{:sfbufs-alloc-failed/%ju} {N:requests for sfbufs denied}\n",
 	    (uintmax_t)sfstat.sf_allocfail);
 	xo_emit("{:sfbufs-alloc-wait/%ju} {N:requests for sfbufs delayed}\n",


More information about the svn-src-projects mailing list