svn commit: r323566 - head/sys/kern

Gleb Smirnoff glebius at FreeBSD.org
Wed Sep 13 22:11:07 UTC 2017


Author: glebius
Date: Wed Sep 13 22:11:05 2017
New Revision: 323566
URL: https://svnweb.freebsd.org/changeset/base/323566

Log:
  Use soref() in sendfile(2) instead fhold() to reference a socket.
  
  The problem is that fdrop() requires syscall context, as it may
  enter sleep in some cases.  The reason to use it in the original
  non-blocking sendfile implementation, was to avoid use of global
  ACCEPT_LOCK() on every I/O completion. Now in head sorele() no
  longer requires this lock.

Modified:
  head/sys/kern/kern_sendfile.c

Modified: head/sys/kern/kern_sendfile.c
==============================================================================
--- head/sys/kern/kern_sendfile.c	Wed Sep 13 21:56:49 2017	(r323565)
+++ head/sys/kern/kern_sendfile.c	Wed Sep 13 22:11:05 2017	(r323566)
@@ -80,7 +80,7 @@ struct sf_io {
 	volatile u_int	nios;
 	u_int		error;
 	int		npages;
-	struct file	*sock_fp;
+	struct socket	*so;
 	struct mbuf	*m;
 	vm_page_t	pa[];
 };
@@ -255,7 +255,7 @@ static void
 sendfile_iodone(void *arg, vm_page_t *pg, int count, int error)
 {
 	struct sf_io *sfio = arg;
-	struct socket *so;
+	struct socket *so = sfio->so;
 
 	for (int i = 0; i < count; i++)
 		if (pg[i] != bogus_page)
@@ -267,8 +267,6 @@ sendfile_iodone(void *arg, vm_page_t *pg, int count, i
 	if (!refcount_release(&sfio->nios))
 		return;
 
-	so = sfio->sock_fp->f_data;
-
 	if (sfio->error) {
 		struct mbuf *m;
 
@@ -296,8 +294,8 @@ sendfile_iodone(void *arg, vm_page_t *pg, int count, i
 		CURVNET_RESTORE();
 	}
 
-	/* XXXGL: curthread */
-	fdrop(sfio->sock_fp, curthread);
+	SOCK_LOCK(so);
+	sorele(so);
 	free(sfio, M_TEMP);
 }
 
@@ -724,6 +722,7 @@ retry_space:
 		sfio = malloc(sizeof(struct sf_io) +
 		    npages * sizeof(vm_page_t), M_TEMP, M_WAITOK);
 		refcount_init(&sfio->nios, 1);
+		sfio->so = so;
 		sfio->error = 0;
 
 		nios = sendfile_swapin(obj, sfio, off, space, npages, rhpages,
@@ -858,9 +857,8 @@ prepend_header:
 			error = (*so->so_proto->pr_usrreqs->pru_send)
 			    (so, 0, m, NULL, NULL, td);
 		} else {
-			sfio->sock_fp = sock_fp;
 			sfio->npages = npages;
-			fhold(sock_fp);
+			soref(so);
 			error = (*so->so_proto->pr_usrreqs->pru_send)
 			    (so, PRUS_NOTREADY, m, NULL, NULL, td);
 			sendfile_iodone(sfio, NULL, 0, 0);


More information about the svn-src-all mailing list