Commit e6e67768 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'tcp_mmap-optmizations'



Eric Dumazet says:

====================
tcp_mmap: optmizations

This series updates tcp_mmap reference tool to use best pratices.

First patch is using madvise(MADV_DONTNEED) to decrease pressure
on the socket lock.

Last patches try to use huge pages when available.
====================

Acked-by: default avatarSoheil Hassas Yeganeh <soheil@google.com>
Acked-by: default avatarArjun Roy <arjunroy@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 394fcd8a 59c0d319
Loading
Loading
Loading
Loading
+35 −7
Original line number Diff line number Diff line
@@ -123,6 +123,28 @@ void hash_zone(void *zone, unsigned int length)
#define ALIGN_UP(x, align_to)	(((x) + ((align_to)-1)) & ~((align_to)-1))
#define ALIGN_PTR_UP(p, ptr_align_to)	((typeof(p))ALIGN_UP((unsigned long)(p), ptr_align_to))


static void *mmap_large_buffer(size_t need, size_t *allocated)
{
	void *buffer;
	size_t sz;

	/* Attempt to use huge pages if possible. */
	sz = ALIGN_UP(need, map_align);
	buffer = mmap(NULL, sz, PROT_READ | PROT_WRITE,
		      MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);

	if (buffer == (void *)-1) {
		sz = need;
		buffer = mmap(NULL, sz, PROT_READ | PROT_WRITE,
			      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
		if (buffer != (void *)-1)
			fprintf(stderr, "MAP_HUGETLB attempt failed, look at /sys/kernel/mm/hugepages for optimal performance\n");
	}
	*allocated = sz;
	return buffer;
}

void *child_thread(void *arg)
{
	unsigned long total_mmap = 0, total = 0;
@@ -135,6 +157,7 @@ void *child_thread(void *arg)
	void *addr = NULL;
	double throughput;
	struct rusage ru;
	size_t buffer_sz;
	int lu, fd;

	fd = (int)(unsigned long)arg;
@@ -142,9 +165,9 @@ void *child_thread(void *arg)
	gettimeofday(&t0, NULL);

	fcntl(fd, F_SETFL, O_NDELAY);
	buffer = malloc(chunk_size);
	if (!buffer) {
		perror("malloc");
	buffer = mmap_large_buffer(chunk_size, &buffer_sz);
	if (buffer == (void *)-1) {
		perror("mmap");
		goto error;
	}
	if (zflg) {
@@ -179,6 +202,10 @@ void *child_thread(void *arg)
				total_mmap += zc.length;
				if (xflg)
					hash_zone(addr, zc.length);
				/* It is more efficient to unmap the pages right now,
				 * instead of doing this in next TCP_ZEROCOPY_RECEIVE.
				 */
				madvise(addr, zc.length, MADV_DONTNEED);
				total += zc.length;
			}
			if (zc.recv_skip_hint) {
@@ -230,7 +257,7 @@ end:
				ru.ru_nvcsw);
	}
error:
	free(buffer);
	munmap(buffer, buffer_sz);
	close(fd);
	if (zflg)
		munmap(raddr, chunk_size + map_align);
@@ -347,6 +374,7 @@ int main(int argc, char *argv[])
	uint64_t total = 0;
	char *host = NULL;
	int fd, c, on = 1;
	size_t buffer_sz;
	char *buffer;
	int sflg = 0;
	int mss = 0;
@@ -437,8 +465,8 @@ int main(int argc, char *argv[])
		}
		do_accept(fdlisten);
	}
	buffer = mmap(NULL, chunk_size, PROT_READ | PROT_WRITE,
			      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

	buffer = mmap_large_buffer(chunk_size, &buffer_sz);
	if (buffer == (char *)-1) {
		perror("mmap");
		exit(1);
@@ -484,6 +512,6 @@ int main(int argc, char *argv[])
		total += wr;
	}
	close(fd);
	munmap(buffer, chunk_size);
	munmap(buffer, buffer_sz);
	return 0;
}