Logo Search packages:      
Sourcecode: dapl version File versions  Download package

dapl_ib_extensions.c

/*
 * Copyright (c) 2007 Intel Corporation.  All rights reserved.
 *
 * This Software is licensed under one of the following licenses:
 *
 * 1) under the terms of the "Common Public License 1.0" a copy of which is
 *    available from the Open Source Initiative, see
 *    http://www.opensource.org/licenses/cpl.php.
 *
 * 2) under the terms of the "The BSD License" a copy of which is
 *    available from the Open Source Initiative, see
 *    http://www.opensource.org/licenses/bsd-license.php.
 *
 * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
 *    copy of which is available from the Open Source Initiative, see
 *    http://www.opensource.org/licenses/gpl-license.php.
 *
 * Licensee has the right to choose one of the above licenses.
 *
 * Redistributions of source code must retain the above copyright
 * notice and one of the license notices.
 *
 * Redistributions in binary form must reproduce both the above copyright
 * notice, one of the license notices in the documentation
 * and/or other materials provided with the distribution.
 */

/**********************************************************************
 * 
 * MODULE: dapl_ib_extensions.c
 *
 * PURPOSE:  Extensions routines for OpenIB uCMA provider
 *
 * $Id: $
 *
 **********************************************************************/

#include "dapl.h"
#include "dapl_adapter_util.h"
#include "dapl_evd_util.h"
#include "dapl_ib_util.h"
#include "dapl_ep_util.h"
#include "dapl_cookie.h"
#include <stdarg.h>

DAT_RETURN
dapli_post_ext(IN DAT_EP_HANDLE ep_handle,
             IN DAT_UINT64 cmp_add,
             IN DAT_UINT64 swap,
             IN DAT_UINT32 immed_data,
             IN DAT_COUNT segments,
             IN DAT_LMR_TRIPLET * local_iov,
             IN DAT_DTO_COOKIE user_cookie,
             IN const DAT_RMR_TRIPLET * remote_iov,
             IN int op_type, IN DAT_COMPLETION_FLAGS flags);

/*
 * dapl_extensions
 *
 * Process extension requests
 *
 * Input:
 *    ext_type,
 *    ...
 *
 * Output:
 *    Depends....
 *
 * Returns:
 *    DAT_SUCCESS
 *    DAT_NOT_IMPLEMENTED
 *      .....
 *
 */
DAT_RETURN
dapl_extensions(IN DAT_HANDLE dat_handle,
            IN DAT_EXTENDED_OP ext_op, IN va_list args)
{
      DAT_EP_HANDLE ep;
      DAT_LMR_TRIPLET *lmr_p;
      DAT_DTO_COOKIE cookie;
      const DAT_RMR_TRIPLET *rmr_p;
      DAT_UINT64 dat_uint64a, dat_uint64b;
      DAT_UINT32 dat_uint32;
      DAT_COUNT segments = 1;
      DAT_COMPLETION_FLAGS comp_flags;
      DAT_RETURN status = DAT_NOT_IMPLEMENTED;

      dapl_dbg_log(DAPL_DBG_TYPE_API,
                 "dapl_extensions(hdl %p operation %d, ...)\n",
                 dat_handle, ext_op);

      switch ((int)ext_op) {

      case DAT_IB_RDMA_WRITE_IMMED_OP:
            dapl_dbg_log(DAPL_DBG_TYPE_RTN,
                       " WRITE_IMMED_DATA extension call\n");

            ep = dat_handle;  /* ep_handle */
            segments = va_arg(args, DAT_COUNT); /* num segments */
            lmr_p = va_arg(args, DAT_LMR_TRIPLET *);
            cookie = va_arg(args, DAT_DTO_COOKIE);
            rmr_p = va_arg(args, const DAT_RMR_TRIPLET *);
            dat_uint32 = va_arg(args, DAT_UINT32);    /* immed data */
            comp_flags = va_arg(args, DAT_COMPLETION_FLAGS);

            status = dapli_post_ext(ep, 0, 0, dat_uint32, segments, lmr_p,
                              cookie, rmr_p, OP_RDMA_WRITE_IMM,
                              comp_flags);
            break;

      case DAT_IB_CMP_AND_SWAP_OP:
            dapl_dbg_log(DAPL_DBG_TYPE_RTN,
                       " CMP_AND_SWAP extension call\n");

            ep = dat_handle;  /* ep_handle */
            dat_uint64a = va_arg(args, DAT_UINT64);   /* cmp_value */
            dat_uint64b = va_arg(args, DAT_UINT64);   /* swap_value */
            lmr_p = va_arg(args, DAT_LMR_TRIPLET *);
            cookie = va_arg(args, DAT_DTO_COOKIE);
            rmr_p = va_arg(args, const DAT_RMR_TRIPLET *);
            comp_flags = va_arg(args, DAT_COMPLETION_FLAGS);

            status = dapli_post_ext(ep, dat_uint64a, dat_uint64b,
                              0, segments, lmr_p, cookie, rmr_p,
                              OP_COMP_AND_SWAP, comp_flags);
            break;

      case DAT_IB_FETCH_AND_ADD_OP:
            dapl_dbg_log(DAPL_DBG_TYPE_RTN,
                       " FETCH_AND_ADD extension call\n");

            ep = dat_handle;  /* ep_handle */
            dat_uint64a = va_arg(args, DAT_UINT64);   /* add value */
            lmr_p = va_arg(args, DAT_LMR_TRIPLET *);
            cookie = va_arg(args, DAT_DTO_COOKIE);
            rmr_p = va_arg(args, const DAT_RMR_TRIPLET *);
            comp_flags = va_arg(args, DAT_COMPLETION_FLAGS);

            status = dapli_post_ext(ep, dat_uint64a, 0, 0, segments,
                              lmr_p, cookie, rmr_p,
                              OP_FETCH_AND_ADD, comp_flags);

            break;

#ifdef DAPL_COUNTERS
      case DAT_QUERY_COUNTERS_OP:
            {
                  int cntr, reset;
                  DAT_UINT64 *p_cntr_out;

                  dapl_dbg_log(DAPL_DBG_TYPE_RTN,
                             " Query counter extension call\n");

                  cntr = va_arg(args, int);
                  p_cntr_out = va_arg(args, DAT_UINT64 *);
                  reset = va_arg(args, int);

                  status = dapl_query_counter(dat_handle, cntr,
                                        p_cntr_out, reset);
                  break;
            }
      case DAT_PRINT_COUNTERS_OP:
            {
                  int cntr, reset;

                  dapl_dbg_log(DAPL_DBG_TYPE_RTN,
                             " Print counter extension call\n");

                  cntr = va_arg(args, int);
                  reset = va_arg(args, int);

                  dapl_print_counter(dat_handle, cntr, reset);
                  status = DAT_SUCCESS;
                  break;
            }
#endif                        /* DAPL_COUNTERS */

      default:
            dapl_dbg_log(DAPL_DBG_TYPE_ERR,
                       "unsupported extension(%d)\n", (int)ext_op);
      }

      return (status);
}

DAT_RETURN
dapli_post_ext(IN DAT_EP_HANDLE ep_handle,
             IN DAT_UINT64 cmp_add,
             IN DAT_UINT64 swap,
             IN DAT_UINT32 immed_data,
             IN DAT_COUNT segments,
             IN DAT_LMR_TRIPLET * local_iov,
             IN DAT_DTO_COOKIE user_cookie,
             IN const DAT_RMR_TRIPLET * remote_iov,
             IN int op_type, IN DAT_COMPLETION_FLAGS flags)
{
      DAPL_EP *ep_ptr;
      ib_qp_handle_t qp_ptr;
      DAPL_COOKIE *cookie = NULL;
      DAT_RETURN dat_status = DAT_SUCCESS;

      dapl_dbg_log(DAPL_DBG_TYPE_API,
                 " post_ext_op: ep %p cmp_val %d "
                 "swap_val %d cookie 0x%x, r_iov %p, flags 0x%x\n",
                 ep_handle, (unsigned)cmp_add, (unsigned)swap,
                 (unsigned)user_cookie.as_64, remote_iov, flags);

      if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP))
            return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP));

      ep_ptr = (DAPL_EP *) ep_handle;
      qp_ptr = ep_ptr->qp_handle;

      /*
       * Synchronization ok since this buffer is only used for send
       * requests, which aren't allowed to race with each other.
       */
      dat_status = dapls_dto_cookie_alloc(&ep_ptr->req_buffer,
                                  DAPL_DTO_TYPE_EXTENSION,
                                  user_cookie, &cookie);
      if (dat_status != DAT_SUCCESS)
            goto bail;

      /*
       * Take reference before posting to avoid race conditions with
       * completions
       */
      dapl_os_atomic_inc(&ep_ptr->req_count);

      /*
       * Invoke provider specific routine to post DTO
       */
      dat_status = dapls_ib_post_ext_send(ep_ptr, op_type, cookie, segments,  /* data segments */
                                  local_iov, remote_iov, immed_data,    /* immed data */
                                  cmp_add,      /* compare or add */
                                  swap,   /* swap */
                                  flags);

      if (dat_status != DAT_SUCCESS) {
            dapl_os_atomic_dec(&ep_ptr->req_count);
            dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
      }

      bail:
      return dat_status;

}

