@@ -76,6 +76,10 @@ static unsigned long nr_cpus, nr_pages, nr_pages_per_cpu, page_size;
76
76
#define BOUNCE_POLL (1<<3)
77
77
static int bounces ;
78
78
79
+ #ifdef HUGETLB_TEST
80
+ static int huge_fd ;
81
+ static char * huge_fd_off0 ;
82
+ #endif
79
83
static unsigned long long * count_verify ;
80
84
static int uffd , finished , * pipefd ;
81
85
static char * area_src , * area_dst ;
@@ -97,6 +101,69 @@ pthread_attr_t attr;
97
101
~(unsigned long)(sizeof(unsigned long long) \
98
102
- 1)))
99
103
104
+ #ifndef HUGETLB_TEST
105
+
106
+ #define EXPECTED_IOCTLS ((1 << _UFFDIO_WAKE) | \
107
+ (1 << _UFFDIO_COPY) | \
108
+ (1 << _UFFDIO_ZEROPAGE))
109
+
110
+ static int release_pages (char * rel_area )
111
+ {
112
+ int ret = 0 ;
113
+
114
+ if (madvise (rel_area , nr_pages * page_size , MADV_DONTNEED )) {
115
+ perror ("madvise" );
116
+ ret = 1 ;
117
+ }
118
+
119
+ return ret ;
120
+ }
121
+
122
+ static void allocate_area (void * * alloc_area )
123
+ {
124
+ if (posix_memalign (alloc_area , page_size , nr_pages * page_size )) {
125
+ fprintf (stderr , "out of memory\n" );
126
+ * alloc_area = NULL ;
127
+ }
128
+ }
129
+
130
+ #else /* HUGETLB_TEST */
131
+
132
+ #define EXPECTED_IOCTLS UFFD_API_RANGE_IOCTLS_HPAGE
133
+
134
+ static int release_pages (char * rel_area )
135
+ {
136
+ int ret = 0 ;
137
+
138
+ if (fallocate (huge_fd , FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE ,
139
+ rel_area == huge_fd_off0 ? 0 :
140
+ nr_pages * page_size ,
141
+ nr_pages * page_size )) {
142
+ perror ("fallocate" );
143
+ ret = 1 ;
144
+ }
145
+
146
+ return ret ;
147
+ }
148
+
149
+
150
+ static void allocate_area (void * * alloc_area )
151
+ {
152
+ * alloc_area = mmap (NULL , nr_pages * page_size , PROT_READ | PROT_WRITE ,
153
+ MAP_PRIVATE | MAP_HUGETLB , huge_fd ,
154
+ * alloc_area == area_src ? 0 :
155
+ nr_pages * page_size );
156
+ if (* alloc_area == MAP_FAILED ) {
157
+ fprintf (stderr , "mmap of hugetlbfs file failed\n" );
158
+ * alloc_area = NULL ;
159
+ }
160
+
161
+ if (* alloc_area == area_src )
162
+ huge_fd_off0 = * alloc_area ;
163
+ }
164
+
165
+ #endif /* HUGETLB_TEST */
166
+
100
167
static int my_bcmp (char * str1 , char * str2 , size_t n )
101
168
{
102
169
unsigned long i ;
@@ -384,10 +451,8 @@ static int stress(unsigned long *userfaults)
384
451
* UFFDIO_COPY without writing zero pages into area_dst
385
452
* because the background threads already completed).
386
453
*/
387
- if (madvise (area_src , nr_pages * page_size , MADV_DONTNEED )) {
388
- perror ("madvise" );
454
+ if (release_pages (area_src ))
389
455
return 1 ;
390
- }
391
456
392
457
for (cpu = 0 ; cpu < nr_cpus ; cpu ++ ) {
393
458
char c ;
@@ -425,16 +490,12 @@ static int userfaultfd_stress(void)
425
490
int uffd_flags , err ;
426
491
unsigned long userfaults [nr_cpus ];
427
492
428
- if ( posix_memalign ( & area , page_size , nr_pages * page_size )) {
429
- fprintf ( stderr , "out of memory\n" );
493
+ allocate_area (( void * * ) & area_src );
494
+ if (! area_src )
430
495
return 1 ;
431
- }
432
- area_src = area ;
433
- if (posix_memalign (& area , page_size , nr_pages * page_size )) {
434
- fprintf (stderr , "out of memory\n" );
496
+ allocate_area ((void * * )& area_dst );
497
+ if (!area_dst )
435
498
return 1 ;
436
- }
437
- area_dst = area ;
438
499
439
500
uffd = syscall (__NR_userfaultfd , O_CLOEXEC | O_NONBLOCK );
440
501
if (uffd < 0 ) {
@@ -528,9 +589,7 @@ static int userfaultfd_stress(void)
528
589
fprintf (stderr , "register failure\n" );
529
590
return 1 ;
530
591
}
531
- expected_ioctls = (1 << _UFFDIO_WAKE ) |
532
- (1 << _UFFDIO_COPY ) |
533
- (1 << _UFFDIO_ZEROPAGE );
592
+ expected_ioctls = EXPECTED_IOCTLS ;
534
593
if ((uffdio_register .ioctls & expected_ioctls ) !=
535
594
expected_ioctls ) {
536
595
fprintf (stderr ,
@@ -562,10 +621,8 @@ static int userfaultfd_stress(void)
562
621
* MADV_DONTNEED only after the UFFDIO_REGISTER, so it's
563
622
* required to MADV_DONTNEED here.
564
623
*/
565
- if (madvise (area_dst , nr_pages * page_size , MADV_DONTNEED )) {
566
- perror ("madvise 2" );
624
+ if (release_pages (area_dst ))
567
625
return 1 ;
568
- }
569
626
570
627
/* bounce pass */
571
628
if (stress (userfaults ))
@@ -606,6 +663,8 @@ static int userfaultfd_stress(void)
606
663
return err ;
607
664
}
608
665
666
+ #ifndef HUGETLB_TEST
667
+
609
668
int main (int argc , char * * argv )
610
669
{
611
670
if (argc < 3 )
@@ -632,6 +691,74 @@ int main(int argc, char **argv)
632
691
return userfaultfd_stress ();
633
692
}
634
693
694
+ #else /* HUGETLB_TEST */
695
+
696
+ /*
697
+ * Copied from mlock2-tests.c
698
+ */
699
+ unsigned long default_huge_page_size (void )
700
+ {
701
+ unsigned long hps = 0 ;
702
+ char * line = NULL ;
703
+ size_t linelen = 0 ;
704
+ FILE * f = fopen ("/proc/meminfo" , "r" );
705
+
706
+ if (!f )
707
+ return 0 ;
708
+ while (getline (& line , & linelen , f ) > 0 ) {
709
+ if (sscanf (line , "Hugepagesize: %lu kB" , & hps ) == 1 ) {
710
+ hps <<= 10 ;
711
+ break ;
712
+ }
713
+ }
714
+
715
+ free (line );
716
+ fclose (f );
717
+ return hps ;
718
+ }
719
+
720
+ int main (int argc , char * * argv )
721
+ {
722
+ if (argc < 4 )
723
+ fprintf (stderr , "Usage: <MiB> <bounces> <hugetlbfs_file>\n" ),
724
+ exit (1 );
725
+ nr_cpus = sysconf (_SC_NPROCESSORS_ONLN );
726
+ page_size = default_huge_page_size ();
727
+ if (!page_size )
728
+ fprintf (stderr , "Unable to determine huge page size\n" ),
729
+ exit (2 );
730
+ if ((unsigned long ) area_count (NULL , 0 ) + sizeof (unsigned long long ) * 2
731
+ > page_size )
732
+ fprintf (stderr , "Impossible to run this test\n" ), exit (2 );
733
+ nr_pages_per_cpu = atol (argv [1 ]) * 1024 * 1024 / page_size /
734
+ nr_cpus ;
735
+ if (!nr_pages_per_cpu ) {
736
+ fprintf (stderr , "invalid MiB\n" );
737
+ fprintf (stderr , "Usage: <MiB> <bounces>\n" ), exit (1 );
738
+ }
739
+ bounces = atoi (argv [2 ]);
740
+ if (bounces <= 0 ) {
741
+ fprintf (stderr , "invalid bounces\n" );
742
+ fprintf (stderr , "Usage: <MiB> <bounces>\n" ), exit (1 );
743
+ }
744
+ nr_pages = nr_pages_per_cpu * nr_cpus ;
745
+ huge_fd = open (argv [3 ], O_CREAT | O_RDWR , 0755 );
746
+ if (huge_fd < 0 ) {
747
+ fprintf (stderr , "Open of %s failed" , argv [3 ]);
748
+ perror ("open" );
749
+ exit (1 );
750
+ }
751
+ if (ftruncate (huge_fd , 0 )) {
752
+ fprintf (stderr , "ftruncate %s to size 0 failed" , argv [3 ]);
753
+ perror ("ftruncate" );
754
+ exit (1 );
755
+ }
756
+ printf ("nr_pages: %lu, nr_pages_per_cpu: %lu\n" ,
757
+ nr_pages , nr_pages_per_cpu );
758
+ return userfaultfd_stress ();
759
+ }
760
+
761
+ #endif
635
762
#else /* __NR_userfaultfd */
636
763
637
764
#warning "missing __NR_userfaultfd definition"
0 commit comments