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 51885Sraf * Common Development and Distribution License (the "License"). 61885Sraf * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 211885Sraf 220Sstevel@tonic-gate /* 23*4123Sdm120769 * Copyright 2006 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_PORT_IMPL_H 280Sstevel@tonic-gate #define _SYS_PORT_IMPL_H 290Sstevel@tonic-gate 300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 310Sstevel@tonic-gate 320Sstevel@tonic-gate #ifdef __cplusplus 330Sstevel@tonic-gate extern "C" { 340Sstevel@tonic-gate #endif 350Sstevel@tonic-gate 360Sstevel@tonic-gate /* 370Sstevel@tonic-gate * Note: 380Sstevel@tonic-gate * The contents of this file are private to the implementation of the 390Sstevel@tonic-gate * Solaris system and event ports subsystem and are subject to change 400Sstevel@tonic-gate * at any time without notice. 410Sstevel@tonic-gate */ 420Sstevel@tonic-gate 430Sstevel@tonic-gate #include <sys/poll_impl.h> 440Sstevel@tonic-gate #include <sys/port.h> 450Sstevel@tonic-gate #include <sys/port_kernel.h> 460Sstevel@tonic-gate #include <sys/vnode.h> 470Sstevel@tonic-gate 480Sstevel@tonic-gate /* 490Sstevel@tonic-gate * port system call codes 500Sstevel@tonic-gate */ 510Sstevel@tonic-gate #define PORT_CREATE 0 /* create a port */ 520Sstevel@tonic-gate #define PORT_ASSOCIATE 1 /* register object or object list */ 530Sstevel@tonic-gate #define PORT_DISSOCIATE 2 /* remove object association */ 540Sstevel@tonic-gate #define PORT_SEND 3 /* send user-defined event to a port */ 550Sstevel@tonic-gate #define PORT_SENDN 4 /* send user-defined event to a list of ports */ 560Sstevel@tonic-gate #define PORT_GET 5 /* receive object with events */ 570Sstevel@tonic-gate #define PORT_GETN 6 /* receive list of objects with events */ 580Sstevel@tonic-gate #define PORT_ALERT 7 /* set port in alert mode */ 590Sstevel@tonic-gate #define PORT_DISPATCH 8 /* dispatch object with events */ 600Sstevel@tonic-gate 610Sstevel@tonic-gate #define PORT_SYS_NOPORT 0x100 /* system call without port-id */ 620Sstevel@tonic-gate #define PORT_SYS_NOSHARE 0x200 /* non shareable event */ 630Sstevel@tonic-gate #define PORT_CODE_MASK 0xff 640Sstevel@tonic-gate 650Sstevel@tonic-gate /* port_dispatch() flags */ 660Sstevel@tonic-gate #define PORT_SHARE_EVENT 0x01 /* event can be shared between procs */ 670Sstevel@tonic-gate 680Sstevel@tonic-gate /* port limits */ 690Sstevel@tonic-gate #define PORT_MAX_LIST 8192 /* max. # of list ent. per syscall */ 700Sstevel@tonic-gate 710Sstevel@tonic-gate #ifdef _KERNEL 720Sstevel@tonic-gate 730Sstevel@tonic-gate #define PORT_SCACHE_SIZE 16 /* start source cache size */ 740Sstevel@tonic-gate #define PORT_SHASH(cookie) (cookie & (PORT_SCACHE_SIZE-1)) 750Sstevel@tonic-gate 760Sstevel@tonic-gate /* portkev_flags masks */ 770Sstevel@tonic-gate #define PORT_CLEANUP_DONE (PORT_KEV_FREE|PORT_KEV_DONEQ) 780Sstevel@tonic-gate #define PORT_KEV_CACHE (PORT_KEV_CACHED|PORT_KEV_SCACHED) 790Sstevel@tonic-gate #define PORT_KEV_WIRED (PORT_KEV_PRIVATE|PORT_KEV_CACHE) 800Sstevel@tonic-gate 810Sstevel@tonic-gate #define PORT_FREE_EVENT(pev) (((pev)->portkev_flags & PORT_KEV_CACHE) == 0) 820Sstevel@tonic-gate 830Sstevel@tonic-gate typedef struct port_alert { 840Sstevel@tonic-gate int portal_events; /* passed to alert event */ 850Sstevel@tonic-gate pid_t portal_pid; /* owner of the alert mode */ 860Sstevel@tonic-gate uintptr_t portal_object; /* passed to alert event */ 870Sstevel@tonic-gate void *portal_user; /* passed to alert event */ 880Sstevel@tonic-gate } port_alert_t; 890Sstevel@tonic-gate 900Sstevel@tonic-gate /* 910Sstevel@tonic-gate * The port_queue_t structure is responsible for the management of all 920Sstevel@tonic-gate * event activities within a port. 930Sstevel@tonic-gate */ 940Sstevel@tonic-gate typedef struct port_queue { 950Sstevel@tonic-gate kmutex_t portq_mutex; 960Sstevel@tonic-gate kcondvar_t portq_closecv; 971885Sraf kcondvar_t portq_block_cv; 980Sstevel@tonic-gate int portq_flags; 990Sstevel@tonic-gate uint_t portq_nent; /* number of events in the queue */ 1000Sstevel@tonic-gate uint_t portq_nget; /* events required for waiting thread */ 1010Sstevel@tonic-gate uint_t portq_tnent; /* number of events in the temp queue */ 1020Sstevel@tonic-gate int portq_thrcnt; /* # of threads waiting for events */ 1030Sstevel@tonic-gate int portq_getn; /* # of threads retrieving events */ 1040Sstevel@tonic-gate struct portget *portq_thread; /* queue of waiting threads */ 1050Sstevel@tonic-gate struct port_fdcache *portq_pcp; /* fd cache */ 1060Sstevel@tonic-gate list_t portq_list; /* port event list */ 1070Sstevel@tonic-gate list_t portq_get_list; /* port event list for port_get(n) */ 1080Sstevel@tonic-gate kmutex_t portq_source_mutex; 1090Sstevel@tonic-gate port_source_t **portq_scache; 1100Sstevel@tonic-gate port_alert_t portq_alert; /* alert event data */ 1110Sstevel@tonic-gate } port_queue_t; 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate /* defines for portq_flags */ 1140Sstevel@tonic-gate #define PORTQ_ALERT 0x01 /* port in alert state */ 1150Sstevel@tonic-gate #define PORTQ_CLOSE 0x02 /* closing port */ 1160Sstevel@tonic-gate #define PORTQ_WAIT_EVENTS 0x04 /* waiting for new events */ 1170Sstevel@tonic-gate #define PORTQ_POLLIN 0x08 /* events available in the event queue */ 1180Sstevel@tonic-gate #define PORTQ_POLLOUT 0x10 /* space available for new events */ 1191885Sraf #define PORTQ_BLOCKED 0x20 /* port is blocked by port_getn() */ 1202948Spraks #define PORTQ_POLLWK_PEND 0x40 /* pollwakeup is pending, blocks port close */ 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate #define VTOEP(v) ((struct port *)(v->v_data)) 1230Sstevel@tonic-gate #define EPTOV(ep) ((struct vnode *)(ep)->port_vnode) 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate typedef struct port { 1270Sstevel@tonic-gate vnode_t *port_vnode; 1280Sstevel@tonic-gate kmutex_t port_mutex; 1290Sstevel@tonic-gate kcondvar_t port_cv; /* resource control */ 1300Sstevel@tonic-gate uint_t port_flags; 1310Sstevel@tonic-gate pid_t port_pid; 1320Sstevel@tonic-gate int port_fd; 1330Sstevel@tonic-gate uint_t port_max_events; /* max. number of event per port */ 1340Sstevel@tonic-gate uint_t port_max_list; /* max. number of list structs */ 1350Sstevel@tonic-gate uint_t port_curr; /* current number of event structs */ 1360Sstevel@tonic-gate pollhead_t port_pollhd; 1370Sstevel@tonic-gate timespec_t port_ctime; 1380Sstevel@tonic-gate uid_t port_uid; 1390Sstevel@tonic-gate gid_t port_gid; 1400Sstevel@tonic-gate port_queue_t port_queue; /* global queue */ 1410Sstevel@tonic-gate } port_t; 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate /* defines for port_flags */ 1440Sstevel@tonic-gate #define PORT_INIT 0x01 /* port initialized */ 1450Sstevel@tonic-gate #define PORT_CLOSED 0x02 /* owner closed the port */ 1460Sstevel@tonic-gate #define PORT_EVENTS 0x04 /* waiting for event resources */ 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate /* 1490Sstevel@tonic-gate * global control structure of port framework 1500Sstevel@tonic-gate */ 1510Sstevel@tonic-gate typedef struct port_control { 1520Sstevel@tonic-gate kmutex_t pc_mutex; 1530Sstevel@tonic-gate uint_t pc_nents; /* ports currently allocated */ 1540Sstevel@tonic-gate struct kmem_cache *pc_cache; /* port event structures */ 1550Sstevel@tonic-gate } port_control_t; 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate /* 1590Sstevel@tonic-gate * Every thread waiting on an object will use this structure to store 1600Sstevel@tonic-gate * all dependencies (flags, counters, events) before it awakes with 1610Sstevel@tonic-gate * some events/transactions completed 1620Sstevel@tonic-gate */ 1630Sstevel@tonic-gate typedef struct portget { 1640Sstevel@tonic-gate int portget_state; 1650Sstevel@tonic-gate uint_t portget_nget; /* number of expected events */ 1660Sstevel@tonic-gate pid_t portget_pid; 1670Sstevel@tonic-gate kcondvar_t portget_cv; 1680Sstevel@tonic-gate port_alert_t portget_alert; 1690Sstevel@tonic-gate struct portget *portget_next; 1700Sstevel@tonic-gate struct portget *portget_prev; 1710Sstevel@tonic-gate } portget_t; 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate /* defines for portget_state */ 1740Sstevel@tonic-gate #define PORTGET_ALERT 0x01 /* wake up and return alert event */ 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate extern port_control_t port_control; 1770Sstevel@tonic-gate extern uint_t port_max_list; 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate /* 1800Sstevel@tonic-gate * port_getn() needs this structure to manage inter-process event delivery. 1810Sstevel@tonic-gate */ 1820Sstevel@tonic-gate typedef struct port_gettimer { 1830Sstevel@tonic-gate ushort_t pgt_flags; 1840Sstevel@tonic-gate ushort_t pgt_loop; 185*4123Sdm120769 int pgt_timecheck; 1860Sstevel@tonic-gate timespec_t pgt_rqtime; 1870Sstevel@tonic-gate timespec_t *pgt_rqtp; 1880Sstevel@tonic-gate struct timespec *pgt_timeout; 1890Sstevel@tonic-gate } port_gettimer_t; 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate /* pgt_flags */ 1920Sstevel@tonic-gate #define PORTGET_ONE 0x01 /* return only 1 object */ 1930Sstevel@tonic-gate #define PORTGET_WAIT_EVENTS 0x02 /* thread is waiting for new events */ 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate /* 1960Sstevel@tonic-gate * portfd_t is required to synchronize the association of fds with a port 1970Sstevel@tonic-gate * and the per-process list of open files. 1980Sstevel@tonic-gate * There is a pointer to a portfd structure in uf_entry_t. 1990Sstevel@tonic-gate * If a fd is closed then closeandsetf() is able to detect the association of 2000Sstevel@tonic-gate * the fd with a port or with a list of ports. closeandsetf() will dissociate 2010Sstevel@tonic-gate * the fd from the port(s). 2020Sstevel@tonic-gate */ 2030Sstevel@tonic-gate typedef struct portfd { 2040Sstevel@tonic-gate struct polldat pfd_pd; 2050Sstevel@tonic-gate struct portfd *pfd_next; 2060Sstevel@tonic-gate struct portfd *pfd_prev; 2070Sstevel@tonic-gate } portfd_t; 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate #define PFTOD(pfd) (&(pfd)->pfd_pd) 2100Sstevel@tonic-gate #define PDTOF(pdp) ((struct portfd *)(pdp)) 2110Sstevel@tonic-gate #define PORT_FD_BUCKET(pcp, fd) \ 2120Sstevel@tonic-gate (&(pcp)->pc_hash[((fd) % (pcp)->pc_hashsize)]) 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate /* 2150Sstevel@tonic-gate * port_kstat_t contains the event port kernel values which are 2160Sstevel@tonic-gate * exported to kstat. 2170Sstevel@tonic-gate * Currently only the number of active ports is exported. 2180Sstevel@tonic-gate */ 2190Sstevel@tonic-gate typedef struct port_kstat { 2200Sstevel@tonic-gate kstat_named_t pks_ports; 2210Sstevel@tonic-gate } port_kstat_t; 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate /* misc functions */ 2240Sstevel@tonic-gate int port_alloc_event_block(port_t *, int, int, struct port_kevent **); 2250Sstevel@tonic-gate void port_push_eventq(port_queue_t *); 2260Sstevel@tonic-gate void port_remove_done_event(struct port_kevent *); 2270Sstevel@tonic-gate struct port_kevent *port_get_kevent(list_t *, struct port_kevent *); 2281885Sraf void port_block(port_queue_t *); 2291885Sraf void port_unblock(port_queue_t *); 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate /* PORT_SOURCE_FD cache management */ 2320Sstevel@tonic-gate void port_pcache_remove_fd(port_fdcache_t *, portfd_t *); 2333734Spraks int port_remove_fd_object(portfd_t *, struct port *, port_fdcache_t *); 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate /* file close management */ 2360Sstevel@tonic-gate extern void addfd_port(int, portfd_t *); 2370Sstevel@tonic-gate extern void delfd_port(int, portfd_t *); 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate #endif /* _KERNEL */ 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate #ifdef __cplusplus 2420Sstevel@tonic-gate } 2430Sstevel@tonic-gate #endif 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate #endif /* _SYS_PORT_IMPL_H */ 246