On Sun, 26 May 2019, Sebastian Andrzej Siewior wrote: > > Okay. The GUP functions are not properly documented for my taste. There > is no indication whether or not the mm_sem has to be acquired prior > invoking it. Following the call chain of get_user_pages() I ended up in > __get_user_pages_locked() `locked = NULL' indicated that mm_sem is no > acquired and then I saw this: > | if (!locked) > | /* VM_FAULT_RETRY couldn't trigger, bypass */ > | return ret; > > kind of suggesting that it is okay to invoke it without holding the > mm_sem prefault. It passed a few tests and then > https://lkml.kernel.org/r/1556657902.6132.13.camel@xxxxxx > > happened. After that, I switched to the locked variant and the problem > disappeared (also I noticed that MPX code is invoked within ->mmap()). Ah, I wasn't following what happened here while it was in linux-next. I certainly agree that all the variants are very confusing, and the matter of mmap_sem particularly so. Because it used to be a simple rule that you needed to hold mmap_sem to call get_user_pages(); but that can be so contended that get_user_pages_fast(), and VM_FAULT_RETRY, optimizations came in, then interfaces like get_user_pages_locked() and get_user_pages_unlocked(). I think when you say that you "switched to the locked variant", you're writing of when you switched to using get_user_pages_unlocked(), which takes and releases the mmap_sem itself: yes, using get_user_pages() without holding mmap_sem would have been open to serious errors. The documentation in comments above get_user_pages_locked() and get_user_pages_unlocked() looks rather good to me, actually. But this is all good reason to use the less challenging fault_in_pages_writable() instead. (And also saves all those GUP developers, who from time to time have to search through all users of GUP in one form or another, to make this or that improvement, from having to visit arch/x86/kernel/fpu/signal.c: they will quietly thank you.) Hugh