Merge tag 'x86_bugs_retbleed' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[linux-2.6-microblaze.git] / tools / testing / selftests / net / tcp_mmap.c
index a61b7b3..00f837c 100644 (file)
@@ -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;
 }