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 */

Reply via email to