gup_test.c (a9bed1e1c2a9bb36cdd29af0ef48044d1b9e8c2a) gup_test.c (f4f9bda418ab8b4dbc5372e9e2a28162f7777154)
1#include <linux/kernel.h>
2#include <linux/mm.h>
3#include <linux/slab.h>
4#include <linux/uaccess.h>
5#include <linux/ktime.h>
6#include <linux/debugfs.h>
7#include "gup_test.h"
8
9static void put_back_pages(unsigned int cmd, struct page **pages,
1#include <linux/kernel.h>
2#include <linux/mm.h>
3#include <linux/slab.h>
4#include <linux/uaccess.h>
5#include <linux/ktime.h>
6#include <linux/debugfs.h>
7#include "gup_test.h"
8
9static void put_back_pages(unsigned int cmd, struct page **pages,
10 unsigned long nr_pages)
10 unsigned long nr_pages, unsigned int gup_test_flags)
11{
12 unsigned long i;
13
14 switch (cmd) {
15 case GUP_FAST_BENCHMARK:
16 case GUP_BASIC_TEST:
17 for (i = 0; i < nr_pages; i++)
18 put_page(pages[i]);
19 break;
20
21 case PIN_FAST_BENCHMARK:
22 case PIN_BASIC_TEST:
23 case PIN_LONGTERM_BENCHMARK:
24 unpin_user_pages(pages, nr_pages);
25 break;
11{
12 unsigned long i;
13
14 switch (cmd) {
15 case GUP_FAST_BENCHMARK:
16 case GUP_BASIC_TEST:
17 for (i = 0; i < nr_pages; i++)
18 put_page(pages[i]);
19 break;
20
21 case PIN_FAST_BENCHMARK:
22 case PIN_BASIC_TEST:
23 case PIN_LONGTERM_BENCHMARK:
24 unpin_user_pages(pages, nr_pages);
25 break;
26 case DUMP_USER_PAGES_TEST:
27 if (gup_test_flags & GUP_TEST_FLAG_DUMP_PAGES_USE_PIN) {
28 unpin_user_pages(pages, nr_pages);
29 } else {
30 for (i = 0; i < nr_pages; i++)
31 put_page(pages[i]);
32
33 }
34 break;
26 }
27}
28
29static void verify_dma_pinned(unsigned int cmd, struct page **pages,
30 unsigned long nr_pages)
31{
32 unsigned long i;
33 struct page *page;

--- 10 unchanged lines hidden (view full) ---

44 dump_page(page, "gup_test failure");
45 break;
46 }
47 }
48 break;
49 }
50}
51
35 }
36}
37
38static void verify_dma_pinned(unsigned int cmd, struct page **pages,
39 unsigned long nr_pages)
40{
41 unsigned long i;
42 struct page *page;

--- 10 unchanged lines hidden (view full) ---

53 dump_page(page, "gup_test failure");
54 break;
55 }
56 }
57 break;
58 }
59}
60
61static void dump_pages_test(struct gup_test *gup, struct page **pages,
62 unsigned long nr_pages)
63{
64 unsigned int index_to_dump;
65 unsigned int i;
66
67 /*
68 * Zero out any user-supplied page index that is out of range. Remember:
69 * .which_pages[] contains a 1-based set of page indices.
70 */
71 for (i = 0; i < GUP_TEST_MAX_PAGES_TO_DUMP; i++) {
72 if (gup->which_pages[i] > nr_pages) {
73 pr_warn("ZEROING due to out of range: .which_pages[%u]: %u\n",
74 i, gup->which_pages[i]);
75 gup->which_pages[i] = 0;
76 }
77 }
78
79 for (i = 0; i < GUP_TEST_MAX_PAGES_TO_DUMP; i++) {
80 index_to_dump = gup->which_pages[i];
81
82 if (index_to_dump) {
83 index_to_dump--; // Decode from 1-based, to 0-based
84 pr_info("---- page #%u, starting from user virt addr: 0x%llx\n",
85 index_to_dump, gup->addr);
86 dump_page(pages[index_to_dump],
87 "gup_test: dump_pages() test");
88 }
89 }
90}
91
52static int __gup_test_ioctl(unsigned int cmd,
53 struct gup_test *gup)
54{
55 ktime_t start_time, end_time;
56 unsigned long i, nr_pages, addr, next;
57 int nr;
58 struct page **pages;
59 int ret = 0;

--- 46 unchanged lines hidden (view full) ---

106 nr = pin_user_pages(addr, nr, gup->flags, pages + i,
107 NULL);
108 break;
109 case PIN_LONGTERM_BENCHMARK:
110 nr = pin_user_pages(addr, nr,
111 gup->flags | FOLL_LONGTERM,
112 pages + i, NULL);
113 break;
92static int __gup_test_ioctl(unsigned int cmd,
93 struct gup_test *gup)
94{
95 ktime_t start_time, end_time;
96 unsigned long i, nr_pages, addr, next;
97 int nr;
98 struct page **pages;
99 int ret = 0;

--- 46 unchanged lines hidden (view full) ---

146 nr = pin_user_pages(addr, nr, gup->flags, pages + i,
147 NULL);
148 break;
149 case PIN_LONGTERM_BENCHMARK:
150 nr = pin_user_pages(addr, nr,
151 gup->flags | FOLL_LONGTERM,
152 pages + i, NULL);
153 break;
154 case DUMP_USER_PAGES_TEST:
155 if (gup->flags & GUP_TEST_FLAG_DUMP_PAGES_USE_PIN)
156 nr = pin_user_pages(addr, nr, gup->flags,
157 pages + i, NULL);
158 else
159 nr = get_user_pages(addr, nr, gup->flags,
160 pages + i, NULL);
161 break;
114 default:
115 ret = -EINVAL;
116 goto unlock;
117 }
118
119 if (nr <= 0)
120 break;
121 i += nr;

--- 7 unchanged lines hidden (view full) ---

129 gup->size = addr - gup->addr;
130
131 /*
132 * Take an un-benchmark-timed moment to verify DMA pinned
133 * state: print a warning if any non-dma-pinned pages are found:
134 */
135 verify_dma_pinned(cmd, pages, nr_pages);
136
162 default:
163 ret = -EINVAL;
164 goto unlock;
165 }
166
167 if (nr <= 0)
168 break;
169 i += nr;

