On Mon, Dec 08, 2025 at 08:20:14AM +0100, Stefano Brivio wrote: > Right now, the only need for this kind of function comes from > tcp_get_sndbuf(), which calculates the amount of sending buffer we > want to use depending on its own size: we want to use more of it > if it's smaller, as bookkeeping overhead is usually lower and we rely > on auto-tuning there, and use less of it when it's bigger. > > For this purpose, the new function is overly generic: @x is the same > as @y, that is, we want to use more or less of the buffer depending > on the size of the buffer itself. > > However, an upcoming change will need that generality, as we'll want > to scale the amount of sending buffer we use depending on another > (scaled) factor. > > Signed-off-by: Stefano Brivio Reviewed-by: David Gibson > --- > tcp.c | 6 +----- > util.c | 38 ++++++++++++++++++++++++++++++++++++++ > util.h | 1 + > 3 files changed, 40 insertions(+), 5 deletions(-) > > diff --git a/tcp.c b/tcp.c > index bb661ee..026546a 100644 > --- a/tcp.c > +++ b/tcp.c > @@ -788,11 +788,7 @@ static void tcp_get_sndbuf(struct tcp_tap_conn *conn) > return; > } > > - v = sndbuf; > - if (v >= SNDBUF_BIG) > - v /= 2; > - else if (v > SNDBUF_SMALL) > - v -= v * (v - SNDBUF_SMALL) / (SNDBUF_BIG - SNDBUF_SMALL) / 2; > + v = clamped_scale(sndbuf, sndbuf, SNDBUF_SMALL, SNDBUF_BIG, 50); > > SNDBUF_SET(conn, MIN(INT_MAX, v)); > } > diff --git a/util.c b/util.c > index f32c9cb..2232a24 100644 > --- a/util.c > +++ b/util.c > @@ -1223,3 +1223,41 @@ void fsync_pcap_and_log(void) > if (log_file != -1) > (void)fsync(log_file); > } > + > +/** > + * clamped_scale() - Scale @x from 100% to f% depending on @y's value > + * @x: Value to scale > + * @y: Value determining scaling > + * @lo: Lower bound for @y (start of y-axis slope) > + * @hi: Upper bound for @y (end of y-axis slope) > + * @f: Scaling factor, percent (might be less or more than 100) > + * > + * Return: @x scaled by @f * linear interpolation of @y between @lo and @hi > + * > + * In pictures: > + * > + * f % -> ,---- * If @y < lo (for example, @y is y0), return @x > + * /| | > + * / | | * If @lo < @y < @hi (for example, @y is y1), > + * / | | return @x scaled by a factor linearly > + * (100 + f) / 2 % ->/ | | interpolated between 100% and f% depending on > + * /| | | @y's position between @lo (100%) and @hi (f%) > + * / | | | > + * / | | | * If @y > @hi (for example, @y is y2), return > + * 100 % -> -----' | | | @x * @f / 100 > + * | | | | | > + * y0 lo y1 hi y2 Example: @f = 150, @lo = 10, @hi = 20, @y = 15, > + * @x = 1000 > + * -> interpolated factor is 125% > + * -> return 1250 > + */ > +long clamped_scale(long x, long y, long lo, long hi, long f) > +{ > + if (y < lo) > + return x; > + > + if (y > hi) > + return x * f / 100; > + > + return x - (x * (y - lo) / (hi - lo)) * (100 - f) / 100; > +} > diff --git a/util.h b/util.h > index 17f5ae0..744880b 100644 > --- a/util.h > +++ b/util.h > @@ -242,6 +242,7 @@ int read_remainder(int fd, const struct iovec *iov, size_t cnt, size_t skip); > void close_open_files(int argc, char **argv); > bool snprintf_check(char *str, size_t size, const char *format, ...); > void fsync_pcap_and_log(void); > +long clamped_scale(long x, long y, long lo, long hi, long f); > > /** > * af_name() - Return name of an address family > -- > 2.43.0 > -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson