On Wed, Mar 14, 2018 at 08:38:53PM +0000, Alexey Brodkin wrote: > > int sys_cmpxchg(u32 __user *user_ptr, u32 old, u32 new) > > { > > u32 val; > > int ret; > > > > again: > > ret = 0; > > > > preempt_disable(); > > val = get_user(user_ptr); > > if (val == old) > > ret = put_user(new, user_ptr); > > preempt_enable(); > > > > if (ret == -EFAULT) { > > struct page *page; > > ret = get_user_pages_fast((unsigned long)user_ptr, 1, 1, &page); > > if (ret < 0) > > return ret; > > put_page(page); > > goto again; > > I guess this jump we need to do only once, right? Typically, yes. It is theoretically possible for the page to get paged-out right after we do put_page() and before we do get/put_user(), But if that happens the machine likely has bigger problems than having to do this loop again. FWIW, look at kernel/futex.c for working examples of this pattern, the above was written purely from memory and could contain a fail or two ;-) Also, it might make sense to stuff this implementation in some lib/ file somewhere and make all platforms that need it use the same code, afaict there really isn't anything platform specific to it.