Skip to content

Commit

Permalink
OS-4855 lxbrand convert epoll_ctl to IKE
Browse files Browse the repository at this point in the history
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
  • Loading branch information
pfmooney committed Oct 16, 2015
1 parent 4893b66 commit 1c50428
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 38 deletions.
4 changes: 2 additions & 2 deletions usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
Expand Up @@ -1173,7 +1173,7 @@ static lx_syscall_handler_t lx_handlers[] = {
lx_clock_nanosleep, /* 230: clock_nanosleep */
lx_group_exit, /* 231: exit_group */
NULL, /* 232: epoll_wait */
lx_epoll_ctl, /* 233: epoll_ctl */
NULL, /* 233: epoll_ctl */
NULL, /* 234: tgkill */
lx_utimes, /* 235: utimes */
NULL, /* 236: vserver */
Expand Down Expand Up @@ -1526,7 +1526,7 @@ static lx_syscall_handler_t lx_handlers[] = {
lx_group_exit, /* 252: group_exit */
NULL, /* 253: lookup_dcookie */
NULL, /* 254: epoll_create */
lx_epoll_ctl, /* 255: epoll_ctl */
NULL, /* 255: epoll_ctl */
NULL, /* 256: epoll_wait */
NULL, /* 257: remap_file_pages */
NULL, /* 258: set_tid_address */
Expand Down
33 changes: 0 additions & 33 deletions usr/src/lib/brand/lx/lx_brand/common/poll_select.c
Expand Up @@ -40,7 +40,6 @@
#include <sys/brand.h>
#include <sys/poll.h>
#include <sys/syscall.h>
#include <sys/epoll.h>
#include <sys/lx_debug.h>
#include <sys/lx_poll.h>
#include <sys/lx_syscall.h>
Expand Down Expand Up @@ -288,35 +287,3 @@ lx_poll(uintptr_t p1, uintptr_t p2, uintptr_t p3)
free(sfds);
return (res);
}

long
lx_epoll_ctl(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4)
{
int epfd = (int)p1;
int op = (int)p2;
int fd = (int)p3;
int rval;
struct epoll_event ev;

/*
* Linux limits the max number of open files to 1m so we can also test
* for this.
*/
if (epfd < 0 || fd < 0 || epfd > (1024 * 1024) || fd > (1024 * 1024))
return (-EBADF);

if (epfd == fd)
return (-EINVAL);

/*
* Unlike the base epoll_ctl, we need to return a fault if the
* event pointer is invalid.
*/
if (op != EPOLL_CTL_DEL) {
if (uucopy((void *)p4, &ev, sizeof (ev)) != 0)
return (-errno);
}

rval = epoll_ctl(epfd, op, fd, (struct epoll_event *)p4);
return ((rval < 0) ? -errno : rval);
}
1 change: 0 additions & 1 deletion usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h
Expand Up @@ -103,7 +103,6 @@ extern long lx_pselect6(uintptr_t, uintptr_t, uintptr_t, uintptr_t,
uintptr_t, uintptr_t);
extern long lx_poll(uintptr_t, uintptr_t, uintptr_t);
extern long lx_ppoll(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
extern long lx_epoll_ctl(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
extern long lx_settimeofday(uintptr_t, uintptr_t);
extern long lx_getrusage(uintptr_t, uintptr_t);
extern long lx_mknod(uintptr_t, uintptr_t, uintptr_t);
Expand Down
4 changes: 2 additions & 2 deletions usr/src/uts/common/brand/lx/os/lx_syscall.c
Expand Up @@ -778,7 +778,7 @@ lx_sysent_t lx_sysent32[] = {
{"group_exit", NULL, 0, 1}, /* 252 */
{"lookup_dcookie", NULL, NOSYS_NO_EQUIV, 0}, /* 253 */
{"epoll_create", lx_epoll_create, 0, 1}, /* 254 */
{"epoll_ctl", NULL, 0, 4}, /* 255 */
{"epoll_ctl", lx_epoll_ctl, 0, 4}, /* 255 */
{"epoll_wait", lx_epoll_wait, 0, 4}, /* 256 */
{"remap_file_pages", NULL, NOSYS_NO_EQUIV, 0}, /* 257 */
{"set_tid_address", lx_set_tid_address, 0, 1}, /* 258 */
Expand Down Expand Up @@ -1127,7 +1127,7 @@ lx_sysent_t lx_sysent64[] = {
{"clock_nanosleep", NULL, 0, 4}, /* 230 */
{"exit_group", NULL, 0, 1}, /* 231 */
{"epoll_wait", lx_epoll_wait, 0, 4}, /* 232 */
{"epoll_ctl", NULL, 0, 4}, /* 233 */
{"epoll_ctl", lx_epoll_ctl, 0, 4}, /* 233 */
{"tgkill", lx_tgkill, 0, 3}, /* 234 */
{"utimes", NULL, 0, 2}, /* 235 */
{"vserver", NULL, NOSYS_NULL, 0}, /* 236 */
Expand Down
1 change: 1 addition & 0 deletions usr/src/uts/common/brand/lx/sys/lx_syscalls.h
Expand Up @@ -46,6 +46,7 @@ extern long lx_clock_settime();
extern long lx_connect();
extern long lx_epoll_create();
extern long lx_epoll_create1();
extern long lx_epoll_ctl();
extern long lx_epoll_pwait();
extern long lx_epoll_wait();
extern long lx_fallocate();
Expand Down
108 changes: 108 additions & 0 deletions usr/src/uts/common/brand/lx/syscall/lx_epoll.c
Expand Up @@ -23,12 +23,25 @@
#include <sys/devpoll.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/sunldi.h>
#include <sys/vnode.h>
#include <sys/lx_brand.h>
#include <sys/lx_types.h>

static major_t devpoll_major = 0;

static boolean_t
lx_epoll_isvalid(file_t *fp)
{
vnode_t *vp = fp->f_vnode;

if (vp->v_type == VCHR && getmajor(vp->v_rdev) == devpoll_major)
return (B_TRUE);
return (B_FALSE);
}

long
lx_epoll_create1(int flags)
{
Expand Down Expand Up @@ -64,6 +77,8 @@ lx_epoll_create1(int flags)
goto error;
}

devpoll_major = getmajor(vp->v_rdev);

fp->f_vnode = vp;
mutex_exit(&fp->f_tlock);
setf(fd, fp);
Expand Down Expand Up @@ -93,6 +108,93 @@ lx_epoll_create(int size)
return (lx_epoll_create1(0));
}


/* Match values from libc implementation */
#define EPOLLIGNORED (EPOLLMSG | EPOLLWAKEUP)
#define EPOLLSWIZZLED \
(EPOLLRDHUP | EPOLLONESHOT | EPOLLET | EPOLLWRBAND | EPOLLWRNORM)

long
lx_epoll_ctl(int fd, int op, int pfd, void *event)
{
epoll_event_t epevent;
dvpoll_epollfd_t dpevent[2];
file_t *fp;
iovec_t aiov;
uio_t auio;
uint32_t events, ev = 0;
int error = 0, i = 0;

dpevent[i].dpep_pollfd.fd = pfd;
switch (op) {
case EPOLL_CTL_DEL:
dpevent[i].dpep_pollfd.events = POLLREMOVE;
break;

case EPOLL_CTL_MOD:
/*
* In the modify case, we pass down two events: one to
* remove the event and another to add it back.
*/
dpevent[i++].dpep_pollfd.events = POLLREMOVE;
dpevent[i].dpep_pollfd.fd = pfd;
/* FALLTHROUGH */

case EPOLL_CTL_ADD:
if (copyin(event, &epevent, sizeof (epevent)) != 0)
return (set_errno(EFAULT));

/*
* Mask off the events that we ignore, and then swizzle the
* events for which our values differ from their epoll(7)
* equivalents.
*/
events = epevent.events;
ev = events & ~(EPOLLIGNORED | EPOLLSWIZZLED);

if (events & EPOLLRDHUP)
ev |= POLLRDHUP;
if (events & EPOLLET)
ev |= POLLET;
if (events & EPOLLONESHOT)
ev |= POLLONESHOT;
if (events & EPOLLWRNORM)
ev |= POLLWRNORM;
if (events & EPOLLWRBAND)
ev |= POLLWRBAND;

dpevent[i].dpep_data = epevent.data.u64;
dpevent[i].dpep_pollfd.events = ev;
break;

default:
return (set_errno(EINVAL));
}

if ((fp = getf(fd)) == NULL) {
return (set_errno(EBADF));
} else if (!lx_epoll_isvalid(fp)) {
releasef(fd);
return (set_errno(EINVAL));
}

aiov.iov_base = (void *)dpevent;
aiov.iov_len = sizeof (dvpoll_epollfd_t) * (i + 1);
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_resid = aiov.iov_len;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_loffset = 0;
auio.uio_fmode = fp->f_flag;

error = VOP_WRITE(fp->f_vnode, &auio, 1, fp->f_cred, NULL);

releasef(fd);
if (error)
return (set_errno(error));
return (0);
}

long
lx_epoll_wait(int fd, void *events, int maxevents, int timeout)
{
Expand All @@ -105,6 +207,9 @@ lx_epoll_wait(int fd, void *events, int maxevents, int timeout)
}
if ((fp = getf(fd)) == NULL) {
return (set_errno(EBADF));
} else if (!lx_epoll_isvalid(fp)) {
releasef(fd);
return (set_errno(EINVAL));
}

arg.dp_nfds = maxevents;
Expand Down Expand Up @@ -133,6 +238,9 @@ lx_epoll_pwait(int fd, void *events, int maxevents, int timeout, void *sigmask)
}
if ((fp = getf(fd)) == NULL) {
return (set_errno(EBADF));
} else if (!lx_epoll_isvalid(fp)) {
releasef(fd);
return (set_errno(EINVAL));
}

arg.dp_nfds = maxevents;
Expand Down

0 comments on commit 1c50428

Please sign in to comment.