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.
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.
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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
36 #include <sys/types.h>
40 #include <sys/sysmacros.h>
41 #include <sys/resource.h>
51 #include <sys/rsm/rsmndi.h>
52 #include <rsmlib_in.h>
53 #include <sys/rsm/rsm.h>
56 extern void __rsmloopback_init_ops(rsm_segops_t
*);
57 extern void __rsmdefault_setops(rsm_segops_t
*);
59 typedef void (*rsm_access_func_t
)(void *, void *, rsm_access_size_t
);
63 #define RSMLOG_BUF_SIZE 256
64 FILE *rsmlog_fd
= NULL
;
65 static mutex_t rsmlog_lock
;
66 int rsmlibdbg_category
= RSM_LIBRARY
;
67 int rsmlibdbg_level
= RSM_ERR
;
68 void dbg_printf(int category
, int level
, char *fmt
, ...);
72 rsm_node_id_t rsm_local_nodeid
= 0;
74 static rsm_controller_t
*controller_list
= NULL
;
76 static rsm_segops_t loopback_ops
;
80 #define RSM_IOTYPE_PUTGET 1
81 #define RSM_IOTYPE_SCATGATH 2
83 #define RSMFILE_BUFSIZE 256
85 #pragma init(_rsm_librsm_init)
87 static mutex_t _rsm_lock
;
89 static int _rsm_fd
= -1;
90 static rsm_gnum_t
*bar_va
, bar_fixed
= 0;
91 static rsm_pollfd_table_t pollfd_table
;
93 static int _rsm_get_hwaddr(rsmapi_controller_handle_t handle
,
94 rsm_node_id_t
, rsm_addr_t
*hwaddrp
);
95 static int _rsm_get_nodeid(rsmapi_controller_handle_t
,
96 rsm_addr_t
, rsm_node_id_t
*);
97 static int __rsm_import_implicit_map(rsmseg_handle_t
*, int);
98 static int __rsm_intr_signal_wait_common(struct pollfd
[], minor_t
[],
101 static rsm_lib_funcs_t lib_functions
= {
102 RSM_LIB_FUNCS_VERSION
,
111 * service module function templates:
115 * The _rsm_librsm_init function is called the first time an application
116 * references the RSMAPI library
124 char logname
[MAXNAMELEN
];
126 mutex_init(&_rsm_lock
, USYNC_THREAD
, NULL
);
129 mutex_init(&rsmlog_lock
, USYNC_THREAD
, NULL
);
130 sprintf(logname
, "%s.%d", TRACELOG
, getpid());
131 rsmlog_fd
= fopen(logname
, "w+F");
132 if (rsmlog_fd
== NULL
) {
133 fprintf(stderr
, "Log file open failed\n");
139 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
140 "_rsm_librsm_init: enter\n"));
142 /* initialize the pollfd_table */
143 mutex_init(&pollfd_table
.lock
, USYNC_THREAD
, NULL
);
145 for (i
= 0; i
< RSM_MAX_BUCKETS
; i
++) {
146 pollfd_table
.buckets
[i
] = NULL
;
149 /* open /dev/rsm and mmap barrier generation pages */
150 mutex_lock(&_rsm_lock
);
151 _rsm_fd
= open(DEVRSM
, O_RDONLY
);
153 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
154 "unable to open /dev/rsm\n"));
155 mutex_unlock(&_rsm_lock
);
160 * DUP the opened file descriptor to something greater than
161 * STDERR_FILENO so that we never use the STDIN_FILENO,
162 * STDOUT_FILENO or STDERR_FILENO.
164 tmpfd
= fcntl(_rsm_fd
, F_DUPFD
, 3);
166 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
167 "F_DUPFD failed\n"));
169 (void) close(_rsm_fd
);
173 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
174 "_rsm_fd is %d\n", _rsm_fd
));
176 if (fcntl(_rsm_fd
, F_SETFD
, FD_CLOEXEC
) < 0) {
177 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
178 "F_SETFD failed\n"));
181 /* get mapping generation number page info */
182 if (ioctl(_rsm_fd
, RSM_IOCTL_BAR_INFO
, &msg
) < 0) {
183 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
184 "RSM_IOCTL_BAR_INFO failed\n"));
185 mutex_unlock(&_rsm_lock
);
190 * bar_va is mapped to the mapping generation number page
191 * in order to support close barrier
194 bar_va
= mmap(NULL
, msg
.len
,
195 PROT_READ
, MAP_SHARED
, _rsm_fd
, msg
.off
);
196 if (bar_va
== (rsm_gnum_t
*)MAP_FAILED
) {
198 mutex_unlock(&_rsm_lock
);
199 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
200 "unable to map barrier page\n"));
201 return (RSMERR_MAP_FAILED
);
204 mutex_unlock(&_rsm_lock
);
206 /* get local nodeid */
207 e
= rsm_get_interconnect_topology(&tp
);
208 if (e
!= RSM_SUCCESS
) {
209 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
210 "unable to obtain topology data\n"));
213 rsm_local_nodeid
= tp
->topology_hdr
.local_nodeid
;
215 rsm_free_interconnect_topology(tp
);
217 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
218 "_rsm_librsm_init: exit\n"));
220 return (RSM_SUCCESS
);
224 _rsm_loopbackload(caddr_t name
, int unit
, rsm_controller_t
**chdl
)
229 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
230 "_rsm_loopbackload: enter\n"));
232 * For now do this, but we should open some file and read the
233 * list of supported controllers and there numbers.
236 p
= (rsm_controller_t
*)malloc(sizeof (*p
) + strlen(name
) + 1);
238 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_ERR
,
239 "not enough memory\n"));
240 return (RSMERR_INSUFFICIENT_MEM
);
244 msg
.cname_len
= strlen(name
) +1;
246 msg
.arg
= (caddr_t
)&p
->cntr_attr
;
247 if (ioctl(_rsm_fd
, RSM_IOCTL_ATTR
, &msg
) < 0) {
250 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_ERR
,
251 "RSM_IOCTL_ATTR failed\n"));
255 __rsmloopback_init_ops(&loopback_ops
);
256 __rsmdefault_setops(&loopback_ops
);
257 p
->cntr_segops
= &loopback_ops
;
260 * Should add this entry into list
262 p
->cntr_fd
= _rsm_fd
;
263 p
->cntr_name
= strcpy((char *)(p
+1), name
);
268 mutex_init(&p
->cntr_lock
, USYNC_THREAD
, NULL
);
269 cond_init(&p
->cntr_cv
, USYNC_THREAD
, NULL
);
270 p
->cntr_rqlist
= NULL
;
271 p
->cntr_segops
->rsm_get_lib_attr(&p
->cntr_lib_attr
);
272 p
->cntr_next
= controller_list
;
277 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
278 "_rsm_loopbackload: exit\n"));
279 return (RSM_SUCCESS
);
284 _rsm_modload(caddr_t name
, int unit
, rsmapi_controller_handle_t
*controller
)
286 int error
= RSM_SUCCESS
;
287 char clib
[MAX_STRLEN
];
288 rsm_controller_t
*p
= NULL
;
290 rsm_attach_entry_t fptr
;
293 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
294 "_rsm_modload: enter\n"));
296 (void) sprintf(clib
, "%s.so", name
);
298 /* found entry, try to load library */
299 dlh
= dlopen(clib
, RTLD_LAZY
);
301 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
302 "unable to find plugin library\n"));
303 error
= RSMERR_CTLR_NOT_PRESENT
;
307 (void) sprintf(clib
, "%s_opendevice", name
);
309 fptr
= (rsm_attach_entry_t
)dlsym(dlh
, clib
); /* lint !e611 */
311 /* allocate new lib structure */
312 /* get ops handler, attr and ops */
313 p
= (rsm_controller_t
*)malloc(sizeof (*p
) + strlen(name
) + 1);
315 error
= fptr(unit
, &p
->cntr_segops
);
317 error
= RSMERR_INSUFFICIENT_MEM
;
318 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
319 "not enough memory\n"));
322 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
323 "can't find symbol %s\n", clib
));
324 error
= RSMERR_CTLR_NOT_PRESENT
;
329 if ((error
!= RSM_SUCCESS
) || (p
== NULL
)) {
332 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
333 "_rsm_modload error %d\n", error
));
337 /* check the version number */
338 if (p
->cntr_segops
->rsm_version
!= RSM_LIB_VERSION
) {
339 /* bad version number */
340 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
342 "found %d, expected %d\n",
343 p
->cntr_segops
->rsm_version
, RSM_LIB_VERSION
));
345 return (RSMERR_BAD_LIBRARY_VERSION
);
347 /* pass the fuctions to NDI library */
348 if ((p
->cntr_segops
->rsm_register_lib_funcs
== NULL
) ||
349 (p
->cntr_segops
->rsm_register_lib_funcs(
350 &lib_functions
) != RSM_SUCCESS
)) {
351 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
352 "RSMNDI library not registering lib functions\n"));
355 /* get controller attributes */
358 msg
.cname_len
= strlen(name
) +1;
359 msg
.arg
= (caddr_t
)&p
->cntr_attr
;
360 if (ioctl(_rsm_fd
, RSM_IOCTL_ATTR
, &msg
) < 0) {
363 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
364 "RSM_IOCTL_ATTR failed\n"));
368 /* set controller access functions */
369 __rsmdefault_setops(p
->cntr_segops
);
371 mutex_init(&p
->cntr_lock
, USYNC_THREAD
, NULL
);
372 cond_init(&p
->cntr_cv
, USYNC_THREAD
, NULL
);
373 p
->cntr_rqlist
= NULL
;
374 p
->cntr_segops
->rsm_get_lib_attr(&p
->cntr_lib_attr
);
375 /* insert into list of controllers */
376 p
->cntr_name
= strcpy((char *)(p
+1), name
);
377 p
->cntr_fd
= _rsm_fd
;
379 p
->cntr_refcnt
= 1; /* first reference */
380 p
->cntr_next
= controller_list
;
382 *controller
= (rsmapi_controller_handle_t
)p
;
386 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
387 "_rsm_modload: exit\n"));
392 * inserts a given segment handle into the pollfd table, this is called
393 * when rsm_memseg_get_pollfd() is called the first time on a segment handle.
394 * Returns RSM_SUCCESS if successful otherwise the error code is returned
397 _rsm_insert_pollfd_table(int segfd
, minor_t segrnum
)
401 rsm_pollfd_chunk_t
*chunk
;
403 hash
= RSM_POLLFD_HASH(segfd
);
405 mutex_lock(&pollfd_table
.lock
);
407 chunk
= pollfd_table
.buckets
[hash
];
409 if (chunk
->nfree
> 0)
414 if (!chunk
) { /* couldn't find a free chunk - allocate a new one */
415 chunk
= malloc(sizeof (rsm_pollfd_chunk_t
));
417 mutex_unlock(&pollfd_table
.lock
);
418 return (RSMERR_INSUFFICIENT_MEM
);
420 chunk
->nfree
= RSM_POLLFD_PER_CHUNK
- 1;
421 chunk
->fdarray
[0].fd
= segfd
;
422 chunk
->fdarray
[0].segrnum
= segrnum
;
423 for (i
= 1; i
< RSM_POLLFD_PER_CHUNK
; i
++) {
424 chunk
->fdarray
[i
].fd
= -1;
425 chunk
->fdarray
[i
].segrnum
= 0;
427 /* insert this into the hash table */
428 chunk
->next
= pollfd_table
.buckets
[hash
];
429 pollfd_table
.buckets
[hash
] = chunk
;
430 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
431 "rsm_insert_pollfd: new chunk(%p) @ %d for %d:%d\n",
432 chunk
, hash
, segfd
, segrnum
));
433 } else { /* a chunk with free slot was found */
434 for (i
= 0; i
< RSM_POLLFD_PER_CHUNK
; i
++) {
435 if (chunk
->fdarray
[i
].fd
== -1) {
436 chunk
->fdarray
[i
].fd
= segfd
;
437 chunk
->fdarray
[i
].segrnum
= segrnum
;
442 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
443 "rsm_insert_pollfd: inserted @ %d for %d:%d chunk(%p)\n",
444 hash
, segfd
, segrnum
, chunk
));
445 assert(i
< RSM_POLLFD_PER_CHUNK
);
448 mutex_unlock(&pollfd_table
.lock
);
449 return (RSM_SUCCESS
);
453 * Given a file descriptor returns the corresponding segment handles
454 * resource number, if the fd is not found returns 0. 0 is not a valid
455 * minor number for a rsmapi segment since it is used for the barrier
459 _rsm_lookup_pollfd_table(int segfd
)
462 rsm_pollfd_chunk_t
*chunk
;
467 mutex_lock(&pollfd_table
.lock
);
469 chunk
= pollfd_table
.buckets
[RSM_POLLFD_HASH(segfd
)];
471 assert(chunk
->nfree
< RSM_POLLFD_PER_CHUNK
);
473 for (i
= 0; i
< RSM_POLLFD_PER_CHUNK
; i
++) {
474 if (chunk
->fdarray
[i
].fd
== segfd
) {
475 mutex_unlock(&pollfd_table
.lock
);
476 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
477 "rsm_lookup_pollfd: found(%d) rnum(%d)\n",
478 segfd
, chunk
->fdarray
[i
].segrnum
));
479 return (chunk
->fdarray
[i
].segrnum
);
485 mutex_unlock(&pollfd_table
.lock
);
487 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
488 "rsm_lookup_pollfd: not found(%d)\n", segfd
));
494 * Remove the entry corresponding to the given file descriptor from the
498 _rsm_remove_pollfd_table(int segfd
)
502 rsm_pollfd_chunk_t
*chunk
;
503 rsm_pollfd_chunk_t
*prev_chunk
;
508 hash
= RSM_POLLFD_HASH(segfd
);
510 mutex_lock(&pollfd_table
.lock
);
512 prev_chunk
= chunk
= pollfd_table
.buckets
[hash
];
514 assert(chunk
->nfree
< RSM_POLLFD_PER_CHUNK
);
516 for (i
= 0; i
< RSM_POLLFD_PER_CHUNK
; i
++) {
517 if (chunk
->fdarray
[i
].fd
== segfd
) {
518 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
519 "rsm_remove_pollfd: %d:%d\n",
520 chunk
->fdarray
[i
].fd
,
521 chunk
->fdarray
[i
].segrnum
));
522 chunk
->fdarray
[i
].fd
= -1;
523 chunk
->fdarray
[i
].segrnum
= 0;
525 if (chunk
->nfree
== RSM_POLLFD_PER_CHUNK
) {
526 /* chunk is empty free it */
527 if (prev_chunk
== chunk
) {
528 pollfd_table
.buckets
[hash
] =
531 prev_chunk
->next
= chunk
->next
;
533 DBPRINTF((RSM_LIBRARY
,
535 "rsm_remove_pollfd:free(%p)\n",
538 mutex_unlock(&pollfd_table
.lock
);
547 mutex_unlock(&pollfd_table
.lock
);
551 rsm_get_controller(char *name
, rsmapi_controller_handle_t
*chdl
)
554 char cntr_name
[MAXNAMELEN
]; /* cntr_name=<cntr_type><unit> */
559 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
560 "rsm_get_controller: enter\n"));
562 * Lookup controller name and return ops vector and controller
567 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
568 "Invalid controller handle\n"));
569 return (RSMERR_BAD_CTLR_HNDL
);
572 /* use loopback if null */
573 cntr_type
= LOOPBACK
;
575 (void) strcpy(cntr_name
, name
);
576 /* scan from the end till a non-digit is found */
577 for (i
= strlen(cntr_name
) - 1; i
>= 0; i
--) {
578 if (! isdigit((int)cntr_name
[i
]))
582 unit
= atoi((char *)cntr_name
+i
);
583 cntr_name
[i
] = '\0'; /* null terminate the cntr_type part */
584 cntr_type
= (char *)cntr_name
;
585 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
586 "cntr_type=%s, instance=%d\n",
590 /* protect the controller_list by locking the device/library */
591 mutex_lock(&_rsm_lock
);
593 for (p
= controller_list
; p
; p
= p
->cntr_next
) {
594 if (!strcasecmp(p
->cntr_name
, cntr_type
) &&
595 !strcasecmp(cntr_type
, LOOPBACK
)) {
597 *chdl
= (rsmapi_controller_handle_t
)p
;
598 mutex_unlock(&_rsm_lock
);
599 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
600 "rsm_get_controller: exit\n"));
601 return (RSM_SUCCESS
);
602 } else if (!strcasecmp(p
->cntr_name
, cntr_type
) &&
603 (p
->cntr_unit
== unit
)) {
605 *chdl
= (rsmapi_controller_handle_t
)p
;
606 mutex_unlock(&_rsm_lock
);
607 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
608 "rsm_get_controller: exit\n"));
609 return (RSM_SUCCESS
);
614 if (!strcasecmp(cntr_type
, LOOPBACK
)) {
615 e
= _rsm_loopbackload(cntr_type
, unit
,
616 (rsm_controller_t
**)chdl
);
618 e
= _rsm_modload(cntr_type
, unit
, chdl
);
621 mutex_unlock(&_rsm_lock
);
623 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
624 " rsm_get_controller: exit\n"));
629 rsm_release_controller(rsmapi_controller_handle_t cntr_handle
)
632 rsm_controller_t
*chdl
= (rsm_controller_t
*)cntr_handle
;
633 rsm_controller_t
*curr
, *prev
;
635 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
636 "rsm_release_controller: enter\n"));
638 mutex_lock(&_rsm_lock
);
640 if (chdl
->cntr_refcnt
== 0) {
641 mutex_unlock(&_rsm_lock
);
642 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
643 "controller reference count is zero\n"));
644 return (RSMERR_BAD_CTLR_HNDL
);
649 if (chdl
->cntr_refcnt
> 0) {
650 mutex_unlock(&_rsm_lock
);
651 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
652 "rsm_release_controller: exit\n"));
653 return (RSM_SUCCESS
);
656 e
= chdl
->cntr_segops
->rsm_closedevice(cntr_handle
);
659 * remove the controller in any case from the controller list
662 prev
= curr
= controller_list
;
663 while (curr
!= NULL
) {
666 controller_list
= curr
->cntr_next
;
668 prev
->cntr_next
= curr
->cntr_next
;
674 curr
= curr
->cntr_next
;
676 mutex_unlock(&_rsm_lock
);
678 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
679 "rsm_release_controller: exit\n"));
685 rsm_get_controller_attr(rsmapi_controller_handle_t chandle
,
686 rsmapi_controller_attr_t
*attr
)
690 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
691 "rsm_get_controller_attr: enter\n"));
694 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
695 "invalid controller handle\n"));
696 return (RSMERR_BAD_CTLR_HNDL
);
700 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
701 "invalid attribute pointer\n"));
702 return (RSMERR_BAD_ADDR
);
705 p
= (rsm_controller_t
*)chandle
;
707 mutex_lock(&_rsm_lock
);
708 if (p
->cntr_refcnt
== 0) {
709 mutex_unlock(&_rsm_lock
);
710 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
711 "cntr refcnt is 0\n"));
712 return (RSMERR_CTLR_NOT_PRESENT
);
715 /* copy only the user part of the attr structure */
716 attr
->attr_direct_access_sizes
=
717 p
->cntr_attr
.attr_direct_access_sizes
;
718 attr
->attr_atomic_sizes
=
719 p
->cntr_attr
.attr_atomic_sizes
;
720 attr
->attr_page_size
=
721 p
->cntr_attr
.attr_page_size
;
722 attr
->attr_max_export_segment_size
=
723 p
->cntr_attr
.attr_max_export_segment_size
;
724 attr
->attr_tot_export_segment_size
=
725 p
->cntr_attr
.attr_tot_export_segment_size
;
726 attr
->attr_max_export_segments
=
727 p
->cntr_attr
.attr_max_export_segments
;
728 attr
->attr_max_import_map_size
=
729 p
->cntr_attr
.attr_max_import_map_size
;
730 attr
->attr_tot_import_map_size
=
731 p
->cntr_attr
.attr_tot_import_map_size
;
732 attr
->attr_max_import_segments
=
733 p
->cntr_attr
.attr_max_import_segments
;
735 mutex_unlock(&_rsm_lock
);
737 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
738 "rsm_get_controller_attr: exit\n"));
740 return (RSM_SUCCESS
);
746 * Create a segment handle for the virtual address range specified
750 rsm_memseg_export_create(rsmapi_controller_handle_t controller
,
751 rsm_memseg_export_handle_t
*memseg
,
757 rsm_controller_t
*chdl
= (rsm_controller_t
*)controller
;
765 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
766 "rsm_memseg_export_create: enter\n"));
769 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
770 "invalid controller handle\n"));
771 return (RSMERR_BAD_CTLR_HNDL
);
774 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
775 "invalid segment handle\n"));
776 return (RSMERR_BAD_SEG_HNDL
);
782 * Check vaddr and size alignment, both must be mmu page size
786 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
787 "invalid arguments\n"));
788 return (RSMERR_BAD_ADDR
);
792 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
793 "invalid arguments\n"));
794 return (RSMERR_BAD_LENGTH
);
797 if (((size_t)vaddr
& (PAGESIZE
- 1)) ||
798 (length
& (PAGESIZE
- 1))) {
799 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
800 "invalid mem alignment for vaddr or length\n"));
801 return (RSMERR_BAD_MEM_ALIGNMENT
);
805 * The following check does not apply for loopback controller
806 * since for the loopback adapter, the attr_max_export_segment_size
809 if (strcasecmp(chdl
->cntr_name
, LOOPBACK
)) {
810 if (length
> chdl
->cntr_attr
.attr_max_export_segment_size
) {
811 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
812 "length exceeds controller limits\n"));
813 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
814 "controller limits %d\n",
815 chdl
->cntr_attr
.attr_max_export_segment_size
));
816 return (RSMERR_BAD_LENGTH
);
820 p
= (rsmseg_handle_t
*)malloc(sizeof (*p
));
822 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
823 "not enough memory\n"));
824 return (RSMERR_INSUFFICIENT_MEM
);
827 p
->rsmseg_fd
= open(DEVRSM
, O_RDWR
);
828 if (p
->rsmseg_fd
< 0) {
829 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
830 "unable to open device /dev/rsm\n"));
832 return (RSMERR_INSUFFICIENT_RESOURCES
);
837 * libc can't handle fd's greater than 255, in order to
838 * insure that these values remain available make /dev/rsm
839 * fd > 255. Note: not needed for LP64
841 tmpfd
= fcntl(p
->rsmseg_fd
, F_DUPFD
, 256);
844 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
845 "F_DUPFD failed\n"));
847 (void) close(p
->rsmseg_fd
);
848 p
->rsmseg_fd
= tmpfd
;
852 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
, ""
853 "rsmseg_fd is %d\n", p
->rsmseg_fd
));
855 if (fcntl(p
->rsmseg_fd
, F_SETFD
, FD_CLOEXEC
) < 0) {
856 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
857 "F_SETFD failed\n"));
860 p
->rsmseg_state
= EXPORT_CREATE
;
861 p
->rsmseg_size
= length
;
862 /* increment controller handle */
863 p
->rsmseg_controller
= chdl
;
865 /* try to bind user address range */
866 msg
.cnum
= chdl
->cntr_unit
;
867 msg
.cname
= chdl
->cntr_name
;
868 msg
.cname_len
= strlen(chdl
->cntr_name
) +1;
876 if (ioctl(p
->rsmseg_fd
, e
, &msg
) < 0) {
878 (void) close(p
->rsmseg_fd
);
880 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
881 "RSM_IOCTL_BIND failed\n"));
885 p
->rsmseg_type
= RSM_EXPORT_SEG
;
886 p
->rsmseg_vaddr
= vaddr
;
887 p
->rsmseg_size
= length
;
888 p
->rsmseg_state
= EXPORT_BIND
;
889 p
->rsmseg_pollfd_refcnt
= 0;
890 p
->rsmseg_rnum
= msg
.rnum
;
892 mutex_init(&p
->rsmseg_lock
, USYNC_THREAD
, NULL
);
894 *memseg
= (rsm_memseg_export_handle_t
)p
;
896 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
897 "rsm_memseg_export_create: exit\n"));
899 return (RSM_SUCCESS
);
903 rsm_memseg_export_destroy(rsm_memseg_export_handle_t memseg
)
905 rsmseg_handle_t
*seg
;
907 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
908 "rsm_memseg_export_destroy: enter\n"));
911 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
912 "invalid segment handle\n"));
913 return (RSMERR_BAD_SEG_HNDL
);
916 seg
= (rsmseg_handle_t
*)memseg
;
918 mutex_lock(&seg
->rsmseg_lock
);
919 if (seg
->rsmseg_pollfd_refcnt
) {
920 mutex_unlock(&seg
->rsmseg_lock
);
921 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
922 "segment reference count not zero\n"));
923 return (RSMERR_POLLFD_IN_USE
);
926 seg
->rsmseg_state
= EXPORT_BIND
;
928 mutex_unlock(&seg
->rsmseg_lock
);
930 (void) close(seg
->rsmseg_fd
);
931 mutex_destroy(&seg
->rsmseg_lock
);
934 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
935 "rsm_memseg_export_destroy: exit\n"));
937 return (RSM_SUCCESS
);
941 rsm_memseg_export_rebind(rsm_memseg_export_handle_t memseg
, void *vaddr
,
942 offset_t off
, size_t length
)
945 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)memseg
;
947 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
948 "rsm_memseg_export_rebind: enter\n"));
953 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
954 "invalid segment handle\n"));
955 return (RSMERR_BAD_SEG_HNDL
);
958 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
960 return (RSMERR_BAD_ADDR
);
964 * Same as bind except it's ok to have elimint in list.
965 * Call into driver to remove any existing mappings.
971 mutex_lock(&seg
->rsmseg_lock
);
972 if (ioctl(seg
->rsmseg_fd
, RSM_IOCTL_REBIND
, &msg
) < 0) {
973 mutex_unlock(&seg
->rsmseg_lock
);
974 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
975 "RSM_IOCTL_REBIND failed\n"));
979 mutex_unlock(&seg
->rsmseg_lock
);
981 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
982 "rsm_memseg_export_rebind: exit\n"));
984 return (RSM_SUCCESS
);
988 rsm_memseg_export_publish(rsm_memseg_export_handle_t memseg
,
989 rsm_memseg_id_t
*seg_id
,
990 rsmapi_access_entry_t access_list
[],
991 uint_t access_list_length
)
995 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)memseg
;
997 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
998 "rsm_memseg_export_publish: enter\n"));
1000 if (seg_id
== NULL
) {
1001 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1002 "invalid segment id\n"));
1003 return (RSMERR_BAD_SEGID
);
1007 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1008 "invalid segment handle\n"));
1009 return (RSMERR_BAD_SEG_HNDL
);
1012 if (access_list_length
> 0 && !access_list
) {
1013 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1014 "invalid access control list\n"));
1015 return (RSMERR_BAD_ACL
);
1018 mutex_lock(&seg
->rsmseg_lock
);
1019 if (seg
->rsmseg_state
!= EXPORT_BIND
) {
1020 mutex_unlock(&seg
->rsmseg_lock
);
1021 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1022 "invalid segment state\n"));
1023 return (RSMERR_SEG_ALREADY_PUBLISHED
);
1027 * seg id < RSM_DLPI_END and in the RSM_USER_APP_ID range
1028 * are reserved for internal use.
1030 if ((*seg_id
> 0) &&
1031 ((*seg_id
<= RSM_DLPI_ID_END
) ||
1032 BETWEEN (*seg_id
, RSM_USER_APP_ID_BASE
, RSM_USER_APP_ID_END
))) {
1033 mutex_unlock(&seg
->rsmseg_lock
);
1034 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1035 "invalid segment id\n"));
1036 return (RSMERR_RESERVED_SEGID
);
1040 msg
.acl
= access_list
;
1041 msg
.acl_len
= access_list_length
;
1043 if (ioctl(seg
->rsmseg_fd
, RSM_IOCTL_PUBLISH
, &msg
) < 0) {
1044 mutex_unlock(&seg
->rsmseg_lock
);
1045 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1046 "RSM_IOCTL_PUBLISH failed\n"));
1050 seg
->rsmseg_keyid
= msg
.key
;
1051 seg
->rsmseg_state
= EXPORT_PUBLISH
;
1052 mutex_unlock(&seg
->rsmseg_lock
);
1057 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
1058 "rsm_memseg_export_publish: exit\n"));
1060 return (RSM_SUCCESS
);
1065 rsm_memseg_export_unpublish(rsm_memseg_export_handle_t memseg
)
1068 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)memseg
;
1070 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
1071 "rsm_memseg_export_unpublish: enter\n"));
1074 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1075 "invalid arguments\n"));
1076 return (RSMERR_BAD_SEG_HNDL
);
1079 mutex_lock(&seg
->rsmseg_lock
);
1080 if (seg
->rsmseg_state
!= EXPORT_PUBLISH
) {
1081 mutex_unlock(&seg
->rsmseg_lock
);
1082 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1083 "segment not published %d\n",
1084 seg
->rsmseg_keyid
));
1085 return (RSMERR_SEG_NOT_PUBLISHED
);
1088 msg
.key
= seg
->rsmseg_keyid
;
1089 if (ioctl(seg
->rsmseg_fd
, RSM_IOCTL_UNPUBLISH
, &msg
) < 0) {
1090 mutex_unlock(&seg
->rsmseg_lock
);
1091 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1092 "RSM_IOCTL_UNPUBLISH failed\n"));
1096 seg
->rsmseg_state
= EXPORT_BIND
;
1097 mutex_unlock(&seg
->rsmseg_lock
);
1099 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
1100 "rsm_memseg_export_unpublish: exit\n"));
1102 return (RSM_SUCCESS
);
1107 rsm_memseg_export_republish(rsm_memseg_export_handle_t memseg
,
1108 rsmapi_access_entry_t access_list
[],
1109 uint_t access_list_length
)
1112 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)memseg
;
1114 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
1115 "rsm_memseg_export_republish: enter\n"));
1118 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1119 "invalid segment or segment state\n"));
1120 return (RSMERR_BAD_SEG_HNDL
);
1123 mutex_lock(&seg
->rsmseg_lock
);
1124 if (seg
->rsmseg_state
!= EXPORT_PUBLISH
) {
1125 mutex_unlock(&seg
->rsmseg_lock
);
1126 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1127 "segment not published\n"));
1128 return (RSMERR_SEG_NOT_PUBLISHED
);
1131 if (access_list_length
> 0 && !access_list
) {
1132 mutex_unlock(&seg
->rsmseg_lock
);
1133 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1134 "invalid access control list\n"));
1135 return (RSMERR_BAD_ACL
);
1138 msg
.key
= seg
->rsmseg_keyid
;
1139 msg
.acl
= access_list
;
1140 msg
.acl_len
= access_list_length
;
1142 if (ioctl(seg
->rsmseg_fd
, RSM_IOCTL_REPUBLISH
, &msg
) < 0) {
1143 mutex_unlock(&seg
->rsmseg_lock
);
1144 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1145 "RSM_IOCTL_REPUBLISH failed\n"));
1148 mutex_unlock(&seg
->rsmseg_lock
);
1150 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_DEBUG_VERBOSE
,
1151 "rsm_memseg_export_republish: exit\n"));
1153 return (RSM_SUCCESS
);
1158 * import side memory segment operations:
1161 rsm_memseg_import_connect(rsmapi_controller_handle_t controller
,
1162 rsm_node_id_t node_id
,
1163 rsm_memseg_id_t segment_id
,
1164 rsm_permission_t perm
,
1165 rsm_memseg_import_handle_t
*im_memseg
)
1169 rsm_controller_t
*cntr
= (rsm_controller_t
*)controller
;
1170 #ifndef _LP64 /* added for fd > 255 fix */
1175 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1176 "rsm_memseg_import_connect: enter\n"));
1179 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1180 "invalid controller handle\n"));
1181 return (RSMERR_BAD_CTLR_HNDL
);
1186 p
= (rsmseg_handle_t
*)malloc(sizeof (*p
));
1188 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1189 "not enough memory\n"));
1190 return (RSMERR_INSUFFICIENT_MEM
);
1193 if (perm
& ~RSM_PERM_RDWR
) {
1194 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1195 "invalid permissions\n"));
1196 return (RSMERR_PERM_DENIED
);
1200 * Get size, va from driver
1202 msg
.cnum
= cntr
->cntr_unit
;
1203 msg
.cname
= cntr
->cntr_name
;
1204 msg
.cname_len
= strlen(cntr
->cntr_name
) +1;
1205 msg
.nodeid
= node_id
;
1206 msg
.key
= segment_id
;
1209 p
->rsmseg_fd
= open(DEVRSM
, O_RDWR
);
1210 if (p
->rsmseg_fd
< 0) {
1211 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1212 "unable to open /dev/rsm"));
1214 return (RSMERR_INSUFFICIENT_RESOURCES
);
1219 * libc can't handle fd's greater than 255, in order to
1220 * insure that these values remain available make /dev/rsm
1221 * fd > 255. Note: not needed for LP64
1223 tmpfd
= fcntl(p
->rsmseg_fd
, F_DUPFD
, 256); /* make fd > 255 */
1226 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1227 "F_DUPFD failed\n"));
1229 (void) close(p
->rsmseg_fd
);
1230 p
->rsmseg_fd
= tmpfd
;
1234 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
1235 "rsmseg_fd is %d\n", p
->rsmseg_fd
));
1237 if (fcntl(p
->rsmseg_fd
, F_SETFD
, FD_CLOEXEC
) < 0) {
1238 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1239 "F_SETFD failed\n"));
1241 if (ioctl(p
->rsmseg_fd
, RSM_IOCTL_CONNECT
, &msg
) < 0) {
1243 (void) close(p
->rsmseg_fd
);
1245 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1246 "RSM_IOCTL_CONNECT failed\n"));
1253 p
->rsmseg_type
= RSM_IMPORT_SEG
;
1254 p
->rsmseg_state
= IMPORT_CONNECT
;
1255 p
->rsmseg_keyid
= segment_id
;
1256 p
->rsmseg_nodeid
= node_id
;
1257 p
->rsmseg_size
= msg
.len
;
1258 p
->rsmseg_perm
= perm
;
1259 p
->rsmseg_controller
= cntr
;
1260 p
->rsmseg_barrier
= NULL
;
1261 p
->rsmseg_barmode
= RSM_BARRIER_MODE_IMPLICIT
;
1262 p
->rsmseg_bar
= (bar_va
? bar_va
+ msg
.off
: &bar_fixed
);
1263 p
->rsmseg_gnum
= msg
.gnum
;
1264 p
->rsmseg_pollfd_refcnt
= 0;
1265 p
->rsmseg_maplen
= 0; /* initialized, set in import_map */
1266 p
->rsmseg_mapoffset
= 0;
1267 p
->rsmseg_flags
= 0;
1268 p
->rsmseg_rnum
= msg
.rnum
;
1269 mutex_init(&p
->rsmseg_lock
, USYNC_THREAD
, NULL
);
1271 p
->rsmseg_ops
= cntr
->cntr_segops
;
1274 * XXX: Based on permission and controller direct_access attribute
1275 * we fix the segment ops vector
1278 p
->rsmseg_vaddr
= 0; /* defer mapping till using maps or trys to rw */
1280 *im_memseg
= (rsm_memseg_import_handle_t
)p
;
1282 e
= p
->rsmseg_ops
->rsm_memseg_import_connect(controller
,
1283 node_id
, segment_id
, perm
, im_memseg
);
1285 if (e
!= RSM_SUCCESS
) {
1286 (void) close(p
->rsmseg_fd
);
1287 mutex_destroy(&p
->rsmseg_lock
);
1291 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1292 "rsm_memseg_import_connect: exit\n"));
1299 rsm_memseg_import_disconnect(rsm_memseg_import_handle_t im_memseg
)
1301 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1304 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1305 "rsm_memseg_import_disconnect: enter\n"));
1308 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1309 "invalid segment handle\n"));
1310 return (RSMERR_BAD_SEG_HNDL
);
1313 if (seg
->rsmseg_state
!= IMPORT_CONNECT
) {
1314 if (seg
->rsmseg_flags
& RSM_IMPLICIT_MAP
) {
1315 e
= rsm_memseg_import_unmap(im_memseg
);
1316 if (e
!= RSM_SUCCESS
) {
1317 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1318 "unmap failure\n"));
1322 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1324 return (RSMERR_SEG_STILL_MAPPED
);
1328 mutex_lock(&seg
->rsmseg_lock
);
1329 if (seg
->rsmseg_pollfd_refcnt
) {
1330 mutex_unlock(&seg
->rsmseg_lock
);
1331 DBPRINTF((RSM_LIBRARY
|RSM_EXPORT
, RSM_ERR
,
1332 "segment reference count not zero\n"));
1333 return (RSMERR_POLLFD_IN_USE
);
1335 mutex_unlock(&seg
->rsmseg_lock
);
1337 e
= seg
->rsmseg_ops
->rsm_memseg_import_disconnect(im_memseg
);
1339 if (e
== RSM_SUCCESS
) {
1340 (void) close(seg
->rsmseg_fd
);
1341 mutex_destroy(&seg
->rsmseg_lock
);
1345 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1346 "rsm_memseg_import_disconnect: exit\n"));
1352 * import side memory segment operations (read access functions):
1356 __rsm_import_verify_access(rsmseg_handle_t
*seg
,
1360 rsm_permission_t perm
,
1361 rsm_access_size_t das
)
1365 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1366 " __rsm_import_verify_access: enter\n"));
1369 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1370 "invalid segment handle\n"));
1371 return (RSMERR_BAD_SEG_HNDL
);
1374 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1375 "invalid data pointer\n"));
1376 return (RSMERR_BAD_ADDR
);
1380 * Check alignment of pointer
1382 if ((uintptr_t)datap
& (das
- 1)) {
1383 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1384 "invalid alignment of data pointer\n"));
1385 return (RSMERR_BAD_MEM_ALIGNMENT
);
1388 if (offset
& (das
- 1)) {
1389 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1390 "invalid offset\n"));
1391 return (RSMERR_BAD_MEM_ALIGNMENT
);
1394 /* make sure that the import seg is connected */
1395 if (seg
->rsmseg_state
!= IMPORT_CONNECT
&&
1396 seg
->rsmseg_state
!= IMPORT_MAP
) {
1397 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1398 "incorrect segment state\n"));
1399 return (RSMERR_BAD_SEG_HNDL
);
1402 /* do an implicit map if required */
1403 if (seg
->rsmseg_state
== IMPORT_CONNECT
) {
1404 error
= __rsm_import_implicit_map(seg
, RSM_IOTYPE_PUTGET
);
1405 if (error
!= RSM_SUCCESS
) {
1406 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1407 "implicit map failure\n"));
1412 if ((seg
->rsmseg_perm
& perm
) != perm
) {
1413 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1414 "invalid permissions\n"));
1415 return (RSMERR_PERM_DENIED
);
1418 if (seg
->rsmseg_state
== IMPORT_MAP
) {
1419 if ((offset
< seg
->rsmseg_mapoffset
) ||
1420 (offset
+ len
> seg
->rsmseg_mapoffset
+
1421 seg
->rsmseg_maplen
)) {
1422 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1423 "incorrect offset+length\n"));
1424 return (RSMERR_BAD_OFFSET
);
1426 } else { /* IMPORT_CONNECT */
1427 if ((len
+ offset
) > seg
->rsmseg_size
) {
1428 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1429 "incorrect offset+length\n"));
1430 return (RSMERR_BAD_LENGTH
);
1434 if ((seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) &&
1435 (seg
->rsmseg_barrier
== NULL
)) {
1436 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1437 "invalid barrier\n"));
1438 return (RSMERR_BARRIER_UNINITIALIZED
);
1441 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1442 " __rsm_import_verify_access: exit\n"));
1444 return (RSM_SUCCESS
);
1448 __rsm_import_implicit_map(rsmseg_handle_t
*seg
, int iotype
)
1451 int flag
= MAP_SHARED
;
1452 int prot
= PROT_READ
|PROT_WRITE
;
1453 int mapping_reqd
= 0;
1455 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1456 " __rsm_import_implicit_map: enter\n"));
1458 if (iotype
== RSM_IOTYPE_PUTGET
)
1459 mapping_reqd
= seg
->rsmseg_controller
->cntr_lib_attr
->
1460 rsm_putget_map_reqd
;
1461 else if (iotype
== RSM_IOTYPE_SCATGATH
)
1462 mapping_reqd
= seg
->rsmseg_controller
->cntr_lib_attr
->
1463 rsm_scatgath_map_reqd
;
1467 va
= mmap(NULL
, seg
->rsmseg_size
, prot
,
1468 flag
, seg
->rsmseg_fd
, 0);
1470 if (va
== MAP_FAILED
) {
1471 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1472 "implicit map failed\n"));
1473 if (errno
== ENOMEM
|| errno
== ENXIO
||
1475 return (RSMERR_BAD_LENGTH
);
1476 else if (errno
== ENODEV
)
1477 return (RSMERR_CONN_ABORTED
);
1478 else if (errno
== EAGAIN
)
1479 return (RSMERR_INSUFFICIENT_RESOURCES
);
1480 else if (errno
== ENOTSUP
)
1481 return (RSMERR_MAP_FAILED
);
1482 else if (errno
== EACCES
)
1483 return (RSMERR_BAD_PERMS
);
1485 return (RSMERR_MAP_FAILED
);
1487 seg
->rsmseg_vaddr
= va
;
1488 seg
->rsmseg_maplen
= seg
->rsmseg_size
;
1489 seg
->rsmseg_mapoffset
= 0;
1490 seg
->rsmseg_state
= IMPORT_MAP
;
1491 seg
->rsmseg_flags
|= RSM_IMPLICIT_MAP
;
1494 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1495 " __rsm_import_implicit_map: exit\n"));
1497 return (RSM_SUCCESS
);
1501 rsm_memseg_import_get8(rsm_memseg_import_handle_t im_memseg
,
1506 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1509 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1510 "rsm_memseg_import_get8: enter\n"));
1512 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)datap
, rep_cnt
,
1515 if (e
== RSM_SUCCESS
) {
1516 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
1517 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
1519 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1520 /* generation number snapshot */
1521 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
1524 e
= ops
->rsm_memseg_import_get8(im_memseg
, offset
, datap
,
1527 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1528 /* check the generation number for force disconnects */
1529 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
1530 return (RSMERR_CONN_ABORTED
);
1535 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1536 "rsm_memseg_import_get8: exit\n"));
1542 rsm_memseg_import_get16(rsm_memseg_import_handle_t im_memseg
,
1547 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1550 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1551 "rsm_memseg_import_get16: enter\n"));
1553 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)datap
, rep_cnt
*2,
1556 if (e
== RSM_SUCCESS
) {
1557 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
1558 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
1560 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1561 /* generation number snapshot */
1562 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
1565 e
= ops
->rsm_memseg_import_get16(im_memseg
, offset
, datap
,
1568 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1569 /* check the generation number for force disconnects */
1570 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
1571 return (RSMERR_CONN_ABORTED
);
1577 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1578 "rsm_memseg_import_get16: exit\n"));
1584 rsm_memseg_import_get32(rsm_memseg_import_handle_t im_memseg
,
1589 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1592 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1593 "rsm_memseg_import_get32: enter\n"));
1595 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)datap
, rep_cnt
*4,
1598 if (e
== RSM_SUCCESS
) {
1599 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
1600 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
1602 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1603 /* generation number snapshot */
1604 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
1607 e
= ops
->rsm_memseg_import_get32(im_memseg
, offset
, datap
,
1610 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1611 /* check the generation number for force disconnects */
1612 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
1613 return (RSMERR_CONN_ABORTED
);
1618 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1619 "rsm_memseg_import_get32: exit\n"));
1625 rsm_memseg_import_get64(rsm_memseg_import_handle_t im_memseg
,
1630 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1633 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1634 "rsm_memseg_import_get64: enter\n"));
1636 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)datap
, rep_cnt
*8,
1639 if (e
== RSM_SUCCESS
) {
1640 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
1641 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
1643 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1644 /* generation number snapshot */
1645 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
1648 e
= ops
->rsm_memseg_import_get64(im_memseg
, offset
, datap
,
1651 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1652 /* check the generation number for force disconnects */
1653 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
1654 return (RSMERR_CONN_ABORTED
);
1659 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1660 "rsm_memseg_import_get64: exit\n"));
1666 rsm_memseg_import_get(rsm_memseg_import_handle_t im_memseg
,
1671 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1674 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1675 "rsm_memseg_import_get: enter\n"));
1677 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)dst_addr
, length
,
1680 if (e
== RSM_SUCCESS
) {
1681 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
1682 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
1684 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1685 /* generation number snapshot */
1686 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
1689 e
= ops
->rsm_memseg_import_get(im_memseg
, offset
, dst_addr
,
1692 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1693 /* check the generation number for force disconnects */
1694 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
1695 return (RSMERR_CONN_ABORTED
);
1700 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1701 "rsm_memseg_import_get: exit\n"));
1708 rsm_memseg_import_getv(rsm_scat_gath_t
*sg_io
)
1710 rsm_controller_t
*cntrl
;
1711 rsmseg_handle_t
*seg
;
1712 uint_t save_sg_io_flags
;
1716 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1717 "rsm_memseg_import_getv: enter\n"));
1719 if (sg_io
== NULL
) {
1720 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1721 "invalid sg_io structure\n"));
1722 return (RSMERR_BAD_SGIO
);
1725 seg
= (rsmseg_handle_t
*)sg_io
->remote_handle
;
1727 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1728 "invalid remote segment handle in sg_io\n"));
1729 return (RSMERR_BAD_SEG_HNDL
);
1732 cntrl
= (rsm_controller_t
*)seg
->rsmseg_controller
;
1733 if (cntrl
== NULL
) {
1734 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1735 "invalid controller handle\n"));
1736 return (RSMERR_BAD_SEG_HNDL
);
1739 if ((sg_io
->io_request_count
> RSM_MAX_SGIOREQS
) ||
1740 (sg_io
->io_request_count
== 0)) {
1741 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1742 "io_request_count value incorrect\n"));
1743 return (RSMERR_BAD_SGIO
);
1746 if (seg
->rsmseg_state
== IMPORT_CONNECT
) {
1747 e
= __rsm_import_implicit_map(seg
, RSM_IOTYPE_SCATGATH
);
1748 if (e
!= RSM_SUCCESS
) {
1749 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
1750 "implicit map failure\n"));
1756 * Copy the flags field of the sg_io structure in a local
1758 * This is required since the flags field can be
1759 * changed by the plugin library routine to indicate that
1760 * the signal post was done.
1761 * This change in the flags field of the sg_io structure
1762 * should not be reflected to the user. Hence once the flags
1763 * field has been used for the purpose of determining whether
1764 * the plugin executed a signal post, it must be restored to
1765 * its original value which is stored in the local variable.
1767 save_sg_io_flags
= sg_io
->flags
;
1769 e
= cntrl
->cntr_segops
->rsm_memseg_import_getv(sg_io
);
1772 * At this point, if an implicit signal post was requested by
1773 * the user, there could be two possibilities that arise:
1774 * 1. the plugin routine has already executed the implicit
1775 * signal post either successfully or unsuccessfully
1776 * 2. the plugin does not have the capability of doing an
1777 * implicit signal post and hence the signal post needs
1779 * The above two cases can be idenfied by the flags
1780 * field within the sg_io structure as follows:
1781 * In case 1, the RSM_IMPLICIT_SIGPOST bit is reset to 0 by the
1782 * plugin, indicating that the signal post was done.
1783 * In case 2, the bit remains set to a 1 as originally given
1784 * by the user, and hence a signal post needs to be done here.
1786 if (sg_io
->flags
& RSM_IMPLICIT_SIGPOST
&&
1788 /* Do the implicit signal post */
1791 * The value of the second argument to this call
1792 * depends on the value of the sg_io->flags field.
1793 * If the RSM_SIGPOST_NO_ACCUMULATE flag has been
1794 * ored into the sg_io->flags field, this indicates
1795 * that the rsm_intr_signal_post is to be done with
1796 * the flags argument set to RSM_SIGPOST_NO_ACCUMULATE
1797 * Else, the flags argument is set to 0. These
1798 * semantics can be achieved simply by masking off
1799 * all other bits in the sg_io->flags field except the
1800 * RSM_SIGPOST_NO_ACCUMULATE bit and using the result
1801 * as the flags argument for the rsm_intr_signal_post.
1804 int sigpost_flags
= sg_io
->flags
& RSM_SIGPOST_NO_ACCUMULATE
;
1805 e
= rsm_intr_signal_post(seg
, sigpost_flags
);
1808 /* Restore the flags field within the users scatter gather structure */
1809 sg_io
->flags
= save_sg_io_flags
;
1811 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1812 "rsm_memseg_import_getv: exit\n"));
1819 * import side memory segment operations (write access functions):
1823 rsm_memseg_import_put8(rsm_memseg_import_handle_t im_memseg
,
1828 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1831 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1832 "rsm_memseg_import_put8: enter\n"));
1834 /* addr of data will always pass the alignment check, avoids */
1835 /* need for a special case in verify_access for PUTs */
1836 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)datap
, rep_cnt
,
1839 if (e
== RSM_SUCCESS
) {
1840 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
1841 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
1843 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1844 /* generation number snapshot */
1845 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
1848 e
= ops
->rsm_memseg_import_put8(im_memseg
, offset
, datap
,
1851 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1852 /* check the generation number for force disconnects */
1853 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
1854 return (RSMERR_CONN_ABORTED
);
1859 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1860 "rsm_memseg_import_put8: exit\n"));
1866 rsm_memseg_import_put16(rsm_memseg_import_handle_t im_memseg
,
1871 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1874 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1875 "rsm_memseg_import_put16: enter\n"));
1877 /* addr of data will always pass the alignment check, avoids */
1878 /* need for a special case in verify_access for PUTs */
1879 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)datap
, rep_cnt
*2,
1882 if (e
== RSM_SUCCESS
) {
1883 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
1884 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
1886 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1887 /* generation number snapshot */
1888 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
1891 e
= ops
->rsm_memseg_import_put16(im_memseg
, offset
, datap
,
1894 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1895 /* check the generation number for force disconnects */
1896 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
1897 return (RSMERR_CONN_ABORTED
);
1903 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1904 "rsm_memseg_import_put16: exit\n"));
1910 rsm_memseg_import_put32(rsm_memseg_import_handle_t im_memseg
,
1915 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1918 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1919 "rsm_memseg_import_put32: enter\n"));
1921 /* addr of data will always pass the alignment check, avoids */
1922 /* need for a special case in verify_access for PUTs */
1923 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)datap
, rep_cnt
*4,
1926 if (e
== RSM_SUCCESS
) {
1927 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
1928 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
1930 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1931 /* generation number snapshot */
1932 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
1935 e
= ops
->rsm_memseg_import_put32(im_memseg
, offset
, datap
,
1938 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1939 /* check the generation number for force disconnects */
1940 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
1941 return (RSMERR_CONN_ABORTED
);
1946 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1947 "rsm_memseg_import_put32: exit\n"));
1953 rsm_memseg_import_put64(rsm_memseg_import_handle_t im_memseg
,
1958 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
1961 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1962 "rsm_memseg_import_put64: enter\n"));
1964 /* addr of data will always pass the alignment check, avoids */
1965 /* need for a special case in verify_access for PUTs */
1966 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)datap
, rep_cnt
*8,
1969 if (e
== RSM_SUCCESS
) {
1970 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
1971 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
1973 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1974 /* generation number snapshot */
1975 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
1978 e
= ops
->rsm_memseg_import_put64(im_memseg
, offset
, datap
,
1981 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
1982 /* check the generation number for force disconnects */
1983 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
1984 return (RSMERR_CONN_ABORTED
);
1989 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
1990 "rsm_memseg_import_put64: exit\n"));
1996 rsm_memseg_import_put(rsm_memseg_import_handle_t im_memseg
,
2001 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
2004 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2005 "rsm_memseg_import_put: enter\n"));
2007 e
= __rsm_import_verify_access(seg
, offset
, (caddr_t
)src_addr
, length
,
2010 if (e
== RSM_SUCCESS
) {
2011 rsm_segops_t
*ops
= seg
->rsmseg_ops
;
2012 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)seg
->rsmseg_barrier
;
2014 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
2015 /* generation number snapshot */
2016 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
;
2019 e
= ops
->rsm_memseg_import_put(im_memseg
, offset
, src_addr
,
2022 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
2023 /* check the generation number for force disconnects */
2024 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
2025 return (RSMERR_CONN_ABORTED
);
2031 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2032 "rsm_memseg_import_put: exit\n"));
2038 rsm_memseg_import_putv(rsm_scat_gath_t
*sg_io
)
2040 rsm_controller_t
*cntrl
;
2041 rsmseg_handle_t
*seg
;
2042 uint_t save_sg_io_flags
;
2046 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2047 "rsm_memseg_import_putv: enter\n"));
2050 if (sg_io
== NULL
) {
2051 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2052 "invalid sg_io structure\n"));
2053 return (RSMERR_BAD_SGIO
);
2056 seg
= (rsmseg_handle_t
*)sg_io
->remote_handle
;
2058 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2059 "invalid remote segment handle in sg_io\n"));
2060 return (RSMERR_BAD_SEG_HNDL
);
2063 cntrl
= (rsm_controller_t
*)seg
->rsmseg_controller
;
2064 if (cntrl
== NULL
) {
2065 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2066 "invalid controller handle\n"));
2067 return (RSMERR_BAD_SEG_HNDL
);
2070 if ((sg_io
->io_request_count
> RSM_MAX_SGIOREQS
) ||
2071 (sg_io
->io_request_count
== 0)) {
2072 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2073 "io_request_count value incorrect\n"));
2074 return (RSMERR_BAD_SGIO
);
2077 /* do an implicit map if required */
2078 if (seg
->rsmseg_state
== IMPORT_CONNECT
) {
2079 e
= __rsm_import_implicit_map(seg
, RSM_IOTYPE_SCATGATH
);
2080 if (e
!= RSM_SUCCESS
) {
2081 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2082 "implicit map failed\n"));
2088 * Copy the flags field of the sg_io structure in a local
2090 * This is required since the flags field can be
2091 * changed by the plugin library routine to indicate that
2092 * the signal post was done.
2093 * This change in the flags field of the sg_io structure
2094 * should not be reflected to the user. Hence once the flags
2095 * field has been used for the purpose of determining whether
2096 * the plugin executed a signal post, it must be restored to
2097 * its original value which is stored in the local variable.
2099 save_sg_io_flags
= sg_io
->flags
;
2101 e
= cntrl
->cntr_segops
->rsm_memseg_import_putv(sg_io
);
2104 * At this point, if an implicit signal post was requested by
2105 * the user, there could be two possibilities that arise:
2106 * 1. the plugin routine has already executed the implicit
2107 * signal post either successfully or unsuccessfully
2108 * 2. the plugin does not have the capability of doing an
2109 * implicit signal post and hence the signal post needs
2111 * The above two cases can be idenfied by the flags
2112 * field within the sg_io structure as follows:
2113 * In case 1, the RSM_IMPLICIT_SIGPOST bit is reset to 0 by the
2114 * plugin, indicating that the signal post was done.
2115 * In case 2, the bit remains set to a 1 as originally given
2116 * by the user, and hence a signal post needs to be done here.
2118 if (sg_io
->flags
& RSM_IMPLICIT_SIGPOST
&&
2120 /* Do the implicit signal post */
2123 * The value of the second argument to this call
2124 * depends on the value of the sg_io->flags field.
2125 * If the RSM_SIGPOST_NO_ACCUMULATE flag has been
2126 * ored into the sg_io->flags field, this indicates
2127 * that the rsm_intr_signal_post is to be done with
2128 * the flags argument set to RSM_SIGPOST_NO_ACCUMULATE
2129 * Else, the flags argument is set to 0. These
2130 * semantics can be achieved simply by masking off
2131 * all other bits in the sg_io->flags field except the
2132 * RSM_SIGPOST_NO_ACCUMULATE bit and using the result
2133 * as the flags argument for the rsm_intr_signal_post.
2136 int sigpost_flags
= sg_io
->flags
& RSM_SIGPOST_NO_ACCUMULATE
;
2137 e
= rsm_intr_signal_post(seg
, sigpost_flags
);
2141 /* Restore the flags field within the users scatter gather structure */
2142 sg_io
->flags
= save_sg_io_flags
;
2144 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2145 "rsm_memseg_import_putv: exit\n"));
2152 * import side memory segment operations (mapping):
2155 rsm_memseg_import_map(rsm_memseg_import_handle_t im_memseg
,
2157 rsm_attribute_t attr
,
2158 rsm_permission_t perm
,
2162 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
2163 int flag
= MAP_SHARED
;
2167 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2168 "rsm_memseg_import_map: enter\n"));
2171 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2172 "invalid segment\n"));
2173 return (RSMERR_BAD_SEG_HNDL
);
2176 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2177 "invalid address\n"));
2178 return (RSMERR_BAD_ADDR
);
2182 * Only one map per segment handle!
2183 * XXX need to take a lock here
2185 mutex_lock(&seg
->rsmseg_lock
);
2187 if (seg
->rsmseg_state
== IMPORT_MAP
) {
2188 mutex_unlock(&seg
->rsmseg_lock
);
2189 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2190 "segment already mapped\n"));
2191 return (RSMERR_SEG_ALREADY_MAPPED
);
2194 /* Only import segments allowed to map */
2195 if (seg
->rsmseg_state
!= IMPORT_CONNECT
) {
2196 mutex_unlock(&seg
->rsmseg_lock
);
2197 return (RSMERR_BAD_SEG_HNDL
);
2200 /* check for permissions */
2201 if (perm
> RSM_PERM_RDWR
) {
2202 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2203 "bad permissions when mapping\n"));
2204 mutex_unlock(&seg
->rsmseg_lock
);
2205 return (RSMERR_BAD_PERMS
);
2209 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2210 "mapping with length 0\n"));
2211 mutex_unlock(&seg
->rsmseg_lock
);
2212 return (RSMERR_BAD_LENGTH
);
2215 if (offset
+ length
> seg
->rsmseg_size
) {
2216 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2217 "map length + offset exceed segment size\n"));
2218 mutex_unlock(&seg
->rsmseg_lock
);
2219 return (RSMERR_BAD_LENGTH
);
2222 if ((size_t)offset
& (PAGESIZE
- 1)) {
2223 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2224 "bad mem alignment\n"));
2225 return (RSMERR_BAD_MEM_ALIGNMENT
);
2228 if (attr
& RSM_MAP_FIXED
) {
2229 if ((uintptr_t)(*address
) & (PAGESIZE
- 1)) {
2230 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2231 "bad mem alignment\n"));
2232 return (RSMERR_BAD_MEM_ALIGNMENT
);
2238 if (perm
& RSM_PERM_READ
)
2240 if (perm
& RSM_PERM_WRITE
)
2243 va
= mmap(*address
, length
, prot
, flag
, seg
->rsmseg_fd
, offset
);
2244 if (va
== MAP_FAILED
) {
2246 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2247 "error %d during map\n", e
));
2249 mutex_unlock(&seg
->rsmseg_lock
);
2250 if (e
== ENXIO
|| e
== EOVERFLOW
||
2252 return (RSMERR_BAD_LENGTH
);
2253 else if (e
== ENODEV
)
2254 return (RSMERR_CONN_ABORTED
);
2255 else if (e
== EAGAIN
)
2256 return (RSMERR_INSUFFICIENT_RESOURCES
);
2257 else if (e
== ENOTSUP
)
2258 return (RSMERR_MAP_FAILED
);
2259 else if (e
== EACCES
)
2260 return (RSMERR_BAD_PERMS
);
2262 return (RSMERR_MAP_FAILED
);
2267 * Fix segment ops vector to handle direct access.
2270 * XXX: Set this only for full segment mapping. Keep a list
2271 * of mappings to use for access functions
2273 seg
->rsmseg_vaddr
= va
;
2274 seg
->rsmseg_maplen
= length
;
2275 seg
->rsmseg_mapoffset
= offset
;
2276 seg
->rsmseg_state
= IMPORT_MAP
;
2278 mutex_unlock(&seg
->rsmseg_lock
);
2280 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2281 "rsm_memseg_import_map: exit\n"));
2283 return (RSM_SUCCESS
);
2287 rsm_memseg_import_unmap(rsm_memseg_import_handle_t im_memseg
)
2290 * Until we fix the rsm driver to catch unload, we unload
2291 * the whole segment.
2294 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
2296 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2297 "rsm_memseg_import_unmap: enter\n"));
2300 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2301 "invalid segment or segment state\n"));
2302 return (RSMERR_BAD_SEG_HNDL
);
2305 mutex_lock(&seg
->rsmseg_lock
);
2306 if (seg
->rsmseg_state
!= IMPORT_MAP
) {
2307 mutex_unlock(&seg
->rsmseg_lock
);
2308 return (RSMERR_SEG_NOT_MAPPED
);
2311 seg
->rsmseg_mapoffset
= 0; /* reset the offset */
2312 seg
->rsmseg_state
= IMPORT_CONNECT
;
2313 seg
->rsmseg_flags
&= ~RSM_IMPLICIT_MAP
;
2314 (void) munmap(seg
->rsmseg_vaddr
, seg
->rsmseg_maplen
);
2316 mutex_unlock(&seg
->rsmseg_lock
);
2318 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2319 "rsm_memseg_import_unmap: exit\n"));
2321 return (RSM_SUCCESS
);
2326 * import side memory segment operations (barriers):
2329 rsm_memseg_import_init_barrier(rsm_memseg_import_handle_t im_memseg
,
2330 rsm_barrier_type_t type
,
2331 rsmapi_barrier_t
*barrier
)
2333 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
2334 rsmbar_handle_t
*bar
;
2336 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2337 "rsm_memseg_import_init_barrier: enter\n"));
2340 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2341 "invalid segment or barrier\n"));
2342 return (RSMERR_BAD_SEG_HNDL
);
2345 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2346 "invalid barrier pointer\n"));
2347 return (RSMERR_BAD_BARRIER_PTR
);
2350 bar
= (rsmbar_handle_t
*)barrier
;
2351 bar
->rsmbar_seg
= seg
;
2353 seg
->rsmseg_barrier
= barrier
; /* used in put/get fns */
2355 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2356 "rsm_memseg_import_init_barrier: exit\n"));
2358 return (seg
->rsmseg_ops
->rsm_memseg_import_init_barrier(im_memseg
,
2359 type
, (rsm_barrier_handle_t
)barrier
));
2363 rsm_memseg_import_open_barrier(rsmapi_barrier_t
*barrier
)
2365 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)barrier
;
2368 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2369 "rsm_memseg_import_open_barrier: enter\n"));
2372 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2373 "invalid barrier\n"));
2374 return (RSMERR_BAD_BARRIER_PTR
);
2376 if (!bar
->rsmbar_seg
) {
2377 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2378 "uninitialized barrier\n"));
2379 return (RSMERR_BARRIER_UNINITIALIZED
);
2382 /* generation number snapshot */
2383 bar
->rsmbar_gen
= bar
->rsmbar_seg
->rsmseg_gnum
; /* bar[0] */
2385 ops
= bar
->rsmbar_seg
->rsmseg_ops
;
2387 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2388 "rsm_memseg_import_open_barrier: exit\n"));
2390 return (ops
->rsm_memseg_import_open_barrier(
2391 (rsm_barrier_handle_t
)barrier
));
2395 rsm_memseg_import_order_barrier(rsmapi_barrier_t
*barrier
)
2397 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)barrier
;
2400 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2401 "rsm_memseg_import_order_barrier: enter\n"));
2404 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2405 "invalid barrier\n"));
2406 return (RSMERR_BAD_BARRIER_PTR
);
2408 if (!bar
->rsmbar_seg
) {
2409 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2410 "uninitialized barrier\n"));
2411 return (RSMERR_BARRIER_UNINITIALIZED
);
2414 ops
= bar
->rsmbar_seg
->rsmseg_ops
;
2416 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2417 "rsm_memseg_import_order_barrier: exit\n"));
2419 return (ops
->rsm_memseg_import_order_barrier(
2420 (rsm_barrier_handle_t
)barrier
));
2424 rsm_memseg_import_close_barrier(rsmapi_barrier_t
*barrier
)
2426 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)barrier
;
2429 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2430 "rsm_memseg_import_close_barrier: enter\n"));
2433 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2434 "invalid barrier\n"));
2435 return (RSMERR_BAD_BARRIER_PTR
);
2437 if (!bar
->rsmbar_seg
) {
2438 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2439 "uninitialized barrier\n"));
2440 return (RSMERR_BARRIER_UNINITIALIZED
);
2443 /* generation number snapshot */
2444 if (bar
->rsmbar_gen
!= bar
->rsmbar_seg
->rsmseg_bar
[0]) {
2445 return (RSMERR_CONN_ABORTED
);
2448 ops
= bar
->rsmbar_seg
->rsmseg_ops
;
2450 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2451 "rsm_memseg_import_close_barrier: exit\n"));
2453 return (ops
->rsm_memseg_import_close_barrier(
2454 (rsm_barrier_handle_t
)barrier
));
2458 rsm_memseg_import_destroy_barrier(rsmapi_barrier_t
*barrier
)
2460 rsmbar_handle_t
*bar
= (rsmbar_handle_t
*)barrier
;
2463 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2464 "rsm_memseg_import_destroy_barrier: enter\n"));
2467 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2468 "invalid barrier\n"));
2469 return (RSMERR_BAD_BARRIER_PTR
);
2471 if (!bar
->rsmbar_seg
) {
2472 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2473 "uninitialized barrier\n"));
2474 return (RSMERR_BARRIER_UNINITIALIZED
);
2477 bar
->rsmbar_seg
->rsmseg_barrier
= NULL
;
2479 ops
= bar
->rsmbar_seg
->rsmseg_ops
;
2481 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2482 "rsm_memseg_import_destroy_barrier: exit\n"));
2484 return (ops
->rsm_memseg_import_destroy_barrier
2485 ((rsm_barrier_handle_t
)barrier
));
2489 rsm_memseg_import_get_mode(rsm_memseg_import_handle_t im_memseg
,
2490 rsm_barrier_mode_t
*mode
)
2492 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
2494 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2495 "rsm_memseg_import_get_mode: enter\n"));
2498 *mode
= seg
->rsmseg_barmode
;
2499 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2500 "rsm_memseg_import_get_mode: exit\n"));
2502 return (seg
->rsmseg_ops
->rsm_memseg_import_get_mode(im_memseg
,
2506 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2507 "invalid arguments \n"));
2509 return (RSMERR_BAD_SEG_HNDL
);
2514 rsm_memseg_import_set_mode(rsm_memseg_import_handle_t im_memseg
,
2515 rsm_barrier_mode_t mode
)
2517 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
2519 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2520 "rsm_memseg_import_set_mode: enter\n"));
2522 if ((mode
== RSM_BARRIER_MODE_IMPLICIT
||
2523 mode
== RSM_BARRIER_MODE_EXPLICIT
)) {
2524 seg
->rsmseg_barmode
= mode
;
2525 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2526 "rsm_memseg_import_set_mode: exit\n"));
2528 return (seg
->rsmseg_ops
->rsm_memseg_import_set_mode(
2532 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_DEBUG_VERBOSE
,
2533 "bad barrier mode\n"));
2534 return (RSMERR_BAD_MODE
);
2538 DBPRINTF((RSM_LIBRARY
|RSM_IMPORT
, RSM_ERR
,
2539 "invalid arguments\n"));
2541 return (RSMERR_BAD_SEG_HNDL
);
2545 rsm_intr_signal_post(void *memseg
, uint_t flags
)
2548 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)memseg
;
2550 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2551 "rsm_intr_signal_post: enter\n"));
2556 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2557 "invalid segment handle\n"));
2558 return (RSMERR_BAD_SEG_HNDL
);
2561 if (ioctl(seg
->rsmseg_fd
, RSM_IOCTL_RING_BELL
, &msg
) < 0) {
2562 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2563 "RSM_IOCTL_RING_BELL failed\n"));
2567 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2568 "rsm_intr_signal_post: exit\n"));
2570 return (RSM_SUCCESS
);
2574 rsm_intr_signal_wait(void *memseg
, int timeout
)
2576 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)memseg
;
2580 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2581 "rsm_intr_signal_wait: enter\n"));
2584 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2585 "invalid segment\n"));
2586 return (RSMERR_BAD_SEG_HNDL
);
2589 fds
.fd
= seg
->rsmseg_fd
;
2590 fds
.events
= POLLRDNORM
;
2592 rnum
= seg
->rsmseg_rnum
;
2594 return (__rsm_intr_signal_wait_common(&fds
, &rnum
, 1, timeout
, NULL
));
2598 rsm_intr_signal_wait_pollfd(struct pollfd fds
[], nfds_t nfds
, int timeout
,
2601 return (__rsm_intr_signal_wait_common(fds
, NULL
, nfds
, timeout
,
2606 * This is the generic wait routine, it takes the following arguments
2608 * - rnums array corresponding to the pollfd if known, if this is
2609 * NULL then the fds are looked up from the pollfd_table.
2610 * - number of fds in pollfd array,
2612 * - pointer to a location where the number of fds with successful
2613 * events is returned.
2616 __rsm_intr_signal_wait_common(struct pollfd fds
[], minor_t rnums
[],
2617 nfds_t nfds
, int timeout
, int *numfdsp
)
2622 int fds_processed
= 0;
2624 rsm_poll_event_t event_arr
[RSM_MAX_POLLFDS
];
2625 rsm_poll_event_t
*event_list
= NULL
;
2626 rsm_poll_event_t
*events
;
2627 rsm_consume_event_msg_t msg
;
2629 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
, "wait_common enter\n"));
2635 numfd
= poll(fds
, nfds
, timeout
);
2638 case -1: /* poll returned error - map to RSMERR_... */
2639 DBPRINTF((RSM_LIBRARY
, RSM_ERR
, "signal wait pollfd err\n"));
2642 return (RSMERR_INSUFFICIENT_RESOURCES
);
2644 return (RSMERR_BAD_ADDR
);
2646 return (RSMERR_INTERRUPTED
);
2649 return (RSMERR_BAD_ARGS_ERRORS
);
2651 case 0: /* timedout - return from here */
2652 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2653 "signal wait timed out\n"));
2654 return (RSMERR_TIMEOUT
);
2659 if (numfd
<= RSM_MAX_POLLFDS
) {
2660 /* use the event array on the stack */
2661 events
= (rsm_poll_event_t
*)event_arr
;
2664 * actual number of fds corresponding to rsmapi segments might
2665 * be < numfd, don't want to scan the list to figure that out
2666 * lets just allocate on the heap
2668 event_list
= (rsm_poll_event_t
*)malloc(
2669 sizeof (rsm_poll_event_t
)*numfd
);
2672 * return with error even if poll might have succeeded
2673 * since the application can retry and the events will
2674 * still be available.
2676 return (RSMERR_INSUFFICIENT_MEM
);
2678 events
= event_list
;
2682 * process the fds for events and if it corresponds to an rsmapi
2683 * segment consume the event
2685 for (i
= 0; i
< nfds
; i
++) {
2686 if (fds
[i
].revents
== POLLRDNORM
) {
2688 * poll returned an event and if its POLLRDNORM, it
2689 * might correspond to an rsmapi segment
2691 if (rnums
) { /* resource num is passed in */
2693 } else { /* lookup pollfd table to get resource num */
2694 segrnum
= _rsm_lookup_pollfd_table(fds
[i
].fd
);
2697 events
[numsegs
].rnum
= segrnum
;
2698 events
[numsegs
].revent
= 0;
2699 events
[numsegs
].fdsidx
= i
; /* fdlist index */
2704 if ((fds
[i
].revents
) && (++fds_processed
== numfd
)) {
2706 * only "numfd" events have revents field set, once we
2707 * process that many break out of the loop
2713 if (numsegs
== 0) { /* No events for rsmapi segs in the fdlist */
2720 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2721 "wait_common exit: no rsmapi segs\n"));
2722 return (RSM_SUCCESS
);
2725 msg
.seglist
= (caddr_t
)events
;
2726 msg
.numents
= numsegs
;
2728 if (ioctl(_rsm_fd
, RSM_IOCTL_CONSUMEEVENT
, &msg
) < 0) {
2733 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_ERR
,
2734 "RSM_IOCTL_CONSUMEEVENT failed(%d)\n", error
));
2738 /* count the number of segs for which consumeevent was successful */
2741 for (i
= 0; i
< numsegs
; i
++) {
2742 if (events
[i
].revent
!= 0) {
2743 fds
[events
[i
].fdsidx
].revents
= POLLRDNORM
;
2745 } else { /* failed to consume event so set revents to 0 */
2746 fds
[events
[i
].fdsidx
].revents
= 0;
2758 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2759 "wait_common exit\n"));
2760 return (RSM_SUCCESS
);
2762 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2763 "wait_common exit\n"));
2764 return (RSMERR_TIMEOUT
);
2769 * This function provides the data (file descriptor and event) for
2770 * the specified pollfd struct. The pollfd struct may then be
2771 * subsequently used with the poll system call to wait for an event
2772 * signalled by rsm_intr_signal_post. The memory segment must be
2773 * currently published for a successful return with a valid pollfd.
2774 * A reference count for the descriptor is incremented.
2777 rsm_memseg_get_pollfd(void *memseg
,
2778 struct pollfd
*poll_fd
)
2781 int err
= RSM_SUCCESS
;
2782 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)memseg
;
2784 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2785 "rsm_memseg_get_pollfd: enter\n"));
2788 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2789 "invalid segment\n"));
2790 return (RSMERR_BAD_SEG_HNDL
);
2793 mutex_lock(&seg
->rsmseg_lock
);
2795 poll_fd
->fd
= seg
->rsmseg_fd
;
2796 poll_fd
->events
= POLLRDNORM
;
2797 seg
->rsmseg_pollfd_refcnt
++;
2798 if (seg
->rsmseg_pollfd_refcnt
== 1) {
2799 /* insert the segment into the pollfd table */
2800 err
= _rsm_insert_pollfd_table(seg
->rsmseg_fd
,
2804 mutex_unlock(&seg
->rsmseg_lock
);
2806 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2807 "rsm_memseg_get_pollfd: exit(%d)\n", err
));
2813 * This function decrements the segment pollfd reference count.
2814 * A segment unpublish or destroy operation will fail if the reference count is
2818 rsm_memseg_release_pollfd(void * memseg
)
2821 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)memseg
;
2823 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2824 "rsm_memseg_release_pollfd: enter\n"));
2827 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2828 "invalid segment handle\n"));
2829 return (RSMERR_BAD_SEG_HNDL
);
2832 mutex_lock(&seg
->rsmseg_lock
);
2834 if (seg
->rsmseg_pollfd_refcnt
) {
2835 seg
->rsmseg_pollfd_refcnt
--;
2836 if (seg
->rsmseg_pollfd_refcnt
== 0) {
2837 /* last reference removed - update the pollfd_table */
2838 _rsm_remove_pollfd_table(seg
->rsmseg_fd
);
2842 mutex_unlock(&seg
->rsmseg_lock
);
2844 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2845 "rsm_memseg_release_pollfd: exit\n"));
2847 return (RSM_SUCCESS
);
2851 * The interconnect topology data is obtained from the Kernel Agent
2852 * and stored in a memory buffer allocated by this function. A pointer
2853 * to the buffer is stored in the location specified by the caller in
2854 * the function argument. It is the callers responsibility to
2855 * call rsm_free_interconnect_topolgy() to free the allocated memory.
2858 rsm_get_interconnect_topology(rsm_topology_t
**topology_data
)
2860 uint32_t topology_data_size
;
2861 rsm_topology_t
*topology_ptr
;
2864 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2865 "rsm_get_interconnect_topology: enter\n"));
2867 if (topology_data
== NULL
)
2868 return (RSMERR_BAD_TOPOLOGY_PTR
);
2870 *topology_data
= NULL
;
2873 /* obtain the size of the topology data */
2874 if (ioctl(_rsm_fd
, RSM_IOCTL_TOPOLOGY_SIZE
, &topology_data_size
) < 0) {
2875 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2876 "RSM_IOCTL_TOPOLOGY_SIZE failed\n"));
2880 /* allocate double-word aligned memory to hold the topology data */
2881 topology_ptr
= (rsm_topology_t
*)memalign(8, topology_data_size
);
2882 if (topology_ptr
== NULL
) {
2883 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2884 "not enough memory\n"));
2885 return (RSMERR_INSUFFICIENT_MEM
);
2889 * Request the topology data.
2890 * Pass in the size to be used as a check in case
2891 * the data has grown since the size was obtained - if
2892 * it has, the errno value will be E2BIG.
2894 topology_ptr
->topology_hdr
.local_nodeid
=
2895 (rsm_node_id_t
)topology_data_size
;
2896 if (ioctl(_rsm_fd
, RSM_IOCTL_TOPOLOGY_DATA
, topology_ptr
) < 0) {
2898 free((void *)topology_ptr
);
2902 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2903 "RSM_IOCTL_TOPOLOGY_DATA failed\n"));
2907 *topology_data
= topology_ptr
;
2909 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2910 " rsm_get_interconnect_topology: exit\n"));
2912 return (RSM_SUCCESS
);
2917 rsm_free_interconnect_topology(rsm_topology_t
*topology_ptr
)
2920 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2921 "rsm_free_interconnect_topology: enter\n"));
2924 free((void *)topology_ptr
);
2927 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2928 "rsm_free_interconnect_topology: exit\n"));
2932 rsm_create_localmemory_handle(rsmapi_controller_handle_t cntrl_handle
,
2933 rsm_localmemory_handle_t
*local_hndl_p
,
2934 caddr_t local_vaddr
, size_t len
)
2937 rsm_controller_t
*cntrl
= (rsm_controller_t
*)cntrl_handle
;
2939 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2940 "rsm_create_localmemory_handle: enter\n"));
2942 if ((size_t)local_vaddr
& (PAGESIZE
- 1)) {
2943 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2944 "invalid arguments\n"));
2945 return (RSMERR_BAD_ADDR
);
2948 if (!cntrl_handle
) {
2949 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2950 "invalid controller handle\n"));
2951 return (RSMERR_BAD_CTLR_HNDL
);
2953 if (!local_hndl_p
) {
2954 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2955 "invalid local memory handle pointer\n"));
2956 return (RSMERR_BAD_LOCALMEM_HNDL
);
2959 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2960 "invalid length\n"));
2961 return (RSMERR_BAD_LENGTH
);
2964 e
= cntrl
->cntr_segops
->rsm_create_localmemory_handle(
2970 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2971 "rsm_create_localmemory_handle: exit\n"));
2977 rsm_free_localmemory_handle(rsmapi_controller_handle_t cntrl_handle
,
2978 rsm_localmemory_handle_t local_handle
)
2982 rsm_controller_t
*cntrl
= (rsm_controller_t
*)cntrl_handle
;
2984 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
2985 "rsm_free_localmemory_handle: enter\n"));
2988 if (!cntrl_handle
) {
2989 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2990 "invalid controller handle\n"));
2991 return (RSMERR_BAD_CTLR_HNDL
);
2994 if (!local_handle
) {
2995 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
2996 "invalid localmemory handle\n"));
2997 return (RSMERR_BAD_LOCALMEM_HNDL
);
3000 e
= cntrl
->cntr_segops
->rsm_free_localmemory_handle(local_handle
);
3002 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
3003 "rsm_free_localmemory_handle: exit\n"));
3009 rsm_get_segmentid_range(const char *appid
, rsm_memseg_id_t
*baseid
,
3012 char buf
[RSMFILE_BUFSIZE
];
3017 int err
= RSMERR_BAD_APPID
;
3020 if (appid
== NULL
|| baseid
== NULL
|| length
== NULL
)
3021 return (RSMERR_BAD_ADDR
);
3023 if ((fp
= fopen(RSMSEGIDFILE
, "rF")) == NULL
) {
3024 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
3025 "cannot open <%s>\n", RSMSEGIDFILE
));
3026 return (RSMERR_BAD_CONF
);
3029 while (s
= fgets(buf
, RSMFILE_BUFSIZE
, fp
)) {
3031 while (isspace(*s
)) /* skip the leading spaces */
3034 if (*s
== '#') { /* comment line - skip it */
3039 * parse the reserved segid file and
3040 * set the pointers appropriately.
3041 * fieldv[0] : keyword
3042 * fieldv[1] : application identifier
3043 * fieldv[2] : baseid
3044 * fieldv[3] : length
3046 while ((*s
!= '\n') && (*s
!= '\0') && (fieldc
< 4)) {
3048 while (isspace(*s
)) /* skip the leading spaces */
3051 fieldv
[fieldc
++] = s
;
3054 if (fieldv
[3][strlen(fieldv
[3])-1] == '\n')
3055 fieldv
[3][strlen(fieldv
[3])-1] = '\0';
3059 while (*s
&& !isspace(*s
))
3060 ++s
; /* move to the next white space */
3066 if (fieldc
< 4) { /* some fields are missing */
3067 err
= RSMERR_BAD_CONF
;
3071 if (strcasecmp(fieldv
[1], appid
) == 0) { /* found a match */
3072 if (strcasecmp(fieldv
[0], RSMSEG_RESERVED
) == 0) {
3074 *baseid
= strtol(fieldv
[2], (char **)NULL
, 16);
3076 err
= RSMERR_BAD_CONF
;
3081 *length
= (int)strtol(fieldv
[3],
3084 err
= RSMERR_BAD_CONF
;
3089 } else { /* error in format */
3090 err
= RSMERR_BAD_CONF
;
3099 return (RSM_SUCCESS
);
3105 _rsm_get_hwaddr(rsmapi_controller_handle_t handle
, rsm_node_id_t nodeid
,
3106 rsm_addr_t
*hwaddrp
)
3108 rsm_ioctlmsg_t msg
= {0};
3109 rsm_controller_t
*ctrlp
;
3111 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
3112 "_rsm_get_hwaddr: enter\n"));
3114 ctrlp
= (rsm_controller_t
*)handle
;
3116 if (ctrlp
== NULL
) {
3117 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
3118 "invalid controller handle\n"));
3119 return (RSMERR_BAD_CTLR_HNDL
);
3122 msg
.cname
= ctrlp
->cntr_name
;
3123 msg
.cname_len
= strlen(ctrlp
->cntr_name
) +1;
3124 msg
.cnum
= ctrlp
->cntr_unit
;
3125 msg
.nodeid
= nodeid
;
3127 if (ioctl(_rsm_fd
, RSM_IOCTL_MAP_TO_ADDR
, &msg
) < 0) {
3129 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
3130 "RSM_IOCTL_MAP_TO_ADDR failed\n"));
3134 *hwaddrp
= msg
.hwaddr
;
3136 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
3137 "_rsm_get_hwaddr: exit\n"));
3139 return (RSM_SUCCESS
);
3144 _rsm_get_nodeid(rsmapi_controller_handle_t handle
, rsm_addr_t hwaddr
,
3145 rsm_node_id_t
*nodeidp
)
3148 rsm_ioctlmsg_t msg
= {0};
3149 rsm_controller_t
*ctrlp
;
3151 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
3152 "_rsm_get_nodeid: enter\n"));
3154 ctrlp
= (rsm_controller_t
*)handle
;
3156 if (ctrlp
== NULL
) {
3157 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
3158 "invalid arguments\n"));
3159 return (RSMERR_BAD_CTLR_HNDL
);
3162 msg
.cname
= ctrlp
->cntr_name
;
3163 msg
.cname_len
= strlen(ctrlp
->cntr_name
) +1;
3164 msg
.cnum
= ctrlp
->cntr_unit
;
3165 msg
.hwaddr
= hwaddr
;
3167 if (ioctl(_rsm_fd
, RSM_IOCTL_MAP_TO_NODEID
, &msg
) < 0) {
3169 DBPRINTF((RSM_LIBRARY
, RSM_ERR
,
3170 "RSM_IOCTL_MAP_TO_NODEID failed\n"));
3174 *nodeidp
= msg
.nodeid
;
3176 DBPRINTF((RSM_LIBRARY
, RSM_DEBUG_VERBOSE
,
3177 "_rsm_get_nodeid: exit\n"));
3179 return (RSM_SUCCESS
);
3185 dbg_printf(int msg_category
, int msg_level
, char *fmt
, ...)
3187 if ((msg_category
& rsmlibdbg_category
) &&
3188 (msg_level
<= rsmlibdbg_level
)) {
3190 va_start(arg_list
, fmt
);
3191 mutex_lock(&rsmlog_lock
);
3192 fprintf(rsmlog_fd
, "Thread %d ", thr_self());
3193 vfprintf(rsmlog_fd
, fmt
, arg_list
);
3195 mutex_unlock(&rsmlog_lock
);