On 06/05, David Laight wrote: > > epoll() would have: > if (restore_user_sigmask(xxx.sigmask, &sigsaved, !ret || ret == -EINTR)) > ret = -EINTR; I don't think so but lets discuss this later. > I also think it could be simplified if code that loaded the 'user sigmask' > saved the old one in 'current->saved_sigmask' (and saved that it had done it). > You'd not need 'sigsaved' nor pass the user sigmask address into > the restore function. Heh. apparently you do not read my emails ;) This is what I proposed in my very 1st email, and I even showed the patch and the code with the patch applied twice. Let me do this again. Let me show the code with the patch applied. I am using epoll_pwait() as an example because it looks very simple. static inline void set_restore_sigmask(void) { // WARN_ON(!TIF_SIGPENDING) was removed by this patch current->restore_sigmask = true; } int set_xxx(const sigset_t __user *umask, size_t sigsetsize) { sigset_t *kmask; if (!umask) return 0; if (sigsetsize != sizeof(sigset_t)) return -EINVAL; if (copy_from_user(kmask, umask, sizeof(sigset_t))) return -EFAULT; // we can safely modify ->saved_sigmask/restore_sigmask, they has no meaning // until the syscall returns. set_restore_sigmask(); current->saved_sigmask = current->blocked; set_current_blocked(kmask); return 0; } void update_xxx(bool interrupted) { // the main reason for this helper is WARN_ON(!TIF_SIGPENDING) which was "moved" // from set_restore_sigmask() above. if (interrupted) WARN_ON(!test_thread_flag(TIF_SIGPENDING)); else restore_saved_sigmask(); } SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout, const sigset_t __user *, sigmask, size_t, sigsetsize) { int error; error = set_xxx(sigmask, sigsetsize); if (error) return error; error = do_epoll_wait(epfd, events, maxevents, timeout); update_xxx(error == -EINTR); return error; } Oleg.