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