Skip to content

Commit 40e4178

Browse files
brenns10Brian Maly
authored andcommitted
RDS: use pin_user_pages_fast()
pin_user_pages_fast() is used in the upstream version of rds_pin_pages(), which is better because so long as all the pages are faulted-in, the operation is lockless. The migration was originally performed 15 years ago, in 830eb7d ("RDS: use get_user_pages_fast()"). Unfortunately, several UEK-specific patches seem to have thad the effect of reverting this change. In commit 347353a ("rds: Handle unsupported rdma request to fs dax memory"), we migrated from _fast() to _longterm() as part of UEK5. In more recent upstream kernels, _longterm() was dropped in favor of the standard get_user_pages() with FOLL_LONGTERM. Through forward-porting this patch, the result was that the commit simply switched back from get_user_pages_fast() to get_user_pages() with FOLL_LONGTERM, adding back in the mandatory locking. Finally, d237411 ("net/rds: Switch to the Linux-5.15 API") converted this call to pin_user_pages(), rather than pin_user_pages_fast(), which is what is used upstream. This has caused problems in some cases where RDMA packets are sent concurrently with very long-running munmap(). To get back the benefit of lockless page pinning, let's switch back to pin_user_pages_fast(), matching upstream. I've introduced a bit more noise into this diff in an effort to make the form of rds_pin_pages exactly match its upstream variant, given that there is now no functional difference. Orabug: 37980705 Signed-off-by: Stephen Brennan <[email protected]> Reviewed-by: Håkon Bugge <[email protected]> Reviewed-by: Lorenzo Stoakes <[email protected]> Signed-off-by: Vijayendra Suman <[email protected]> Signed-off-by: Brian Maly <[email protected]>
1 parent abc9b15 commit 40e4178

File tree

1 file changed

+5
-8
lines changed

1 file changed

+5
-8
lines changed

net/rds/rdma.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,20 +164,17 @@ EXPORT_SYMBOL_GPL(rds_rdma_drop_keys);
164164
static int rds_pin_pages(unsigned long user_addr, unsigned int nr_pages,
165165
struct page **pages, int write)
166166
{
167+
unsigned int gup_flags = FOLL_LONGTERM;
167168
int ret;
168-
struct mm_struct *mm = current->mm;
169-
int gup_flags = FOLL_LONGTERM | (write ? FOLL_WRITE : 0);
170169

171-
mmgrab(mm);
172-
down_read(&mm->mmap_lock);
173-
ret = pin_user_pages(user_addr, nr_pages, gup_flags, pages, NULL);
170+
if (write)
171+
gup_flags |= FOLL_WRITE;
174172

175-
if (ret >= 0 && (unsigned) ret < nr_pages) {
173+
ret = pin_user_pages_fast(user_addr, nr_pages, gup_flags, pages);
174+
if (ret >= 0 && ret < nr_pages) {
176175
unpin_user_pages(pages, ret);
177176
ret = -EFAULT;
178177
}
179-
up_read(&mm->mmap_lock);
180-
mmdrop(mm);
181178

182179
return ret;
183180
}

0 commit comments

Comments
 (0)