Diff below adds an extra argument, a pointer to the socket corresponding to the buffer given to: sballoc(), sbfree(), sbcompress(), sbcheck() and sbdroprecord().
This pointer will be used to assert for or grab a per-socket lock. There is no functional change in this diff. Its goal is to simplify the review (and possible revert) of the change introducing `so_mtx' [0]. Note that this diff includes the removal of sbinsertoob() sent previously. ok? [0] https://marc.info/?l=openbsd-tech&m=162685565421248&w=2 Index: kern/uipc_socket.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.263 diff -u -p -r1.263 uipc_socket.c --- kern/uipc_socket.c 28 May 2021 16:24:53 -0000 1.263 +++ kern/uipc_socket.c 24 Jul 2021 09:32:10 -0000 @@ -860,7 +860,7 @@ dontblock: *paddr = m_copym(m, 0, m->m_len, M_NOWAIT); m = m->m_next; } else { - sbfree(&so->so_rcv, m); + sbfree(so, &so->so_rcv, m); if (paddr) { *paddr = m; so->so_rcv.sb_mb = m->m_next; @@ -884,7 +884,7 @@ dontblock: *controlp = m_copym(m, 0, m->m_len, M_NOWAIT); m = m->m_next; } else { - sbfree(&so->so_rcv, m); + sbfree(so, &so->so_rcv, m); so->so_rcv.sb_mb = m->m_next; m->m_nextpkt = m->m_next = NULL; cm = m; @@ -984,7 +984,7 @@ dontblock: orig_resid = 0; } else { nextrecord = m->m_nextpkt; - sbfree(&so->so_rcv, m); + sbfree(so, &so->so_rcv, m); if (mp) { *mp = m; mp = &m->m_next; @@ -1065,7 +1065,7 @@ dontblock: if (m && pr->pr_flags & PR_ATOMIC) { flags |= MSG_TRUNC; if ((flags & MSG_PEEK) == 0) - (void) sbdroprecord(&so->so_rcv); + (void) sbdroprecord(so, &so->so_rcv); } if ((flags & MSG_PEEK) == 0) { if (m == NULL) { @@ -1452,7 +1452,7 @@ somove(struct socket *so, int wait) while (m && m->m_type == MT_CONTROL) m = m->m_next; if (m == NULL) { - sbdroprecord(&so->so_rcv); + sbdroprecord(so, &so->so_rcv); if (so->so_proto->pr_flags & PR_WANTRCVD && so->so_pcb) (so->so_proto->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL, NULL); @@ -1492,7 +1492,7 @@ somove(struct socket *so, int wait) * that the whole first record can be processed. */ m = so->so_rcv.sb_mb; - sbfree(&so->so_rcv, m); + sbfree(so, &so->so_rcv, m); so->so_rcv.sb_mb = m_free(m); sbsync(&so->so_rcv, nextrecord); } @@ -1502,7 +1502,7 @@ somove(struct socket *so, int wait) */ m = so->so_rcv.sb_mb; while (m && m->m_type == MT_CONTROL) { - sbfree(&so->so_rcv, m); + sbfree(so, &so->so_rcv, m); so->so_rcv.sb_mb = m_free(m); m = so->so_rcv.sb_mb; sbsync(&so->so_rcv, nextrecord); @@ -1541,7 +1541,7 @@ somove(struct socket *so, int wait) so->so_rcv.sb_datacc -= size; } else { *mp = so->so_rcv.sb_mb; - sbfree(&so->so_rcv, *mp); + sbfree(so, &so->so_rcv, *mp); so->so_rcv.sb_mb = (*mp)->m_next; sbsync(&so->so_rcv, nextrecord); } @@ -1550,7 +1550,7 @@ somove(struct socket *so, int wait) SBLASTRECORDCHK(&so->so_rcv, "somove 3"); SBLASTMBUFCHK(&so->so_rcv, "somove 3"); - SBCHECK(&so->so_rcv); + SBCHECK(so, &so->so_rcv); if (m == NULL) goto release; m->m_nextpkt = NULL; Index: kern/uipc_socket2.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_socket2.c,v retrieving revision 1.111 diff -u -p -r1.111 uipc_socket2.c --- kern/uipc_socket2.c 7 Jun 2021 09:10:32 -0000 1.111 +++ kern/uipc_socket2.c 24 Jul 2021 09:34:21 -0000 @@ -654,7 +654,7 @@ sbappend(struct socket *so, struct sockb */ sb->sb_lastrecord = m; } - sbcompress(sb, m, n); + sbcompress(so, sb, m, n); SBLASTRECORDCHK(sb, "sbappend 2"); } @@ -673,7 +673,7 @@ sbappendstream(struct socket *so, struct SBLASTMBUFCHK(sb, __func__); - sbcompress(sb, m, sb->sb_mbtail); + sbcompress(so, sb, m, sb->sb_mbtail); sb->sb_lastrecord = sb->sb_mb; SBLASTRECORDCHK(sb, __func__); @@ -681,7 +681,7 @@ sbappendstream(struct socket *so, struct #ifdef SOCKBUF_DEBUG void -sbcheck(struct sockbuf *sb) +sbcheck(struct socket *so, struct sockbuf *sb) { struct mbuf *m, *n; u_long len = 0, mbcnt = 0; @@ -723,7 +723,7 @@ sbappendrecord(struct socket *so, struct * Put the first mbuf on the queue. * Note this permits zero length records. */ - sballoc(sb, m0); + sballoc(so, sb, m0); SBLASTRECORDCHK(sb, "sbappendrecord 1"); SBLINKRECORD(sb, m0); m = m0->m_next; @@ -732,60 +732,11 @@ sbappendrecord(struct socket *so, struct m0->m_flags &= ~M_EOR; m->m_flags |= M_EOR; } - sbcompress(sb, m, m0); + sbcompress(so, sb, m, m0); SBLASTRECORDCHK(sb, "sbappendrecord 2"); } /* - * As above except that OOB data - * is inserted at the beginning of the sockbuf, - * but after any other OOB data. - */ -void -sbinsertoob(struct sockbuf *sb, struct mbuf *m0) -{ - struct mbuf *m, **mp; - - if (m0 == NULL) - return; - - SBLASTRECORDCHK(sb, "sbinsertoob 1"); - - for (mp = &sb->sb_mb; (m = *mp) != NULL; mp = &((*mp)->m_nextpkt)) { - again: - switch (m->m_type) { - - case MT_OOBDATA: - continue; /* WANT next train */ - - case MT_CONTROL: - if ((m = m->m_next) != NULL) - goto again; /* inspect THIS train further */ - } - break; - } - /* - * Put the first mbuf on the queue. - * Note this permits zero length records. - */ - sballoc(sb, m0); - m0->m_nextpkt = *mp; - if (*mp == NULL) { - /* m0 is actually the new tail */ - sb->sb_lastrecord = m0; - } - *mp = m0; - m = m0->m_next; - m0->m_next = NULL; - if (m && (m0->m_flags & M_EOR)) { - m0->m_flags &= ~M_EOR; - m->m_flags |= M_EOR; - } - sbcompress(sb, m, m0); - SBLASTRECORDCHK(sb, "sbinsertoob 2"); -} - -/* * Append address and data, and optionally, control (ancillary) data * to the receive queue of a socket. If present, * m0 must include a packet header with total length. @@ -827,8 +778,8 @@ sbappendaddr(struct socket *so, struct s SBLASTRECORDCHK(sb, "sbappendaddr 1"); for (n = m; n->m_next != NULL; n = n->m_next) - sballoc(sb, n); - sballoc(sb, n); + sballoc(so, sb, n); + sballoc(so, sb, n); nlast = n; SBLINKRECORD(sb, m); @@ -864,8 +815,8 @@ sbappendcontrol(struct socket *so, struc SBLASTRECORDCHK(sb, "sbappendcontrol 1"); for (m = control; m->m_next != NULL; m = m->m_next) - sballoc(sb, m); - sballoc(sb, m); + sballoc(so, sb, m); + sballoc(so, sb, m); mlast = m; SBLINKRECORD(sb, control); @@ -883,7 +834,8 @@ sbappendcontrol(struct socket *so, struc * is null, the buffer is presumed empty. */ void -sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n) +sbcompress(struct socket *so, struct sockbuf *sb, struct mbuf *m, + struct mbuf *n) { int eor = 0; struct mbuf *o; @@ -919,7 +871,7 @@ sbcompress(struct sockbuf *sb, struct mb else sb->sb_mb = m; sb->sb_mbtail = m; - sballoc(sb, m); + sballoc(so, sb, m); n = m; m->m_flags &= ~M_EOR; m = m->m_next; @@ -984,12 +936,12 @@ sbdrop(struct socket *so, struct sockbuf break; } len -= m->m_len; - sbfree(sb, m); + sbfree(so, sb, m); mn = m_free(m); m = mn; } while (m && m->m_len == 0) { - sbfree(sb, m); + sbfree(so, sb, m); mn = m_free(m); m = mn; } @@ -1016,7 +968,7 @@ sbdrop(struct socket *so, struct sockbuf * and move the next record to the front. */ void -sbdroprecord(struct sockbuf *sb) +sbdroprecord(struct socket *so, struct sockbuf *sb) { struct mbuf *m, *mn; @@ -1024,7 +976,7 @@ sbdroprecord(struct sockbuf *sb) if (m) { sb->sb_mb = m->m_nextpkt; do { - sbfree(sb, m); + sbfree(so, sb, m); mn = m_free(m); } while ((m = mn) != NULL); } Index: sys/socketvar.h =================================================================== RCS file: /cvs/src/sys/sys/socketvar.h,v retrieving revision 1.98 diff -u -p -r1.98 socketvar.h --- sys/socketvar.h 7 Jun 2021 09:10:32 -0000 1.98 +++ sys/socketvar.h 24 Jul 2021 09:34:21 -0000 @@ -223,7 +223,7 @@ soreadable(struct socket *so) ((so)->so_state & SS_CANTSENDMORE) || (so)->so_error) /* adjust counters in sb reflecting allocation of m */ -#define sballoc(sb, m) do { \ +#define sballoc(so, sb, m) do { \ (sb)->sb_cc += (m)->m_len; \ if ((m)->m_type != MT_CONTROL && (m)->m_type != MT_SONAME) \ (sb)->sb_datacc += (m)->m_len; \ @@ -233,7 +233,7 @@ soreadable(struct socket *so) } while (/* CONSTCOND */ 0) /* adjust counters in sb reflecting freeing of m */ -#define sbfree(sb, m) do { \ +#define sbfree(so, sb, m) do { \ (sb)->sb_cc -= (m)->m_len; \ if ((m)->m_type != MT_CONTROL && (m)->m_type != MT_SONAME) \ (sb)->sb_datacc -= (m)->m_len; \ @@ -287,13 +287,13 @@ int sbappendaddr(struct socket *, struct int sbappendcontrol(struct socket *, struct sockbuf *, struct mbuf *, struct mbuf *); void sbappendrecord(struct socket *, struct sockbuf *, struct mbuf *); -void sbcompress(struct sockbuf *, struct mbuf *, struct mbuf *); +void sbcompress(struct socket *, struct sockbuf *, struct mbuf *, + struct mbuf *); struct mbuf * sbcreatecontrol(const void *, size_t, int, int); void sbdrop(struct socket *, struct sockbuf *, int); -void sbdroprecord(struct sockbuf *); +void sbdroprecord(struct socket *, struct sockbuf *); void sbflush(struct socket *, struct sockbuf *); -void sbinsertoob(struct sockbuf *, struct mbuf *); void sbrelease(struct socket *, struct sockbuf *); int sbcheckreserve(u_long, u_long); int sbchecklowmem(void); @@ -349,12 +349,12 @@ void sblastrecordchk(struct sockbuf *, c void sblastmbufchk(struct sockbuf *, const char *); #define SBLASTMBUFCHK(sb, where) sblastmbufchk((sb), (where)) -void sbcheck(struct sockbuf *); -#define SBCHECK(sb) sbcheck(sb) +void sbcheck(struct socket *, struct sockbuf *); +#define SBCHECK(so, sb) sbcheck((so), (sb)) #else #define SBLASTRECORDCHK(sb, where) /* nothing */ #define SBLASTMBUFCHK(sb, where) /* nothing */ -#define SBCHECK(sb) /* nothing */ +#define SBCHECK(so, sb) /* nothing */ #endif /* SOCKBUF_DEBUG */ #endif /* _KERNEL */
