svn commit: r198015 - in user/kmacy/releng_8_fcs/sys: kern sys

Kip Macy kmacy at FreeBSD.org
Tue Oct 13 04:14:49 UTC 2009


Author: kmacy
Date: Tue Oct 13 04:14:48 2009
New Revision: 198015
URL: http://svn.freebsd.org/changeset/base/198015

Log:
  - fix fp sendfile offset accounting
  - eliminate gratuitous sbdrop wakeup attempts

Modified:
  user/kmacy/releng_8_fcs/sys/kern/uipc_sockbuf.c
  user/kmacy/releng_8_fcs/sys/kern/uipc_socket.c
  user/kmacy/releng_8_fcs/sys/kern/uipc_syscalls.c
  user/kmacy/releng_8_fcs/sys/sys/sockbuf.h

Modified: user/kmacy/releng_8_fcs/sys/kern/uipc_sockbuf.c
==============================================================================
--- user/kmacy/releng_8_fcs/sys/kern/uipc_sockbuf.c	Tue Oct 13 04:13:39 2009	(r198014)
+++ user/kmacy/releng_8_fcs/sys/kern/uipc_sockbuf.c	Tue Oct 13 04:14:48 2009	(r198015)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/aio.h> /* for aio_swake proto */
 #include <sys/kernel.h>
+#include <sys/ktr.h>
 #include <sys/lock.h>
 #include <sys/mbuf.h>
 #include <sys/mutex.h>