--- 7 unchanged lines hidden (view full) ---

177 gup->size = addr - gup->addr;
178
179 /*
180 * Take an un-benchmark-timed moment to verify DMA pinned
181 * state: print a warning if any non-dma-pinned pages are found:
182 */
183 verify_dma_pinned(cmd, pages, nr_pages);
184
185 if (cmd == DUMP_USER_PAGES_TEST)
186 dump_pages_test(gup, pages, nr_pages);
187
137 start_time = ktime_get();
138
188 start_time = ktime_get();
189
139 put_back_pages(cmd, pages, nr_pages);
190 put_back_pages(cmd, pages, nr_pages, gup->flags);
140
141 end_time = ktime_get();
142 gup->put_delta_usec = ktime_us_delta(end_time, start_time);
143
144unlock:
145 if (needs_mmap_lock)
146 mmap_read_unlock(current->mm);
147free_pages:

--- 8 unchanged lines hidden (view full) ---

156 int ret;
157
158 switch (cmd) {
159 case GUP_FAST_BENCHMARK:
160 case PIN_FAST_BENCHMARK:
161 case PIN_LONGTERM_BENCHMARK:
162 case GUP_BASIC_TEST:
163 case PIN_BASIC_TEST:
191
192 end_time = ktime_get();
193 gup->put_delta_usec = ktime_us_delta(end_time, start_time);
194
195unlock:
196 if (needs_mmap_lock)
197 mmap_read_unlock(current->mm);
198free_pages:

--- 8 unchanged lines hidden (view full) ---

207 int ret;
208
209 switch (cmd) {
210 case GUP_FAST_BENCHMARK:
211 case PIN_FAST_BENCHMARK:
212 case PIN_LONGTERM_BENCHMARK:
213 case GUP_BASIC_TEST:
214 case PIN_BASIC_TEST:
215 case DUMP_USER_PAGES_TEST:
164 break;
165 default:
166 return -EINVAL;
167 }
168
169 if (copy_from_user(&gup, (void __user *)arg, sizeof(gup)))
170 return -EFAULT;
171

--- 24 unchanged lines hidden ---
216 break;
217 default:
218 return -EINVAL;
219 }
220
221 if (copy_from_user(&gup, (void __user *)arg, sizeof(gup)))
222 return -EFAULT;
223

--- 24 unchanged lines hidden ---