Diff below shuffle the socket buffer definition to "properly" memset()
all required fields in sorflush(). It also gets rid of the sbrelease()
abstraction since zeroing out `sb_hiwat' and `sb_mbmax' is required in
only one place.
ok?
Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.210
diff -u -p -r1.210 uipc_socket.c
--- kern/uipc_socket.c 10 Dec 2017 11:31:54 -0000 1.210
+++ kern/uipc_socket.c 11 Dec 2017 07:46:02 -0000
@@ -216,7 +216,7 @@ sofree(struct socket *so)
so->so_sp = NULL;
}
#endif /* SOCKET_SPLICE */
- sbrelease(so, &so->so_snd);
+ sbflush(so, &so->so_snd);
sorflush(so);
pool_put(&socket_pool, so);
}
@@ -1052,15 +1052,11 @@ sorflush(struct socket *so)
sbunlock(so, sb);
aso.so_proto = pr;
aso.so_rcv = *sb;
- memset(sb, 0, sizeof (*sb));
- /* XXX - the memset stomps all over so_rcv */
- if (aso.so_rcv.sb_flagsintr & SB_KNOTE) {
- sb->sb_sel.si_note = aso.so_rcv.sb_sel.si_note;
- sb->sb_flagsintr = SB_KNOTE;
- }
+ memset(&sb->sb_startzero, 0,
+ (caddr_t)&sb->sb_endzero - (caddr_t)&sb->sb_startzero);
if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
(*pr->pr_domain->dom_dispose)(aso.so_rcv.sb_mb);
- sbrelease(&aso, &aso.so_rcv);
+ sbflush(&aso, &aso.so_rcv);
}
#ifdef SOCKET_SPLICE
Index: kern/uipc_socket2.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.88
diff -u -p -r1.88 uipc_socket2.c
--- kern/uipc_socket2.c 10 Dec 2017 11:31:54 -0000 1.88
+++ kern/uipc_socket2.c 11 Dec 2017 07:43:29 -0000
@@ -423,8 +423,7 @@ sowakeup(struct socket *so, struct sockb
* Before using a new socket structure it is first necessary to reserve
* buffer space to the socket, by calling sbreserve(). This should commit
* some of the available buffer space in the system buffer pool for the
- * socket (currently, it does nothing but enforce limits). The space
- * should be released by calling sbrelease() when the socket is destroyed.
+ * socket (currently, it does nothing but enforce limits).
*/
int
@@ -446,7 +445,8 @@ soreserve(struct socket *so, u_long sndc
so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
return (0);
bad2:
- sbrelease(so, &so->so_snd);
+ sbflush(so, &so->so_snd);
+ so->so_snd.sb_hiwat = so->so_snd.sb_mbmax = 0;
bad:
return (ENOBUFS);
}
@@ -495,17 +495,6 @@ sbchecklowmem(void)
mbpool.pr_nout > mbpool.pr_hardlimit * 80 / 100)
sblowmem = 1;
return (sblowmem);
-}
-
-/*
- * Free mbufs held by a socket, and reserved mbuf space.
- */
-void
-sbrelease(struct socket *so, struct sockbuf *sb)
-{
-
- sbflush(so, sb);
- sb->sb_hiwat = sb->sb_mbmax = 0;
}
/*
Index: sys/socketvar.h
===================================================================
RCS file: /cvs/src/sys/sys/socketvar.h,v
retrieving revision 1.79
diff -u -p -r1.79 socketvar.h
--- sys/socketvar.h 23 Nov 2017 13:45:46 -0000 1.79
+++ sys/socketvar.h 11 Dec 2017 07:49:06 -0000
@@ -98,6 +98,8 @@ struct socket {
* Variables for socket buffering.
*/
struct sockbuf {
+/* The following fields are all zeroed on flush. */
+#define sb_startzero sb_cc
u_long sb_cc; /* actual chars in buffer */
u_long sb_datacc; /* data only chars in buffer */
u_long sb_hiwat; /* max actual char count */
@@ -109,10 +111,12 @@ struct socket {
struct mbuf *sb_mbtail; /* the last mbuf in the chain */
struct mbuf *sb_lastrecord;/* first mbuf of last record in
socket buffer */
- struct selinfo sb_sel; /* process selecting read/write */
- int sb_flagsintr; /* flags, changed during interrupt */
- short sb_flags; /* flags, see below */
u_short sb_timeo; /* timeout for read/write */
+ short sb_flags; /* flags, see below */
+/* End area that is zeroed on flush. */
+#define sb_endzero sb_flags
+ int sb_flagsintr; /* flags, changed atomically */
+ struct selinfo sb_sel; /* process selecting read/write */
} so_rcv, so_snd;
#define SB_MAX (2*1024*1024) /* default for max chars in
sockbuf */
#define SB_LOCK 0x01 /* lock on data queue */