59aa93e1b6
This commit adds a access_flags argument to the mpool registration function. This flag indicates what kind of access is being requested: local write, remote read, remote write, and remote atomic. The values of the registration access flags in the btl are tied to the new flags in the mpool. All mpools have been updated to include the new argument but only the grdma and udreg mpools have been updated to make use of the access flags. In both mpools existing registrations are checked for sufficient access before being returned. If a registration does not contain sufficient access it is marked as invalid and a new registration is generated. Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
200 строки
6.0 KiB
C
200 строки
6.0 KiB
C
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
|
/*
|
|
* Copyright (c) 2014-2015 Los Alamos National Security, LLC. All rights
|
|
* reserved.
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
#include "btl_vader.h"
|
|
|
|
#if OPAL_BTL_VADER_HAVE_KNEM
|
|
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include "opal/util/show_help.h"
|
|
#include "opal/mca/mpool/grdma/mpool_grdma.h"
|
|
|
|
OBJ_CLASS_INSTANCE(mca_btl_vader_registration_handle_t, mca_mpool_base_registration_t, NULL, NULL);
|
|
|
|
static int mca_btl_vader_knem_reg (void *reg_data, void *base, size_t size,
|
|
mca_mpool_base_registration_t *reg)
|
|
{
|
|
mca_btl_vader_registration_handle_t *knem_reg = (mca_btl_vader_registration_handle_t *) reg;
|
|
struct knem_cmd_create_region knem_cr;
|
|
struct knem_cmd_param_iovec knem_iov;
|
|
|
|
knem_iov.base = (uintptr_t) base;
|
|
knem_iov.len = size;
|
|
|
|
knem_cr.iovec_array = (uintptr_t) &knem_iov;
|
|
knem_cr.iovec_nr = 1;
|
|
knem_cr.protection = 0;
|
|
|
|
if (reg->access_flags & (MCA_MPOOL_ACCESS_LOCAL_WRITE | MCA_MPOOL_ACCESS_REMOTE_WRITE)) {
|
|
knem_cr.protection |= PROT_WRITE;
|
|
}
|
|
|
|
if (reg->access_flags & MCA_MPOOL_ACCESS_REMOTE_READ) {
|
|
knem_cr.protection |= PROT_READ;
|
|
}
|
|
|
|
/* Vader will explicitly destroy this cookie */
|
|
knem_cr.flags = 0;
|
|
if (OPAL_UNLIKELY(ioctl(mca_btl_vader.knem_fd, KNEM_CMD_CREATE_REGION, &knem_cr) < 0)) {
|
|
return OPAL_ERROR;
|
|
}
|
|
|
|
knem_reg->btl_handle.cookie = knem_cr.cookie;
|
|
knem_reg->btl_handle.base_addr = (intptr_t) base;
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
static int mca_btl_vader_knem_dereg (void *reg_data, mca_mpool_base_registration_t *reg)
|
|
{
|
|
mca_btl_vader_registration_handle_t *knem_reg = (mca_btl_vader_registration_handle_t *) reg;
|
|
|
|
/* NTH: explicity ignore the return code. Don't care about this cookie anymore anyway. */
|
|
(void) ioctl(mca_btl_vader.knem_fd, KNEM_CMD_DESTROY_REGION, &knem_reg->btl_handle.cookie);
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
static mca_btl_base_registration_handle_t *
|
|
mca_btl_vader_register_mem_knem (struct mca_btl_base_module_t* btl,
|
|
struct mca_btl_base_endpoint_t *endpoint,
|
|
void *base, size_t size, uint32_t flags)
|
|
{
|
|
mca_btl_vader_registration_handle_t *reg = NULL;
|
|
int access_flags = flags & MCA_BTL_REG_FLAG_ACCESS_ANY;
|
|
int rc;
|
|
|
|
rc = btl->btl_mpool->mpool_register (btl->btl_mpool, base, size, 0, access_flags,
|
|
(mca_mpool_base_registration_t **) ®);
|
|
if (OPAL_UNLIKELY(OPAL_SUCCESS != rc)) {
|
|
return NULL;
|
|
}
|
|
|
|
return ®->btl_handle;
|
|
}
|
|
|
|
static int
|
|
mca_btl_vader_deregister_mem_knem (struct mca_btl_base_module_t *btl, struct mca_btl_base_registration_handle_t *handle)
|
|
{
|
|
mca_btl_vader_registration_handle_t *reg =
|
|
(mca_btl_vader_registration_handle_t *)((intptr_t) handle - offsetof (mca_btl_vader_registration_handle_t, btl_handle));
|
|
|
|
btl->btl_mpool->mpool_deregister (btl->btl_mpool, ®->base);
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
int mca_btl_vader_knem_init (void)
|
|
{
|
|
mca_mpool_base_resources_t mpool_resources = {
|
|
.pool_name = "vader", .reg_data = NULL,
|
|
.sizeof_reg = sizeof (mca_btl_vader_registration_handle_t),
|
|
.register_mem = mca_btl_vader_knem_reg,
|
|
.deregister_mem = mca_btl_vader_knem_dereg
|
|
};
|
|
struct knem_cmd_info knem_info;
|
|
int rc;
|
|
|
|
/* Open the knem device. Try to print a helpful message if we
|
|
fail to open it. */
|
|
mca_btl_vader.knem_fd = open("/dev/knem", O_RDWR);
|
|
if (mca_btl_vader.knem_fd < 0) {
|
|
if (EACCES == errno) {
|
|
struct stat sbuf;
|
|
if (0 != stat("/dev/knem", &sbuf)) {
|
|
sbuf.st_mode = 0;
|
|
}
|
|
opal_show_help("help-btl-vader.txt", "knem permission denied",
|
|
true, opal_process_info.nodename, sbuf.st_mode);
|
|
} else {
|
|
opal_show_help("help-btl-vader.txt", "knem fail open",
|
|
true, opal_process_info.nodename, errno,
|
|
strerror(errno));
|
|
}
|
|
|
|
return OPAL_ERR_NOT_AVAILABLE;
|
|
}
|
|
|
|
do {
|
|
/* Check that the ABI if kernel module running is the same
|
|
* as what we were compiled against. */
|
|
rc = ioctl(mca_btl_vader.knem_fd, KNEM_CMD_GET_INFO, &knem_info);
|
|
if (rc < 0) {
|
|
opal_show_help("help-btl-vader.txt", "knem get ABI fail",
|
|
true, opal_process_info.nodename, errno,
|
|
strerror(errno));
|
|
break;
|
|
}
|
|
|
|
if (KNEM_ABI_VERSION != knem_info.abi) {
|
|
opal_show_help("help-btl-vader.txt", "knem ABI mismatch",
|
|
true, opal_process_info.nodename, KNEM_ABI_VERSION,
|
|
knem_info.abi);
|
|
break;
|
|
}
|
|
|
|
if (!(mca_btl_vader_component.knem_dma_min && (knem_info.features & KNEM_FEATURE_DMA))) {
|
|
/* disable DMA */
|
|
mca_btl_vader_component.knem_dma_min = UINT_MAX;
|
|
}
|
|
|
|
/* TODO: add async support */
|
|
|
|
/* knem set up successfully */
|
|
mca_btl_vader.super.btl_get = mca_btl_vader_get_knem;
|
|
mca_btl_vader.super.btl_put = mca_btl_vader_put_knem;
|
|
|
|
/* knem requires registration */
|
|
mca_btl_vader.super.btl_register_mem = mca_btl_vader_register_mem_knem;
|
|
mca_btl_vader.super.btl_deregister_mem = mca_btl_vader_deregister_mem_knem;
|
|
mca_btl_vader.super.btl_registration_handle_size = sizeof (mca_btl_base_registration_handle_t);
|
|
|
|
mca_btl_vader.super.btl_mpool = mca_mpool_base_module_create ("grdma", NULL,
|
|
&mpool_resources);
|
|
if (NULL == mca_btl_vader.super.btl_mpool) {
|
|
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
}
|
|
|
|
return OPAL_SUCCESS;
|
|
} while (0);
|
|
|
|
mca_btl_vader_knem_fini ();
|
|
|
|
return OPAL_ERR_NOT_AVAILABLE;;
|
|
}
|
|
|
|
int mca_btl_vader_knem_fini (void)
|
|
{
|
|
if (-1 != mca_btl_vader.knem_fd) {
|
|
close (mca_btl_vader.knem_fd);
|
|
mca_btl_vader.knem_fd = -1;
|
|
}
|
|
|
|
if (mca_btl_vader.super.btl_mpool) {
|
|
(void) mca_mpool_base_module_destroy (mca_btl_vader.super.btl_mpool);
|
|
mca_btl_vader.super.btl_mpool = NULL;
|
|
}
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
int mca_btl_vader_knem_progress (void)
|
|
{
|
|
/* NTH: does nothing until async support is added */
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
#endif
|