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 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #ifndef _SYS_PORT_KERNEL_H
  28 #define _SYS_PORT_KERNEL_H
  29 
  30 #pragma ident   "%Z%%M% %I%     %E% SMI"
  31 
  32 #include <sys/vnode.h>
  33 #include <sys/list.h>
  34 
  35 #ifdef  __cplusplus
  36 extern "C" {
  37 #endif
  38 
  39 /*
  40  * Note:
  41  * The contents of this file are private to the implementation of the
  42  * Solaris system and event ports subsystem and are subject to change
  43  * at any time without notice.
  44  */
  45 
  46 #ifdef _KERNEL
  47 
  48 /*
  49  * The port_kevent_t struct represents the kernel internal port event.
  50  * Every event is associated to a port (portkev_port).
  51  */
  52 typedef struct  port_kevent {
  53         kmutex_t        portkev_lock;   /* used by PORT_SOURCE_FD source */
  54         int     portkev_source;         /* event: source */
  55         int     portkev_events;         /* event: data */
  56         int     portkev_flags;          /* internal flags */
  57         pid_t   portkev_pid;            /* pid of process using this struct */
  58         long    portkev_object;         /* event: object */
  59         void    *portkev_user;          /* event: user-defined value */
  60         int     (*portkev_callback)(void *, int *, pid_t, int, void *);
  61         void    *portkev_arg;           /* event source callback arg */
  62         struct  port *portkev_port;     /* associated port */
  63         list_node_t portkev_node;       /* pointer to neighbor events */
  64 } port_kevent_t;
  65 
  66 /* portkev_flags */
  67 #define PORT_KEV_PRIVATE        0x01    /* subsystem private, don't free */
  68 #define PORT_KEV_CACHED         0x02    /* port local cached, don't free */
  69 #define PORT_KEV_SCACHED        0x04    /* source local cached, don't free */
  70 #define PORT_KEV_VALID          0x08    /* event associated and enabled */
  71 #define PORT_KEV_DONEQ          0x10    /* event is in done queue */
  72 #define PORT_KEV_FREE           0x20    /* free event and don't copyout it */
  73 #define PORT_KEV_NOSHARE        0x40    /* non-shareable across processes */
  74 
  75 /* flags : port_alloc_event() */
  76 #define PORT_ALLOC_DEFAULT      0
  77 #define PORT_ALLOC_PRIVATE      PORT_KEV_PRIVATE
  78 #define PORT_ALLOC_CACHED       PORT_KEV_CACHED
  79 #define PORT_ALLOC_SCACHED      PORT_KEV_SCACHED
  80 
  81 /* flags : callback function */
  82 #define PORT_CALLBACK_DEFAULT   0       /* free resources, event delivery */
  83 #define PORT_CALLBACK_CLOSE     1       /* free resources, don't copyout */
  84 #define PORT_CALLBACK_DISSOCIATE 2      /* dissociate object */
  85 
  86 #define PORT_DEFAULT_PORTS      0x02000
  87 #define PORT_MAX_PORTS          0x10000
  88 #define PORT_DEFAULT_EVENTS     0x10000 /* default # of events per port */
  89 #define PORT_MAX_EVENTS         UINT_MAX/2 /* max. # of events per port */
  90 
  91 /*
  92  * port_source_t represents a source associated with a port.
  93  * The portsrc_close() function is required to notify the source when
  94  * a port is closed.
  95  */
  96 typedef struct port_source {
  97         int     portsrc_source;
  98         int     portsrc_cnt;            /* # of associations */
  99         void    (*portsrc_close)(void *, int, pid_t, int);
 100         void    *portsrc_closearg;      /* callback arg */
 101         void    *portsrc_data;          /* Private data of source */
 102         struct port_source *portsrc_next;
 103         struct port_source *portsrc_prev;
 104 } port_source_t;
 105 
 106 
 107 /*
 108  * PORT_SOURCE_FILE cache structure.
 109  */
 110 #define PORTFOP_HASHSIZE        256     /* cache space for fop events */
 111 
 112 /*
 113  * One cache for each port that uses PORT_SOURCE_FILE.
 114  */
 115 typedef struct portfop_cache {
 116         kmutex_t        pfc_lock;       /* lock to protect cache */
 117         kcondvar_t      pfc_lclosecv;   /* last close cv */
 118         int             pfc_objcount;   /* track how many file obj are hashed */
 119         struct portfop  *pfc_hash[PORTFOP_HASHSIZE]; /* hash table */
 120 } portfop_cache_t;
 121 
 122 /*
 123  * PORT_SOURCE_FD cache per port.
 124  * One cache for each port that uses PORT_SOURCE_FD.
 125  * pc_lock must be the first element of port_fdcache_t to keep it
 126  * synchronized with the offset of pc_lock in pollcache_t (see pollrelock()).
 127  */
 128 typedef struct port_fdcache {
 129         kmutex_t        pc_lock;        /* lock to protect portcache */
 130         kcondvar_t      pc_lclosecv;
 131         struct portfd   **pc_hash;      /* points to a hash table of ptrs */
 132         int             pc_hashsize;    /* the size of current hash table */
 133         int             pc_fdcount;     /* track how many fd's are hashed */
 134 } port_fdcache_t;
 135 
 136 /*
 137  * Structure of port_ksource_tab[] table.
 138  * The port_ksource_tab[] is required to allow kernel sources to become
 139  * associated with a port at the time of port creation. This feature is
 140  * required to avoid performance degradation in sub-systems, specially when
 141  * they should need to check the association on every event activity.
 142  */
 143 typedef struct  port_ksource {
 144         int     pks_source;
 145         void    (*pks_close)(void *, int, pid_t, int);
 146         void    *pks_closearg;
 147         void    *pks_portsrc;
 148 } port_ksource_t;
 149 
 150 /* event port and source management */
 151 int     port_associate_ksource(int, int, struct port_source **,
 152     void (*)(void *, int, pid_t, int), void *arg,
 153     int (*)(port_kevent_t *, int, int, uintptr_t, void *));
 154 int     port_dissociate_ksource(int, int, struct port_source *);
 155 
 156 /* event management */
 157 int     port_alloc_event(int, int, int, port_kevent_t **);
 158 int     port_pollwkup(struct port *);
 159 void    port_pollwkdone(struct port *);
 160 void    port_send_event(port_kevent_t *);
 161 void    port_free_event(port_kevent_t *);
 162 void    port_init_event(port_kevent_t *, uintptr_t, void *,
 163     int (*)(void *, int *, pid_t, int, void *), void *);
 164 int     port_dup_event(port_kevent_t *, port_kevent_t **, int);
 165 int     port_associate_fd(struct port *, int, uintptr_t, int, void *);
 166 int     port_dissociate_fd(struct port *, uintptr_t);
 167 int     port_associate_fop(struct port *, int, uintptr_t, int, void *);
 168 int     port_dissociate_fop(struct port *, uintptr_t);
 169 
 170 /* misc functions */
 171 void    port_free_event_local(port_kevent_t *, int counter);
 172 int     port_alloc_event_local(struct port *, int, int, port_kevent_t **);
 173 void    port_close_pfd(struct portfd *);
 174 
 175 #endif  /* _KERNEL */
 176 
 177 #ifdef  __cplusplus
 178 }
 179 #endif
 180 
 181 #endif  /* _SYS_PORT_KERNEL_H */