Exemplo n.º 1
0
void openib_network_unlock(int proc)
{
    void *src = l_state.local_lock_buf;
    void *dst = l_state.atomic_lock_buf[proc];

    assert(src && dst);

    int bytes = sizeof(long);
    // The source is the buffer from which the data is read
    struct _reg_entry_t *local_reg, *remote_reg;

    // Search for local key
    local_reg = reg_cache_find(l_state.rank, 
            src, sizeof(long));

    // Search for remote key
    remote_reg = reg_cache_find(proc, dst, 
            sizeof(long));

    // Ensure that the registration entries are valid
    assert(local_reg);
    assert(remote_reg);

    // Prepare a send decriptor and post
    do {
        prepare_and_post_send_desc(src, dst, proc, bytes,
                local_reg->lkey, remote_reg->rkey, 
                IBV_WR_ATOMIC_CMP_AND_SWP, OPENIB_UNLOCK);
        openib_waitall();
    } while (*(long *)(src) != l_state.rank + 1);
}
Exemplo n.º 2
0
int openib_get_nbi(void *src, void *dst, int bytes, int proc)
{
    void *dst_ptr;
    int local_reg_failure = 0;

    // Due to location consistency semantics, we need to call waitall here
    //openib_waitall();

    // The source is the buffer from which the data is read
    struct _reg_entry_t *local_reg, *remote_reg;

    // Search for local key
    local_reg = reg_cache_find(l_state.rank, dst, bytes);

    // Search for remote key
    remote_reg = reg_cache_find(proc, src, bytes);
    assert(remote_reg);

    if (!local_reg && l_state.armci_openib_use_dreg) {
        local_reg = openib_register_memory(dst, bytes);
    }

    // Ensure that the registration entries are valid
    if (local_reg) {
        dst_ptr = dst;
    }
    else {
        local_reg_failure = 1;
        assert(bytes <= l_state.get_buf_len);
        dst_ptr = l_state.get_buf;
        local_reg = reg_cache_find(l_state.rank, dst_ptr, bytes);
        assert(local_reg);
        openib_waitall();
    }

    assert(remote_reg);

    // Prepare a send decriptor and post
    prepare_and_post_send_desc(src, dst_ptr, proc, bytes,
            local_reg->lkey, remote_reg->rkey, IBV_WR_RDMA_READ, -1);

    if (local_reg_failure) {
        openib_waitall();
        memcpy(dst, dst_ptr, bytes);
    }

}
Exemplo n.º 3
0
int openib_put_nbi(void *src, void *dst, int bytes, int proc)
{
    void *src_ptr;
    int local_reg_failure = 0;

    struct _reg_entry_t *local_reg, *remote_reg;

    // Search for local key
    local_reg = reg_cache_find(l_state.rank, src, bytes);

    // Search for remote key
    remote_reg = reg_cache_find(proc, dst, bytes);

    if (!local_reg && l_state.armci_openib_use_dreg) {
        local_reg = openib_register_memory(src, bytes);
    }

    if (local_reg) {
        src_ptr = src;
    }
    else {
        local_reg_failure = 1;
        openib_waitall();
        src_ptr = l_state.put_buf;
        assert(bytes <= l_state.put_buf_len);
        memcpy(src_ptr, src, bytes);
        local_reg = reg_cache_find(l_state.rank, src_ptr, bytes);
        assert(local_reg);
    }
    // Ensure that the registration entries are valid
    assert(remote_reg);

    // Prepare a send decriptor and post
    prepare_and_post_send_desc(src_ptr, dst, proc, bytes,
            local_reg->lkey, remote_reg->rkey, IBV_WR_RDMA_WRITE, -1);

    if (local_reg_failure) {
        openib_waitall();
    }

}
Exemplo n.º 4
0
int openib_deregister_memory(void *buf)
{
    struct _reg_entry_t *reg = reg_cache_find(l_state.rank, buf, 0);
    assert(reg);

    if (ibv_dereg_mr(reg->mr)) {
        assert(0);
    }

    reg_cache_delete(l_state.rank, buf);
    return 0;
}
Exemplo n.º 5
0
/**
 * Removes the reg cache entry associated with the given rank and buffer.
 *
 * If this process owns the buffer, it will unregister the buffer, as well.
 *
 * @param[in] rank
 * @param[in] buf
 *
 * @pre 0 <= rank && rank < reg_nprocs
 * @pre NULL != buf
 * @pre reg_cache_init() was previously called
 * @pre NULL != reg_cache_find(rank, buf, 0)
 *
 * @return RR_SUCCESS on success
 *         RR_FAILURE otherwise
 */
reg_return_t
reg_cache_delete(int rank, void *buf)
{
    reg_return_t status = RR_FAILURE;
    reg_entry_t *runner = NULL;
    reg_entry_t *previous_runner = NULL;

    /* preconditions */
    assert(NULL != reg_cache);
    assert(0 <= rank && rank < reg_nprocs);
    assert(NULL != buf);
    assert(NULL != reg_cache_find(rank, buf, 0));

    /* this is more restrictive than reg_cache_find() in that we locate
     * exactlty the same region starting address */
    runner = reg_cache[rank];
    while (runner) {
        if (runner->buf == buf) {
            break;
        }
        previous_runner = runner;
        runner = runner->next;
    }
    /* we should have found an entry */
    if (NULL == runner) {
        assert(0);
        return RR_FAILURE;
    }

    /* pop the entry out of the linked list */
    if (previous_runner) {
        previous_runner->next = runner->next;
    }
    else {
        reg_cache[rank] = reg_cache[rank]->next;
    }

    status = reg_entry_destroy(rank, runner);

    return status;
}
Exemplo n.º 6
0
/**
 * Create a new registration entry based on the given members.
 *
 * @pre 0 <= rank && rank < reg_nprocs
 * @pre NULL != buf
 * @pre 0 <= len
 * @pre reg_cache_init() was previously called
 * @pre NULL == reg_cache_find(rank, buf, 0)
 * @pre NULL == reg_cache_find_intersection(rank, buf, 0)
 *
 * @return RR_SUCCESS on success
 */
reg_entry_t*
reg_cache_insert(int rank, void *buf, size_t len, dmapp_seg_desc_t mr)
{
    reg_entry_t *node = NULL;

    /* preconditions */
    assert(NULL != reg_cache);
    assert(0 <= rank && rank < reg_nprocs);
    assert(NULL != buf);
    assert(len >= 0);
    assert(NULL == reg_cache_find(rank, buf, len));
    assert(NULL == reg_cache_find_intersection(rank, buf, len));

    if (rank == l_state.rank) {
        dmapp_cache_insert(mr);
    }

    /* allocate the new entry */
    node = (reg_entry_t *)malloc(sizeof(reg_entry_t));
    assert(node);

    /* initialize the new entry */
    node->buf = buf;
    node->len = len;
    node->mr = mr;
    node->next = NULL;

    /* push new entry to tail of linked list */
    if (NULL == reg_cache[rank]) {
        reg_cache[rank] = node;
    }
    else {
        reg_entry_t *runner = reg_cache[rank];
        while (runner->next) {
            runner = runner->next;
        }
        runner->next = node;
    }

    return RR_SUCCESS;
}