xref: /onnv-gate/usr/src/uts/common/sys/aio_impl.h (revision 304:80feb3217668)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23*304Spraks  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #ifndef _SYS_AIO_IMPL_H
280Sstevel@tonic-gate #define	_SYS_AIO_IMPL_H
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate #include <sys/aio_req.h>
330Sstevel@tonic-gate #include <sys/aio.h>
340Sstevel@tonic-gate #include <sys/aiocb.h>
350Sstevel@tonic-gate #include <sys/uio.h>
360Sstevel@tonic-gate #include <sys/dditypes.h>
370Sstevel@tonic-gate #include <sys/siginfo.h>
380Sstevel@tonic-gate #include <sys/port.h>
390Sstevel@tonic-gate #include <sys/port_kernel.h>
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #ifdef	__cplusplus
420Sstevel@tonic-gate extern "C" {
430Sstevel@tonic-gate #endif
440Sstevel@tonic-gate 
450Sstevel@tonic-gate #ifdef _KERNEL
460Sstevel@tonic-gate 
470Sstevel@tonic-gate #define	AIO_HASHSZ		8192L		/* power of 2 */
480Sstevel@tonic-gate #define	AIO_HASH(cookie)	(((uintptr_t)(cookie) >> 3) & (AIO_HASHSZ-1))
490Sstevel@tonic-gate #define	DUPLICATE 1
500Sstevel@tonic-gate #define	AIO_IOCB_MAX		32768L
510Sstevel@tonic-gate 
520Sstevel@tonic-gate /*
530Sstevel@tonic-gate  * an aio_list_t is the head of a list. a group of requests are in
540Sstevel@tonic-gate  * the same list if their aio_req_list field point to the same list
550Sstevel@tonic-gate  * head.
560Sstevel@tonic-gate  *
570Sstevel@tonic-gate  * a list head is used for notification. a group of requests that
580Sstevel@tonic-gate  * should only notify a process when they are done will have a
590Sstevel@tonic-gate  * list head. notification is sent when the group of requests are
600Sstevel@tonic-gate  * done. individual requests do not send out any notification.
610Sstevel@tonic-gate  */
620Sstevel@tonic-gate typedef struct aio_lio {
630Sstevel@tonic-gate 	int 		lio_nent;		/* number of requests in list */
640Sstevel@tonic-gate 	int 		lio_refcnt;		/* number of requests active */
650Sstevel@tonic-gate 	struct aio_lio	*lio_next;		/* free list pointer */
660Sstevel@tonic-gate 	kcondvar_t	lio_notify;		/* list notification */
670Sstevel@tonic-gate 	sigqueue_t	*lio_sigqp;		/* sigqueue_t pointer */
680Sstevel@tonic-gate } aio_lio_t;
690Sstevel@tonic-gate 
700Sstevel@tonic-gate /*
710Sstevel@tonic-gate  * async I/O request struct - one per I/O request.
720Sstevel@tonic-gate  */
730Sstevel@tonic-gate 
740Sstevel@tonic-gate /*
750Sstevel@tonic-gate  * Clustering: The aio_req_t structure is used by the PXFS module
760Sstevel@tonic-gate  * as a contract private interface.
770Sstevel@tonic-gate  */
780Sstevel@tonic-gate 
790Sstevel@tonic-gate typedef struct aio_req_t {
800Sstevel@tonic-gate 	struct aio_req	aio_req;
810Sstevel@tonic-gate 	int		aio_req_fd;		/* aio's file descriptor */
820Sstevel@tonic-gate 	int		aio_req_flags;		/* flags */
830Sstevel@tonic-gate 	aio_result_t	*aio_req_resultp;	/* pointer to user's results */
840Sstevel@tonic-gate 	int		(*aio_req_cancel)();	/* driver's cancel cb. */
850Sstevel@tonic-gate 	struct aio_req_t *aio_req_next;		/* doneq and pollq pointers */
860Sstevel@tonic-gate 	struct aio_req_t *aio_req_prev;		/* doubly linked list */
870Sstevel@tonic-gate 	struct aio_req_t *aio_hash_next;	/* next in a hash bucket */
880Sstevel@tonic-gate 	aio_lio_t 	*aio_req_lio;		/* head of list IO chain */
890Sstevel@tonic-gate 	struct uio	aio_req_uio;		/* uio struct */
900Sstevel@tonic-gate 	struct iovec	aio_req_iov;		/* iovec struct */
910Sstevel@tonic-gate 	struct buf	aio_req_buf;		/* buf struct */
920Sstevel@tonic-gate 	sigqueue_t	*aio_req_sigqp;		/* sigqueue_t pointer */
930Sstevel@tonic-gate 	union {
940Sstevel@tonic-gate 		caddr_t 	iocb;		/* ptr to aiocb: 32-32, 64-64 */
950Sstevel@tonic-gate 		caddr32_t	iocb32;		/* ptr to aiocb: 32-64 */
960Sstevel@tonic-gate 	} aio_req_iocb;
970Sstevel@tonic-gate 	port_kevent_t	*aio_req_portkev;	/* port event structure */
980Sstevel@tonic-gate 	int		aio_req_port;		/* port id */
990Sstevel@tonic-gate } aio_req_t;
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate /*
1020Sstevel@tonic-gate  * Struct for asynchronous I/O (aio) information per process.
1030Sstevel@tonic-gate  * Each proc stucture has a field pointing to this struct.
1040Sstevel@tonic-gate  * The field will be null if no aio is used.
1050Sstevel@tonic-gate  */
1060Sstevel@tonic-gate typedef struct aio {
1070Sstevel@tonic-gate 	int		aio_pending;		/* # uncompleted requests */
1080Sstevel@tonic-gate 	int		aio_outstanding;	/* total # of requests */
1090Sstevel@tonic-gate 	int		aio_ok;			/* everything ok when set */
1100Sstevel@tonic-gate 	int		aio_flags;		/* flags */
111*304Spraks 	int		aio_rqclnup;		/* cleanup request used by DR */
1120Sstevel@tonic-gate 	int		aio_portpendcnt;	/* # pending req. per port */
1130Sstevel@tonic-gate 	aio_req_t	*aio_portq;  		/* port queue head */
1140Sstevel@tonic-gate 	aio_req_t	*aio_portcleanupq;	/* port cleanup queue head */
1150Sstevel@tonic-gate 	aio_req_t	*aio_portpending;	/* list of pending requests */
1160Sstevel@tonic-gate 	aio_req_t	*aio_free;  		/* freelist of aio requests */
1170Sstevel@tonic-gate 	aio_lio_t	*aio_lio_free;		/* freelist of lio heads */
1180Sstevel@tonic-gate 	aio_req_t	*aio_doneq;		/* done queue head */
1190Sstevel@tonic-gate 	aio_req_t	*aio_pollq;		/* poll queue head */
1200Sstevel@tonic-gate 	aio_req_t	*aio_notifyq;		/* notify queue head */
1210Sstevel@tonic-gate 	aio_req_t	*aio_cleanupq;		/* cleanup queue head */
1220Sstevel@tonic-gate 	kmutex_t    	aio_mutex;		/* mutex for aio struct */
1230Sstevel@tonic-gate 	kmutex_t	aio_cleanupq_mutex;	/* cleanupq processing */
1240Sstevel@tonic-gate 	kcondvar_t  	aio_waitcv;		/* cv for aiowait()'ers */
1250Sstevel@tonic-gate 	kcondvar_t  	aio_cleanupcv;		/* notify cleanup, aio_done */
1260Sstevel@tonic-gate 	kcondvar_t  	aio_waitncv;		/* cv for further aiowaitn() */
1270Sstevel@tonic-gate 	kcondvar_t  	aio_portcv;		/* cv for port events */
1280Sstevel@tonic-gate 	aiocb_t		**aio_iocb;		/* list of 32 & 64 bit ptrs */
1290Sstevel@tonic-gate 	size_t		aio_iocbsz;		/* reserved space for iocbs */
1300Sstevel@tonic-gate 	uint_t		aio_waitncnt;		/* # requests for aiowaitn */
1310Sstevel@tonic-gate 	int 		aio_notifycnt;		/* # user-level notifications */
1320Sstevel@tonic-gate 	kmutex_t	aio_portq_mutex;	/* mutex for aio_portq */
1330Sstevel@tonic-gate 	aio_req_t 	*aio_hash[AIO_HASHSZ];	/* hash list of requests */
1340Sstevel@tonic-gate } aio_t;
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate /*
1370Sstevel@tonic-gate  * aio_flags for an aio_t.
1380Sstevel@tonic-gate  */
1390Sstevel@tonic-gate #define	AIO_CLEANUP		0x1		/* do aio cleanup processing */
1400Sstevel@tonic-gate #define	AIO_WAITN		0x2		/* aiowaitn in progress */
1410Sstevel@tonic-gate #define	AIO_WAITN_PENDING	0x4		/* aiowaitn requests pending */
1420Sstevel@tonic-gate #define	AIO_REQ_BLOCK		0x8		/* block new requests */
1430Sstevel@tonic-gate #define	AIO_CLEANUP_PORT	0x10
1440Sstevel@tonic-gate #define	AIO_DONE_ACTIVE		0x20		/* aio_done call in progress */
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate /*
1470Sstevel@tonic-gate  * aio_req_flags for an aio_req_t
1480Sstevel@tonic-gate  */
1490Sstevel@tonic-gate #define	AIO_POLL	0x1			/* AIO_INPROGRESS is set */
1500Sstevel@tonic-gate #define	AIO_PENDING	0x2			/* aio is in progress */
1510Sstevel@tonic-gate #define	AIO_PHYSIODONE	0x4			/* unlocked phys pages */
1520Sstevel@tonic-gate #define	AIO_COPYOUTDONE	0x8			/* result copied to userland */
1530Sstevel@tonic-gate #define	AIO_NOTIFYQ	0x10			/* aio req is on the notifyq */
1540Sstevel@tonic-gate #define	AIO_CLEANUPQ	0x20			/* aio req is on the cleanupq */
1550Sstevel@tonic-gate #define	AIO_POLLQ	0x40			/* aio req is on the pollq */
1560Sstevel@tonic-gate #define	AIO_DONEQ	0x80			/* aio req is on the doneq */
1570Sstevel@tonic-gate #define	AIO_ZEROLEN	0x100			/* aio req is zero length */
1580Sstevel@tonic-gate #define	AIO_PAGELOCKDONE	0x200		/* aio called as_pagelock() */
1590Sstevel@tonic-gate #define	AIO_CLOSE_PORT		0x400		/* port is being closed */
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate #ifdef DEBUG
1620Sstevel@tonic-gate #define	AIO_REQ_PEND	0x1000			/* req in pending queue */
1630Sstevel@tonic-gate #define	AIO_REQ_CLEAN	0x2000			/* req in cleanup queue */
1640Sstevel@tonic-gate #define	AIO_REQ_PORTQ	0x4000			/* req in port done queue */
1650Sstevel@tonic-gate #define	AIO_REQ_FREE	0x8000			/* req in free queue */
1660Sstevel@tonic-gate #endif
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate /* flag argument of aio_cleanup() */
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate #define	AIO_CLEANUP_POLL	0		/* check kaio poll queue */
1710Sstevel@tonic-gate #define	AIO_CLEANUP_EXIT	1		/* aio_cleanup_exit() */
1720Sstevel@tonic-gate #define	AIO_CLEANUP_THREAD	2		/* aio_cleanup_thread() */
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate /* functions exported by common/os/aio_subr.c */
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate extern int aphysio(int (*)(), int (*)(), dev_t, int, void (*)(),
1770Sstevel@tonic-gate 		struct aio_req *);
1780Sstevel@tonic-gate extern void aphysio_unlock(aio_req_t *);
1790Sstevel@tonic-gate extern void aio_cleanup(int);
1800Sstevel@tonic-gate extern void aio_cleanup_exit(void);
1810Sstevel@tonic-gate extern void aio_zerolen(aio_req_t *);
1820Sstevel@tonic-gate extern void aio_req_free(aio_t *, aio_req_t *);
1830Sstevel@tonic-gate extern void aio_cleanupq_concat(aio_t *, aio_req_t *, int);
1840Sstevel@tonic-gate extern void aio_copyout_result(aio_req_t *);
1850Sstevel@tonic-gate extern void aio_copyout_result_port(struct iovec *, struct buf *, void *);
1860Sstevel@tonic-gate extern void aio_enq_port_pending(aio_t *, aio_req_t *);
1870Sstevel@tonic-gate extern void aio_req_remove_portq(aio_t *, aio_req_t *);
1880Sstevel@tonic-gate /* Clustering: PXFS module uses this interface */
1890Sstevel@tonic-gate extern void aio_done(struct buf *);
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate #endif /* _KERNEL */
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate #ifdef	__cplusplus
1940Sstevel@tonic-gate }
1950Sstevel@tonic-gate #endif
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate #endif /* _SYS_AIO_IMPL_H */
198