Here's one more dmesg output with more information captured in __get_user_pages() as well. It basically confirms that handle_mm_fault() returns VM_FAULT_RETRY. I'm not sure where and what to change ("fix with a FOLL_TRIED somewhere") to make it work. My (uneducated) impression is, that only __get_user_pages() needs to be changed - but I might be wrong. On Tue, 2019-11-05 at 21:05 +0100, Robert Stupp wrote: > On Tue, 2019-11-05 at 13:22 -0500, Johannes Weiner wrote: > > Judging from Robert's stack captures, the task is not hung but > > busy-looping in __mm_populate(). AFAICS, the only way this can > > occur > > is if populate_vma_page_range() returns 0 and we don't advance the > > iteration position (if it returned an error, we wouldn't reset nend > > and move on to the next vma as ignore_errors is 1 for mlockall.) > > > > populate_vma_page_range() returns 0 when the first page is not > > found > > and faultin_page() returns -EBUSY (if it were processing pages, or > > if > > the error from faultin_page() would be a different one, we would > > return the number of pages processed or -error). > > > > faultin_page() returns -EBUSY when VM_FAULT_RETRY is set, i.e. we > > dropped the mmap_sem in order to initiate IO and require a retry. > > That > > is consistent with the bisect result (new VM_FAULT_RETRY > > conditions). > > > > At this point, regular page fault would retry with FAULT_FLAG_TRIED > > to > > indicate that the mmap_sem cannot be dropped a second time. But > > this > > mlock path doesn't set that flag and we can loop repeatedly. That > > is > > something we probably need to fix with a FOLL_TRIED somewhere. > > > > What I don't quite understand yet is why the fault path doesn't > > make > > progress eventually. We must drop the mmap_sem without changing the > > state in any way. How can we keep looping on the same page? > > I've played a bit around by adding some `printk` messages (see > attached > patch) and found exactly what you describe: it's busy-looping in > __mm_populate(), because populate_vma_page_range returns 0. > > However, there's a slightly interesting thing in there. Before it > loops > forever, it processes > nstart=5574d92e1000 > locked=1 > vma->vm_start=7f5e4bfec000 > vma->vm_end= 7f5e4c011000 > vma->vm_flags=8002071 > for which populate_vma_page_range() returns 1, then it processes this > over and over again: > nstart=7f5e4bfed000 > locked=0 > vma->vm_start=7f5e4bfec000 (same as before) > vma->vm_end= 7f5e4c011000 > vma->vm_flags=8002071 > These are the additional dmesg messages with timestamp 105.x. At > timestamp 106.x, I've hit ctrl-c (ret=-512). > > dmesg output with the patch applied (on top of the v5.3.8 git tag) > attached. >
[ 84.533231] _mm_populate 0 7ffffffff000 7ffffffff000 1 ENTER [ 84.533235] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 0 0 0 [ 84.533238] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=5626b4b8f000 vma->vm_end=5626b4b90000 vma->vm_flags=8002871 [ 84.533240] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=5626b4b90000 7ffffffff000 5626b4b90000 [ 84.533242] __get_user_pages start=5626b4b8f000 nr_pages=1 gup_flags=1052 ctx.page_mask=0 [ 84.533243] __get_user_pages @1 vma==NULL [ 84.533245] __get_user_pages @2 start=5626b4b8f000 vma->vm_start=5626b4b8f000 vma->vm_end=5626b4b90000 vma->vm_flags=8002871 [ 84.533250] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533251] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533253] __get_user_pages @10 i=1 start=5626b4b90000 nr_pages=0 [ 84.533254] __get_user_pages LEAVE i=1 ret=0 [ 84.533256] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-3 ret=1 nend=5626b4b90000 [ 84.533258] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 5626b4b90000 1 0 [ 84.533260] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=5626b4b90000 vma->vm_end=5626b4b91000 vma->vm_flags=8002875 [ 84.533262] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=5626b4b91000 7ffffffff000 5626b4b91000 [ 84.533263] __get_user_pages start=5626b4b90000 nr_pages=1 gup_flags=1052 ctx.page_mask=0 [ 84.533264] __get_user_pages @1 vma==NULL [ 84.533266] __get_user_pages @2 start=5626b4b90000 vma->vm_start=5626b4b90000 vma->vm_end=5626b4b91000 vma->vm_flags=8002875 [ 84.533268] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533269] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533270] __get_user_pages @10 i=1 start=5626b4b91000 nr_pages=0 [ 84.533271] __get_user_pages LEAVE i=1 ret=0 [ 84.533273] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-3 ret=1 nend=5626b4b91000 [ 84.533275] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 5626b4b91000 1 0 [ 84.533276] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=5626b4b91000 vma->vm_end=5626b4b92000 vma->vm_flags=8002871 [ 84.533278] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=5626b4b92000 7ffffffff000 5626b4b92000 [ 84.533280] __get_user_pages start=5626b4b91000 nr_pages=1 gup_flags=1052 ctx.page_mask=0 [ 84.533280] __get_user_pages @1 vma==NULL [ 84.533282] __get_user_pages @2 start=5626b4b91000 vma->vm_start=5626b4b91000 vma->vm_end=5626b4b92000 vma->vm_flags=8002871 [ 84.533284] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533285] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533286] __get_user_pages @10 i=1 start=5626b4b92000 nr_pages=0 [ 84.533287] __get_user_pages LEAVE i=1 ret=0 [ 84.533289] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-3 ret=1 nend=5626b4b92000 [ 84.533290] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 5626b4b92000 1 0 [ 84.533292] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=5626b4b92000 vma->vm_end=5626b4b93000 vma->vm_flags=8102871 [ 84.533294] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=5626b4b93000 7ffffffff000 5626b4b93000 [ 84.533295] __get_user_pages start=5626b4b92000 nr_pages=1 gup_flags=1052 ctx.page_mask=0 [ 84.533296] __get_user_pages @1 vma==NULL [ 84.533298] __get_user_pages @2 start=5626b4b92000 vma->vm_start=5626b4b92000 vma->vm_end=5626b4b93000 vma->vm_flags=8102871 [ 84.533300] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533301] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533302] __get_user_pages @10 i=1 start=5626b4b93000 nr_pages=0 [ 84.533303] __get_user_pages LEAVE i=1 ret=0 [ 84.533304] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-3 ret=1 nend=5626b4b93000 [ 84.533306] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 5626b4b93000 1 0 [ 84.533308] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=5626b4b93000 vma->vm_end=5626b4b94000 vma->vm_flags=8102873 [ 84.533310] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=5626b4b94000 7ffffffff000 5626b4b94000 [ 84.533311] __get_user_pages start=5626b4b93000 nr_pages=1 gup_flags=1053 ctx.page_mask=0 [ 84.533312] __get_user_pages @1 vma==NULL [ 84.533313] __get_user_pages @2 start=5626b4b93000 vma->vm_start=5626b4b93000 vma->vm_end=5626b4b94000 vma->vm_flags=8102873 [ 84.533315] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533316] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533317] __get_user_pages @10 i=1 start=5626b4b94000 nr_pages=0 [ 84.533318] __get_user_pages LEAVE i=1 ret=0 [ 84.533320] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-3 ret=1 nend=5626b4b94000 [ 84.533322] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 5626b4b94000 1 0 [ 84.533324] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=5626b5a54000 vma->vm_end=5626b5a75000 vma->vm_flags=8102073 [ 84.533325] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=5626b5a75000 7ffffffff000 5626b5a75000 [ 84.533327] __get_user_pages start=5626b5a54000 nr_pages=33 gup_flags=1053 ctx.page_mask=0 [ 84.533328] __get_user_pages @1 vma==NULL [ 84.533329] __get_user_pages @2 start=5626b5a54000 vma->vm_start=5626b5a54000 vma->vm_end=5626b5a75000 vma->vm_flags=8102073 [ 84.533331] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533332] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533333] __get_user_pages @10 i=1 start=5626b5a55000 nr_pages=32 [ 84.533335] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533337] faultin_page handle_mm_fault --> ret = 0 [ 84.533338] faultin_page-->0 [ 84.533339] __get_user_pages @8 faultin_page --> 0 [ 84.533341] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533342] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533343] __get_user_pages @10 i=2 start=5626b5a56000 nr_pages=31 [ 84.533344] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533346] faultin_page handle_mm_fault --> ret = 0 [ 84.533347] faultin_page-->0 [ 84.533348] __get_user_pages @8 faultin_page --> 0 [ 84.533349] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533350] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533351] __get_user_pages @10 i=3 start=5626b5a57000 nr_pages=30 [ 84.533353] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533354] faultin_page handle_mm_fault --> ret = 0 [ 84.533355] faultin_page-->0 [ 84.533356] __get_user_pages @8 faultin_page --> 0 [ 84.533357] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533358] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533360] __get_user_pages @10 i=4 start=5626b5a58000 nr_pages=29 [ 84.533361] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533362] faultin_page handle_mm_fault --> ret = 0 [ 84.533363] faultin_page-->0 [ 84.533364] __get_user_pages @8 faultin_page --> 0 [ 84.533366] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533366] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533368] __get_user_pages @10 i=5 start=5626b5a59000 nr_pages=28 [ 84.533369] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533371] faultin_page handle_mm_fault --> ret = 0 [ 84.533371] faultin_page-->0 [ 84.533372] __get_user_pages @8 faultin_page --> 0 [ 84.533374] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533374] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533376] __get_user_pages @10 i=6 start=5626b5a5a000 nr_pages=27 [ 84.533377] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533379] faultin_page handle_mm_fault --> ret = 0 [ 84.533379] faultin_page-->0 [ 84.533380] __get_user_pages @8 faultin_page --> 0 [ 84.533382] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533382] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533384] __get_user_pages @10 i=7 start=5626b5a5b000 nr_pages=26 [ 84.533385] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533387] faultin_page handle_mm_fault --> ret = 0 [ 84.533387] faultin_page-->0 [ 84.533388] __get_user_pages @8 faultin_page --> 0 [ 84.533390] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533391] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533392] __get_user_pages @10 i=8 start=5626b5a5c000 nr_pages=25 [ 84.533393] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533395] faultin_page handle_mm_fault --> ret = 0 [ 84.533396] faultin_page-->0 [ 84.533397] __get_user_pages @8 faultin_page --> 0 [ 84.533398] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533399] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533401] __get_user_pages @10 i=9 start=5626b5a5d000 nr_pages=24 [ 84.533402] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533404] faultin_page handle_mm_fault --> ret = 0 [ 84.533404] faultin_page-->0 [ 84.533405] __get_user_pages @8 faultin_page --> 0 [ 84.533407] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533408] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533409] __get_user_pages @10 i=10 start=5626b5a5e000 nr_pages=23 [ 84.533410] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533412] faultin_page handle_mm_fault --> ret = 0 [ 84.533413] faultin_page-->0 [ 84.533414] __get_user_pages @8 faultin_page --> 0 [ 84.533415] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533416] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533417] __get_user_pages @10 i=11 start=5626b5a5f000 nr_pages=22 [ 84.533419] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533421] faultin_page handle_mm_fault --> ret = 0 [ 84.533421] faultin_page-->0 [ 84.533422] __get_user_pages @8 faultin_page --> 0 [ 84.533424] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533425] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533426] __get_user_pages @10 i=12 start=5626b5a60000 nr_pages=21 [ 84.533427] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533429] faultin_page handle_mm_fault --> ret = 0 [ 84.533430] faultin_page-->0 [ 84.533430] __get_user_pages @8 faultin_page --> 0 [ 84.533432] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533433] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533434] __get_user_pages @10 i=13 start=5626b5a61000 nr_pages=20 [ 84.533435] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533437] faultin_page handle_mm_fault --> ret = 0 [ 84.533438] faultin_page-->0 [ 84.533439] __get_user_pages @8 faultin_page --> 0 [ 84.533440] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533441] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533442] __get_user_pages @10 i=14 start=5626b5a62000 nr_pages=19 [ 84.533443] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533445] faultin_page handle_mm_fault --> ret = 0 [ 84.533446] faultin_page-->0 [ 84.533447] __get_user_pages @8 faultin_page --> 0 [ 84.533448] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533449] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533451] __get_user_pages @10 i=15 start=5626b5a63000 nr_pages=18 [ 84.533452] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533454] faultin_page handle_mm_fault --> ret = 0 [ 84.533455] faultin_page-->0 [ 84.533455] __get_user_pages @8 faultin_page --> 0 [ 84.533457] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533458] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533459] __get_user_pages @10 i=16 start=5626b5a64000 nr_pages=17 [ 84.533460] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533462] faultin_page handle_mm_fault --> ret = 0 [ 84.533463] faultin_page-->0 [ 84.533464] __get_user_pages @8 faultin_page --> 0 [ 84.533465] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533466] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533467] __get_user_pages @10 i=17 start=5626b5a65000 nr_pages=16 [ 84.533468] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533470] faultin_page handle_mm_fault --> ret = 0 [ 84.533471] faultin_page-->0 [ 84.533472] __get_user_pages @8 faultin_page --> 0 [ 84.533473] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533474] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533476] __get_user_pages @10 i=18 start=5626b5a66000 nr_pages=15 [ 84.533477] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533479] faultin_page handle_mm_fault --> ret = 0 [ 84.533479] faultin_page-->0 [ 84.533480] __get_user_pages @8 faultin_page --> 0 [ 84.533482] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533483] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533484] __get_user_pages @10 i=19 start=5626b5a67000 nr_pages=14 [ 84.533485] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533487] faultin_page handle_mm_fault --> ret = 0 [ 84.533488] faultin_page-->0 [ 84.533489] __get_user_pages @8 faultin_page --> 0 [ 84.533490] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533491] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533492] __get_user_pages @10 i=20 start=5626b5a68000 nr_pages=13 [ 84.533494] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533496] faultin_page handle_mm_fault --> ret = 0 [ 84.533496] faultin_page-->0 [ 84.533497] __get_user_pages @8 faultin_page --> 0 [ 84.533499] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533500] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533501] __get_user_pages @10 i=21 start=5626b5a69000 nr_pages=12 [ 84.533502] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533504] faultin_page handle_mm_fault --> ret = 0 [ 84.533504] faultin_page-->0 [ 84.533505] __get_user_pages @8 faultin_page --> 0 [ 84.533507] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533508] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533509] __get_user_pages @10 i=22 start=5626b5a6a000 nr_pages=11 [ 84.533510] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533512] faultin_page handle_mm_fault --> ret = 0 [ 84.533512] faultin_page-->0 [ 84.533513] __get_user_pages @8 faultin_page --> 0 [ 84.533515] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533516] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533517] __get_user_pages @10 i=23 start=5626b5a6b000 nr_pages=10 [ 84.533518] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533520] faultin_page handle_mm_fault --> ret = 0 [ 84.533521] faultin_page-->0 [ 84.533521] __get_user_pages @8 faultin_page --> 0 [ 84.533523] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533524] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533525] __get_user_pages @10 i=24 start=5626b5a6c000 nr_pages=9 [ 84.533526] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533528] faultin_page handle_mm_fault --> ret = 0 [ 84.533529] faultin_page-->0 [ 84.533530] __get_user_pages @8 faultin_page --> 0 [ 84.533531] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533532] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533534] __get_user_pages @10 i=25 start=5626b5a6d000 nr_pages=8 [ 84.533535] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533537] faultin_page handle_mm_fault --> ret = 0 [ 84.533537] faultin_page-->0 [ 84.533538] __get_user_pages @8 faultin_page --> 0 [ 84.533540] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533541] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533542] __get_user_pages @10 i=26 start=5626b5a6e000 nr_pages=7 [ 84.533543] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533545] faultin_page handle_mm_fault --> ret = 0 [ 84.533545] faultin_page-->0 [ 84.533546] __get_user_pages @8 faultin_page --> 0 [ 84.533548] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533549] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533550] __get_user_pages @10 i=27 start=5626b5a6f000 nr_pages=6 [ 84.533551] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533553] faultin_page handle_mm_fault --> ret = 0 [ 84.533554] faultin_page-->0 [ 84.533555] __get_user_pages @8 faultin_page --> 0 [ 84.533557] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533558] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533559] __get_user_pages @10 i=28 start=5626b5a70000 nr_pages=5 [ 84.533560] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533562] faultin_page handle_mm_fault --> ret = 0 [ 84.533563] faultin_page-->0 [ 84.533564] __get_user_pages @8 faultin_page --> 0 [ 84.533565] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533566] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533567] __get_user_pages @10 i=29 start=5626b5a71000 nr_pages=4 [ 84.533568] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533570] faultin_page handle_mm_fault --> ret = 0 [ 84.533571] faultin_page-->0 [ 84.533572] __get_user_pages @8 faultin_page --> 0 [ 84.533573] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533574] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533576] __get_user_pages @10 i=30 start=5626b5a72000 nr_pages=3 [ 84.533577] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533579] faultin_page handle_mm_fault --> ret = 0 [ 84.533579] faultin_page-->0 [ 84.533580] __get_user_pages @8 faultin_page --> 0 [ 84.533582] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533583] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533584] __get_user_pages @10 i=31 start=5626b5a73000 nr_pages=2 [ 84.533585] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533587] faultin_page handle_mm_fault --> ret = 0 [ 84.533588] faultin_page-->0 [ 84.533588] __get_user_pages @8 faultin_page --> 0 [ 84.533590] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533591] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533592] __get_user_pages @10 i=32 start=5626b5a74000 nr_pages=1 [ 84.533593] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533595] faultin_page handle_mm_fault --> ret = 0 [ 84.533596] faultin_page-->0 [ 84.533597] __get_user_pages @8 faultin_page --> 0 [ 84.533598] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533599] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533600] __get_user_pages @10 i=33 start=5626b5a75000 nr_pages=0 [ 84.533601] __get_user_pages LEAVE i=33 ret=0 [ 84.533603] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-3 ret=33 nend=5626b5a75000 [ 84.533605] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 5626b5a75000 1 0 [ 84.533607] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e2be000 vma->vm_end=7f247e2e3000 vma->vm_flags=8002071 [ 84.533608] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e2e3000 7ffffffff000 7f247e2e3000 [ 84.533610] __get_user_pages start=7f247e2be000 nr_pages=37 gup_flags=1052 ctx.page_mask=0 [ 84.533611] __get_user_pages @1 vma==NULL [ 84.533612] __get_user_pages @2 start=7f247e2be000 vma->vm_start=7f247e2be000 vma->vm_end=7f247e2e3000 vma->vm_flags=8002071 [ 84.533613] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533617] faultin_page handle_mm_fault --> ret = 256 [ 84.533618] faultin_page-->0 [ 84.533619] __get_user_pages @8 faultin_page --> 0 [ 84.533620] __get_user_pages @7 follow_page_mask --> 1 ctx.page_mask=0 [ 84.533621] __get_user_pages @9 page_increm=1 ctx.page_mask=0 [ 84.533622] __get_user_pages @10 i=1 start=7f247e2bf000 nr_pages=36 [ 84.533624] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533627] faultin_page handle_mm_fault --> ret = 1024 [ 84.533629] faultin_page-->EBUSY VM_FAULT_RETRY non-blocking?1 FAULT_FLAG_RETRY_NOWAIT?0 [ 84.533630] __get_user_pages @8 faultin_page --> -16 [ 84.533631] __get_user_pages LEAVE i=1 ret=0 [ 84.533632] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-3 ret=1 nend=7f247e2bf000 [ 84.533634] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e2bf000 0 0 [ 84.533636] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e2be000 vma->vm_end=7f247e2e3000 vma->vm_flags=8002071 [ 84.533638] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e2e3000 7ffffffff000 7f247e2e3000 [ 84.533639] __get_user_pages start=7f247e2bf000 nr_pages=36 gup_flags=1052 ctx.page_mask=0 [ 84.533640] __get_user_pages @1 vma==NULL [ 84.533642] __get_user_pages @2 start=7f247e2bf000 vma->vm_start=7f247e2be000 vma->vm_end=7f247e2e3000 vma->vm_flags=8002071 [ 84.533643] __get_user_pages @7 follow_page_mask --> 0 ctx.page_mask=0 [ 84.533646] faultin_page handle_mm_fault --> ret = 1024 [ 84.533647] faultin_page-->EBUSY VM_FAULT_RETRY non-blocking?1 FAULT_FLAG_RETRY_NOWAIT?0 [ 84.533648] __get_user_pages @8 faultin_page --> -16 [ 84.533649] __get_user_pages LEAVE i=0 ret=0 [ 84.533650] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-3 ret=0 nend=7f247e2bf000 [ 94.274156] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e2e3000 1 0 [ 94.274157] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e2e3000 vma->vm_end=7f247e45b000 vma->vm_flags=8002075 [ 94.274158] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e45b000 7ffffffff000 7f247e45b000 [ 94.274159] __get_user_pages start=7f247e2e3000 nr_pages=376 gup_flags=1052 ctx.page_mask=0 [ 94.274159] __get_user_pages @1 vma==NULL [ 94.274160] __get_user_pages @2 start=7f247e2e3000 vma->vm_start=7f247e2e3000 vma->vm_end=7f247e45b000 vma->vm_flags=8002075 [ 94.274161] __get_user_pages @6 ERESTARTSYS [ 94.274161] __get_user_pages LEAVE i=0 ret=-512 [ 94.274162] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274162] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e45b000 1 0 [ 94.274163] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e45b000 vma->vm_end=7f247e4a5000 vma->vm_flags=8002071 [ 94.274164] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e4a5000 7ffffffff000 7f247e4a5000 [ 94.274164] __get_user_pages start=7f247e45b000 nr_pages=74 gup_flags=1052 ctx.page_mask=0 [ 94.274164] __get_user_pages @1 vma==NULL [ 94.274165] __get_user_pages @2 start=7f247e45b000 vma->vm_start=7f247e45b000 vma->vm_end=7f247e4a5000 vma->vm_flags=8002071 [ 94.274165] __get_user_pages @6 ERESTARTSYS [ 94.274166] __get_user_pages LEAVE i=0 ret=-512 [ 94.274166] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274167] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e4a5000 1 0 [ 94.274167] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e4a5000 vma->vm_end=7f247e4a8000 vma->vm_flags=8102071 [ 94.274168] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e4a8000 7ffffffff000 7f247e4a8000 [ 94.274168] __get_user_pages start=7f247e4a5000 nr_pages=3 gup_flags=1052 ctx.page_mask=0 [ 94.274169] __get_user_pages @1 vma==NULL [ 94.274169] __get_user_pages @2 start=7f247e4a5000 vma->vm_start=7f247e4a5000 vma->vm_end=7f247e4a8000 vma->vm_flags=8102071 [ 94.274170] __get_user_pages @6 ERESTARTSYS [ 94.274170] __get_user_pages LEAVE i=0 ret=-512 [ 94.274170] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274171] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e4a8000 1 0 [ 94.274171] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e4a8000 vma->vm_end=7f247e4ab000 vma->vm_flags=8102073 [ 94.274172] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e4ab000 7ffffffff000 7f247e4ab000 [ 94.274172] __get_user_pages start=7f247e4a8000 nr_pages=3 gup_flags=1053 ctx.page_mask=0 [ 94.274173] __get_user_pages @1 vma==NULL [ 94.274173] __get_user_pages @2 start=7f247e4a8000 vma->vm_start=7f247e4a8000 vma->vm_end=7f247e4ab000 vma->vm_flags=8102073 [ 94.274174] __get_user_pages @6 ERESTARTSYS [ 94.274174] __get_user_pages LEAVE i=0 ret=-512 [ 94.274174] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274175] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e4ab000 1 0 [ 94.274175] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e4ab000 vma->vm_end=7f247e4b1000 vma->vm_flags=8102073 [ 94.274176] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e4b1000 7ffffffff000 7f247e4b1000 [ 94.274176] __get_user_pages start=7f247e4ab000 nr_pages=6 gup_flags=1053 ctx.page_mask=0 [ 94.274177] __get_user_pages @1 vma==NULL [ 94.274177] __get_user_pages @2 start=7f247e4ab000 vma->vm_start=7f247e4ab000 vma->vm_end=7f247e4b1000 vma->vm_flags=8102073 [ 94.274177] __get_user_pages @6 ERESTARTSYS [ 94.274178] __get_user_pages LEAVE i=0 ret=-512 [ 94.274178] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274179] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e4b1000 1 0 [ 94.274179] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e4dc000 vma->vm_end=7f247e4dd000 vma->vm_flags=8002871 [ 94.274180] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e4dd000 7ffffffff000 7f247e4dd000 [ 94.274180] __get_user_pages start=7f247e4dc000 nr_pages=1 gup_flags=1052 ctx.page_mask=0 [ 94.274181] __get_user_pages @1 vma==NULL [ 94.274181] __get_user_pages @2 start=7f247e4dc000 vma->vm_start=7f247e4dc000 vma->vm_end=7f247e4dd000 vma->vm_flags=8002871 [ 94.274181] __get_user_pages @6 ERESTARTSYS [ 94.274182] __get_user_pages LEAVE i=0 ret=-512 [ 94.274182] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274183] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e4dd000 1 0 [ 94.274183] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e4dd000 vma->vm_end=7f247e4ff000 vma->vm_flags=8002875 [ 94.274184] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e4ff000 7ffffffff000 7f247e4ff000 [ 94.274184] __get_user_pages start=7f247e4dd000 nr_pages=34 gup_flags=1052 ctx.page_mask=0 [ 94.274185] __get_user_pages @1 vma==NULL [ 94.274185] __get_user_pages @2 start=7f247e4dd000 vma->vm_start=7f247e4dd000 vma->vm_end=7f247e4ff000 vma->vm_flags=8002875 [ 94.274185] __get_user_pages @6 ERESTARTSYS [ 94.274186] __get_user_pages LEAVE i=0 ret=-512 [ 94.274186] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274187] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e4ff000 1 0 [ 94.274187] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e4ff000 vma->vm_end=7f247e507000 vma->vm_flags=8002871 [ 94.274188] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e507000 7ffffffff000 7f247e507000 [ 94.274188] __get_user_pages start=7f247e4ff000 nr_pages=8 gup_flags=1052 ctx.page_mask=0 [ 94.274189] __get_user_pages @1 vma==NULL [ 94.274189] __get_user_pages @2 start=7f247e4ff000 vma->vm_start=7f247e4ff000 vma->vm_end=7f247e507000 vma->vm_flags=8002871 [ 94.274189] __get_user_pages @6 ERESTARTSYS [ 94.274190] __get_user_pages LEAVE i=0 ret=-512 [ 94.274190] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274191] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e507000 1 0 [ 94.274191] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e508000 vma->vm_end=7f247e509000 vma->vm_flags=8102871 [ 94.274192] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e509000 7ffffffff000 7f247e509000 [ 94.274192] __get_user_pages start=7f247e508000 nr_pages=1 gup_flags=1052 ctx.page_mask=0 [ 94.274192] __get_user_pages @1 vma==NULL [ 94.274193] __get_user_pages @2 start=7f247e508000 vma->vm_start=7f247e508000 vma->vm_end=7f247e509000 vma->vm_flags=8102871 [ 94.274193] __get_user_pages @6 ERESTARTSYS [ 94.274193] __get_user_pages LEAVE i=0 ret=-512 [ 94.274194] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274194] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e509000 1 0 [ 94.274195] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e509000 vma->vm_end=7f247e50a000 vma->vm_flags=8102873 [ 94.274196] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e50a000 7ffffffff000 7f247e50a000 [ 94.274196] __get_user_pages start=7f247e509000 nr_pages=1 gup_flags=1053 ctx.page_mask=0 [ 94.274196] __get_user_pages @1 vma==NULL [ 94.274197] __get_user_pages @2 start=7f247e509000 vma->vm_start=7f247e509000 vma->vm_end=7f247e50a000 vma->vm_flags=8102873 [ 94.274197] __get_user_pages @6 ERESTARTSYS [ 94.274198] __get_user_pages LEAVE i=0 ret=-512 [ 94.274198] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274199] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e50a000 1 0 [ 94.274199] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7f247e50a000 vma->vm_end=7f247e50b000 vma->vm_flags=8102073 [ 94.274200] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7f247e50b000 7ffffffff000 7f247e50b000 [ 94.274200] __get_user_pages start=7f247e50a000 nr_pages=1 gup_flags=1053 ctx.page_mask=0 [ 94.274200] __get_user_pages @1 vma==NULL [ 94.274201] __get_user_pages @2 start=7f247e50a000 vma->vm_start=7f247e50a000 vma->vm_end=7f247e50b000 vma->vm_flags=8102073 [ 94.274201] __get_user_pages @6 ERESTARTSYS [ 94.274202] __get_user_pages LEAVE i=0 ret=-512 [ 94.274202] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274203] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7f247e50b000 1 0 [ 94.274203] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7ffe95c8c000 vma->vm_end=7ffe95cae000 vma->vm_flags=102173 [ 94.274204] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7ffe95cae000 7ffffffff000 7ffe95cae000 [ 94.274204] __get_user_pages start=7ffe95c8c000 nr_pages=34 gup_flags=1053 ctx.page_mask=0 [ 94.274204] __get_user_pages @1 vma==NULL [ 94.274205] __get_user_pages @2 start=7ffe95c8c000 vma->vm_start=7ffe95c8c000 vma->vm_end=7ffe95cae000 vma->vm_flags=102173 [ 94.274205] __get_user_pages @6 ERESTARTSYS [ 94.274206] __get_user_pages LEAVE i=0 ret=-512 [ 94.274206] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274207] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7ffe95cae000 1 0 [ 94.274207] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7ffe95db1000 vma->vm_end=7ffe95db4000 vma->vm_flags=c044411 [ 94.274208] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7ffe95db4000 7ffffffff000 7ffe95db4000 [ 94.274208] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-1 c044411 [ 94.274209] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7ffe95db4000 1 0 [ 94.274209] _mm_populate 0 7ffffffff000 7ffffffff000 1 vma->vm_start=7ffe95db4000 vma->vm_end=7ffe95db5000 vma->vm_flags=8040075 [ 94.274210] _mm_populate 0 7ffffffff000 7ffffffff000 1 nend=7ffe95db5000 7ffffffff000 7ffe95db5000 [ 94.274210] __get_user_pages start=7ffe95db4000 nr_pages=1 gup_flags=1052 ctx.page_mask=0 [ 94.274211] __get_user_pages @1 vma==NULL [ 94.274211] __get_user_pages @2 start=7ffe95db4000 vma->vm_start=7ffe95db4000 vma->vm_end=7ffe95db5000 vma->vm_flags=8040075 [ 94.274211] __get_user_pages @6 ERESTARTSYS [ 94.274212] __get_user_pages LEAVE i=0 ret=-512 [ 94.274212] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP-2 -512 [ 94.274213] _mm_populate 0 7ffffffff000 7ffffffff000 1 LOOP 7ffe95db5000 1 0 [ 94.274213] _mm_populate END 0 140737488351232 1
diff --git a/mm/gup.c b/mm/gup.c index 98f13ab37bac..5c9825745bb2 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -3,6 +3,7 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/spinlock.h> +#include <linux/printk.h> #include <linux/mm.h> #include <linux/memremap.h> @@ -626,8 +627,8 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address, * *@flags does not include FOLL_NOWAIT, the mmap_sem may be released. * If it is, *@nonblocking will be set to 0 and -EBUSY returned. */ -static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, - unsigned long address, unsigned int *flags, int *nonblocking) +static int faultin_page_x(struct task_struct *tsk, struct vm_area_struct *vma, + unsigned long address, unsigned int *flags, int *nonblocking, int ign) { unsigned int fault_flags = 0; vm_fault_t ret; @@ -649,8 +650,14 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, } ret = handle_mm_fault(vma, address, fault_flags); + if (!ign) { + printk(KERN_WARNING "faultin_page handle_mm_fault --> ret = %u\n", ret); + } if (ret & VM_FAULT_ERROR) { int err = vm_fault_to_errno(ret, *flags); + if (!ign) { + printk(KERN_WARNING "faultin_page handle_mm_fault --> err = %d\n", err); + } if (err) return err; @@ -665,6 +672,9 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, } if (ret & VM_FAULT_RETRY) { + if (!ign) { + printk(KERN_WARNING "faultin_page-->EBUSY VM_FAULT_RETRY non-blocking?%d FAULT_FLAG_RETRY_NOWAIT?%d\n", nonblocking?1:0, (fault_flags & FAULT_FLAG_RETRY_NOWAIT)?1:0); + } if (nonblocking && !(fault_flags & FAULT_FLAG_RETRY_NOWAIT)) *nonblocking = 0; return -EBUSY; @@ -681,8 +691,16 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, */ if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE)) *flags |= FOLL_COW; + if (!ign) { + printk(KERN_WARNING "faultin_page-->0\n"); + } return 0; } +static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, + unsigned long address, unsigned int *flags, int *nonblocking) +{ + return faultin_page_x(tsk, vma, address, flags, nonblocking, 1); +} static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) { @@ -787,15 +805,18 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) * instead of __get_user_pages. __get_user_pages should be used only if * you need some special @gup_flags. */ -static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +static long __get_user_pages_x(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, unsigned int gup_flags, struct page **pages, - struct vm_area_struct **vmas, int *nonblocking) + struct vm_area_struct **vmas, int *nonblocking, int ign) { long ret = 0, i = 0; struct vm_area_struct *vma = NULL; struct follow_page_context ctx = { NULL }; + if (!ign) + printk(KERN_WARNING "__get_user_pages start=%lx nr_pages=%lu gup_flags=%x ctx.page_mask=%u\n", start, nr_pages, gup_flags, ctx.page_mask); + if (!nr_pages) return 0; @@ -816,11 +837,25 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, /* first iteration or cross vma bound */ if (!vma || start >= vma->vm_end) { + if (!ign) { + if (!vma) + printk(KERN_WARNING "__get_user_pages @1 vma==NULL\n"); + else + printk(KERN_WARNING "__get_user_pages @1 start=%lx vma->vm_start=%lx vma->vm_end=%lx vma->vm_flags=%lx\n", start, vma->vm_start, vma->vm_end, vma->vm_flags); + } vma = find_extend_vma(mm, start); + if (!ign) { + if (!vma) + printk(KERN_WARNING "__get_user_pages @2 vma==NULL\n"); + else + printk(KERN_WARNING "__get_user_pages @2 start=%lx vma->vm_start=%lx vma->vm_end=%lx vma->vm_flags=%lx\n", start, vma->vm_start, vma->vm_end, vma->vm_flags); + } if (!vma && in_gate_area(mm, start)) { ret = get_gate_page(mm, start & PAGE_MASK, gup_flags, &vma, pages ? &pages[i] : NULL); + if (!ign) + printk(KERN_WARNING "__get_user_pages @3 get_gate_page --> %ld\n", ret); if (ret) goto out; ctx.page_mask = 0; @@ -828,6 +863,8 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, } if (!vma || check_vma_flags(vma, gup_flags)) { + if (!ign) + printk(KERN_WARNING "__get_user_pages @4 EFAULT\n"); ret = -EFAULT; goto out; } @@ -835,6 +872,8 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, i = follow_hugetlb_page(mm, vma, pages, vmas, &start, &nr_pages, i, gup_flags, nonblocking); + if (!ign) + printk(KERN_WARNING "__get_user_pages @5 follow_hugetlb_page --> %ld\n", i); continue; } } @@ -844,15 +883,21 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, * potentially allocating memory. */ if (fatal_signal_pending(current)) { + if (!ign) + printk(KERN_WARNING "__get_user_pages @6 ERESTARTSYS\n"); ret = -ERESTARTSYS; goto out; } cond_resched(); page = follow_page_mask(vma, start, foll_flags, &ctx); + if (!ign) + printk(KERN_WARNING "__get_user_pages @7 follow_page_mask --> %d ctx.page_mask=%u\n", page ? 1 : 0, ctx.page_mask); if (!page) { - ret = faultin_page(tsk, vma, start, &foll_flags, - nonblocking); + ret = faultin_page_x(tsk, vma, start, &foll_flags, + nonblocking, ign); + if (!ign) + printk(KERN_WARNING "__get_user_pages @8 faultin_page --> %ld\n", ret); switch (ret) { case 0: goto retry; @@ -868,6 +913,8 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, } BUG(); } else if (PTR_ERR(page) == -EEXIST) { + if (!ign) + printk(KERN_WARNING "__get_user_pages @8 EEXIST\n"); /* * Proper page table entry exists, but no corresponding * struct page. @@ -875,6 +922,8 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, goto next_page; } else if (IS_ERR(page)) { ret = PTR_ERR(page); + if (!ign) + printk(KERN_WARNING "__get_user_pages @8 IS_ERR -> ret=%ld\n", ret); goto out; } if (pages) { @@ -889,17 +938,31 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, ctx.page_mask = 0; } page_increm = 1 + (~(start >> PAGE_SHIFT) & ctx.page_mask); + if (!ign) + printk(KERN_WARNING "__get_user_pages @9 page_increm=%u ctx.page_mask=%u\n", page_increm, ctx.page_mask); if (page_increm > nr_pages) page_increm = nr_pages; i += page_increm; start += page_increm * PAGE_SIZE; nr_pages -= page_increm; + if (!ign) + printk(KERN_WARNING "__get_user_pages @10 i=%ld start=%lx nr_pages=%ld\n", i, start, nr_pages); } while (nr_pages); out: if (ctx.pgmap) put_dev_pagemap(ctx.pgmap); + if (!ign) { + printk(KERN_WARNING "__get_user_pages LEAVE i=%ld ret=%ld\n", i, ret); + } return i ? i : ret; } +static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, + unsigned int gup_flags, struct page **pages, + struct vm_area_struct **vmas, int *nonblocking) +{ + return __get_user_pages_x(tsk, mm, start, nr_pages, gup_flags, pages, vmas, nonblocking, 1); +} static bool vma_permits_fault(struct vm_area_struct *vma, unsigned int fault_flags) @@ -1192,8 +1255,9 @@ EXPORT_SYMBOL(get_user_pages_remote); * If @nonblocking is non-NULL, it must held for read only and may be * released. If it's released, *@nonblocking will be set to 0. */ -long populate_vma_page_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end, int *nonblocking) +long populate_vma_page_range_x(struct vm_area_struct *vma, + unsigned long start, unsigned long end, int *nonblocking, + int ign) { struct mm_struct *mm = vma->vm_mm; unsigned long nr_pages = (end - start) / PAGE_SIZE; @@ -1227,8 +1291,13 @@ long populate_vma_page_range(struct vm_area_struct *vma, * We made sure addr is within a VMA, so the following will * not result in a stack expansion that recurses back here. */ - return __get_user_pages(current, mm, start, nr_pages, gup_flags, - NULL, NULL, nonblocking); + return __get_user_pages_x(current, mm, start, nr_pages, gup_flags, + NULL, NULL, nonblocking, ign); +} +long populate_vma_page_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end, int *nonblocking) +{ + return populate_vma_page_range_x(vma, start, end, nonblocking, 1); } /* @@ -1241,14 +1310,23 @@ long populate_vma_page_range(struct vm_area_struct *vma, int __mm_populate(unsigned long start, unsigned long len, int ignore_errors) { struct mm_struct *mm = current->mm; - unsigned long end, nstart, nend; + unsigned long end, nstart, nend = 0L; struct vm_area_struct *vma = NULL; int locked = 0; long ret = 0; + unsigned long nstart_prev = 0L - 1L, nend_prev = 0L - 1L; + int ign; end = start + len; + printk(KERN_WARNING "_mm_populate %lx %lx %lx %d ENTER\n", start, len, end, ignore_errors); + for (nstart = start; nstart < end; nstart = nend) { + ign = nstart == nstart_prev && nend == nend_prev; + nstart_prev = nstart; + nend_prev = nend; + if (!ign) + printk(KERN_WARNING "_mm_populate %lx %lx %lx %d LOOP %lx %d %ld\n", start, len, end, ignore_errors, nstart, locked, ret); /* * We want to fault in pages for [nstart; end) address range. * Find first corresponding VMA. @@ -1259,6 +1337,8 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors) vma = find_vma(mm, nstart); } else if (nstart >= vma->vm_end) vma = vma->vm_next; + if (!ign && vma) + printk(KERN_WARNING "_mm_populate %lx %lx %lx %d vma->vm_start=%lx vma->vm_end=%lx vma->vm_flags=%lx\n", start, len, end, ignore_errors, vma->vm_start, vma->vm_end, vma->vm_flags); if (!vma || vma->vm_start >= end) break; /* @@ -1266,8 +1346,13 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors) * range with the first VMA. Also, skip undesirable VMA types. */ nend = min(end, vma->vm_end); - if (vma->vm_flags & (VM_IO | VM_PFNMAP)) - continue; + if (!ign) + printk(KERN_WARNING "_mm_populate %lx %lx %lx %d nend=%lx %lx %lx\n", start, len, end, ignore_errors, nend, end, vma->vm_end); + if (vma->vm_flags & (VM_IO | VM_PFNMAP)) { + if (!ign) + printk(KERN_WARNING "_mm_populate %lx %lx %lx %d LOOP-1 %lx\n", start, len, end, ignore_errors, vma->vm_flags); + continue; + } if (nstart < vma->vm_start) nstart = vma->vm_start; /* @@ -1275,8 +1360,10 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors) * double checks the vma flags, so that it won't mlock pages * if the vma was already munlocked. */ - ret = populate_vma_page_range(vma, nstart, nend, &locked); + ret = populate_vma_page_range_x(vma, nstart, nend, &locked, ign); if (ret < 0) { + if (!ign) + printk(KERN_WARNING "_mm_populate %lx %lx %lx %d LOOP-2 %ld\n", start, len, end, ignore_errors, ret); if (ignore_errors) { ret = 0; continue; /* continue at next VMA */ @@ -1284,8 +1371,11 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors) break; } nend = nstart + ret * PAGE_SIZE; + if (!ign) + printk(KERN_WARNING "_mm_populate %lx %lx %lx %d LOOP-3 ret=%ld nend=%lx\n", start, len, end, ignore_errors, ret, nend); ret = 0; } + printk(KERN_WARNING "_mm_populate END %lu %lu %d\n", start, len, locked); if (locked) up_read(&mm->mmap_sem); return ret; /* 0 or negative error code */