Home | History | Annotate | Download | only in sys
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #ifndef _SYS_AIO_IMPL_H
     28 #define	_SYS_AIO_IMPL_H
     29 
     30 #pragma ident	"@(#)aio_impl.h	1.30	06/04/16 SMI"
     31 
     32 #include <sys/aio_req.h>
     33 #include <sys/aio.h>
     34 #include <sys/aiocb.h>
     35 #include <sys/uio.h>
     36 #include <sys/dditypes.h>
     37 #include <sys/siginfo.h>
     38 #include <sys/port.h>
     39 #include <sys/port_kernel.h>
     40 
     41 #ifdef	__cplusplus
     42 extern "C" {
     43 #endif
     44 
     45 #ifdef _KERNEL
     46 
     47 #define	AIO_HASHSZ		8192L		/* power of 2 */
     48 #define	AIO_HASH(cookie)	(((uintptr_t)(cookie) >> 3) & (AIO_HASHSZ-1))
     49 #define	DUPLICATE 1
     50 #define	AIO_IOCB_MAX		32768L
     51 
     52 /*
     53  * an aio_list_t is the head of a list. a group of requests are in
     54  * the same list if their aio_req_list field point to the same list
     55  * head.
     56  *
     57  * a list head is used for notification. a group of requests that
     58  * should only notify a process when they are done will have a
     59  * list head. notification is sent when the group of requests are
     60  * done.
     61  */
     62 typedef struct aio_lio {
     63 	int 		lio_nent;		/* number of requests in list */
     64 	int 		lio_refcnt;		/* number of requests active */
     65 	struct aio_lio	*lio_next;		/* free list pointer */
     66 	kcondvar_t	lio_notify;		/* list notification */
     67 	sigqueue_t	*lio_sigqp;		/* sigqueue_t pointer */
     68 	int		lio_port;		/* port number notification */
     69 	port_kevent_t	*lio_portkev;		/* port event structure */
     70 } aio_lio_t;
     71 
     72 /*
     73  * async I/O request struct - one per I/O request.
     74  */
     75 
     76 /*
     77  * Clustering: The aio_req_t structure is used by the PXFS module
     78  * as a contract private interface.
     79  */
     80 
     81 typedef struct aio_req_t {
     82 	struct aio_req	aio_req;
     83 	int		aio_req_fd;		/* aio's file descriptor */
     84 	int		aio_req_flags;		/* flags */
     85 	aio_result_t	*aio_req_resultp;	/* pointer to user's results */
     86 	int		(*aio_req_cancel)();	/* driver's cancel cb. */
     87 	struct aio_req_t *aio_req_next;		/* doneq and pollq pointers */
     88 	struct aio_req_t *aio_req_prev;		/* doubly linked list */
     89 	struct aio_req_t *aio_hash_next;	/* next in a hash bucket */
     90 	aio_lio_t 	*aio_req_lio;		/* head of list IO chain */
     91 	struct uio	aio_req_uio;		/* uio struct */
     92 	struct iovec	aio_req_iov;		/* iovec struct */
     93 	struct buf	aio_req_buf;		/* buf struct */
     94 	sigqueue_t	*aio_req_sigqp;		/* sigqueue_t pointer */
     95 	union {
     96 		caddr_t 	iocb;		/* ptr to aiocb: 32-32, 64-64 */
     97 		caddr32_t	iocb32;		/* ptr to aiocb: 32-64 */
     98 	} aio_req_iocb;
     99 	port_kevent_t	*aio_req_portkev;	/* port event structure */
    100 	int		aio_req_port;		/* port id */
    101 } aio_req_t;
    102 
    103 /*
    104  * Struct for asynchronous I/O (aio) information per process.
    105  * Each proc stucture has a field pointing to this struct.
    106  * The field will be null if no aio is used.
    107  */
    108 typedef struct aio {
    109 	int		aio_pending;		/* # uncompleted requests */
    110 	int		aio_outstanding;	/* total # of requests */
    111 	int		aio_ok;			/* everything ok when set */
    112 	int		aio_flags;		/* flags */
    113 	int		aio_rqclnup;		/* cleanup request used by DR */
    114 	int		aio_portpendcnt;	/* # pending req. per port */
    115 	aio_req_t	*aio_portq;  		/* port queue head */
    116 	aio_req_t	*aio_portcleanupq;	/* port cleanup queue head */
    117 	aio_req_t	*aio_portpending;	/* list of pending requests */
    118 	aio_req_t	*aio_free;  		/* freelist of aio requests */
    119 	aio_lio_t	*aio_lio_free;		/* freelist of lio heads */
    120 	aio_req_t	*aio_doneq;		/* done queue head */
    121 	aio_req_t	*aio_pollq;		/* poll queue head */
    122 	aio_req_t	*aio_notifyq;		/* notify queue head */
    123 	aio_req_t	*aio_cleanupq;		/* cleanup queue head */
    124 	kmutex_t    	aio_mutex;		/* mutex for aio struct */
    125 	kmutex_t	aio_cleanupq_mutex;	/* cleanupq processing */
    126 	kcondvar_t  	aio_waitcv;		/* cv for aiowait()'ers */
    127 	kcondvar_t  	aio_cleanupcv;		/* notify cleanup, aio_done */
    128 	kcondvar_t  	aio_waitncv;		/* cv for further aiowaitn() */
    129 	kcondvar_t  	aio_portcv;		/* cv for port events */
    130 	aiocb_t		**aio_iocb;		/* list of 32 & 64 bit ptrs */
    131 	size_t		aio_iocbsz;		/* reserved space for iocbs */
    132 	uint_t		aio_waitncnt;		/* # requests for aiowaitn */
    133 	int 		aio_notifycnt;		/* # user-level notifications */
    134 	kmutex_t	aio_portq_mutex;	/* mutex for aio_portq */
    135 	aio_req_t 	*aio_hash[AIO_HASHSZ];	/* hash list of requests */
    136 } aio_t;
    137 
    138 /*
    139  * aio_flags for an aio_t.
    140  */
    141 #define	AIO_CLEANUP		0x1		/* do aio cleanup processing */
    142 #define	AIO_WAITN		0x2		/* aiowaitn in progress */
    143 #define	AIO_WAITN_PENDING	0x4		/* aiowaitn requests pending */
    144 #define	AIO_REQ_BLOCK		0x8		/* block new requests */
    145 #define	AIO_CLEANUP_PORT	0x10
    146 #define	AIO_DONE_ACTIVE		0x20		/* aio_done call in progress */
    147 
    148 /*
    149  * aio_req_flags for an aio_req_t
    150  */
    151 #define	AIO_POLL	0x1			/* AIO_INPROGRESS is set */
    152 #define	AIO_PENDING	0x2			/* aio is in progress */
    153 #define	AIO_PHYSIODONE	0x4			/* unlocked phys pages */
    154 #define	AIO_COPYOUTDONE	0x8			/* result copied to userland */
    155 #define	AIO_NOTIFYQ	0x10			/* aio req is on the notifyq */
    156 #define	AIO_CLEANUPQ	0x20			/* aio req is on the cleanupq */
    157 #define	AIO_POLLQ	0x40			/* aio req is on the pollq */
    158 #define	AIO_DONEQ	0x80			/* aio req is on the doneq */
    159 #define	AIO_ZEROLEN	0x100			/* aio req is zero length */
    160 #define	AIO_PAGELOCKDONE	0x200		/* aio called as_pagelock() */
    161 #define	AIO_CLOSE_PORT		0x400		/* port is being closed */
    162 
    163 /* flag argument of aio_cleanup() */
    164 
    165 #define	AIO_CLEANUP_POLL	0		/* check kaio poll queue */
    166 #define	AIO_CLEANUP_EXIT	1		/* aio_cleanup_exit() */
    167 #define	AIO_CLEANUP_THREAD	2		/* aio_cleanup_thread() */
    168 
    169 /* functions exported by common/os/aio_subr.c */
    170 
    171 extern int aphysio(int (*)(), int (*)(), dev_t, int, void (*)(),
    172 		struct aio_req *);
    173 extern void aphysio_unlock(aio_req_t *);
    174 extern void aio_cleanup(int);
    175 extern void aio_cleanup_exit(void);
    176 extern void aio_zerolen(aio_req_t *);
    177 extern void aio_req_free(aio_t *, aio_req_t *);
    178 extern void aio_cleanupq_concat(aio_t *, aio_req_t *, int);
    179 extern void aio_copyout_result(aio_req_t *);
    180 extern void aio_copyout_result_port(struct iovec *, struct buf *, void *);
    181 extern void aio_req_remove_portq(aio_t *, aio_req_t *);
    182 extern void aio_enq(aio_req_t **, aio_req_t *, int);
    183 extern void aio_deq(aio_req_t **, aio_req_t *);
    184 /* Clustering: PXFS module uses this interface */
    185 extern void aio_done(struct buf *);
    186 
    187 #endif /* _KERNEL */
    188 
    189 #ifdef	__cplusplus
    190 }
    191 #endif
    192 
    193 #endif /* _SYS_AIO_IMPL_H */
    194