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