1
1
openmpi/opal/mca/btl/vader/btl_vader_knem.c
Nathan Hjelm 59aa93e1b6 opal/mpool: add support for passing access flags to register
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>
2015-10-05 13:53:55 -06:00

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 **) &reg);
if (OPAL_UNLIKELY(OPAL_SUCCESS != rc)) {
return NULL;
}
return &reg->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, &reg->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