From: Vitaliy Makkoveev Subject: Re: Relax sockets splicing locking To: Alexander Bluhm Cc: tech@openbsd.org Date: Sat, 4 Jan 2025 20:07:14 +0300 On Sat, Jan 04, 2025 at 06:39:26PM +0300, Vitaliy Makkoveev wrote: > > On 4 Jan 2025, at 16:34, Alexander Bluhm 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 #include #include #include #include #include #include #include #include #include #include #include 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; }