49
49
*/
50
50
51
51
#include <linux/mm.h>
52
+ #include <linux/sched.h>
52
53
#include <linux/device.h>
53
54
54
55
#include "hfi.h"
55
56
56
- static void __hfi1_release_user_pages (struct page * * p , size_t num_pages ,
57
- int dirty )
58
- {
59
- size_t i ;
60
-
61
- for (i = 0 ; i < num_pages ; i ++ ) {
62
- if (dirty )
63
- set_page_dirty_lock (p [i ]);
64
- put_page (p [i ]);
65
- }
66
- }
67
-
68
- /*
69
- * Call with current->mm->mmap_sem held.
70
- */
71
- static int __hfi1_get_user_pages (unsigned long start_page , size_t num_pages ,
72
- struct page * * p )
73
- {
74
- unsigned long lock_limit ;
75
- size_t got ;
76
- int ret ;
77
-
78
- lock_limit = rlimit (RLIMIT_MEMLOCK ) >> PAGE_SHIFT ;
79
-
80
- if (num_pages > lock_limit && !capable (CAP_IPC_LOCK )) {
81
- ret = - ENOMEM ;
82
- goto bail ;
83
- }
84
-
85
- for (got = 0 ; got < num_pages ; got += ret ) {
86
- ret = get_user_pages (current , current -> mm ,
87
- start_page + got * PAGE_SIZE ,
88
- num_pages - got , 1 , 1 ,
89
- p + got , NULL );
90
- if (ret < 0 )
91
- goto bail_release ;
92
- }
93
-
94
- current -> mm -> pinned_vm += num_pages ;
95
-
96
- ret = 0 ;
97
- goto bail ;
98
-
99
- bail_release :
100
- __hfi1_release_user_pages (p , got , 0 );
101
- bail :
102
- return ret ;
103
- }
104
-
105
57
/**
106
58
* hfi1_map_page - a safety wrapper around pci_map_page()
107
59
*
@@ -116,41 +68,44 @@ dma_addr_t hfi1_map_page(struct pci_dev *hwdev, struct page *page,
116
68
return phys ;
117
69
}
118
70
119
- /**
120
- * hfi1_get_user_pages - lock user pages into memory
121
- * @start_page: the start page
122
- * @num_pages: the number of pages
123
- * @p: the output page structures
124
- *
125
- * This function takes a given start page (page aligned user virtual
126
- * address) and pins it and the following specified number of pages. For
127
- * now, num_pages is always 1, but that will probably change at some point
128
- * (because caller is doing expected sends on a single virtually contiguous
129
- * buffer, so we can do all pages at once).
130
- */
131
- int hfi1_get_user_pages (unsigned long start_page , size_t num_pages ,
132
- struct page * * p )
71
+ int hfi1_acquire_user_pages (unsigned long vaddr , size_t npages , bool writable ,
72
+ struct page * * pages )
133
73
{
74
+ unsigned long pinned , lock_limit = rlimit (RLIMIT_MEMLOCK ) >> PAGE_SHIFT ;
75
+ bool can_lock = capable (CAP_IPC_LOCK );
134
76
int ret ;
135
77
136
- down_write (& current -> mm -> mmap_sem );
78
+ down_read (& current -> mm -> mmap_sem );
79
+ pinned = current -> mm -> pinned_vm ;
80
+ up_read (& current -> mm -> mmap_sem );
137
81
138
- ret = __hfi1_get_user_pages (start_page , num_pages , p );
82
+ if (pinned + npages > lock_limit && !can_lock )
83
+ return - ENOMEM ;
139
84
85
+ ret = get_user_pages_fast (vaddr , npages , writable , pages );
86
+ if (ret < 0 )
87
+ return ret ;
88
+
89
+ down_write (& current -> mm -> mmap_sem );
90
+ current -> mm -> pinned_vm += ret ;
140
91
up_write (& current -> mm -> mmap_sem );
141
92
142
93
return ret ;
143
94
}
144
95
145
- void hfi1_release_user_pages (struct page * * p , size_t num_pages )
96
+ void hfi1_release_user_pages (struct page * * p , size_t npages , bool dirty )
146
97
{
147
- if (current -> mm ) /* during close after signal, mm can be NULL */
148
- down_write (& current -> mm -> mmap_sem );
98
+ size_t i ;
149
99
150
- __hfi1_release_user_pages (p , num_pages , 1 );
100
+ for (i = 0 ; i < npages ; i ++ ) {
101
+ if (dirty )
102
+ set_page_dirty_lock (p [i ]);
103
+ put_page (p [i ]);
104
+ }
151
105
152
- if (current -> mm ) {
153
- current -> mm -> pinned_vm -= num_pages ;
106
+ if (current -> mm ) { /* during close after signal, mm can be NULL */
107
+ down_write (& current -> mm -> mmap_sem );
108
+ current -> mm -> pinned_vm -= npages ;
154
109
up_write (& current -> mm -> mmap_sem );
155
110
}
156
111
}
0 commit comments