1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _RSM_IN_H
#define _RSM_IN_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/rsm/rsm.h>
#include <sys/rsm/rsmpi.h>
#define DRIVER_NAME "rsm"
#define RSM_DRIVER_MINOR 0
#define RSM_CNUM 8
#define RSMIPC_SZ 10 /* number of outstanding requests, max: 256 */
#define RSMIPC_MAX_MESSAGES 64 /* max msgs that receiver can buffer */
#define RSMIPC_LOTSFREE_MSGBUFS 16 /* chunks of credits sent to sender */
/*
* The base for Sun RSMAPI Kernel Agent service idenitifiers is RSM_INTR_T_KA
* as defined below. This is as per the RSMPI specification. Thus,
* in the kernel agent, we need to use this value as the service identifier
* while registering the service handlers.
*/
#define RSM_INTR_T_KA 0x88
#define RSM_SERVICE RSM_INTR_T_KA
#define RSM_PRI 2
#define RSM_QUEUE_SZ 256
#define RSM_LOCK 0
#define RSM_NOLOCK 1
#define RSM_MAX_NUM_SEG 4095 /* default value for max imp and exp segs */
#define RSM_MAX_NODE 64 /* maximum number of nodes in the cluster */
#define RSM_MAX_CTRL 32 /* maximum number of controllers per node */
/*
* The following defines UINT_MAX rounded down to a page aligned value.
*/
#define RSM_MAXSZ_PAGE_ALIGNED (UINT_MAX & PAGEMASK)
/*
* Define TRASHSIZE as the maximum possible size which is page aligned
* This value cannot be 0xffffffffffffe000 since this is taken as a
* negative value in the devmap_umem_remap call, thus causing the call
* to fail.
*/
#define TRASHSIZE 0x7fffffffffffe000
#define RSM_ACCESS_READ 0444
#define RSM_ACCESS_WRITE 0222
#define RSM_ACCESS_TRUSTED 0666
/* flag values for rsmseg_unload */
#define DISCONNECT 1
#define NO_DISCONNECT 0
struct rsm_driver_data {
kmutex_t drv_lock;
kcondvar_t drv_cv;
int drv_state; /* RSM_DRV_YYYY states */
int drv_memdel_cnt; /* number of memdel callbacks */
};
/* rsm driver state */
#define RSM_DRV_NEW 0
#define RSM_DRV_OK 1
#define RSM_DRV_PREDEL_STARTED 2
#define RSM_DRV_PREDEL_COMPLETED 3
#define RSM_DRV_POSTDEL_IN_PROGRESS 4
#define RSM_DRV_DR_IN_PROGRESS 5
#define RSM_DRV_REG_PROCESSING 6
#define RSM_DRV_UNREG_PROCESSING 7
/* internal flags */
#define RSM_DR_QUIESCE 0
#define RSM_DR_UNQUIESCE 1
typedef enum {
RSM_STATE_NEW = 0,
RSM_STATE_NEW_QUIESCED,
RSM_STATE_BIND,
RSM_STATE_BIND_QUIESCED,
RSM_STATE_EXPORT,
RSM_STATE_EXPORT_QUIESCING,
RSM_STATE_EXPORT_QUIESCED,
RSM_STATE_ZOMBIE,
RSM_STATE_CONNECTING,
RSM_STATE_ABORT_CONNECT,
RSM_STATE_CONNECT,
RSM_STATE_CONN_QUIESCE,
RSM_STATE_MAPPING,
RSM_STATE_ACTIVE,
RSM_STATE_MAP_QUIESCE,
RSM_STATE_DISCONNECT,
RSM_STATE_END
} rsm_resource_state_t;
typedef enum {
RSM_RESOURCE_EXPORT_SEGMENT,
RSM_RESOURCE_IMPORT_SEGMENT,
RSM_RESOURCE_BAR
}rsm_resource_type_t;
/*
* All resources have the only common info. whether it is a segment or
* a notification queue.
*/
typedef struct rsm_resource {
kmutex_t rsmrc_lock; /* sync on resource */
minor_t rsmrc_num; /* (minor) number */
rsm_memseg_id_t rsmrc_key; /* user key */
mode_t rsmrc_mode; /* access permission */
struct adapter *rsmrc_adapter; /* controller number */
rsm_node_id_t rsmrc_node; /* nodeid */
rsm_resource_type_t rsmrc_type; /* type of this resource */
rsm_resource_state_t rsmrc_state; /* segment state */
struct rsm_resource *rsmrc_next;
} rsmresource_t;
#define RSMRC_BLKSZ 16
#define RSMRC_RESERVED ((rsmresource_t *)0x1)
#define RSM_HASHSZ 128
#define RSM_USER_MEMORY 0x1
#define RSM_KERNEL_MEMORY 0x2
#define RSM_EXPORT_WAIT 0x4
#define RSM_SEGMENT_POLL 0x8
#define RSM_FORCE_DISCONNECT 0x10
#define RSM_IMPORT_DUMMY 0x20
/*
* The following macro is used within the kernel agent to indicate that
* rebind/unbind is allowed for an exported segment. It is a part of the
* segment's s_flags field.
*/
#define RSMKA_ALLOW_UNBIND_REBIND 0x40
#define RSM_REPUBLISH_WAIT 0x80
#define RSM_DR_INPROGRESS 0x100
#define RSM_FORCE_DESTROY_WAIT 0x200
#define RSMKA_SET_RESOURCE_DONTWAIT 0x400
#define RSMRC_LOCK(p) mutex_enter(&(p)->rsmrc_lock)
#define RSMRC_UNLOCK(p) mutex_exit(&(p)->rsmrc_lock)
#define RSMRC_HELD(p) MUTEX_HELD(&(p)->rsmrc_lock)
#define RSMRC_TRY(p) mutex_tryenter(&(p)->rsmrc_lock)
typedef struct rsm_region {
caddr_t r_vaddr; /* exported virtual address */
size_t r_len; /* length of export region */
offset_t r_off; /* offset of this region in segment */
struct as *r_asp;
struct rsm_region *r_next; /* next region of segment */
}rsm_region;
typedef struct rsm_cookie {
devmap_cookie_t c_dhp; /* devmap cookie handle */
offset_t c_off; /* offset of mapping */
size_t c_len; /* len of mapping */
struct rsm_cookie *c_next; /* next handle */
}rsmcookie_t;
typedef struct rsm_mapinfo {
dev_info_t *dip;
uint_t dev_register;
off_t dev_offset;
off_t start_offset;
size_t individual_len;
struct rsm_mapinfo *next;
} rsm_mapinfo_t;
/*
* Shared Importer data structure
*
*/
typedef struct rsm_import_share {
kmutex_t rsmsi_lock; /* lock for shared importers */
kcondvar_t rsmsi_cv; /* condvar to wait at */
rsm_node_id_t rsmsi_node;
rsm_memseg_id_t rsmsi_segid;
size_t rsmsi_seglen;
rsm_memseg_import_handle_t rsmsi_handle; /* RSMPI handle */
uint_t rsmsi_state;
#define RSMSI_STATE_NEW 0x0001
#define RSMSI_STATE_CONNECTING 0x0002
#define RSMSI_STATE_ABORT_CONNECT 0x0004
#define RSMSI_STATE_CONNECTED 0x0008
#define RSMSI_STATE_CONN_QUIESCE 0x0010
#define RSMSI_STATE_MAPPED 0x0020
#define RSMSI_STATE_MAP_QUIESCE 0x0040
#define RSMSI_STATE_DISCONNECTED 0x0080
uint_t rsmsi_refcnt; /* ref count of importers */
uint_t rsmsi_mapcnt; /* count of mapped importers */
mode_t rsmsi_mode; /* mode of last (re)publish */
uid_t rsmsi_uid;
gid_t rsmsi_gid;
rsm_mapinfo_t *rsmsi_mapinfo; /* register, offset, len values */
uint_t rsmsi_flags; /* flags */
#define RSMSI_FLAGS_ABORTDONE 0x0001 /* NOT_IMPORTING msg for abort conn */
/* has been sent */
void *rsmsi_cookie; /* cookie of the first seg connect */
} rsm_import_share_t;
#define RSMSI_LOCK(sharep) mutex_enter(&(sharep)->rsmsi_lock)
#define RSMSI_UNLOCK(sharep) mutex_exit(&(sharep)->rsmsi_lock)
#define RSMSI_HELD(sharep) MUTEX_HELD(&(sharep)->rsmsi_lock)
#define RSMSI_TRY(sharep) mutex_tryenter(&(sharep)->rsmsi_lock)
typedef struct rsm_seginfo {
rsmresource_t s_hdr; /* resource hdr */
#define s_state s_hdr.rsmrc_state /* segment state */
#define s_adapter s_hdr.rsmrc_adapter
#define s_node s_hdr.rsmrc_node
#define s_lock s_hdr.rsmrc_lock
#define s_minor s_hdr.rsmrc_num /* minor # of segment */
#define s_key s_hdr.rsmrc_key /* user segment key */
#define s_mode s_hdr.rsmrc_mode /* user segment mode */
#define s_type s_hdr.rsmrc_type /* segment type */
uid_t s_uid; /* owner id */
gid_t s_gid; /* owner id */
size_t s_len; /* total segment size */
rsm_region s_region; /* regions of segment */
int s_flags;
int s_pollflag; /* indicates poll status */
kcondvar_t s_cv; /* condition to wait on */
rsm_memseg_id_t s_segid; /* NIC segment id */
int s_acl_len; /* length of access list */
rsmapi_access_entry_t *s_acl; /* access list */
rsm_access_entry_t *s_acl_in; /* access list with hwaddr */
struct pollhead s_poll;
uint32_t s_pollevent;
pid_t s_pid;
rsmcookie_t *s_ckl; /* list of devmap cookie */
size_t s_total_maplen;
rsm_mapinfo_t *s_mapinfo; /* register, offset, len */
union {
rsm_memseg_import_handle_t in;
rsm_memseg_export_handle_t out;
} s_handle; /* NIC handle for segment */
/*
* This field is used to indicate the cookie returned by the
* ddi_umem_lock when binding pages for an export segment.
* Also, for importers on the same node as the export segment,
* this field indicates the cookie used during import mapping.
*/
ddi_umem_cookie_t s_cookie;
rsm_import_share_t *s_share; /* shared importer data */
/*
* This field in an import segments indicates the number of
* putv/getv operations in progress and in an export segment
* it is the number of putv/getv ops currently using it as
* a handle in the iovec.
*/
uint_t s_rdmacnt;
struct proc *s_proc;
} rsmseg_t;
#define rsmseglock_acquire(p) RSMRC_LOCK((rsmresource_t *)(p))
#define rsmseglock_release(p) RSMRC_UNLOCK((rsmresource_t *)(p))
#define rsmseglock_held(p) RSMRC_HELD((rsmresource_t *)(p))
#define rsmseglock_try(p) RSMRC_TRY((rsmresource_t *)(p))
#define rsmsharelock_acquire(p) RSMSI_LOCK(p->s_share)
#define rsmsharelock_release(p) RSMSI_UNLOCK(p->s_share)
#define rsmsharelock_held(p) RSMSI_HELD(p->s_share)
#define rsmsharelock_try(p) RSMSI_TRY(p->s_share)
/*
* Resource elements structure
*/
typedef struct {
int rsmrcblk_avail;
rsmresource_t *rsmrcblk_blks[RSMRC_BLKSZ];
}rsmresource_blk_t;
struct rsmresource_table {
krwlock_t rsmrc_lock;
int rsmrc_len;
int rsmrc_sz;
rsmresource_blk_t **rsmrc_root;
};
/*
* Struct for advertised resource list
*/
/*
* Hashtable structs
* bucket points to an array of pointers, each entry in the bucket array
* points to a linked list of resource items.
* bucket index = bucket_address%RSM_HASHSZ
*/
typedef struct rsmhash_table {
krwlock_t rsmhash_rw;
rsmresource_t **bucket;
} rsmhash_table_t;
/*
* Remote messaging related structure
*/
/*
* Flags for ipc slot
*/
#define RSMIPC_FREE 0x1 /* slot is free */
#define RSMIPC_PENDING 0x2 /* slot has pending request */
#define RSMIPC_SET(x, v) ((x)->rsmipc_flags |= (v))
#define RSMIPC_GET(x, v) ((x)->rsmipc_flags & (v))
#define RSMIPC_CLEAR(x, v) ((x)->rsmipc_flags &= ~(v))
typedef struct rsmipc_slot {
kmutex_t rsmipc_lock; /* lock for remote msgs */
kcondvar_t rsmipc_cv; /* condition var to wait on */
int rsmipc_flags;
rsmipc_cookie_t rsmipc_cookie; /* cookie of request in wire */
void *rsmipc_data; /* ptr to data to copy */
}rsmipc_slot_t;
/*
* Messaging struc
*/
typedef struct {
kmutex_t lock;
kcondvar_t cv;
int count;
int wanted;
int sequence;
rsmipc_slot_t slots[RSMIPC_SZ];
}rsm_ipc_t;
/*
* These tokens are used for building the list of remote node importers
* of a segment exported from the local node
*/
typedef struct importing_token {
struct importing_token *next;
rsm_memseg_id_t key;
rsm_node_id_t importing_node;
void *import_segment_cookie;
rsm_addr_t importing_adapter_hwaddr;
} importing_token_t;
typedef struct {
kmutex_t lock;
importing_token_t **bucket;
} importers_table_t;
/*
* Used by the rsm_send_republish() fn
*/
typedef struct republish_token {
struct republish_token *next;
rsm_memseg_id_t key;
rsm_node_id_t importing_node;
rsm_permission_t permission;
} republish_token_t;
/*
* data strucuture for list manipulation
*/
typedef struct list_element {
struct list_element *next;
rsm_node_id_t nodeid;
uint32_t flags;
#define RSM_SUSPEND_ACKPENDING 0x01
#define RSM_SUSPEND_NODEDEAD 0x02
} list_element_t;
typedef struct list_head {
struct list_element *list_head;
kmutex_t list_lock;
} list_head_t;
#ifdef __cplusplus
}
#endif
#endif /* _RSM_IN_H */
|