/* 
 * New provider routine to process extended DTO events 
 */
void
dapls_cqe_to_event_extension(IN DAPL_EP * ep_ptr,
                       IN DAPL_COOKIE * cookie,
                       IN ib_work_completion_t * cqe_ptr,
                       IN DAT_EVENT * event_ptr)
{
      uint32_t ibtype;
      DAT_DTO_COMPLETION_EVENT_DATA *dto =
          &event_ptr->event_data.dto_completion_event_data;
      DAT_IB_EXTENSION_EVENT_DATA *ext_data = (DAT_IB_EXTENSION_EVENT_DATA *)
          & event_ptr->event_extension_data[0];
      DAT_DTO_COMPLETION_STATUS dto_status;

      /* Get status from cqe */
      dto_status = dapls_ib_get_dto_status(cqe_ptr);

      dapl_dbg_log(DAPL_DBG_TYPE_EVD,
                 " cqe_to_event_ext: dto_ptr %p ext_ptr %p status %d\n",
                 dto, ext_data, dto_status);

      event_ptr->event_number = DAT_IB_DTO_EVENT;
      dto->ep_handle = cookie->ep;
      dto->user_cookie = cookie->val.dto.cookie;
      dto->operation = DAPL_GET_CQE_DTOS_OPTYPE(cqe_ptr);   /* new for 2.0 */
      dto->status = ext_data->status = dto_status;

      if (dto_status != DAT_DTO_SUCCESS)
            return;

      /* 
       * Get operation type from CQ work completion entry and
       * if extented operation then set extended event data
       */
      ibtype = DAPL_GET_CQE_OPTYPE(cqe_ptr);

      switch (ibtype) {

      case OP_RDMA_WRITE_IMM:
            dapl_dbg_log(DAPL_DBG_TYPE_EVD,
                       " cqe_to_event_ext: OP_RDMA_WRITE_IMMED\n");

            /* type and outbound rdma write transfer size */
            dto->transfered_length = cookie->val.dto.size;
            ext_data->type = DAT_IB_RDMA_WRITE_IMMED;
            break;
      case OP_RECEIVE_IMM:
            dapl_dbg_log(DAPL_DBG_TYPE_EVD,
                       " cqe_to_event_ext: OP_RECEIVE_RDMA_IMMED\n");

            /* immed recvd, type and inbound rdma write transfer size */
            dto->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);
            ext_data->type = DAT_IB_RDMA_WRITE_IMMED_DATA;
            ext_data->val.immed.data = DAPL_GET_CQE_IMMED_DATA(cqe_ptr);
            break;
      case OP_COMP_AND_SWAP:
            dapl_dbg_log(DAPL_DBG_TYPE_EVD,
                       " cqe_to_event_ext: COMP_AND_SWAP_RESP\n");

            /* original data is returned in LMR provided with post */
            ext_data->type = DAT_IB_CMP_AND_SWAP;
            dto->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);
            break;
      case OP_FETCH_AND_ADD:
            dapl_dbg_log(DAPL_DBG_TYPE_EVD,
                       " cqe_to_event_ext: FETCH_AND_ADD_RESP\n");

            /* original data is returned in LMR provided with post */
            ext_data->type = DAT_IB_FETCH_AND_ADD;
            dto->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);
            break;
      default:
            /* not extended operation */
            ext_data->status = DAT_IB_OP_ERR;
            dto->status = DAT_DTO_ERR_TRANSPORT;
            break;
      }
}

Generated by  Doxygen 1.6.0   Back to index