Date: Sat, 9 Jan 2016 17:45:02 +0000 (UTC) From: Dmitry Chagin <dchagin@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r293585 - in stable/10/sys: amd64/linux amd64/linux32 compat/linux i386/linux Message-ID: <201601091745.u09Hj2Ul065022@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dchagin Date: Sat Jan 9 17:45:02 2016 New Revision: 293585 URL: https://svnweb.freebsd.org/changeset/base/293585 Log: MFC r283484: Implement epoll_pwait() system call. Modified: stable/10/sys/amd64/linux/linux_dummy.c stable/10/sys/amd64/linux32/linux32_dummy.c stable/10/sys/amd64/linux32/syscalls.master stable/10/sys/compat/linux/linux_event.c stable/10/sys/i386/linux/linux_dummy.c stable/10/sys/i386/linux/syscalls.master Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/amd64/linux/linux_dummy.c ============================================================================== --- stable/10/sys/amd64/linux/linux_dummy.c Sat Jan 9 17:44:08 2016 (r293584) +++ stable/10/sys/amd64/linux/linux_dummy.c Sat Jan 9 17:45:02 2016 (r293585) @@ -98,7 +98,6 @@ DUMMY(tee); DUMMY(sync_file_range); DUMMY(vmsplice); DUMMY(move_pages); -DUMMY(epoll_pwait); DUMMY(signalfd); DUMMY(timerfd); DUMMY(timerfd_settime); Modified: stable/10/sys/amd64/linux32/linux32_dummy.c ============================================================================== --- stable/10/sys/amd64/linux32/linux32_dummy.c Sat Jan 9 17:44:08 2016 (r293584) +++ stable/10/sys/amd64/linux32/linux32_dummy.c Sat Jan 9 17:45:02 2016 (r293585) @@ -103,7 +103,6 @@ DUMMY(vmsplice); DUMMY(move_pages); /* linux 2.6.19: */ DUMMY(getcpu); -DUMMY(epoll_pwait); /* linux 2.6.22: */ DUMMY(signalfd); DUMMY(timerfd_create); Modified: stable/10/sys/amd64/linux32/syscalls.master ============================================================================== --- stable/10/sys/amd64/linux32/syscalls.master Sat Jan 9 17:44:08 2016 (r293584) +++ stable/10/sys/amd64/linux32/syscalls.master Sat Jan 9 17:45:02 2016 (r293585) @@ -531,7 +531,7 @@ ; linux 2.6.19: 318 AUE_NULL STD { int linux_getcpu(void); } 319 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \ - l_int maxevents, l_int timeout, l_osigset_t *mask); } + l_int maxevents, l_int timeout, l_sigset_t *mask); } ; linux 2.6.22: 320 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \ const struct l_timespec *times, l_int flags); } Modified: stable/10/sys/compat/linux/linux_event.c ============================================================================== --- stable/10/sys/compat/linux/linux_event.c Sat Jan 9 17:44:08 2016 (r293584) +++ stable/10/sys/compat/linux/linux_event.c Sat Jan 9 17:45:02 2016 (r293585) @@ -468,8 +468,9 @@ leave1: /* * Wait for a filter to be triggered on the epoll file descriptor. */ -int -linux_epoll_wait(struct thread *td, struct linux_epoll_wait_args *args) +static int +linux_epoll_wait_common(struct thread *td, int epfd, struct epoll_event *events, + int maxevents, int timeout, sigset_t *uset) { struct file *epfp; struct timespec ts, *tsp; @@ -480,33 +481,49 @@ linux_epoll_wait(struct thread *td, stru NULL}; int error; - if (args->maxevents <= 0 || args->maxevents > LINUX_MAX_EVENTS) + if (maxevents <= 0 || maxevents > LINUX_MAX_EVENTS) return (EINVAL); - error = fget(td, args->epfd, + if (uset != NULL) { + error = kern_sigprocmask(td, SIG_SETMASK, uset, + &td->td_oldsigmask, 0); + if (error != 0) + return (error); + td->td_pflags |= TDP_OLDMASK; + /* + * Make sure that ast() is called on return to + * usermode and TDP_OLDMASK is cleared, restoring old + * sigmask. + */ + thread_lock(td); + td->td_flags |= TDF_ASTPENDING; + thread_unlock(td); + } + + error = fget(td, epfd, cap_rights_init(&rights, CAP_KQUEUE_EVENT), &epfp); if (error != 0) return (error); - coargs.leventlist = args->events; + coargs.leventlist = events; coargs.p = td->td_proc; coargs.count = 0; coargs.error = 0; - if (args->timeout != -1) { - if (args->timeout < 0) { + if (timeout != -1) { + if (timeout < 0) { error = EINVAL; goto leave; } /* Convert from milliseconds to timespec. */ - ts.tv_sec = args->timeout / 1000; - ts.tv_nsec = (args->timeout % 1000) * 1000000; + ts.tv_sec = timeout / 1000; + ts.tv_nsec = (timeout % 1000) * 1000000; tsp = &ts; } else { tsp = NULL; } - error = kern_kevent_fp(td, epfp, 0, args->maxevents, &k_ops, tsp); + error = kern_kevent_fp(td, epfp, 0, maxevents, &k_ops, tsp); if (error == 0 && coargs.error != 0) error = coargs.error; @@ -521,6 +538,33 @@ leave: return (error); } +int +linux_epoll_wait(struct thread *td, struct linux_epoll_wait_args *args) +{ + + return (linux_epoll_wait_common(td, args->epfd, args->events, + args->maxevents, args->timeout, NULL)); +} + +int +linux_epoll_pwait(struct thread *td, struct linux_epoll_pwait_args *args) +{ + sigset_t mask, *pmask; + l_sigset_t lmask; + int error; + + if (args->mask != NULL) { + error = copyin(args->mask, &lmask, sizeof(l_sigset_t)); + if (error != 0) + return (error); + linux_to_bsd_sigset(&lmask, &mask); + pmask = &mask; + } else + pmask = NULL; + return (linux_epoll_wait_common(td, args->epfd, args->events, + args->maxevents, args->timeout, pmask)); +} + static int epoll_delete_event(struct thread *td, struct file *epfp, int fd, int filter) { Modified: stable/10/sys/i386/linux/linux_dummy.c ============================================================================== --- stable/10/sys/i386/linux/linux_dummy.c Sat Jan 9 17:44:08 2016 (r293584) +++ stable/10/sys/i386/linux/linux_dummy.c Sat Jan 9 17:45:02 2016 (r293585) @@ -99,7 +99,6 @@ DUMMY(vmsplice); DUMMY(move_pages); /* linux 2.6.19: */ DUMMY(getcpu); -DUMMY(epoll_pwait); /* linux 2.6.22: */ DUMMY(signalfd); DUMMY(timerfd_create); Modified: stable/10/sys/i386/linux/syscalls.master ============================================================================== --- stable/10/sys/i386/linux/syscalls.master Sat Jan 9 17:44:08 2016 (r293584) +++ stable/10/sys/i386/linux/syscalls.master Sat Jan 9 17:45:02 2016 (r293585) @@ -539,7 +539,7 @@ ; linux 2.6.19: 318 AUE_NULL STD { int linux_getcpu(void); } 319 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \ - l_int maxevents, l_int timeout, l_osigset_t *mask); } + l_int maxevents, l_int timeout, l_sigset_t *mask); } ; linux 2.6.22: 320 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \ const struct l_timespec *times, l_int flags); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601091745.u09Hj2Ul065022>