Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Feb 2023 20:52:25 GMT
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 2631a2599b8b - stable/13 - sockbufs: add sbreserve_locked_limit() with custom maxsockbuf limit.
Message-ID:  <202302092052.319KqPkW013463@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=2631a2599b8b3b4c6f651a9bbe54454167b13bcf

commit 2631a2599b8b3b4c6f651a9bbe54454167b13bcf
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2022-09-27 13:52:11 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-02-09 20:40:58 +0000

    sockbufs: add sbreserve_locked_limit() with custom maxsockbuf limit.
    
    Protocols such as netlink may need a large socket receive buffer,
     measured in tens of megabytes. This change allows netlink to
     set larger socket buffers (given the privs are in place), without
     requiring user to manuall bump maxsockbuf.
    
    Reviewed by:    glebius
    Differential Revision: https://reviews.freebsd.org/D36747
    
    (cherry picked from commit 7b660faa9e30c15d3be9b2c44c3ca046a33331f4)
---
 sys/kern/uipc_sockbuf.c | 22 +++++++++++++++-------
 sys/sys/sockbuf.h       |  2 ++
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 80505dd4dbd2..cbfcc0e5fe95 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -64,9 +64,10 @@ void	(*aio_swake)(struct socket *, struct sockbuf *);
  * Primitive routines for operating on socket buffers
  */
 
+#define	BUF_MAX_ADJ(_sz)	(((u_quad_t)(_sz)) * MCLBYTES / (MSIZE + MCLBYTES))
+
 u_long	sb_max = SB_MAX;
-u_long sb_max_adj =
-       (quad_t)SB_MAX * MCLBYTES / (MSIZE + MCLBYTES); /* adjusted sb_max */
+u_long sb_max_adj = BUF_MAX_ADJ(SB_MAX);
 
 static	u_long sb_efficiency = 8;	/* parameter for sbreserve() */
 
@@ -592,7 +593,7 @@ sysctl_handle_sb_max(SYSCTL_HANDLER_ARGS)
 	if (tmp_sb_max < MSIZE + MCLBYTES)
 		return (EINVAL);
 	sb_max = tmp_sb_max;
-	sb_max_adj = (u_quad_t)sb_max * MCLBYTES / (MSIZE + MCLBYTES);
+	sb_max_adj = BUF_MAX_ADJ(sb_max);
 	return (0);
 }
 
@@ -601,8 +602,8 @@ sysctl_handle_sb_max(SYSCTL_HANDLER_ARGS)
  * become limiting if buffering efficiency is near the normal case.
  */
 int
-sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
-    struct thread *td)
+sbreserve_locked_limit(struct sockbuf *sb, u_long cc, struct socket *so,
+    u_long buf_max, struct thread *td)
 {
 	rlim_t sbsize_limit;
 
@@ -615,7 +616,7 @@ sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
 	 * appropriate thread resource limits are available.  In that case,
 	 * we don't apply a process limit.
 	 */
-	if (cc > sb_max_adj)
+	if (cc > BUF_MAX_ADJ(buf_max))
 		return (0);
 	if (td != NULL) {
 		sbsize_limit = lim_cur(td, RLIMIT_SBSIZE);
@@ -624,12 +625,19 @@ sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
 	if (!chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, cc,
 	    sbsize_limit))
 		return (0);
-	sb->sb_mbmax = min(cc * sb_efficiency, sb_max);
+	sb->sb_mbmax = min(cc * sb_efficiency, buf_max);
 	if (sb->sb_lowat > sb->sb_hiwat)
 		sb->sb_lowat = sb->sb_hiwat;
 	return (1);
 }
 
+int
+sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
+    struct thread *td)
+{
+	return (sbreserve_locked_limit(sb, cc, so, sb_max, td));
+}
+
 int
 sbsetopt(struct socket *so, int cmd, u_long cc)
 {
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
index a263555b3a21..57f080615bdc 100644
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -176,6 +176,8 @@ void	sbrelease_locked(struct sockbuf *sb, struct socket *so);
 int	sbsetopt(struct socket *so, int cmd, u_long cc);
 int	sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
 	    struct thread *td);
+int	sbreserve_locked_limit(struct sockbuf *sb, u_long cc, struct socket *so,
+	    u_long buf_max, struct thread *td);
 void	sbsndptr_adv(struct sockbuf *sb, struct mbuf *mb, u_int len);
 struct mbuf *
 	sbsndptr_noadv(struct sockbuf *sb, u_int off, u_int *moff);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202302092052.319KqPkW013463>