xref: /illumos-gate/usr/src/uts/common/sys/aio_impl.h (revision 1b9bce10)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
534709573Sraf  * Common Development and Distribution License (the "License").
634709573Sraf  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
2134709573Sraf 
227c478bd9Sstevel@tonic-gate /*
23dd1e66b6SVamsi Nagineni  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #ifndef _SYS_AIO_IMPL_H
287c478bd9Sstevel@tonic-gate #define	_SYS_AIO_IMPL_H
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <sys/aio_req.h>
317c478bd9Sstevel@tonic-gate #include <sys/aio.h>
327c478bd9Sstevel@tonic-gate #include <sys/aiocb.h>
337c478bd9Sstevel@tonic-gate #include <sys/uio.h>
347c478bd9Sstevel@tonic-gate #include <sys/dditypes.h>
357c478bd9Sstevel@tonic-gate #include <sys/siginfo.h>
367c478bd9Sstevel@tonic-gate #include <sys/port.h>
377c478bd9Sstevel@tonic-gate #include <sys/port_kernel.h>
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
407c478bd9Sstevel@tonic-gate extern "C" {
417c478bd9Sstevel@tonic-gate #endif
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #ifdef _KERNEL
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #define	AIO_HASHSZ		8192L		/* power of 2 */
467c478bd9Sstevel@tonic-gate #define	AIO_HASH(cookie)	(((uintptr_t)(cookie) >> 3) & (AIO_HASHSZ-1))
477c478bd9Sstevel@tonic-gate #define	DUPLICATE 1
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate /*
507c478bd9Sstevel@tonic-gate  * an aio_list_t is the head of a list. a group of requests are in
517c478bd9Sstevel@tonic-gate  * the same list if their aio_req_list field point to the same list
527c478bd9Sstevel@tonic-gate  * head.
537c478bd9Sstevel@tonic-gate  *
547c478bd9Sstevel@tonic-gate  * a list head is used for notification. a group of requests that
557c478bd9Sstevel@tonic-gate  * should only notify a process when they are done will have a
567c478bd9Sstevel@tonic-gate  * list head. notification is sent when the group of requests are
5734709573Sraf  * done.
587c478bd9Sstevel@tonic-gate  */
597c478bd9Sstevel@tonic-gate typedef struct aio_lio {
607c478bd9Sstevel@tonic-gate 	int 		lio_nent;		/* number of requests in list */
617c478bd9Sstevel@tonic-gate 	int 		lio_refcnt;		/* number of requests active */
627c478bd9Sstevel@tonic-gate 	struct aio_lio	*lio_next;		/* free list pointer */
637c478bd9Sstevel@tonic-gate 	kcondvar_t	lio_notify;		/* list notification */
647c478bd9Sstevel@tonic-gate 	sigqueue_t	*lio_sigqp;		/* sigqueue_t pointer */
6534709573Sraf 	int		lio_port;		/* port number notification */
6634709573Sraf 	port_kevent_t	*lio_portkev;		/* port event structure */
677c478bd9Sstevel@tonic-gate } aio_lio_t;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate  * async I/O request struct - one per I/O request.
717c478bd9Sstevel@tonic-gate  */
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate  * Clustering: The aio_req_t structure is used by the PXFS module
757c478bd9Sstevel@tonic-gate  * as a contract private interface.
767c478bd9Sstevel@tonic-gate  */
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate typedef struct aio_req_t {
797c478bd9Sstevel@tonic-gate 	struct aio_req	aio_req;
807c478bd9Sstevel@tonic-gate 	int		aio_req_fd;		/* aio's file descriptor */
817c478bd9Sstevel@tonic-gate 	int		aio_req_flags;		/* flags */
827c478bd9Sstevel@tonic-gate 	aio_result_t	*aio_req_resultp;	/* pointer to user's results */
837c478bd9Sstevel@tonic-gate 	int		(*aio_req_cancel)();	/* driver's cancel cb. */
847c478bd9Sstevel@tonic-gate 	struct aio_req_t *aio_req_next;		/* doneq and pollq pointers */
857c478bd9Sstevel@tonic-gate 	struct aio_req_t *aio_req_prev;		/* doubly linked list */
867c478bd9Sstevel@tonic-gate 	struct aio_req_t *aio_hash_next;	/* next in a hash bucket */
877c478bd9Sstevel@tonic-gate 	aio_lio_t 	*aio_req_lio;		/* head of list IO chain */
887c478bd9Sstevel@tonic-gate 	struct uio	aio_req_uio;		/* uio struct */
897c478bd9Sstevel@tonic-gate 	struct iovec	aio_req_iov;		/* iovec struct */
907c478bd9Sstevel@tonic-gate 	struct buf	aio_req_buf;		/* buf struct */
917c478bd9Sstevel@tonic-gate 	sigqueue_t	*aio_req_sigqp;		/* sigqueue_t pointer */
927c478bd9Sstevel@tonic-gate 	union {
937c478bd9Sstevel@tonic-gate 		caddr_t 	iocb;		/* ptr to aiocb: 32-32, 64-64 */
947c478bd9Sstevel@tonic-gate 		caddr32_t	iocb32;		/* ptr to aiocb: 32-64 */
957c478bd9Sstevel@tonic-gate 	} aio_req_iocb;
967c478bd9Sstevel@tonic-gate 	port_kevent_t	*aio_req_portkev;	/* port event structure */
977c478bd9Sstevel@tonic-gate 	int		aio_req_port;		/* port id */
987c478bd9Sstevel@tonic-gate } aio_req_t;
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate /*
1017c478bd9Sstevel@tonic-gate  * Struct for asynchronous I/O (aio) information per process.
1027c478bd9Sstevel@tonic-gate  * Each proc stucture has a field pointing to this struct.
1037c478bd9Sstevel@tonic-gate  * The field will be null if no aio is used.
1047c478bd9Sstevel@tonic-gate  */
1057c478bd9Sstevel@tonic-gate typedef struct aio {
1067c478bd9Sstevel@tonic-gate 	int		aio_pending;		/* # uncompleted requests */
1077c478bd9Sstevel@tonic-gate 	int		aio_outstanding;	/* total # of requests */
1087c478bd9Sstevel@tonic-gate 	int		aio_ok;			/* everything ok when set */
1097c478bd9Sstevel@tonic-gate 	int		aio_flags;		/* flags */
110b0b27ce6Spraks 	int		aio_rqclnup;		/* cleanup request used by DR */
1117c478bd9Sstevel@tonic-gate 	int		aio_portpendcnt;	/* # pending req. per port */
1127c478bd9Sstevel@tonic-gate 	aio_req_t	*aio_portq;  		/* port queue head */
1137c478bd9Sstevel@tonic-gate 	aio_req_t	*aio_portcleanupq;	/* port cleanup queue head */
1147c478bd9Sstevel@tonic-gate 	aio_req_t	*aio_portpending;	/* list of pending requests */
1157c478bd9Sstevel@tonic-gate 	aio_req_t	*aio_free;  		/* freelist of aio requests */
1167c478bd9Sstevel@tonic-gate 	aio_lio_t	*aio_lio_free;		/* freelist of lio heads */
1177c478bd9Sstevel@tonic-gate 	aio_req_t	*aio_doneq;		/* done queue head */
1187c478bd9Sstevel@tonic-gate 	aio_req_t	*aio_pollq;		/* poll queue head */
1197c478bd9Sstevel@tonic-gate 	aio_req_t	*aio_notifyq;		/* notify queue head */
1207c478bd9Sstevel@tonic-gate 	aio_req_t	*aio_cleanupq;		/* cleanup queue head */
1217c478bd9Sstevel@tonic-gate 	kmutex_t    	aio_mutex;		/* mutex for aio struct */
1227c478bd9Sstevel@tonic-gate 	kmutex_t	aio_cleanupq_mutex;	/* cleanupq processing */
1237c478bd9Sstevel@tonic-gate 	kcondvar_t  	aio_waitcv;		/* cv for aiowait()'ers */
1247c478bd9Sstevel@tonic-gate 	kcondvar_t  	aio_cleanupcv;		/* notify cleanup, aio_done */
1257c478bd9Sstevel@tonic-gate 	kcondvar_t  	aio_waitncv;		/* cv for further aiowaitn() */
1267c478bd9Sstevel@tonic-gate 	kcondvar_t  	aio_portcv;		/* cv for port events */
1277c478bd9Sstevel@tonic-gate 	aiocb_t		**aio_iocb;		/* list of 32 & 64 bit ptrs */
1287c478bd9Sstevel@tonic-gate 	size_t		aio_iocbsz;		/* reserved space for iocbs */
1297c478bd9Sstevel@tonic-gate 	uint_t		aio_waitncnt;		/* # requests for aiowaitn */
1307c478bd9Sstevel@tonic-gate 	int 		aio_notifycnt;		/* # user-level notifications */
1317c478bd9Sstevel@tonic-gate 	kmutex_t	aio_portq_mutex;	/* mutex for aio_portq */
1327c478bd9Sstevel@tonic-gate 	aio_req_t 	*aio_hash[AIO_HASHSZ];	/* hash list of requests */
1337c478bd9Sstevel@tonic-gate } aio_t;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate  * aio_flags for an aio_t.
1377c478bd9Sstevel@tonic-gate  */
138d2749ac6SRoger A. Faulkner #define	AIO_CLEANUP		0x0001	/* do aio cleanup processing */
139d2749ac6SRoger A. Faulkner #define	AIO_WAITN		0x0002	/* aiowaitn in progress */
140d2749ac6SRoger A. Faulkner #define	AIO_WAITN_PENDING	0x0004	/* aiowaitn requests pending */
141d2749ac6SRoger A. Faulkner #define	AIO_REQ_BLOCK		0x0008	/* block new requests */
142d2749ac6SRoger A. Faulkner #define	AIO_CLEANUP_PORT	0x0010
143d2749ac6SRoger A. Faulkner #define	AIO_DONE_ACTIVE		0x0020	/* aio_done call in progress */
144d2749ac6SRoger A. Faulkner #define	AIO_SOLARIS_REQ		0x0040	/* an old solaris aio req was issued */
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate /*
1477c478bd9Sstevel@tonic-gate  * aio_req_flags for an aio_req_t
1487c478bd9Sstevel@tonic-gate  */
149d2749ac6SRoger A. Faulkner #define	AIO_POLL	0x0001		/* AIO_INPROGRESS is set */
150d2749ac6SRoger A. Faulkner #define	AIO_PENDING	0x0002		/* aio is in progress */
151d2749ac6SRoger A. Faulkner #define	AIO_PHYSIODONE	0x0004		/* unlocked phys pages */
152d2749ac6SRoger A. Faulkner #define	AIO_COPYOUTDONE	0x0008		/* result copied to userland */
153d2749ac6SRoger A. Faulkner #define	AIO_NOTIFYQ	0x0010		/* aio req is on the notifyq */
154d2749ac6SRoger A. Faulkner #define	AIO_CLEANUPQ	0x0020		/* aio req is on the cleanupq */
155d2749ac6SRoger A. Faulkner #define	AIO_POLLQ	0x0040		/* aio req is on the pollq */
156d2749ac6SRoger A. Faulkner #define	AIO_DONEQ	0x0080		/* aio req is on the doneq */
157d2749ac6SRoger A. Faulkner #define	AIO_ZEROLEN	0x0100		/* aio req is zero length */
158d2749ac6SRoger A. Faulkner #define	AIO_PAGELOCKDONE 0x0200		/* aio called as_pagelock() */
159d2749ac6SRoger A. Faulkner #define	AIO_CLOSE_PORT	0x0400		/* port is being closed */
160d2749ac6SRoger A. Faulkner #define	AIO_SIGNALLED	0x0800		/* process signalled by this req */
161d2749ac6SRoger A. Faulkner #define	AIO_SOLARIS	0x1000		/* this is an old solaris aio req */
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate /* flag argument of aio_cleanup() */
1647c478bd9Sstevel@tonic-gate 
165d2749ac6SRoger A. Faulkner #define	AIO_CLEANUP_POLL	0	/* check kaio poll queue */
166d2749ac6SRoger A. Faulkner #define	AIO_CLEANUP_EXIT	1	/* aio_cleanup_exit() */
167d2749ac6SRoger A. Faulkner #define	AIO_CLEANUP_THREAD	2	/* aio_cleanup_thread() */
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate /* functions exported by common/os/aio_subr.c */
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate extern int aphysio(int (*)(), int (*)(), dev_t, int, void (*)(),
1727c478bd9Sstevel@tonic-gate 		struct aio_req *);
1737c478bd9Sstevel@tonic-gate extern void aphysio_unlock(aio_req_t *);
1747c478bd9Sstevel@tonic-gate extern void aio_cleanup(int);
1757c478bd9Sstevel@tonic-gate extern void aio_cleanup_exit(void);
1767c478bd9Sstevel@tonic-gate extern void aio_zerolen(aio_req_t *);
1777c478bd9Sstevel@tonic-gate extern void aio_req_free(aio_t *, aio_req_t *);
1787c478bd9Sstevel@tonic-gate extern void aio_cleanupq_concat(aio_t *, aio_req_t *, int);
1797c478bd9Sstevel@tonic-gate extern void aio_copyout_result(aio_req_t *);
1807c478bd9Sstevel@tonic-gate extern void aio_copyout_result_port(struct iovec *, struct buf *, void *);
1817c478bd9Sstevel@tonic-gate extern void aio_req_remove_portq(aio_t *, aio_req_t *);
18234709573Sraf extern void aio_enq(aio_req_t **, aio_req_t *, int);
18334709573Sraf extern void aio_deq(aio_req_t **, aio_req_t *);
1847c478bd9Sstevel@tonic-gate /* Clustering: PXFS module uses this interface */
185*1b9bce10SToomas Soome extern int aio_done(struct buf *);
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate #endif
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate #endif /* _SYS_AIO_IMPL_H */
194