rsmgen.c revision 1219:f89f56c2d9ac
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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23/* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28#pragma ident "%Z%%M% %I% %E% SMI" 29 30#include "c_synonyms.h" 31#include <stdio.h> 32#include <stdlib.h> 33#include <unistd.h> 34#include <string.h> 35#include <strings.h> 36#include <sys/types.h> 37#include <sys/stat.h> 38#include <sys/mman.h> 39#include <sys/uio.h> 40#include <sys/sysmacros.h> 41#include <unistd.h> 42#include <errno.h> 43#include <assert.h> 44#include <malloc.h> 45#include <fcntl.h> 46#include <dlfcn.h> 47#include <sched.h> 48 49#include <rsmapi.h> 50#include <sys/rsm/rsmndi.h> 51#include <rsmlib_in.h> 52#include <sys/rsm/rsm.h> 53 54/* lint -w2 */ 55 56extern rsm_node_id_t rsm_local_nodeid; 57extern int loopback_getv(rsm_scat_gath_t *); 58extern int loopback_putv(rsm_scat_gath_t *); 59 60static rsm_ndlib_attr_t _rsm_genlib_attr = { 61 B_TRUE, /* mapping needed for put/get */ 62 B_FALSE /* mapping needed for putv/getv */ 63}; 64 65static int 66__rsm_import_connect( 67 rsmapi_controller_handle_t controller, rsm_node_id_t node_id, 68 rsm_memseg_id_t segment_id, rsm_permission_t perm, 69 rsm_memseg_import_handle_t *im_memseg) { 70 71 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 72 "__rsm_import_connect: enter\n")); 73 74 controller = controller; 75 node_id = node_id; 76 segment_id = segment_id; 77 perm = perm; 78 im_memseg = im_memseg; 79 80 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 81 "__rsm_import_connect: exit\n")); 82 83 return (RSM_SUCCESS); 84} 85 86static int 87__rsm_import_disconnect(rsm_memseg_import_handle_t im_memseg) { 88 89 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 90 "__rsm_import_disconnect: enter\n")); 91 92 im_memseg = im_memseg; 93 94 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 95 "__rsm_import_disconnect: exit\n")); 96 97 return (RSM_SUCCESS); 98} 99 100/* 101 * XXX: one day we ought to rewrite this stuff based on 64byte atomic access. 102 * We can have a new ops vector that makes that assumption. 103 */ 104 105static int 106__rsm_get8x8(rsm_memseg_import_handle_t im_memseg, off_t off, 107 uint8_t *datap, 108 ulong_t rep_cnt, 109 boolean_t swap) 110{ 111 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 112 uint8_t *data_addr = 113 (uint8_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; 114 uint_t i = 0; 115 int e; 116 117 swap = swap; 118 119 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 120 "__rsm_import_get8x8: enter\n")); 121 122 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 123 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 124 (rsm_barrier_handle_t)seg->rsmseg_barrier); 125 if (e != RSM_SUCCESS) { 126 return (e); 127 } 128 } 129 130 for (i = 0; i < rep_cnt; i++) { 131 datap[i] = data_addr[i]; 132 } 133 134 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 135 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 136 (rsm_barrier_handle_t)seg->rsmseg_barrier); 137 if (e != RSM_SUCCESS) { 138 return (e); 139 } 140 } 141 142 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 143 "__rsm_import_get8x8: exit\n")); 144 145 return (RSM_SUCCESS); 146} 147 148static int 149__rsm_get16x16(rsm_memseg_import_handle_t im_memseg, off_t off, 150 uint16_t *datap, 151 ulong_t rep_cnt, 152 boolean_t swap) 153{ 154 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 155 uint16_t *data_addr = 156 /* LINTED */ 157 (uint16_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; 158 uint_t i = 0; 159 int e; 160 161 swap = swap; 162 163 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 164 "__rsm_import_get16x16: enter\n")); 165 166 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 167 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 168 (rsm_barrier_handle_t)seg->rsmseg_barrier); 169 if (e != RSM_SUCCESS) { 170 return (e); 171 } 172 } 173 174 for (i = 0; i < rep_cnt; i++) { 175 datap[i] = data_addr[i]; 176 } 177 178 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 179 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 180 (rsm_barrier_handle_t)seg->rsmseg_barrier); 181 if (e != RSM_SUCCESS) { 182 return (e); 183 } 184 } 185 186 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 187 "__rsm_import_get16x16: exit\n")); 188 189 return (RSM_SUCCESS); 190} 191 192static int 193__rsm_get32x32(rsm_memseg_import_handle_t im_memseg, off_t off, 194 uint32_t *datap, 195 ulong_t rep_cnt, 196 boolean_t swap) 197{ 198 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 199 uint32_t *data_addr = 200 /* LINTED */ 201 (uint32_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; 202 uint_t i = 0; 203 int e; 204 205 swap = swap; 206 207 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 208 "__rsm_import_get32x32: enter\n")); 209 210 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 211 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 212 (rsm_barrier_handle_t)seg->rsmseg_barrier); 213 if (e != RSM_SUCCESS) { 214 return (e); 215 } 216 } 217 218 for (i = 0; i < rep_cnt; i++) { 219 datap[i] = data_addr[i]; 220 } 221 222 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 223 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 224 (rsm_barrier_handle_t)seg->rsmseg_barrier); 225 if (e != RSM_SUCCESS) { 226 return (e); 227 } 228 } 229 230 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 231 "__rsm_import_get32x32: exit\n")); 232 233 return (RSM_SUCCESS); 234} 235 236static int 237__rsm_get64x64(rsm_memseg_import_handle_t im_memseg, off_t off, 238 uint64_t *datap, 239 ulong_t rep_cnt, 240 boolean_t swap) 241{ 242 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 243 uint64_t *data_addr = 244 /* LINTED */ 245 (uint64_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; 246 uint_t i = 0; 247 int e; 248 249 swap = swap; 250 251 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 252 "__rsm_import_get64x64: enter\n")); 253 254 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 255 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 256 (rsm_barrier_handle_t)seg->rsmseg_barrier); 257 if (e != RSM_SUCCESS) { 258 return (e); 259 } 260 } 261 262 for (i = 0; i < rep_cnt; i++) { 263 datap[i] = data_addr[i]; 264 } 265 266 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 267 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 268 (rsm_barrier_handle_t)seg->rsmseg_barrier); 269 if (e != RSM_SUCCESS) { 270 return (e); 271 } 272 } 273 274 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 275 "__rsm_import_get64x64: exit\n")); 276 277 return (RSM_SUCCESS); 278} 279 280 /* 281 * import side memory segment operations (write access functions): 282 */ 283 284/* 285 * XXX: Each one of the following cases ought to be a separate function loaded 286 * into a segment access ops vector. We determine the correct function at 287 * segment connect time. When a new controller is register, we can decode 288 * it's direct_access_size attribute and load the correct function. For 289 * loop back we need to create a special ops vector that bypasses all of 290 * this stuff. 291 * 292 * XXX: We need to create a special interrupt queue for the library to handle 293 * partial writes in the remote process. 294 */ 295static int 296__rsm_put8x8(rsm_memseg_import_handle_t im_memseg, off_t off, 297 uint8_t *datap, 298 ulong_t rep_cnt, 299 boolean_t swap) 300{ 301 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 302 uint8_t *data_addr = 303 (uint8_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; 304 uint_t i = 0; 305 int e; 306 307 swap = swap; 308 309 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 310 "__rsm_put8x8: enter\n")); 311 312 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 313 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 314 (rsm_barrier_handle_t)seg->rsmseg_barrier); 315 if (e != RSM_SUCCESS) { 316 return (e); 317 } 318 } 319 320 for (i = 0; i < rep_cnt; i++) { 321 data_addr[i] = datap[i]; 322 } 323 324 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 325 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 326 (rsm_barrier_handle_t)seg->rsmseg_barrier); 327 if (e != RSM_SUCCESS) { 328 return (e); 329 } 330 } 331 332 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 333 "__rsm_put8x8: exit\n")); 334 335 return (RSM_SUCCESS); 336} 337 338static int 339__rsm_put16x16(rsm_memseg_import_handle_t im_memseg, off_t off, 340 uint16_t *datap, 341 ulong_t rep_cnt, 342 boolean_t swap) 343{ 344 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 345 uint16_t *data_addr = 346 /* LINTED */ 347 (uint16_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; 348 uint_t i = 0; 349 int e; 350 351 swap = swap; 352 353 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 354 "__rsm_put16x16: enter\n")); 355 356 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 357 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 358 (rsm_barrier_handle_t)seg->rsmseg_barrier); 359 if (e != RSM_SUCCESS) { 360 return (e); 361 } 362 } 363 364 for (i = 0; i < rep_cnt; i++) { 365 data_addr[i] = datap[i]; 366 } 367 368 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 369 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 370 (rsm_barrier_handle_t)seg->rsmseg_barrier); 371 if (e != RSM_SUCCESS) { 372 return (e); 373 } 374 } 375 376 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 377 "__rsm_put16x16: exit\n")); 378 379 return (RSM_SUCCESS); 380} 381 382static int 383__rsm_put32x32(rsm_memseg_import_handle_t im_memseg, off_t off, 384 uint32_t *datap, 385 ulong_t rep_cnt, 386 boolean_t swap) 387{ 388 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 389 uint32_t *data_addr = 390 /* LINTED */ 391 (uint32_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; 392 uint_t i = 0; 393 int e; 394 395 swap = swap; 396 397 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 398 "__rsm_put32x32: enter\n")); 399 400 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 401 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 402 (rsm_barrier_handle_t)seg->rsmseg_barrier); 403 if (e != RSM_SUCCESS) { 404 return (e); 405 } 406 } 407 408 for (i = 0; i < rep_cnt; i++) { 409 data_addr[i] = datap[i]; 410 } 411 412 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 413 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 414 (rsm_barrier_handle_t)seg->rsmseg_barrier); 415 if (e != RSM_SUCCESS) { 416 return (e); 417 } 418 } 419 420 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 421 "__rsm_put32x32: exit\n")); 422 423 return (RSM_SUCCESS); 424} 425 426static int 427__rsm_put64x64(rsm_memseg_import_handle_t im_memseg, off_t off, 428 uint64_t *datap, 429 ulong_t rep_cnt, 430 boolean_t swap) 431{ 432 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 433 uint64_t *data_addr = 434 /* LINTED */ 435 (uint64_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; 436 uint_t i = 0; 437 int e; 438 439 swap = swap; 440 441 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 442 "__rsm_put64x64: enter\n")); 443 444 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 445 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 446 (rsm_barrier_handle_t)seg->rsmseg_barrier); 447 if (e != RSM_SUCCESS) { 448 return (e); 449 } 450 } 451 452 for (i = 0; i < rep_cnt; i++) { 453 data_addr[i] = datap[i]; 454 } 455 456 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 457 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 458 (rsm_barrier_handle_t)seg->rsmseg_barrier); 459 if (e != RSM_SUCCESS) { 460 return (e); 461 } 462 } 463 464 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 465 "__rsm_put64x64: exit\n")); 466 467 return (RSM_SUCCESS); 468} 469 470static int 471__rsm_get(rsm_memseg_import_handle_t im_memseg, off_t offset, void *dst_addr, 472 size_t length) 473{ 474 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 475 int e; 476 477 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 478 "__rsm_get: enter\n")); 479 480 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 481 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 482 (rsm_barrier_handle_t)seg->rsmseg_barrier); 483 if (e != RSM_SUCCESS) { 484 return (e); 485 } 486 } 487 488 (void) bcopy(seg->rsmseg_vaddr + offset - seg->rsmseg_mapoffset, 489 dst_addr, length); 490 491 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 492 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 493 (rsm_barrier_handle_t)seg->rsmseg_barrier); 494 if (e != RSM_SUCCESS) { 495 return (e); 496 } 497 } 498 499 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 500 "__rsm_get: exit\n")); 501 502 return (RSM_SUCCESS); 503} 504 505static int 506__rsm_getv(rsm_scat_gath_t *sg_io) 507{ 508 rsm_iovec_t *iovec = sg_io->iovec; 509 rsmka_iovec_t ka_iovec_arr[RSM_MAX_IOVLEN]; 510 rsmka_iovec_t *ka_iovec, *ka_iovec_start; 511 rsmka_iovec_t l_iovec_arr[RSM_MAX_IOVLEN]; 512 rsmka_iovec_t *l_iovec, *l_iovec_start; 513 rsmseg_handle_t *im_seg_hndl = (rsmseg_handle_t *)sg_io->remote_handle; 514 rsmseg_handle_t *seg_hndl; 515 int iovec_size = sizeof (rsmka_iovec_t) * sg_io->io_request_count; 516 int e, i; 517 518 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 519 "__rsm_getv: enter\n")); 520 521 /* 522 * Use loopback for single node operations. 523 * replace local handles with virtual addresses 524 */ 525 526 if (im_seg_hndl->rsmseg_nodeid == rsm_local_nodeid) { 527 /* 528 * To use the loopback optimization map the segment 529 * here implicitly. 530 */ 531 if (im_seg_hndl->rsmseg_state == IMPORT_CONNECT) { 532 caddr_t va; 533 va = mmap(NULL, im_seg_hndl->rsmseg_size, 534 PROT_READ|PROT_WRITE, 535 MAP_SHARED|MAP_NORESERVE, 536 im_seg_hndl->rsmseg_fd, 0); 537 538 if (va == MAP_FAILED) { 539 DBPRINTF((RSM_LIBRARY, RSM_ERR, 540 "implicit map failed:%d\n", errno)); 541 if (errno == EINVAL) 542 return (RSMERR_BAD_MEM_ALIGNMENT); 543 else if (errno == ENOMEM || errno == ENXIO || 544 errno == EOVERFLOW) 545 return (RSMERR_BAD_LENGTH); 546 else if (errno == EAGAIN) 547 return (RSMERR_INSUFFICIENT_RESOURCES); 548 else 549 return (errno); 550 } 551 552 im_seg_hndl->rsmseg_vaddr = va; 553 im_seg_hndl->rsmseg_maplen = im_seg_hndl->rsmseg_size; 554 im_seg_hndl->rsmseg_mapoffset = 0; 555 im_seg_hndl->rsmseg_state = IMPORT_MAP; 556 im_seg_hndl->rsmseg_flags |= RSM_IMPLICIT_MAP; 557 } 558 559 if (sg_io->io_request_count > RSM_MAX_IOVLEN) 560 l_iovec_start = l_iovec = malloc(iovec_size); 561 else 562 l_iovec_start = l_iovec = l_iovec_arr; 563 564 bcopy((caddr_t)iovec, (caddr_t)l_iovec, iovec_size); 565 for (i = 0; i < sg_io->io_request_count; i++) { 566 if (l_iovec->io_type == RSM_HANDLE_TYPE) { 567 /* Get the surrogate export segment handle */ 568 seg_hndl = (rsmseg_handle_t *) 569 l_iovec->local.handle; 570 l_iovec->local.vaddr = seg_hndl->rsmseg_vaddr; 571 l_iovec->io_type = RSM_VA_TYPE; 572 } 573 l_iovec++; 574 } 575 sg_io->iovec = (rsm_iovec_t *)l_iovec_start; 576 e = loopback_getv(sg_io); 577 sg_io->iovec = iovec; 578 if (sg_io->io_request_count > RSM_MAX_IOVLEN) 579 free(l_iovec_start); 580 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 581 "__rsm_getv: exit\n")); 582 return (e); 583 } 584 585 /* for the Kernel Agent, replace local handles with segment ids */ 586 if (sg_io->io_request_count > RSM_MAX_IOVLEN) 587 ka_iovec_start = ka_iovec = malloc(iovec_size); 588 else 589 ka_iovec_start = ka_iovec = ka_iovec_arr; 590 591 bcopy((caddr_t)iovec, (caddr_t)ka_iovec, iovec_size); 592 for (i = 0; i < sg_io->io_request_count; i++) { 593 if (ka_iovec->io_type == RSM_HANDLE_TYPE) { 594 seg_hndl = (rsmseg_handle_t *)ka_iovec->local.handle; 595 ka_iovec->local.segid = seg_hndl->rsmseg_keyid; 596 } 597 ka_iovec++; 598 } 599 600 sg_io->iovec = (rsm_iovec_t *)ka_iovec_start; 601 e = ioctl(im_seg_hndl->rsmseg_fd, RSM_IOCTL_GETV, sg_io); 602 sg_io->iovec = iovec; 603 604 if (sg_io->io_request_count > RSM_MAX_IOVLEN) 605 free(ka_iovec_start); 606 607 if (e < 0) { 608 DBPRINTF((RSM_LIBRARY, RSM_ERR, 609 " RSM_IOCTL_GETV failed\n")); 610 return (errno); 611 } 612 613 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 614 "__rsm_getv: exit\n")); 615 616 return (RSM_SUCCESS); 617} 618 619 620static int 621__rsm_put(rsm_memseg_import_handle_t im_memseg, off_t offset, void *src_addr, 622 size_t length) 623{ 624 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 625 int e; 626 627 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 628 "__rsm_put: enter\n")); 629 630 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 631 e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( 632 (rsm_barrier_handle_t)seg->rsmseg_barrier); 633 if (e != RSM_SUCCESS) { 634 return (e); 635 } 636 } 637 638 bcopy(src_addr, seg->rsmseg_vaddr + offset - seg->rsmseg_mapoffset, 639 length); 640 641 if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 642 e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( 643 (rsm_barrier_handle_t)seg->rsmseg_barrier); 644 if (e != RSM_SUCCESS) { 645 return (e); 646 } 647 } 648 649 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 650 "__rsm_put: exit\n")); 651 652 return (RSM_SUCCESS); 653} 654 655static int 656__rsm_putv(rsm_scat_gath_t *sg_io) 657{ 658 rsm_iovec_t *iovec = sg_io->iovec; 659 rsmka_iovec_t ka_iovec_arr[RSM_MAX_IOVLEN]; 660 rsmka_iovec_t *ka_iovec, *ka_iovec_start; 661 rsmka_iovec_t l_iovec_arr[RSM_MAX_IOVLEN]; 662 rsmka_iovec_t *l_iovec, *l_iovec_start; 663 rsmseg_handle_t *im_seg_hndl = (rsmseg_handle_t *)sg_io->remote_handle; 664 rsmseg_handle_t *seg_hndl; 665 int iovec_size = sizeof (rsmka_iovec_t) * sg_io->io_request_count; 666 int e, i; 667 668 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 669 "__rsm_putv: enter\n")); 670 671 /* 672 * Use loopback for single node operations. 673 * replace local handles with virtual addresses 674 */ 675 676 if (im_seg_hndl->rsmseg_nodeid == rsm_local_nodeid) { 677 /* 678 * To use the loopback optimization map the segment 679 * here implicitly. 680 */ 681 if (im_seg_hndl->rsmseg_state == IMPORT_CONNECT) { 682 caddr_t va; 683 va = mmap(NULL, im_seg_hndl->rsmseg_size, 684 PROT_READ|PROT_WRITE, 685 MAP_SHARED|MAP_NORESERVE, 686 im_seg_hndl->rsmseg_fd, 0); 687 688 if (va == MAP_FAILED) { 689 DBPRINTF((RSM_LIBRARY, RSM_ERR, 690 "implicit map failed:%d\n", errno)); 691 if (errno == EINVAL) 692 return (RSMERR_BAD_MEM_ALIGNMENT); 693 else if (errno == ENOMEM || errno == ENXIO || 694 errno == EOVERFLOW) 695 return (RSMERR_BAD_LENGTH); 696 else if (errno == EAGAIN) 697 return (RSMERR_INSUFFICIENT_RESOURCES); 698 else 699 return (errno); 700 } 701 im_seg_hndl->rsmseg_vaddr = va; 702 im_seg_hndl->rsmseg_maplen = im_seg_hndl->rsmseg_size; 703 im_seg_hndl->rsmseg_mapoffset = 0; 704 im_seg_hndl->rsmseg_state = IMPORT_MAP; 705 im_seg_hndl->rsmseg_flags |= RSM_IMPLICIT_MAP; 706 } 707 708 if (sg_io->io_request_count > RSM_MAX_IOVLEN) 709 l_iovec_start = l_iovec = malloc(iovec_size); 710 else 711 l_iovec_start = l_iovec = l_iovec_arr; 712 713 bcopy((caddr_t)iovec, (caddr_t)l_iovec, iovec_size); 714 for (i = 0; i < sg_io->io_request_count; i++) { 715 if (l_iovec->io_type == RSM_HANDLE_TYPE) { 716 /* Get the surrogate export segment handle */ 717 seg_hndl = (rsmseg_handle_t *) 718 l_iovec->local.handle; 719 l_iovec->local.vaddr = seg_hndl->rsmseg_vaddr; 720 l_iovec->io_type = RSM_VA_TYPE; 721 } 722 l_iovec++; 723 } 724 sg_io->iovec = (rsm_iovec_t *)l_iovec_start; 725 e = loopback_putv(sg_io); 726 sg_io->iovec = iovec; 727 728 if (sg_io->io_request_count > RSM_MAX_IOVLEN) 729 free(l_iovec_start); 730 731 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 732 "__rsm_putv: exit\n")); 733 734 735 return (e); 736 } 737 738 /* for the Kernel Agent, replace local handles with segment ids */ 739 if (sg_io->io_request_count > RSM_MAX_IOVLEN) 740 ka_iovec_start = ka_iovec = malloc(iovec_size); 741 else 742 ka_iovec_start = ka_iovec = ka_iovec_arr; 743 744 bcopy((caddr_t)iovec, (caddr_t)ka_iovec, iovec_size); 745 746 for (i = 0; i < sg_io->io_request_count; i++) { 747 if (ka_iovec->io_type == RSM_HANDLE_TYPE) { 748 seg_hndl = (rsmseg_handle_t *)ka_iovec->local.handle; 749 ka_iovec->local.segid = seg_hndl->rsmseg_keyid; 750 } 751 ka_iovec++; 752 } 753 754 sg_io->iovec = (rsm_iovec_t *)ka_iovec_start; 755 e = ioctl(im_seg_hndl->rsmseg_fd, RSM_IOCTL_PUTV, sg_io); 756 sg_io->iovec = iovec; 757 758 if (sg_io->io_request_count > RSM_MAX_IOVLEN) 759 free(ka_iovec_start); 760 761 if (e < 0) { 762 DBPRINTF((RSM_LIBRARY, RSM_ERR, 763 " RSM_IOCTL_PUTV failed\n")); 764 return (errno); 765 } 766 767 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 768 "__rsm_putv: exit\n")); 769 770 return (RSM_SUCCESS); 771} 772 773 /* 774 * import side memory segment operations (barriers): 775 */ 776static int 777__rsm_memseg_import_init_barrier(rsm_memseg_import_handle_t im_memseg, 778 rsm_barrier_type_t type, 779 rsm_barrier_handle_t barrier) 780{ 781 rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 782 rsmgenbar_handle_t *bar = (rsmgenbar_handle_t *)barrier; 783 784 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 785 "" 786 "__rsm_memseg_import_init_barrier: enter\n")); 787 788 type = type; 789 790 if (!seg) { 791 DBPRINTF((RSM_LIBRARY, RSM_ERR, 792 "invalid segment handle\n")); 793 return (RSMERR_BAD_SEG_HNDL); 794 } 795 if (!bar) { 796 DBPRINTF((RSM_LIBRARY, RSM_ERR, 797 "invalid barrier handle\n")); 798 return (RSMERR_BAD_BARRIER_PTR); 799 } 800 801 /* XXX: fix later. We only support span-of-node barriers */ 802 803 bar->rsmgenbar_data = (rsm_barrier_t *)malloc(sizeof (rsm_barrier_t)); 804 if (bar->rsmgenbar_data == NULL) { 805 DBPRINTF((RSM_LIBRARY, RSM_ERR, 806 "not enough memory\n")); 807 return (RSMERR_INSUFFICIENT_MEM); 808 } 809 bar->rsmgenbar_seg = seg; 810 811 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 812 "__rsm_memseg_import_init_barrier: exit\n")); 813 814 return (RSM_SUCCESS); 815} 816 817static int 818__rsm_memseg_import_open_barrier(rsm_barrier_handle_t barrier) 819{ 820 rsmgenbar_handle_t *bar = (rsmgenbar_handle_t *)barrier; 821 rsmseg_handle_t *seg; 822 rsm_ioctlmsg_t msg; 823 824 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 825 "__rsm_memseg_import_open_barrier: enter\n")); 826 827 if (!bar) { 828 DBPRINTF((RSM_LIBRARY, RSM_ERR, 829 "invalid barrier pointer\n")); 830 return (RSMERR_BAD_BARRIER_PTR); 831 } 832 833 if ((seg = bar->rsmgenbar_seg) == 0) { 834 DBPRINTF((RSM_LIBRARY, RSM_ERR, 835 "uninitialized barrier\n")); 836 return (RSMERR_BARRIER_UNINITIALIZED); 837 } 838 839/* lint -save -e718 -e746 */ 840 msg.bar = *(bar->rsmgenbar_data); 841 if (ioctl(seg->rsmseg_fd, 842 RSM_IOCTL_BAR_OPEN, &msg) < 0) { 843 DBPRINTF((RSM_LIBRARY, RSM_ERR, 844 " RSM_IOCTL_BAR_OPEN failed\n")); 845/* lint -restore */ 846 return (RSMERR_BARRIER_OPEN_FAILED); 847 } 848 849 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 850 "__rsm_memseg_import_open_barrier: exit\n")); 851 852 return (RSM_SUCCESS); 853} 854 855static int 856__rsm_memseg_import_order_barrier(rsm_barrier_handle_t barrier) 857{ 858 rsmgenbar_handle_t *bar = (rsmgenbar_handle_t *)barrier; 859 rsmseg_handle_t *seg; 860 rsm_ioctlmsg_t msg; 861 862 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 863 "__rsm_memseg_import_order_barrier: enter\n")); 864 865 if (!bar) { 866 DBPRINTF((RSM_LIBRARY, RSM_ERR, 867 "invalid barrier\n")); 868 return (RSMERR_BAD_BARRIER_PTR); 869 } 870 if ((seg = bar->rsmgenbar_seg) == 0) { 871 DBPRINTF((RSM_LIBRARY, RSM_ERR, 872 "uninitialized barrier\n")); 873 return (RSMERR_BARRIER_UNINITIALIZED); 874 } 875 876 msg.bar = *(bar->rsmgenbar_data); 877 if (ioctl(seg->rsmseg_fd, RSM_IOCTL_BAR_ORDER, &msg) < 0) { 878 DBPRINTF((RSM_LIBRARY, RSM_ERR, 879 "RSM_IOCTL_BAR_ORDER failed\n")); 880 return (RSMERR_BARRIER_FAILURE); 881 } 882 883 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 884 "__rsm_memseg_import_order_barrier: exit\n")); 885 886 return (RSM_SUCCESS); 887} 888 889static int 890__rsm_memseg_import_close_barrier(rsm_barrier_handle_t barrier) 891{ 892 rsmgenbar_handle_t *bar = (rsmgenbar_handle_t *)barrier; 893 rsmseg_handle_t *seg; 894 rsm_ioctlmsg_t msg; 895 896 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 897 "__rsm_memseg_import_close_barrier: enter\n")); 898 899 if (!bar) { 900 DBPRINTF((RSM_LIBRARY, RSM_ERR, 901 "invalid barrier\n")); 902 return (RSMERR_BAD_BARRIER_PTR); 903 } 904 if ((seg = bar->rsmgenbar_seg) == 0) { 905 DBPRINTF((RSM_LIBRARY, RSM_ERR, 906 "uninitialized barrier\n")); 907 return (RSMERR_BARRIER_UNINITIALIZED); 908 } 909 910 msg.bar = *(bar->rsmgenbar_data); 911 if (ioctl(seg->rsmseg_fd, RSM_IOCTL_BAR_CLOSE, &msg) < 0) { 912 DBPRINTF((RSM_LIBRARY, RSM_ERR, 913 " RSM_IOCTL_BAR_CLOSE failed\n")); 914 return (RSMERR_BARRIER_FAILURE); 915 } 916 917 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 918 "__rsm_memseg_import_close_barrier: exit\n")); 919 920 return (RSM_SUCCESS); 921} 922 923static int 924__rsm_memseg_import_destroy_barrier(rsm_barrier_handle_t barrier) 925{ 926 rsmgenbar_handle_t *bar = (rsmgenbar_handle_t *)barrier; 927 928 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 929 "__rsm_memseg_import_destroy_barrier: enter\n")); 930 931 if (!bar) { 932 DBPRINTF((RSM_LIBRARY, RSM_ERR, 933 "invalid barrier\n")); 934 return (RSMERR_BAD_BARRIER_PTR); 935 } 936 937 free((void *) bar->rsmgenbar_data); 938 939 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 940 "__rsm_memseg_import_destroy_barrier: exit\n")); 941 942 return (RSM_SUCCESS); 943} 944 945/* lint -w1 */ 946static int 947__rsm_memseg_import_get_mode(rsm_memseg_import_handle_t im_memseg, 948 rsm_barrier_mode_t *mode) 949{ 950 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 951 "__rsm_memseg_import_get_mode: enter\n")); 952 953 im_memseg = im_memseg; mode = mode; 954 955 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 956 "__rsm_memseg_import_get_mode: exit\n")); 957 958 return (RSM_SUCCESS); 959} 960static int 961__rsm_memseg_import_set_mode(rsm_memseg_import_handle_t im_memseg, 962 rsm_barrier_mode_t mode) 963{ 964 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 965 "__rsm_memseg_import_set_mode: enter\n")); 966 967 im_memseg = im_memseg; mode = mode; 968 969 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 970 "__rsm_memseg_import_set_mode: exit\n")); 971 972 return (RSM_SUCCESS); 973} 974 975static int 976__rsm_create_memory_handle(rsmapi_controller_handle_t controller, 977 rsm_localmemory_handle_t *local_hndl_p, 978 caddr_t local_va, size_t len) 979{ 980 rsm_memseg_export_handle_t memseg; 981 rsmapi_access_entry_t acl[1]; 982 rsm_memseg_id_t segid = 0; 983 size_t size; 984 int e; 985 986 987 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 988 "__rsm_create_memory_handle: enter\n")); 989 990 /* 991 * create a surrogate segment (local memory will be locked down). 992 */ 993 size = roundup(len, PAGESIZE); 994 e = rsm_memseg_export_create(controller, &memseg, 995 (void *)local_va, size, 996 RSM_ALLOW_REBIND); 997 if (e != RSM_SUCCESS) { 998 DBPRINTF((RSM_LIBRARY, RSM_ERR, 999 "export create failed\n")); 1000 return (e); 1001 } 1002 1003 /* 1004 * Publish the segment to the local node only. If the segment 1005 * length is very large then don't publish to the adapter driver 1006 * because that will consume too much DVMA space - this is indicated 1007 * to the Kernel Agent using null permissions. DVMA binding will 1008 * be done when the RDMA is set up. 1009 */ 1010 acl[0].ae_node = rsm_local_nodeid; 1011 if (len > RSM_MAX_HANDLE_DVMA) 1012 acl[0].ae_permission = 0; 1013 else 1014 acl[0].ae_permission = RSM_PERM_RDWR; 1015 1016 e = rsm_memseg_export_publish(memseg, &segid, acl, 1); 1017 if (e != RSM_SUCCESS) { 1018 DBPRINTF((RSM_LIBRARY, RSM_ERR, 1019 "export publish failed\n")); 1020 rsm_memseg_export_destroy(memseg); 1021 return (e); 1022 } 1023 1024 /* Use the surrogate seghandle as the local memory handle */ 1025 *local_hndl_p = (rsm_localmemory_handle_t)memseg; 1026 1027 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1028 "__rsm_create_memory_handle: exit\n")); 1029 1030 return (e); 1031} 1032 1033static int 1034__rsm_free_memory_handle(rsm_localmemory_handle_t local_handle) 1035{ 1036 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1037 "__rsm_free_memory_handle: enter\n")); 1038 1039 rsm_memseg_export_destroy((rsm_memseg_export_handle_t)local_handle); 1040 1041 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1042 "__rsm_free_memory_handle: exit\n")); 1043 1044 return (RSM_SUCCESS); 1045} 1046 1047static int 1048__rsm_get_lib_attr(rsm_ndlib_attr_t **libattrp) 1049{ 1050 1051 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1052 "__rsm_get_lib_attr: enter\n")); 1053 1054 *libattrp = &_rsm_genlib_attr; 1055 1056 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1057 "__rsm_get_lib_attr: exit\n")); 1058 1059 return (RSM_SUCCESS); 1060} 1061 1062static int 1063__rsm_closedevice(rsmapi_controller_handle_t cntr_handle) 1064{ 1065 1066 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1067 "__rsm_closedevice: enter\n")); 1068 1069 cntr_handle = cntr_handle; 1070 1071 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1072 "__rsm_closedevice: exit\n")); 1073 1074 return (RSM_SUCCESS); 1075} 1076 1077void 1078__rsmdefault_setops(rsm_segops_t *segops) 1079{ 1080 1081 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1082 "__rsmdefault_setops: enter\n")); 1083 1084 if (segops->rsm_memseg_import_connect == NULL) { 1085 segops->rsm_memseg_import_connect = __rsm_import_connect; 1086 } 1087 if (segops->rsm_memseg_import_disconnect == NULL) { 1088 segops->rsm_memseg_import_disconnect = __rsm_import_disconnect; 1089 } 1090 1091 if (segops->rsm_memseg_import_get8 == NULL) { 1092 segops->rsm_memseg_import_get8 = __rsm_get8x8; 1093 } 1094 if (segops->rsm_memseg_import_get16 == NULL) { 1095 segops->rsm_memseg_import_get16 = __rsm_get16x16; 1096 } 1097 if (segops->rsm_memseg_import_get32 == NULL) { 1098 segops->rsm_memseg_import_get32 = __rsm_get32x32; 1099 } 1100 if (segops->rsm_memseg_import_get64 == NULL) { 1101 segops->rsm_memseg_import_get64 = __rsm_get64x64; 1102 } 1103 if (segops->rsm_memseg_import_get == NULL) { 1104 segops->rsm_memseg_import_get = __rsm_get; 1105 } 1106 1107 if (segops->rsm_memseg_import_put8 == NULL) { 1108 segops->rsm_memseg_import_put8 = __rsm_put8x8; 1109 } 1110 if (segops->rsm_memseg_import_put16 == NULL) { 1111 segops->rsm_memseg_import_put16 = __rsm_put16x16; 1112 } 1113 if (segops->rsm_memseg_import_put32 == NULL) { 1114 segops->rsm_memseg_import_put32 = __rsm_put32x32; 1115 } 1116 if (segops->rsm_memseg_import_put64 == NULL) { 1117 segops->rsm_memseg_import_put64 = __rsm_put64x64; 1118 } 1119 if (segops->rsm_memseg_import_put == NULL) { 1120 segops->rsm_memseg_import_put = __rsm_put; 1121 } 1122 1123 if (segops->rsm_memseg_import_putv == NULL) { 1124 segops->rsm_memseg_import_putv = __rsm_putv; 1125 } 1126 1127 if (segops->rsm_memseg_import_getv == NULL) { 1128 segops->rsm_memseg_import_getv = __rsm_getv; 1129 } 1130 1131 if (segops->rsm_create_localmemory_handle == NULL) { 1132 segops->rsm_create_localmemory_handle = 1133 __rsm_create_memory_handle; 1134 } 1135 1136 if (segops->rsm_free_localmemory_handle == NULL) { 1137 segops->rsm_free_localmemory_handle = 1138 __rsm_free_memory_handle; 1139 } 1140 1141 /* XXX: Need to support barrier functions */ 1142 if (segops->rsm_memseg_import_init_barrier == NULL) { 1143 segops->rsm_memseg_import_init_barrier = 1144 __rsm_memseg_import_init_barrier; 1145 } 1146 if (segops->rsm_memseg_import_open_barrier == NULL) { 1147 segops->rsm_memseg_import_open_barrier = 1148 __rsm_memseg_import_open_barrier; 1149 } 1150 if (segops->rsm_memseg_import_order_barrier == NULL) { 1151 segops->rsm_memseg_import_order_barrier = 1152 __rsm_memseg_import_order_barrier; 1153 } 1154 if (segops->rsm_memseg_import_close_barrier == NULL) { 1155 segops->rsm_memseg_import_close_barrier = 1156 __rsm_memseg_import_close_barrier; 1157 } 1158 if (segops->rsm_memseg_import_destroy_barrier == NULL) { 1159 segops->rsm_memseg_import_destroy_barrier = 1160 __rsm_memseg_import_destroy_barrier; 1161 } 1162 1163 if (segops->rsm_memseg_import_get_mode == NULL) { 1164 segops->rsm_memseg_import_get_mode = 1165 __rsm_memseg_import_get_mode; 1166 } 1167 if (segops->rsm_memseg_import_set_mode == NULL) { 1168 segops->rsm_memseg_import_set_mode = 1169 __rsm_memseg_import_set_mode; 1170 } 1171 1172 if (segops->rsm_get_lib_attr == NULL) { 1173 segops->rsm_get_lib_attr = 1174 __rsm_get_lib_attr; 1175 } 1176 1177 if (segops->rsm_closedevice == NULL) { 1178 segops->rsm_closedevice = 1179 __rsm_closedevice; 1180 } 1181 1182 1183 DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1184 "__rsmdefault_setops: exit\n")); 1185 1186} 1187