Download raw body.
Relax sockets splicing locking
On Sat, Jan 04, 2025 at 06:39:26PM +0300, Vitaliy Makkoveev wrote:
> > On 4 Jan 2025, at 16:34, Alexander Bluhm <bluhm@openbsd.org> wrote:
> >
> > [skip]
> > I have tested it with my regress and netlink setup. My perform
> > testing machines are currently busy with other tests.
> >
> > We have no propper regression tests for splicing and unsplicing
> > under heavy load. I am currently trying to write a test.
> >
>
> We need something like multithreaded attempts of simultaneous
> splicing and unsplicing one socket to itself. Or the same but
> for two sockets.
>
The simplest test to concurrently splice/unsplice socket.
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <netinet/in.h>
static int s;
static int spliced = 0;
static int unspliced = 0;
static void *
thr_splice(void *arg)
{
while (1) {
if (setsockopt(s, SOL_SOCKET, SO_SPLICE, &s, sizeof(s)) == 0)
spliced = 1;
}
return NULL;
}
static void *
thr_unsplice(void *arg)
{
while (1) {
if (setsockopt(s, SOL_SOCKET, SO_SPLICE, NULL, 0) == 0)
unspliced = 1;
}
return NULL;
}
int
main(int argc, char *argv[])
{
struct timespec testtime = {
.tv_sec = 60,
.tv_nsec = 0,
};
int mib[2], ncpu;
size_t len;
struct sockaddr_in sin;
socklen_t slen;
pthread_t thr;
int i, error;
if (argc == 2 && !strcmp(argv[1], "--infinite"))
testtime.tv_sec = (10 * 365 * 86400);
mib[0] = CTL_HW;
mib[1] = HW_NCPUONLINE;
len = sizeof(ncpu);
if (sysctl(mib, 2, &ncpu, &len, NULL, 0) < 0)
err(1, "sysctl");
if (ncpu <= 0)
errx(1, "Wrong number of CPUs online: %d", ncpu);
if (ncpu == 1)
ncpu = 2;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
err(1, "bind");
slen = sizeof(sin);
if (getsockname(s, (struct sockaddr *)&sin, &slen) < 0)
err(1, "getsockname");
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
err(1, "connect");
for (i = 0; i < ncpu; ++i) {
error = pthread_create(&thr, NULL, thr_splice, NULL);
if (error)
errc(1, error, "pthread_create");
error = pthread_create(&thr, NULL, thr_unsplice, NULL);
if (error)
errc(1, error, "pthread_create");
}
nanosleep(&testtime, NULL);
if (!(spliced && unspliced))
errx(1, "was %sspliced, was %sunspliced",
spliced ? "" : "not ", unspliced ? "" : "not ");
return 0;
}
Relax sockets splicing locking