diff options
author | glebius <glebius@FreeBSD.org> | 2013-06-08 13:27:57 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2013-06-08 13:27:57 +0000 |
commit | 9a02f3097ddccd309eb701a3492242b74427cc2b (patch) | |
tree | 74456d69981c688882dfa80e300e43d3cc2bb64c /sys | |
parent | bf96f17d6fd96b6131ace044bb51efb86a5b07b6 (diff) | |
download | FreeBSD-src-9a02f3097ddccd309eb701a3492242b74427cc2b.zip FreeBSD-src-9a02f3097ddccd309eb701a3492242b74427cc2b.tar.gz |
Add new system call - aio_mlock(). The name speaks for itself. It allows
to perform the mlock(2) operation, which can consume a lot of time, under
control of aio(4).
Reviewed by: kib, jilles
Sponsored by: Nginx, Inc.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/compat/freebsd32/syscalls.master | 2 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 1 | ||||
-rw-r--r-- | sys/kern/vfs_aio.c | 49 | ||||
-rw-r--r-- | sys/sys/aio.h | 6 |
4 files changed, 54 insertions, 4 deletions
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index e537bc9..bcca754 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -1044,3 +1044,5 @@ __socklen_t * __restrict anamelen, \ int flags); } 542 AUE_PIPE NOPROTO { int pipe2(int *fildes, int flags); } +543 AUE_NULL NOSTD { int freebsd32_aio_mlock( \ + struct aiocb32 *aiocbp); } diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 316f0c2..789f95a5 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -977,5 +977,6 @@ __socklen_t * __restrict anamelen, \ int flags); } 542 AUE_PIPE STD { int pipe2(int *fildes, int flags); } +543 AUE_NULL NOSTD { int aio_mlock(struct aiocb *aiocbp); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 208901e..5fb9341 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -340,6 +340,7 @@ static int aio_onceonly(void); static int aio_free_entry(struct aiocblist *aiocbe); static void aio_process_rw(struct aiocblist *aiocbe); static void aio_process_sync(struct aiocblist *aiocbe); +static void aio_process_mlock(struct aiocblist *aiocbe); static int aio_newproc(int *); int aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lio, int type, struct aiocb_ops *ops); @@ -426,6 +427,7 @@ static struct syscall_helper_data aio_syscalls[] = { SYSCALL_INIT_HELPER(aio_cancel), SYSCALL_INIT_HELPER(aio_error), SYSCALL_INIT_HELPER(aio_fsync), + SYSCALL_INIT_HELPER(aio_mlock), SYSCALL_INIT_HELPER(aio_read), SYSCALL_INIT_HELPER(aio_return), SYSCALL_INIT_HELPER(aio_suspend), @@ -453,6 +455,7 @@ static struct syscall_helper_data aio32_syscalls[] = { SYSCALL32_INIT_HELPER(freebsd32_aio_cancel), SYSCALL32_INIT_HELPER(freebsd32_aio_error), SYSCALL32_INIT_HELPER(freebsd32_aio_fsync), + SYSCALL32_INIT_HELPER(freebsd32_aio_mlock), SYSCALL32_INIT_HELPER(freebsd32_aio_read), SYSCALL32_INIT_HELPER(freebsd32_aio_write), SYSCALL32_INIT_HELPER(freebsd32_aio_waitcomplete), @@ -702,7 +705,8 @@ aio_free_entry(struct aiocblist *aiocbe) * at open time, but this is already true of file descriptors in * a multithreaded process. */ - fdrop(aiocbe->fd_file, curthread); + if (aiocbe->fd_file) + fdrop(aiocbe->fd_file, curthread); crfree(aiocbe->cred); uma_zfree(aiocb_zone, aiocbe); AIO_LOCK(ki); @@ -968,6 +972,21 @@ aio_process_sync(struct aiocblist *aiocbe) } static void +aio_process_mlock(struct aiocblist *aiocbe) +{ + struct aiocb *cb = &aiocbe->uaiocb; + int error; + + KASSERT(aiocbe->uaiocb.aio_lio_opcode == LIO_MLOCK, + ("%s: opcode %d", __func__, aiocbe->uaiocb.aio_lio_opcode)); + + error = vm_mlock(aiocbe->userproc, aiocbe->cred, + __DEVOLATILE(void *, cb->aio_buf), cb->aio_nbytes); + cb->_aiocb_private.error = error; + cb->_aiocb_private.status = 0; +} + +static void aio_bio_done_notify(struct proc *userp, struct aiocblist *aiocbe, int type) { struct aioliojob *lj; @@ -1143,6 +1162,9 @@ aio_daemon(void *_id) case LIO_SYNC: aio_process_sync(aiocbe); break; + case LIO_MLOCK: + aio_process_mlock(aiocbe); + break; } mtx_lock(&aio_job_mtx); @@ -1283,7 +1305,7 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) cb = &aiocbe->uaiocb; fp = aiocbe->fd_file; - if (fp->f_type != DTYPE_VNODE) + if (fp == NULL || fp->f_type != DTYPE_VNODE) return (-1); vp = fp->f_vnode; @@ -1635,6 +1657,9 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, case LIO_SYNC: error = fget(td, fd, CAP_FSYNC, &fp); break; + case LIO_MLOCK: + fp = NULL; + break; case LIO_NOP: error = fget(td, fd, CAP_NONE, &fp); break; @@ -1692,7 +1717,8 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, error = kqfd_register(kqfd, &kev, td, 1); aqueue_fail: if (error) { - fdrop(fp, td); + if (fp) + fdrop(fp, td); uma_zfree(aiocb_zone, aiocbe); ops->store_error(job, error); goto done; @@ -1709,7 +1735,7 @@ no_kqueue: if (opcode == LIO_SYNC) goto queueit; - if (fp->f_type == DTYPE_SOCKET) { + if (fp && fp->f_type == DTYPE_SOCKET) { /* * Alternate queueing for socket ops: Reach down into the * descriptor to get the socket data. Then check to see if the @@ -2187,6 +2213,13 @@ sys_aio_write(struct thread *td, struct aio_write_args *uap) return (aio_aqueue(td, uap->aiocbp, NULL, LIO_WRITE, &aiocb_ops)); } +int +sys_aio_mlock(struct thread *td, struct aio_mlock_args *uap) +{ + + return (aio_aqueue(td, uap->aiocbp, NULL, LIO_MLOCK, &aiocb_ops)); +} + static int kern_lio_listio(struct thread *td, int mode, struct aiocb * const *uacb_list, struct aiocb **acb_list, int nent, struct sigevent *sig, @@ -2929,6 +2962,14 @@ freebsd32_aio_write(struct thread *td, struct freebsd32_aio_write_args *uap) } int +freebsd32_aio_mlock(struct thread *td, struct freebsd32_aio_mlock_args *uap) +{ + + return (aio_aqueue(td, (struct aiocb *)uap->aiocbp, NULL, LIO_MLOCK, + &aiocb32_ops)); +} + +int freebsd32_aio_waitcomplete(struct thread *td, struct freebsd32_aio_waitcomplete_args *uap) { diff --git a/sys/sys/aio.h b/sys/sys/aio.h index 5a8779b..d6ef6aa 100644 --- a/sys/sys/aio.h +++ b/sys/sys/aio.h @@ -37,6 +37,7 @@ #define LIO_READ 0x2 #ifdef _KERNEL #define LIO_SYNC 0x3 +#define LIO_MLOCK 0x4 #endif /* @@ -124,6 +125,11 @@ int aio_cancel(int, struct aiocb *); */ int aio_suspend(const struct aiocb * const[], int, const struct timespec *); +/* + * Asynchronous mlock + */ +int aio_mlock(struct aiocb *); + #ifdef __BSD_VISIBLE int aio_waitcomplete(struct aiocb **, struct timespec *); #endif |