@@ -905,11 +906,13 @@ sbdrop_internal(struct sockbuf *sb, int 
 void
 sbdrop_locked(struct sockbuf *sb, int len)
 {
+	int flags;
 
 	SOCKBUF_LOCK_ASSERT(sb);
 
 	sbdrop_internal(sb, len);
-	if (sb->sb_flags & SB_SENDING)
+	if ((sb->sb_flags & (SB_SENDING|SB_SENDING_TASK)) == SB_SENDING	&&
+	    sbspace(sb) >= sb->sb_lowat)
 		sosendingwakeup(sb);
 }
 

Modified: user/kmacy/releng_8_fcs/sys/kern/uipc_socket.c
==============================================================================
--- user/kmacy/releng_8_fcs/sys/kern/uipc_socket.c	Tue Oct 13 04:13:39 2009	(r198014)
+++ user/kmacy/releng_8_fcs/sys/kern/uipc_socket.c	Tue Oct 13 04:14:48 2009	(r198015)
@@ -3370,7 +3370,7 @@ struct taskqueue *sendfile_tq;
 extern int getsock(struct filedesc *fdp, int fd,
     struct file **fpp, u_int *fflagp);
 static void sendfile_task_func(void *context, int pending __unused);
-static int srsendingwakeup(struct socketref *sr);
+static int srsendingwakeup(struct socketref *sr, int external);
 
 MALLOC_DEFINE(M_SOCKREF, "sockref", "socket reference memory");
 
@@ -3462,7 +3462,7 @@ soissending(struct socket *so, struct th
 	ref->sr_uap.sbytes = NULL;
 	ref->sr_sock_fp->f_sfbytes = 0;
 	CTR4(KTR_SPARE2, "sock %p off %ld sbytes %ld total_sbytes %ld",
-	    so, ref->sr_uap.offset, sbytes, ref->sr_fp->f_sfbytes);
+	    so, ref->sr_uap.offset, sbytes, ref->sr_sock_fp->f_sfbytes);
 	ref->sr_uap.offset += sbytes;
 	if (uap->nbytes)
 		ref->sr_uap.nbytes -= sbytes;
@@ -3506,7 +3506,6 @@ sendfile_task_func(void *context, int pe
 	off_t sbytes = 0;
 
 	sr = context;
-	CTR0(KTR_SPARE2, "task_func running");
 	if (sr->sr_magic != 0xCAFEBABE) {
 		printf("bad magic! 0x%x\n", sr->sr_magic);
 		/* XXX memory leak */
@@ -3515,13 +3514,10 @@ sendfile_task_func(void *context, int pe
 
 	sock_fp = sr->sr_sock_fp;
 	fp = sr->sr_fp;
-	CTR2(KTR_SPARE2, "processing sr %p sock_fp %p", sr, sock_fp);
 	if (sock_fp->f_type != DTYPE_SOCKET)
 		goto done;
 		
 	so = sock_fp->f_data;
-	CTR1(KTR_SPARE2, "task processing socket %p", so);
-		
 	if ((so->so_state & SS_ISCONNECTED) == 0)
 		goto done;
 
@@ -3532,13 +3528,13 @@ sendfile_task_func(void *context, int pe
 	sb = &so->so_snd;
 	SOCKBUF_UNLOCK_ASSERT(sb);
 	SOCKBUF_LOCK(sb);
-	sb->sb_flags &= ~SB_SENDING;
+	sb->sb_flags &= ~(SB_SENDING|SB_SENDING_TASK);
 	if (sb->sb_state & SBS_CANTSENDMORE) {
 		CTR1(KTR_SPARE2, "SBS_CANTSENDMORE - socket %p", so);
 		sowwakeup_locked(so);
 		goto done;
 	} else if (sowriteable(so)) {
-		sb->sb_flags |= SB_SENDING;
+		sb->sb_flags |= (SB_SENDING|SB_SENDING_TASK);
 		SOCKBUF_UNLOCK(sb);
 		if (sr->sr_hdr_uio.uio_td != NULL)
 			hdr_uio = &sr->sr_hdr_uio;
@@ -3547,39 +3543,36 @@ sendfile_task_func(void *context, int pe
 
 		sr->sr_uap.sbytes = &sbytes;
 		sr->sr_uap.flags |= SF_TASKQ;
-		CTR1(KTR_SPARE2, "task sending on socket %p", so);
-		
+
 		error = kern_sendfile(curthread, &sr->sr_uap,
 		    hdr_uio, trl_uio,
 		    sr->sr_compat, fp, so, sr->sr_ucred);
-		CTR4(KTR_SPARE2, "sock %p off %ld sbytes %ld total_sbytes %ld",
-		    so, sr->sr_uap.offset, sbytes, fp->f_sfbytes);
-		atomic_add_long(&fp->f_sfbytes, sbytes);
+		CTR5(KTR_SPARE2, "sock %p error %d off %ld sbytes %ld total_sbytes %ld",
+		    so, error, sr->sr_uap.offset, sbytes, sock_fp->f_sfbytes);
+		SOCKBUF_LOCK(sb);
+		atomic_add_long(&sock_fp->f_sfbytes, sbytes);
 		sr->sr_uap.offset += sbytes;
 		if (sr->sr_uap.nbytes)
 			sr->sr_uap.nbytes -= sbytes;
-		if (error == EAGAIN &&
-		    (sr->sr_uap.offset + sbytes == sr->sr_vnp_size)) {
-			CTR0(KTR_SPARE2, "EAGAIN on full send");
-			error = 0;
+		sb->sb_flags &= ~(SB_SENDING|SB_SENDING_TASK);
+		if (error == EAGAIN) {
+			if (sr->sr_uap.offset + sbytes == sr->sr_vnp_size) {
+				CTR0(KTR_SPARE2, "EAGAIN on full send");
+				error = 0;
+			}
+			if (srsendingwakeup(sr, 0) != ENOTCONN) {
+				SOCKBUF_UNLOCK(sb);
+				return;
+			}
 		}
-		SOCKBUF_LOCK(sb);
-	}
-#ifdef KTR
-	else
-		CTR2(KTR_SPARE2, "sock %p off %ld - not writeable in task_func",
-		    so, sr->sr_uap.offset);
-#endif		
-	if (error == EAGAIN && srsendingwakeup(sr) != ENOTCONN) {
-		SOCKBUF_UNLOCK(sb);
-		return;
+			
 	}
+
 #ifdef KTR
 	if (error && error != EAGAIN && error != EPIPE) 
 		CTR1(KTR_SPARE2, "error %d", error); 
 #endif
 	
-	sb->sb_flags &= ~SB_SENDING;
 	sowwakeup_locked(so);
 done:
 	SOCKBUF_UNLOCK_ASSERT(sb);
@@ -3587,7 +3580,7 @@ done:
 }
 
 static int
-srsendingwakeup(struct socketref *sr) 
+srsendingwakeup(struct socketref *sr, int external)
 {
 	struct socket *so;
 	struct file *fp;
@@ -3604,30 +3597,29 @@ srsendingwakeup(struct socketref *sr) 
 	}
 
 	fp = sr->sr_sock_fp;
-	CTR2(KTR_SPARE2, "processing s %d sock_fp %p", sr->sr_uap.s, fp);
 	if (fp->f_type != DTYPE_SOCKET) {
 		CTR1(KTR_SPARE2, "not socket - type %d", fp->f_type);
 		goto error;
 	}
 	so = fp->f_data;
+	sb = &so->so_snd;
+	SOCKBUF_LOCK_ASSERT(sb);
+	sb->sb_flags &= ~(SB_SENDING|SB_SENDING_TASK);
 	if ((so->so_state & SS_ISCONNECTED) == 0) {
 		CTR1(KTR_SPARE2, "not connected %p", so);
 		goto error;
 	}
 
-	CTR1(KTR_SPARE2, "processing socket %p", so);
-	sb = &so->so_snd;
-	SOCKBUF_LOCK_ASSERT(sb);
-	sb->sb_flags &= ~SB_SENDING;
 	if (sb->sb_state & SBS_CANTSENDMORE) {
 		CTR1(KTR_SPARE2, "SBS_CANTSENDMORE %p", so);
 	} else if (sowriteable(so)) {
 		CTR2(KTR_SPARE2, "enqueue socket to task %p sr %p", so, sr);
-		sb->sb_flags |= SB_SENDING;
+		sb->sb_flags |= (SB_SENDING|SB_SENDING_TASK);
 		taskqueue_enqueue(sendfile_tq, &sr->sr_task);
 	} else {
-		CTR2(KTR_SPARE2, "sock %p off %ld - not writeable in srsendingwakeup",
-		    so, sr->sr_uap.offset);
+		if (external)
+			CTR3(KTR_SPARE2, "sock %p off %ld sbspace %ld - not writeable in srsendingwakeup",
+			    so, sr->sr_uap.offset, sbspace(sb));
 		sb->sb_flags |= SB_SENDING;
 		mtx_lock(&sendfile_bg_lock);
 		TAILQ_INSERT_TAIL(sendfile_bg_queue, sr, entry);
@@ -3648,7 +3640,8 @@ sosendingwakeup(struct sockbuf *sb)
 	if (!TAILQ_EMPTY(sendfile_bg_queue)) {
 		TAILQ_FOREACH(sr, sendfile_bg_queue, entry) {
 			if (sb == &sr->sr_so->so_snd) {
-				sb->sb_flags &= ~SB_SENDING;
+				CTR3(KTR_SPARE2,
+				    "dequeueing socket %p sock_fp %p s %d", sr->sr_so, sr->sr_sock_fp, sr->sr_uap.s);
 				TAILQ_REMOVE(sendfile_bg_queue, sr, entry);
 				break;
 			}
@@ -3657,10 +3650,13 @@ sosendingwakeup(struct sockbuf *sb)
 	}
 	mtx_unlock(&sendfile_bg_lock);
 	
+	if (sb->sb_flags & SB_SENDING_TASK)
+		panic("task flag set while task not running");
+
 	/*
 	 * Buffer in flight
 	 */
-	if (sr != NULL && srsendingwakeup(sr) == ENOTCONN) {
+	if (sr != NULL && srsendingwakeup(sr, 1) == ENOTCONN) {
 		CTR2(KTR_SPARE2, "freeing expired socket %p ref %p",
 		    sr->sr_so, sr);
 		socketref_free(sr);

Modified: user/kmacy/releng_8_fcs/sys/kern/uipc_syscalls.c
==============================================================================
--- user/kmacy/releng_8_fcs/sys/kern/uipc_syscalls.c	Tue Oct 13 04:13:39 2009	(r198014)
+++ user/kmacy/releng_8_fcs/sys/kern/uipc_syscalls.c	Tue Oct 13 04:14:48 2009	(r198015)
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/fcntl.h>
 #include <sys/file.h>
+#include <sys/ktr.h>
 #include <sys/filio.h>
 #include <sys/mount.h>
 #include <sys/mbuf.h>
@@ -1906,22 +1907,20 @@ kern_sendfile(struct thread *td, struct 
 			error = ENOTCONN;
 			goto out;
 		}
-	} else {
+		if (sock_fp->f_sfbytes != 0) {
+			if (uap->sbytes != NULL)
+				CTR2(KTR_SPARE2, "sock %p f_sfbytes %ld",
+				    so, sock_fp->f_sfbytes);
+			else
+				CTR2(KTR_SPARE2, "sock %p !sbytes f_sfbytes %ld",
+				    so, sock_fp->f_sfbytes);
+			error = 0;
+			goto out;
+		}
+	} else
 		so = bgso;
-	}
 
-	if ((uap->flags & SF_TASKQ) == 0 &&
-	    sock_fp->f_sfbytes != 0) {
-		SOCKBUF_UNLOCK(&so->so_snd);
-		if (uap->sbytes != NULL) {
-			copyout(&sbytes, uap->sbytes, sizeof(off_t));
-			sock_fp->f_sfbytes = 0;
-		}
-		error = 0;
-		goto out;
-	}
 
-	
 	/*
 	 * Do not wait on memory allocations but return ENOMEM for
 	 * caller to retry later.
@@ -2297,9 +2296,12 @@ out:
 		td->td_retval[0] = 0;
 	}
 	if (uap->sbytes != NULL) {
-		if ((uap->flags & SF_TASKQ) == 0)
-			copyout(&sbytes, uap->sbytes, sizeof(off_t));
-		else
+		if ((uap->flags & SF_TASKQ) == 0) {
+			if (sock_fp != NULL && sock_fp->f_sfbytes != 0)
+				copyout(&sock_fp->f_sfbytes, uap->sbytes, sizeof(off_t));
+			else
+				copyout(&sbytes, uap->sbytes, sizeof(off_t));
+		} else
 			*(uap->sbytes) = sbytes;
 	}
 	if (obj != NULL)

Modified: user/kmacy/releng_8_fcs/sys/sys/sockbuf.h
==============================================================================
--- user/kmacy/releng_8_fcs/sys/sys/sockbuf.h	Tue Oct 13 04:13:39 2009	(r198014)
+++ user/kmacy/releng_8_fcs/sys/sys/sockbuf.h	Tue Oct 13 04:14:48 2009	(r198015)
@@ -53,6 +53,7 @@
 #define	SB_IN_TOE	0x400		/* socket buffer is in the middle of an operation */
 #define	SB_AUTOSIZE	0x800		/* automatically size socket buffer */
 #define	SB_SENDING	0x1000		/* socket is owned by sendfile thread */
+#define	SB_SENDING_TASK	0x2000		/* socket is in taskqueue queue */
 
 #define	SBS_CANTSENDMORE	0x0010	/* can't send more data to peer */
 #define	SBS_CANTRCVMORE		0x0020	/* can't receive more data from peer */


More information about the svn-src-user mailing list