Subject: Re: sokva still.
To: None <tech-net@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: current-users
Date: 12/29/2003 20:13:09
--NextPart-20031229201232-0029100
Content-Type: Text/Plain; charset=us-ascii

[added tech-net@]

hi,

> if one sends some data by loan and then keeps the socket,
> the mbuf will stay in the socket's local so_pendfree queue 
> up to forever.  i think this is a problem.
> although i doubt if it eats 64MB...

i'll remove per-socket so_pendfree if no one objects.
(patch attached)

YAMAMOTO Takashi


--NextPart-20031229201232-0029100
Content-Type: Text/Plain; charset=us-ascii
Content-Disposition: attachment; filename="sopend.diff"

Index: kern/uipc_socket.c
===================================================================
--- kern/uipc_socket.c	(revision 480)
+++ kern/uipc_socket.c	(revision 481)
@@ -147,6 +147,7 @@ int use_sosend_loan = 0;
 int use_sosend_loan = 1;
 #endif
 
+struct simplelock so_pendfree_slock = SIMPLELOCK_INITIALIZER;
 struct mbuf *so_pendfree;
 
 #ifndef SOMAXKVA
@@ -235,25 +236,14 @@ sodopendfree(struct socket *so)
 	s = splvm();
 
 	for (;;) {
+		simple_lock(&so_pendfree_slock);
 		m = so_pendfree;
-		if (m == NULL)
+		if (m == NULL) {
+			simple_unlock(&so_pendfree_slock);
 			break;
+		}
 		so_pendfree = m->m_next;
-		splx(s);
-
-		rv += m->m_ext.ext_size;
-		sodoloanfree((m->m_flags & M_EXT_PAGES) ?
-		    m->m_ext.ext_pgs : NULL, m->m_ext.ext_buf,
-		    m->m_ext.ext_size);
-		s = splvm();
-		pool_cache_put(&mbpool_cache, m);
-	}
-
-	for (;;) {
-		m = so->so_pendfree;
-		if (m == NULL)
-			break;
-		so->so_pendfree = m->m_next;
+		simple_unlock(&so_pendfree_slock);
 		splx(s);
 
 		rv += m->m_ext.ext_size;
@@ -271,7 +261,6 @@ sodopendfree(struct socket *so)
 void
 soloanfree(struct mbuf *m, caddr_t buf, size_t size, void *arg)
 {
-	struct socket *so = arg;
 	int s;
 
 	if (m == NULL) {
@@ -280,8 +269,10 @@ soloanfree(struct mbuf *m, caddr_t buf, 
 	}
 
 	s = splvm();
-	m->m_next = so->so_pendfree;
-	so->so_pendfree = m;
+	simple_lock(&so_pendfree_slock);
+	m->m_next = so_pendfree;
+	so_pendfree = m;
+	simple_unlock(&so_pendfree_slock);
 	splx(s);
 	if (sokvawaiters)
 		wakeup(&socurkva);
@@ -435,7 +426,6 @@ solisten(struct socket *so, int backlog)
 void
 sofree(struct socket *so)
 {
-	struct mbuf *m;
 
 	if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
 		return;
@@ -450,11 +440,6 @@ sofree(struct socket *so)
 	}
 	sbrelease(&so->so_snd);
 	sorflush(so);
-	while ((m = so->so_pendfree) != NULL) {
-		so->so_pendfree = m->m_next;
-		m->m_next = so_pendfree;
-		so_pendfree = m;
-	}
 	pool_put(&socket_pool, so);
 }
 
Index: sys/socketvar.h
===================================================================
--- sys/socketvar.h	(revision 480)
+++ sys/socketvar.h	(revision 481)
@@ -129,7 +129,6 @@ struct socket {
 					struct mbuf **, int *));
 	struct mowner	*so_mowner;	/* who owns mbufs for this socket */
 	uid_t		so_uid;		/* who opened the socket */
-	struct mbuf	*so_pendfree;	/* loaned-page mbufs w/ frees pending */
 };
 
 #define	SB_EMPTY_FIXUP(sb)						\

--NextPart-20031229201232-0029100--