[openib-general] [RFC][PATCH][REV2] uDAPL atomic extensions and immediate data changes
Arlin Davis
arlin.r.davis at intel.com
Wed Jan 18 16:37:11 PST 2006
James,
Attached is a patch that includes immediate data as a standard API and atomics via extensions.
Changes have been made to the extensions based on discussions with Arkady (name changes and addition
of extended dat_return and memory privileges). This matches the DAT 2.0 extension proposal that I
sent out earlier.
-arlin
Signed-off by: Arlin Davis <mailto:ardavis at ichips.intel.com> <ardavis at ichips.intel.com>
Index: test/dtest/dtest_ext.c
===================================================================
--- test/dtest/dtest_ext.c (revision 0)
+++ test/dtest/dtest_ext.c (revision 0)
@@ -0,0 +1,952 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <getopt.h>
+#include <endian.h>
+#include <byteswap.h>
+
+#include "dat/udat.h"
+
+/*
+ * Map DAT_RETURN values to readable strings,
+ * but don't assume the values are zero-based or contiguous.
+ */
+char errmsg[256] = {0};
+char majmsg[64] = {0};
+char minmsg[64] = {0};
+char extmsg[64] = {0};
+const char *
+DT_RetToString (DAT_RETURN ret_value)
+{
+ const char *major_msg = majmsg;
+ const char *minor_msg = minmsg;
+ const char *ext_msg = extmsg;
+ int sz;
+
+ /* DAT_NOT_IMPLEMENTED definition masked improperly in dat_error.h */
+ if (ret_value == DAT_NOT_IMPLEMENTED) {
+ strcpy(errmsg, "DAT_NOT_IMPLEMENTED");
+ return errmsg;
+ }
+
+ dat_strerror(ret_value, &major_msg, &minor_msg);
+ dat_strerror_extension(ret_value, &ext_msg);
+ strcpy(errmsg, major_msg);
+ strcat(errmsg, " ");
+ strcpy(errmsg, ext_msg);
+ strcat(errmsg, " ");
+ strcat(errmsg, minor_msg);
+
+ return errmsg;
+}
+
+/*
+ * Map DAT_EVENT_CODE values to readable strings
+ */
+const char *
+DT_EventToSTr (DAT_EVENT_NUMBER event_code)
+{
+ unsigned int i;
+ static struct {
+ const char *name;
+ DAT_RETURN value;
+ }
+ dat_events[] =
+ {
+ # define DATxx(x) { # x, x }
+ DATxx (DAT_DTO_COMPLETION_EVENT),
+ DATxx (DAT_RMR_BIND_COMPLETION_EVENT),
+ DATxx (DAT_CONNECTION_REQUEST_EVENT),
+ DATxx (DAT_CONNECTION_EVENT_ESTABLISHED),
+ DATxx (DAT_CONNECTION_EVENT_PEER_REJECTED),
+ DATxx (DAT_CONNECTION_EVENT_NON_PEER_REJECTED),
+ DATxx (DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR),
+ DATxx (DAT_CONNECTION_EVENT_DISCONNECTED),
+ DATxx (DAT_CONNECTION_EVENT_BROKEN),
+ DATxx (DAT_CONNECTION_EVENT_TIMED_OUT),
+ DATxx (DAT_CONNECTION_EVENT_UNREACHABLE),
+ DATxx (DAT_ASYNC_ERROR_EVD_OVERFLOW),
+ DATxx (DAT_ASYNC_ERROR_IA_CATASTROPHIC),
+ DATxx (DAT_ASYNC_ERROR_EP_BROKEN),
+ DATxx (DAT_ASYNC_ERROR_TIMED_OUT),
+ DATxx (DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR),
+ DATxx (DAT_SOFTWARE_EVENT)
+ # undef DATxx
+ };
+ # define NUM_EVENTS (sizeof(dat_events)/sizeof(dat_events[0]))
+
+ for (i = 0; i < NUM_EVENTS; i++) {
+ if (dat_events[i].value == event_code)
+ {
+ return ( dat_events[i].name );
+ }
+ }
+ return ( "Invalid_DAT_EVENT_NUMBER" );
+}
+
+/*
+ * Map DAT_EVENT_CODE values to readable strings
+ */
+const char *
+DT_DtoStatusToSTr (DAT_DTO_COMPLETION_STATUS dto_status )
+{
+ unsigned int i;
+ static struct {
+ const char *name;
+ DAT_RETURN value;
+ }
+ dat_dto[] =
+ {
+ # define DATxx(x) { # x, x }
+ DATxx (DAT_DTO_SUCCESS),
+ DATxx (DAT_DTO_ERR_FLUSHED),
+ DATxx (DAT_DTO_ERR_LOCAL_LENGTH),
+ DATxx (DAT_DTO_ERR_LOCAL_EP),
+ DATxx (DAT_DTO_ERR_LOCAL_PROTECTION),
+ DATxx (DAT_DTO_ERR_BAD_RESPONSE),
+ DATxx (DAT_DTO_ERR_REMOTE_ACCESS),
+ DATxx (DAT_DTO_ERR_REMOTE_RESPONDER),
+ DATxx (DAT_DTO_ERR_TRANSPORT),
+ DATxx (DAT_DTO_ERR_RECEIVER_NOT_READY),
+ DATxx (DAT_DTO_ERR_PARTIAL_PACKET),
+ DATxx (DAT_RMR_OPERATION_FAILED)
+ # undef DATxx
+ };
+ # define NUM_DTO_ERRS (sizeof(dat_dto)/sizeof(dat_dto[0]))
+
+ for (i = 0; i < NUM_DTO_ERRS; i++) {
+ if (dat_dto[i].value == dto_status)
+ {
+ return ( dat_dto[i].name );
+ }
+ }
+ return ( "Invalid DAT_DTO_COMPLETION_STATUS" );
+}
+
+#define _OK( status, str ) \
+{ \
+ if ( status != DAT_SUCCESS ) { \
+ fprintf(stderr, str " returned %s\n", \
+ DT_RetToString(status) ); \
+ exit ( 1 ); \
+ } \
+}
+
+#define _OK_EVENT( event, status, str ) \
+{ \
+ if ( status != DAT_SUCCESS ) { \
+ fprintf(stderr, str " event %s status %s\n", \
+ DT_EventToSTr(event), DT_DtoStatusToSTr(status)); \
+ exit ( 1 ); \
+ } \
+}
+
+#define SECONDS( secs ) (1000*1000*secs)
+
+#define SERVER_CONN_QUAL 31111
+#define BUF_SIZE 256
+#define BUF_SIZE_ATOMIC 8
+#define REG_MEM_COUNT 10
+
+#define SND_RDMA_BUF_INDEX 0
+#define RCV_RDMA_BUF_INDEX 1
+#define SEND_BUF_INDEX 2
+#define RECV_BUF_INDEX 3
+
+u_int64_t *atomic_buf;
+DAT_LMR_HANDLE lmr_atomic;
+DAT_LMR_CONTEXT lmr_atomic_context;
+DAT_RMR_CONTEXT rmr_atomic_context;
+DAT_VLEN reg_atomic_size;
+DAT_VADDR reg_atomic_addr;
+
+DAT_LMR_HANDLE lmr[ REG_MEM_COUNT ];
+DAT_LMR_CONTEXT lmr_context[ REG_MEM_COUNT ];
+DAT_RMR_TRIPLET rmr[ REG_MEM_COUNT ];
+DAT_RMR_CONTEXT rmr_context[ REG_MEM_COUNT ];
+DAT_VLEN reg_size[ REG_MEM_COUNT ];
+DAT_VADDR reg_addr[ REG_MEM_COUNT ];
+DAT_RMR_TRIPLET * buf[ REG_MEM_COUNT ];
+DAT_EP_HANDLE ep;
+DAT_EVD_HANDLE async_evd = DAT_HANDLE_NULL;
+DAT_IA_HANDLE ia = DAT_HANDLE_NULL;
+DAT_PZ_HANDLE pz = DAT_HANDLE_NULL;
+DAT_EVD_HANDLE cr_evd = DAT_HANDLE_NULL;
+DAT_EVD_HANDLE con_evd = DAT_HANDLE_NULL;
+DAT_EVD_HANDLE dto_evd = DAT_HANDLE_NULL;
+DAT_PSP_HANDLE psp = DAT_HANDLE_NULL;
+DAT_CR_HANDLE cr = DAT_HANDLE_NULL;
+int server = 1;
+
+void
+send_msg(
+ void *data,
+ DAT_COUNT size,
+ DAT_LMR_CONTEXT context,
+ DAT_DTO_COOKIE cookie,
+ DAT_COMPLETION_FLAGS flags )
+{
+ DAT_LMR_TRIPLET iov;
+ DAT_EVENT event;
+ DAT_COUNT nmore;
+ DAT_RETURN status;
+
+ iov.lmr_context = context;
+ iov.pad = 0;
+ iov.virtual_address = (DAT_VADDR)(unsigned long)data;
+ iov.segment_length = (DAT_VLEN)size;
+
+ status = dat_ep_post_send( ep,
+ 1,
+ &iov,
+ cookie,
+ flags );
+ _OK( status, "dat_ep_post_send" );
+
+ if ( ! (flags & DAT_COMPLETION_SUPPRESS_FLAG) ) {
+ status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+ _OK( status, "dat_evd_wait after dat_ep_post_send" );
+
+ if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+ printf("unexpected event waiting for post_send completion - 0x%x\n",
event.event_number);
+ exit ( 1 );
+ }
+
+ _OK( event.event_data.dto_completion_event_data.status, "event status for post_send" );
+ }
+}
+
+int
+connect_ep( char *hostname )
+{
+ DAT_SOCK_ADDR remote_addr;
+ DAT_EP_ATTR ep_attr;
+ DAT_RETURN status;
+ DAT_REGION_DESCRIPTION region;
+ DAT_EVENT event;
+ DAT_COUNT nmore;
+ DAT_LMR_TRIPLET iov;
+ DAT_RMR_TRIPLET r_iov;
+ DAT_DTO_COOKIE cookie;
+ DAT_PROVIDER_ATTR provider_attr;
+ DAT_NAMED_ATTR named_attrs;
+ int i,ext_cnt;
+ DAT_DTO_COMPLETION_EVENT_DATA *dto_event = &event.event_data.dto_completion_event_data;
+
+ status = dat_ia_open( "OpenIB-ib0", 8, &async_evd, &ia );
+ _OK( status, "dat_ia_open" );
+
+ /* query for immediate data and atomic operation extensions */
+ status = dat_ia_query( ia, NULL, DAT_IA_FIELD_NONE, NULL,
+ DAT_PROVIDER_FIELD_PROVIDER_SPECIFIC_ATTR,
+ &provider_attr );
+ _OK( status, "dat_ia_query" );
+
+ /* look for extension support, ALL or nothing */
+ ext_cnt=0;
+ printf(" Extension Attributes:\n");
+ for (i=0;i<provider_attr.num_provider_specific_attr;i++) {
+ /* check extension version */
+ if ((!strcmp(provider_attr.provider_specific_attr[i].name,
+ DAT_EXTENSION_ATTR_VERSION))) {
+ printf(" %s = %s\n",
+ provider_attr.provider_specific_attr[i].name,
+ provider_attr.provider_specific_attr[i].value);
+ if (!strcmp(provider_attr.provider_specific_attr[i].value,
+ DAT_EXTENSION_ATTR_VERSION_VALUE)) {
+ ext_cnt++;
+ continue;
+ } else
+ break;
+ }
+ /* check extension names set to TRUE */
+ if ((!strcmp(provider_attr.provider_specific_attr[i].name,
+ DAT_EXTENSION_ATTR)) ||
+ (!strcmp(provider_attr.provider_specific_attr[i].name,
+ DAT_EXTENSION_ATTR_FETCH_AND_ADD)) ||
+ (!strcmp(provider_attr.provider_specific_attr[i].name,
+ DAT_EXTENSION_ATTR_CMP_AND_SWAP)) ) {
+ printf(" %s = %s\n",
+ provider_attr.provider_specific_attr[i].name,
+ provider_attr.provider_specific_attr[i].value);
+ if (strcmp(provider_attr.provider_specific_attr[i].value,
+ DAT_EXTENSION_ATTR_TRUE)) {
+ break;
+ } else
+ ext_cnt++;
+ } else {
+ printf(" Extension Attribute: %s unknown\n",
+ provider_attr.provider_specific_attr[i].name);
+ continue;
+ }
+ }
+ /* all or nothing */
+ if (ext_cnt != 4) {
+ _OK( DAT_INVALID_HANDLE, "provider attr checking" );
+ }
+
+ status = dat_pz_create( ia, &pz );
+ _OK( status, "dat_pz_create" );
+
+ status = dat_evd_create( ia, 10, DAT_HANDLE_NULL, DAT_EVD_CR_FLAG, &cr_evd );
+ _OK( status, "dat_evd_create CR" );
+ status = dat_evd_create( ia, 10, DAT_HANDLE_NULL, DAT_EVD_CONNECTION_FLAG, &con_evd );
+ _OK( status, "dat_evd_create CR" );
+ status = dat_evd_create( ia, 10, DAT_HANDLE_NULL, DAT_EVD_DTO_FLAG, &dto_evd );
+ _OK( status, "dat_evd_create DTO" );
+
+ memset( &ep_attr, 0, sizeof(ep_attr) );
+ ep_attr.service_type = DAT_SERVICE_TYPE_RC;
+ ep_attr.max_rdma_size = 0x10000;
+ ep_attr.qos = 0;
+ ep_attr.recv_completion_flags = 0;
+ ep_attr.max_recv_dtos = 10;
+ ep_attr.max_request_dtos = 10;
+ ep_attr.max_recv_iov = 1;
+ ep_attr.max_request_iov = 1;
+ ep_attr.max_rdma_read_in = 4;
+ ep_attr.max_rdma_read_out = 4;
+ ep_attr.request_completion_flags = DAT_COMPLETION_DEFAULT_FLAG;
+ ep_attr.ep_transport_specific_count = 0;
+ ep_attr.ep_transport_specific = NULL;
+ ep_attr.ep_provider_specific_count = 0;
+ ep_attr.ep_provider_specific = NULL;
+
+ status = dat_ep_create( ia, pz, dto_evd, dto_evd, con_evd, &ep_attr, &ep );
+ _OK( status, "dat_ep_create" );
+
+ for ( i = 0; i < REG_MEM_COUNT; i++ ) {
+ buf[ i ] = (DAT_RMR_TRIPLET*)malloc( BUF_SIZE );
+ region.for_va = buf[ i ];
+ status = dat_lmr_create( ia,
+ DAT_MEM_TYPE_VIRTUAL,
+ region,
+ BUF_SIZE,
+ pz,
+ DAT_MEM_PRIV_ALL_FLAG | DAT_MEM_PRIV_EXT_REMOTE_ATOMIC,
+ &lmr[ i ],
+ &lmr_context[ i ],
+ &rmr_context[ i ],
+ ®_size[ i ],
+ ®_addr[ i ] );
+ _OK( status, "dat_lmr_create" );
+#if 0
+ printf(" buf[%d]=%p, reg_addr[%d]=%p\n",
+ i, buf[ i ], i, reg_addr[ i ]);
+#endif
+ }
+
+ printf(" PRIV_REMOTE_ATOMIC = 0x%x all=0x%x\n",
+ DAT_MEM_PRIV_EXT_REMOTE_ATOMIC,
+ DAT_MEM_PRIV_ALL_FLAG );
+
+ /* register atomic return buffer for original data */
+ atomic_buf = (u_int64_t*)malloc( BUF_SIZE );
+ region.for_va = atomic_buf;
+ status = dat_lmr_create( ia,
+ DAT_MEM_TYPE_VIRTUAL,
+ region,
+ BUF_SIZE_ATOMIC,
+ pz,
+ //DAT_MEM_PRIV_ALL_FLAG,
+ DAT_MEM_PRIV_ALL_FLAG | DAT_MEM_PRIV_EXT_REMOTE_ATOMIC,
+ &lmr_atomic,
+ &lmr_atomic_context,
+ &rmr_atomic_context,
+ ®_atomic_size,
+ ®_atomic_addr );
+ _OK( status, "dat_lmr_create atomic" );
+
+ for ( i = RECV_BUF_INDEX; i < REG_MEM_COUNT; i++ ) {
+ cookie.as_64 = i;
+ iov.lmr_context = lmr_context[ i ];
+ iov.pad = 0;
+ iov.virtual_address = (DAT_VADDR)(unsigned long)buf[ i ];
+ iov.segment_length = BUF_SIZE;
+
+ status = dat_ep_post_recv_immed(ep,
+ 1,
+ &iov,
+ cookie,
+ DAT_COMPLETION_DEFAULT_FLAG );
+ _OK( status, "dat_ep_post_recv_immed" );
+ }
+
+ /* setup receive buffer to initial string to be overwritten */
+ strcpy( (char*)buf[ RCV_RDMA_BUF_INDEX ], "blah, blah, blah\n" );
+
+ if ( server ) {
+
+ strcpy( (char*)buf[ SND_RDMA_BUF_INDEX ], "server written data" );
+
+ status = dat_psp_create( ia,
+ SERVER_CONN_QUAL,
+ cr_evd,
+ DAT_PSP_CONSUMER_FLAG,
+ &psp );
+ _OK( status, "dat_psp_create" );
+
+ printf("Server waiting for connect request\n");
+ status = dat_evd_wait( cr_evd, SECONDS( 20 ), 1, &event, &nmore );
+ _OK( status, "listen dat_evd_wait" );
+
+ if ( event.event_number != DAT_CONNECTION_REQUEST_EVENT ) {
+ printf("unexpected event after dat_psp_create: 0x%x\n", event.event_number);
+ exit ( 1 );
+ }
+
+ if ( (event.event_data.cr_arrival_event_data.conn_qual != SERVER_CONN_QUAL) ||
+ (event.event_data.cr_arrival_event_data.sp_handle.psp_handle != psp) ) {
+
+ printf("wrong cr event data\n");
+ exit ( 1 );
+ }
+
+ cr = event.event_data.cr_arrival_event_data.cr_handle;
+ status = dat_cr_accept( cr, ep, 0, (DAT_PVOID)0 );
+
+ } else {
+ struct addrinfo *target;
+ int rval;
+
+ if (getaddrinfo (hostname, NULL, NULL, &target) != 0) {
+ printf("Error getting remote address.\n");
+ exit ( 1 );
+ }
+
+ rval = ((struct sockaddr_in *)target->ai_addr)->sin_addr.s_addr;
+ printf ("Server Name: %s \n", hostname);
+ printf ("Server Net Address: %d.%d.%d.%d\n",
+ (rval >> 0) & 0xff,
+ (rval >> 8) & 0xff,
+ (rval >> 16) & 0xff,
+ (rval >> 24) & 0xff);
+
+ remote_addr = *((DAT_IA_ADDRESS_PTR)target->ai_addr);
+
+ strcpy( (char*)buf[ SND_RDMA_BUF_INDEX ], "client written data" );
+
+ status = dat_ep_connect( ep,
+ &remote_addr,
+ SERVER_CONN_QUAL,
+ SECONDS( 20 ),
+ 0,
+ (DAT_PVOID)0,
+ 0,
+ DAT_CONNECT_DEFAULT_FLAG );
+ _OK( status, "dat_psp_create" );
+
+
+ }
+
+ printf("Client waiting for connect response\n");
+ status = dat_evd_wait( con_evd, SECONDS( 5 ), 1, &event, &nmore );
+ _OK( status, "connect dat_evd_wait" );
+
+ if ( event.event_number != DAT_CONNECTION_EVENT_ESTABLISHED ) {
+ printf("unexpected event after dat_ep_connect: 0x%x\n", event.event_number);
+ exit ( 1 );
+ }
+
+ printf("Connected!\n");
+
+ /*
+ * Setup our remote memory and tell the other side about it
+ */
+ printf("Sending RMR data to remote\n");
+ r_iov.rmr_context = rmr_context[ RCV_RDMA_BUF_INDEX ];
+ r_iov.pad = 0;
+ r_iov.target_address = (DAT_VADDR)((unsigned long)buf[ RCV_RDMA_BUF_INDEX ]);
+ r_iov.segment_length = BUF_SIZE;
+
+ *buf[ SEND_BUF_INDEX ] = r_iov;
+
+ send_msg(buf[ SEND_BUF_INDEX ],
+ sizeof( DAT_RMR_TRIPLET ),
+ lmr_context[ SEND_BUF_INDEX ],
+ cookie,
+ DAT_COMPLETION_SUPPRESS_FLAG );
+
+ /*
+ * Wait for their RMR
+ */
+ printf("Waiting for remote to send RMR data\n");
+ status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+ _OK( status, "dat_evd_wait after dat_ep_post_send" );
+
+ if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+ printf("unexpected event waiting for RMR context - 0x%x\n",
+ event.event_number);
+ exit ( 1 );
+ }
+
+ _OK_EVENT( event.event_number, dto_event->status, " post_send" );
+ if ( (dto_event->transfered_length != sizeof( DAT_RMR_TRIPLET )) ||
+ (dto_event->user_cookie.as_64 != RECV_BUF_INDEX) ) {
+ printf("unexpected event data for receive: len=%d cookie=%d expected %d/%d\n",
+ (int)dto_event->transfered_length,
+ (int)dto_event->user_cookie.as_64,
+ sizeof(DAT_RMR_TRIPLET), RECV_BUF_INDEX);
+ exit ( 1 );
+ }
+
+ r_iov = *buf[ RECV_BUF_INDEX ];
+
+ printf("Received RMR from remote: r_iov: ctx=%x,pad=%x,va=%p,len=%d\n",
+ r_iov.rmr_context,
+ r_iov.pad,
+ (void*)(unsigned long)r_iov.target_address,
+ r_iov.segment_length );
+
+ return ( 0 );
+}
+
+int
+disconnect_ep( )
+{
+ DAT_RETURN status;
+ int i;
+
+ status = dat_ep_disconnect( ep, DAT_CLOSE_DEFAULT );
+ _OK( status, "dat_ep_disconnect" );
+
+ printf("EP disconnected\n");
+
+ if ( server ) {
+ status = dat_psp_free( psp );
+ _OK( status, "dat_ep_disconnect" );
+ }
+
+ for ( i = 0; i < REG_MEM_COUNT; i++ ) {
+ status = dat_lmr_free( lmr[ i ] );
+ _OK( status, "dat_lmr_free" );
+ }
+
+ status = dat_lmr_free( lmr_atomic );
+ _OK( status, "dat_lmr_free_atomic" );
+
+ status = dat_ep_free( ep );
+ _OK( status, "dat_ep_free" );
+
+ status = dat_evd_free( dto_evd );
+ _OK( status, "dat_evd_free DTO" );
+ status = dat_evd_free( con_evd );
+ _OK( status, "dat_evd_free CON" );
+ status = dat_evd_free( cr_evd );
+ _OK( status, "dat_evd_free CR" );
+
+ status = dat_pz_free( pz );
+ _OK( status, "dat_pz_free" );
+
+ status = dat_ia_close( ia, DAT_CLOSE_DEFAULT );
+ _OK( status, "dat_ia_close" );
+
+ return ( 0 );
+}
+
+int
+do_immediate( )
+{
+ DAT_REGION_DESCRIPTION region;
+ DAT_EVENT event;
+ DAT_COUNT nmore;
+ DAT_LMR_TRIPLET iov;
+ DAT_RMR_TRIPLET r_iov;
+ DAT_DTO_COOKIE cookie;
+ DAT_RMR_CONTEXT their_context;
+ DAT_RETURN status;
+ DAT_UINT32 immed_data;
+ DAT_UINT32 immed_data_recv;
+ DAT_DTO_COMPLETION_EVENT_DATA *dto_event =
+ &event.event_data.dto_completion_event_data;
+
+ printf("\nDoing RDMA WRITE IMMEDIATE DATA\n");
+
+ if ( server ) {
+ immed_data = 0x1111;
+ } else {
+ immed_data = 0x7777;
+ }
+
+ cookie.as_64 = 0x5555;
+
+ r_iov = *buf[ RECV_BUF_INDEX ];
+
+ iov.lmr_context = lmr_context[ SND_RDMA_BUF_INDEX ];
+ iov.pad = 0;
+ iov.virtual_address = (DAT_VADDR)(unsigned long)buf[ SND_RDMA_BUF_INDEX ];
+ iov.segment_length = BUF_SIZE;
+
+ cookie.as_64 = 0x9999;
+
+ status = dat_ep_post_rdma_write_immed( ep, // ep_handle
+ 1, // num_segments
+ &iov, // LMR
+ cookie, // user_cookie
+ &r_iov, // RMR
+ immed_data,
+ DAT_DTO_IMMED_FLAG,
+ DAT_COMPLETION_DEFAULT_FLAG );
+
+ _OK( status, "dat_ep_post_rdma_write_immed" );
+ printf("dat_ep_post_rdma_write_immed posted\n");
+
+ /*
+ * Collect first event, write completion or the inbound rdma with immed
+ */
+ status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+ _OK( status, "dat_evd_wait after dat_ep_post_rdma_write" );
+ if ( event.event_number != DAT_DTO_COMPLETION_EVENT )
+ {
+ printf("unexpected event waiting for RMR context - 0x%x\n",
+ event.event_number );
+ exit ( 1 );
+ }
+
+ _OK_EVENT( event.event_number, dto_event->status, " rdma_write_immed" );
+ if (dto_event->operation == DAT_RDMA_WRITE_IMMED )
+ {
+ if ((dto_event->transfered_length != BUF_SIZE) ||
+ (dto_event->user_cookie.as_64 != 0x9999) )
+ {
+ printf("unexpected event data for rdma_write_immed: len=%d cookie=0x%x\n",
+ (int)dto_event->transfered_length,
+ (int)dto_event->user_cookie.as_64);
+ exit ( 1 );
+ }
+ }
+ else if (dto_event->operation == DAT_RECEIVE_RDMA_IMMED )
+ {
+ if ((dto_event->transfered_length != BUF_SIZE) ||
+ (dto_event->user_cookie.as_64 != RECV_BUF_INDEX+1)) {
+ printf("unexpected event data of immediate write:"
+ "len=%d cookie=%d expected %d/%d\n",
+ (int)dto_event->transfered_length,
+ (int)dto_event->user_cookie.as_64,
+ sizeof(int), RECV_BUF_INDEX+1);
+ exit ( 1 );
+ }
+ /* get immediate data from DTO event */
+ immed_data_recv = dto_event->immed_data;
+ }
+ else
+ {
+ printf("unexpected operation type - 0x%x, 0x%x\n",
+ event.event_number, dto_event->operation);
+ exit ( 1 );
+ }
+
+ /*
+ * Collect second event, write completion or the inbound rdma with immed
+ */
+ status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+ _OK( status, "dat_evd_wait after dat_ep_post_rdma_write" );
+ if ( event.event_number != DAT_DTO_COMPLETION_EVENT )
+ {
+ printf("unexpected event waiting for RMR context - 0x%x\n",
+ event.event_number );
+ exit ( 1 );
+ }
+
+ _OK_EVENT( event.event_number, dto_event->status, " rdma_write_immed" );
+ if (dto_event->operation == DAT_RDMA_WRITE_IMMED )
+ {
+ if ((dto_event->transfered_length != BUF_SIZE) ||
+ (dto_event->user_cookie.as_64 != 0x9999) )
+ {
+ printf("unexpected event data for rdma_write_immed: len=%d cookie=0x%x\n",
+ (int)dto_event->transfered_length,
+ (int)dto_event->user_cookie.as_64);
+ exit ( 1 );
+ }
+ }
+ else if (dto_event->operation == DAT_RECEIVE_RDMA_IMMED )
+ {
+ if ((dto_event->transfered_length != BUF_SIZE) ||
+ (dto_event->user_cookie.as_64 != RECV_BUF_INDEX+1)) {
+ printf("unexpected event data of immediate write:"
+ "len=%d cookie=%d expected %d/%d\n",
+ (int)dto_event->transfered_length,
+ (int)dto_event->user_cookie.as_64,
+ sizeof(int), RECV_BUF_INDEX+1);
+ exit ( 1 );
+ }
+ /* get immediate data from DTO event */
+ immed_data_recv = dto_event->immed_data;
+ }
+ else
+ {
+ printf("unexpected operation type - 0x%x, 0x%x\n",
+ event.event_number, dto_event->operation);
+ exit ( 1 );
+ }
+
+ if ((server) && (immed_data_recv != 0x7777))
+ {
+ printf("Server got unexpected immed_data_recv 0x%x/0x%x\n",
+ 0x7777, immed_data_recv );
+ exit ( 1 );
+ }
+ else if ((!server) && (immed_data_recv != 0x1111))
+ {
+ printf("Client got unexpected immed_data_recv 0x%x/0x%x\n",
+ 0x1111, immed_data_recv );
+ exit ( 1 );
+ }
+
+ if (server)
+ printf("Server received immed_data=0x%x, expected 0x7777\n", immed_data_recv );
+ else
+ printf("Client received immed_data=0x%x, expected 0x1111\n", immed_data_recv );
+
+ printf("RCV buffer %p contains: %s\n",
+ buf[ RCV_RDMA_BUF_INDEX ], buf[ RCV_RDMA_BUF_INDEX ]);
+
+ return ( 0 );
+}
+
+int
+do_cmp_swap()
+{
+ DAT_DTO_COOKIE cookie;
+ DAT_RETURN status;
+ DAT_EVENT event;
+ DAT_COUNT nmore;
+ DAT_LMR_TRIPLET l_iov;
+ DAT_RMR_TRIPLET r_iov;
+ volatile DAT_UINT64 *target = (DAT_UINT64*)buf[ RCV_RDMA_BUF_INDEX ];
+ DAT_DTO_COMPLETION_EVENT_DATA *dto_event =
+ &event.event_data.dto_completion_event_data;
+
+ printf("\nDoing CMP and SWAP\n");
+
+ r_iov = *buf[ RECV_BUF_INDEX ];
+
+ l_iov.lmr_context = lmr_atomic_context;
+ l_iov.pad = 0;
+ l_iov.virtual_address = (DAT_VADDR)(unsigned long)atomic_buf;
+ l_iov.segment_length = BUF_SIZE_ATOMIC;
+
+ cookie.as_64 = 3333;
+ if ( server ) {
+ *target = 0x12345;
+ sleep(1);
+ /* server does not compare and should not swap */
+ status = dat_ep_post_cmp_and_swap( ep,
+ (DAT_UINT64)0x654321,
+ (DAT_UINT64)0x6789A,
+ &l_iov,
+ cookie,
+ &r_iov,
+ DAT_COMPLETION_DEFAULT_FLAG);
+ } else {
+ *target = 0x54321;
+ sleep(1);
+ /* client does compare and should swap */
+ status = dat_ep_post_cmp_and_swap( ep,
+ (DAT_UINT64)0x12345,
+ (DAT_UINT64)0x98765,
+ &l_iov,
+ cookie,
+ &r_iov,
+ DAT_COMPLETION_DEFAULT_FLAG);
+ }
+ _OK( status, "dat_ep_post_cmp_and_swap" );
+ printf("dat_ep_post_cmp_and_swap posted\n");
+
+ status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+ _OK( status, "dat_evd_wait for compare and swap" );
+ if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+ printf("unexpected event after post_cmp_and_swap: 0x%x\n",
+ event.event_number);
+ exit ( 1 );
+ }
+
+ _OK_EVENT( event.event_number, dto_event->status, " cmp_swap" );
+ if ( dto_event->extension.type != DAT_DTO_EXTENSION_CMP_AND_SWAP ) {
+ printf("unexpected event data of cmp and swap : type=%d cookie=%d original 0x%llx\n",
+ (int)dto_event->extension.type,
+ (int)dto_event->user_cookie.as_64,
+ *atomic_buf);
+ exit ( 1 );
+ }
+ sleep(1);
+ if ( server ) {
+ printf("Server got original data = 0x%llx, expected 0x54321\n", *atomic_buf);
+ printf("Client final result (on server) = 0x%llx, expected 0x98765\n", *target);
+ } else {
+ printf("Client got original data = 0x%llx, expected 0x12345\n",*atomic_buf);
+ printf("Server final result (on client) = 0x%llx, expected 0x54321\n", *target);
+ }
+ return(0);
+}
+
+int
+do_fetch_add()
+{
+ DAT_DTO_COOKIE cookie;
+ DAT_RETURN status;
+ DAT_EVENT event;
+ DAT_COUNT nmore;
+ DAT_LMR_TRIPLET l_iov;
+ DAT_RMR_TRIPLET r_iov;
+ volatile DAT_UINT64 *target = (DAT_UINT64*)buf[ RCV_RDMA_BUF_INDEX ];
+ DAT_DTO_COMPLETION_EVENT_DATA *dto_event =
+ &event.event_data.dto_completion_event_data;
+
+ printf("\nDoing FETCH and ADD\n");
+
+ r_iov = *buf[ RECV_BUF_INDEX ];
+
+ l_iov.lmr_context = lmr_atomic_context;
+ l_iov.pad = 0;
+ l_iov.virtual_address = (DAT_VADDR)(unsigned long)atomic_buf;
+ l_iov.segment_length = BUF_SIZE_ATOMIC;
+
+ cookie.as_64 = 0x7777;
+ if ( server ) {
+ *target = 0x10;
+ sleep( 1 );
+ status = dat_ep_post_fetch_and_add( ep,
+ (DAT_UINT64)0x100,
+ &l_iov,
+ cookie,
+ &r_iov,
+ DAT_COMPLETION_DEFAULT_FLAG);
+ } else {
+ *target = 0x100;
+ sleep( 1 );
+ status = dat_ep_post_fetch_and_add( ep,
+ (DAT_UINT64)0x10,
+ &l_iov,
+ cookie,
+ &r_iov,
+ DAT_COMPLETION_DEFAULT_FLAG);
+ }
+ _OK( status, "dat_ep_post_fetch_and_add" );
+ printf("dat_ep_post_fetch_and_add posted\n");
+ status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+ _OK( status, "dat_evd_wait for fetch and add" );
+ if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+ printf("unexpected event after post_fetch_and_add: 0x%x\n", event.event_number);
+ exit ( 1 );
+ }
+
+ _OK_EVENT( event.event_number, dto_event->status, " fetch_add" );
+ if ( dto_event->extension.type != DAT_DTO_EXTENSION_FETCH_AND_ADD ) {
+ printf("unexpected event data of fetch and add : type=%d cookie=%d original%d\n",
+ (int)dto_event->extension.type,
+ (int)dto_event->user_cookie.as_64,
+ (int)*atomic_buf );
+ exit ( 1 );
+ }
+
+ if ( server ) {
+ printf("Client original data (on server) = 0x%llx, expected 0x100\n", *atomic_buf );
+ } else {
+ printf("Server original data (on client) = 0x%llx, expected 0x10\n", *atomic_buf );
+ }
+
+ sleep( 1 );
+
+ if ( server ) {
+ status = dat_ep_post_fetch_and_add( ep,
+ (DAT_UINT64)0x100,
+ &l_iov,
+ cookie,
+ &r_iov,
+ DAT_COMPLETION_DEFAULT_FLAG);
+ } else {
+ status = dat_ep_post_fetch_and_add( ep,
+ (DAT_UINT64)0x10,
+ &l_iov,
+ cookie,
+ &r_iov,
+ DAT_COMPLETION_DEFAULT_FLAG);
+ }
+
+ status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+ _OK( status, "dat_evd_wait for second fetch and add" );
+ if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+ printf("unexpected event after second post_fetch_and_add: 0x%x\n", event.event_number);
+ exit ( 1 );
+ }
+
+ _OK_EVENT( event.event_number, dto_event->status, " fetch_add" );
+ if ( dto_event->extension.type != DAT_DTO_EXTENSION_FETCH_AND_ADD ) {
+ printf("unexpected event data of second fetch and add : type=%d cookie=%d original%d\n",
+ (int)dto_event->extension.type,
+ (int)dto_event->user_cookie.as_64,
+ (long)atomic_buf);
+ exit ( 1 );
+ }
+
+ sleep( 1 );
+ if ( server ) {
+ printf("Server got original data = 0x%llx, expected 0x200\n", *atomic_buf);
+ printf("Client final result (on server) = 0x%llx, expected 0x30\n", *target);
+ } else {
+ printf("Server side original data = 0x%llx, expected 0x20\n", *atomic_buf);
+ printf("Server final result (on client) = 0x%llx, expected 0x300\n", *target);
+ }
+
+ return ( 0 );
+}
+
+void print_usage()
+{
+ printf("\n dtest_ext usage \n\n");
+ printf("s: server\n");
+ printf("h: hostname\n");
+ printf("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ int i,c;
+ char hostname[100];
+
+ /* parse arguments */
+ while ((c = getopt(argc, argv, "sh:")) != -1)
+ {
+ switch(c)
+ {
+ case 's':
+ server = 1;
+ break;
+ case 'h':
+ server = 0;
+ strcpy(hostname, optarg);
+ break;
+ default:
+ print_usage();
+ exit(1);
+ }
+ }
+
+ if (server)
+ printf("Server: using provider OpenIB-ib0\n");
+ else
+ printf("Client: using provider OpenIB-ib0, connect to %s \n",
+ hostname);
+
+ /* connect and send rdma buffer information */
+ if (connect_ep(hostname))
+ exit(1);
+
+ if (do_immediate())
+ exit(1);
+
+ if (do_cmp_swap())
+ exit(1);
+
+ if (do_fetch_add())
+ exit(1);
+
+ return (disconnect_ep());
+}
Index: test/dtest/makefile
===================================================================
--- test/dtest/makefile (revision 5065)
+++ test/dtest/makefile (working copy)
@@ -4,13 +4,18 @@ CFLAGS = -O2 -g
DAT_INC = ../../dat/include
DAT_LIB = /usr/local/lib
-all: dtest
+all: dtest dtest_ext
clean:
- rm -f *.o;touch *.c;rm -f dtest
+ rm -f *.o;touch *.c;rm -f dtest dtest_ext
dtest: ./dtest.c
$(CC) $(CFLAGS) ./dtest.c -o dtest \
-DDAPL_PROVIDER='"OpenIB-cma-ip"' \
-I $(DAT_INC) -L $(DAT_LIB) -ldat
+dtest_ext: ./dtest_ext.c
+ $(CC) $(CFLAGS) ./dtest_ext.c -o dtest_ext \
+ -DDAPL_PROVIDER='"OpenIB-cma-ip"' \
+ -I $(DAT_INC) -L $(DAT_LIB) -ldat
+
Index: dapl/include/dapl.h
===================================================================
--- dapl/include/dapl.h (revision 5065)
+++ dapl/include/dapl.h (working copy)
@@ -1,25 +1,28 @@
/*
- * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
+ * Copyright (c) 2002-2005, Network Appliance, Inc. 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
+ * in the file LICENSE.txt in the root directory. The license is also
+ * 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
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is in the file
+ * LICENSE2.txt in the root directory. The license is also 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
+ * copy of which is in the file LICENSE3.txt in the root directory. The
+ * license is also 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.
@@ -61,6 +64,8 @@
#include "dapl_dummy_util.h"
#elif OPENIB
#include "dapl_ib_util.h"
+#elif DET
+#include "dapl_det_util.h"
#endif
/*********************************************************************
@@ -178,6 +183,11 @@ typedef enum dapl_qp_state
#define DAT_ERROR(Type, SubType) ((DAT_RETURN)(DAT_CLASS_ERROR | Type | SubType))
+#ifdef DAT_EXTENSIONS
+#define DAT_ERROR_EXTENSION(Type, ExtType, SubType) \
+ ((DAT_RETURN)(DAT_CLASS_ERROR | Type | ExtType | SubType))
+#endif
+
/*********************************************************************
* *
* Typedefs *
@@ -563,6 +573,15 @@ typedef enum dapl_dto_type
DAPL_DTO_TYPE_RECV,
DAPL_DTO_TYPE_RDMA_WRITE,
DAPL_DTO_TYPE_RDMA_READ,
+#ifdef DAT_IMMEDIATE_DATA
+ DAPL_DTO_TYPE_SEND_IMMED,
+ DAPL_DTO_TYPE_RECV_IMMED,
+ DAPL_DTO_TYPE_RDMA_WRITE_IMMED,
+#endif
+#ifdef DAT_EXTENSIONS
+ DAPL_DTO_TYPE_EXTENSION
+#endif
+
} DAPL_DTO_TYPE;
typedef enum dapl_cookie_type
@@ -570,6 +589,7 @@ typedef enum dapl_cookie_type
DAPL_COOKIE_TYPE_NULL,
DAPL_COOKIE_TYPE_DTO,
DAPL_COOKIE_TYPE_RMR,
+
} DAPL_COOKIE_TYPE;
/* DAPL_DTO_COOKIE used as context for DTO WQEs */
@@ -578,6 +598,9 @@ struct dapl_dto_cookie
DAPL_DTO_TYPE type;
DAT_DTO_COOKIE cookie;
DAT_COUNT size; /* used for SEND and RDMA write */
+#ifdef DAT_EXTENSIONS
+ DAT_PVOID extension; /* extended DTO ops */
+#endif
};
/* DAPL_RMR_COOKIE used as context for bind WQEs */
@@ -1116,6 +1139,42 @@ extern DAT_RETURN dapl_srq_set_lw(
IN DAT_SRQ_HANDLE, /* srq_handle */
IN DAT_COUNT); /* low_watermark */
+#ifdef DAT_IMMEDIATE_DATA
+extern DAT_RETURN dapl_ep_post_send_immed (
+ IN DAT_EP_HANDLE, /* ep_handle */
+ IN DAT_COUNT, /* num_segments */
+ IN DAT_LMR_TRIPLET *, /* local_iov */
+ IN DAT_DTO_COOKIE, /* user_cookie */
+ IN DAT_UINT32, /* immediate data */
+ IN DAT_DTO_FLAGS, /* dto_flags */
+ IN DAT_COMPLETION_FLAGS ); /* completion_flags */
+
+extern DAT_RETURN dapl_ep_post_recv_immed (
+ IN DAT_EP_HANDLE, /* ep_handle */
+ IN DAT_COUNT, /* num_segments */
+ IN DAT_LMR_TRIPLET *, /* local_iov */
+ IN DAT_DTO_COOKIE, /* user_cookie */
+ IN DAT_COMPLETION_FLAGS ); /* completion_flags */
+
+extern DAT_RETURN dapl_ep_post_rdma_write_immed (
+ IN DAT_EP_HANDLE, /* ep_handle */
+ IN DAT_COUNT, /* num_segments */
+ IN DAT_LMR_TRIPLET *, /* local_iov */
+ IN DAT_DTO_COOKIE, /* user_cookie */
+ IN const DAT_RMR_TRIPLET *,/* remote_iov */
+ IN DAT_UINT32, /* immediate data */
+ IN DAT_DTO_FLAGS, /* dto_flags */
+ IN DAT_COMPLETION_FLAGS ); /* completion_flags */
+#endif
+
+#ifdef DAT_EXTENSIONS
+extern DAT_RETURN dapl_extensions(
+ IN DAT_HANDLE, /* dat_handle */
+ IN DAT_DTO_EXTENSION_OP, /* extension operation */
+ IN va_list ); /* va_list args */
+
+#endif
+
/*
* DAPL internal utility function prototpyes
*/
Index: dapl/include/dapl_debug.h
===================================================================
--- dapl/include/dapl_debug.h (revision 5065)
+++ dapl/include/dapl_debug.h (working copy)
@@ -112,7 +112,16 @@ extern void dapl_internal_dbg_log ( DAPL
#define DCNT_EVD_DEQUEUE_NOT_FOUND 18
#define DCNT_TIMER_SET 19
#define DCNT_TIMER_CANCEL 20
+
+#ifdef DAT_IMMEDIATE_DATA
+#define DCNT_POST_SEND_IMMED 21
+#define DCNT_POST_RECV_IMMED 22
+#define DCNT_POST_RDMA_WRITE_IMMED 23
+#define DCNT_NUM_COUNTERS 24
+#else
#define DCNT_NUM_COUNTERS 21
+#endif
+
#define DCNT_ALL_COUNTERS DCNT_NUM_COUNTERS
#if defined(DAPL_COUNTERS)
Index: dapl/udapl/Makefile
===================================================================
--- dapl/udapl/Makefile (revision 5065)
+++ dapl/udapl/Makefile (working copy)
@@ -80,6 +80,13 @@ ifdef OS_VENDOR
CFLAGS += -D$(OS_VENDOR)
endif
+# If an implementation supports immdiate data and extensions
+CFLAGS += -DDAT_EXTENSIONS
+CFLAGS += -DDAT_IMMEDIATE_DATA
+
+# If an implementation supports DAPL provider specific attributes
+CFLAGS += -DDAPL_PROVIDER_SPECIFIC_ATTR
+
#
# dummy provider
#
@@ -283,6 +290,8 @@ LDFLAGS += -libverbs -lrdmacm
LDFLAGS += -rpath /usr/local/lib -L /usr/local/lib
PROVIDER_SRCS = dapl_ib_util.c dapl_ib_cq.c dapl_ib_qp.c \
dapl_ib_cm.c dapl_ib_mem.c
+# implementation supports extensions
+PROVIDER_SRCS += dapl_ib_extensions.c
endif
UDAPL_SRCS = dapl_init.c \
@@ -320,6 +329,9 @@ COMMON_SRCS = dapl_cookie.c \
dapl_ep_post_rdma_write.c \
dapl_ep_post_recv.c \
dapl_ep_post_send.c \
+ dapl_ep_post_recv_immed.c \
+ dapl_ep_post_send_immed.c \
+ dapl_ep_post_rdma_write_immed.c \
dapl_ep_query.c \
dapl_ep_util.c \
dapl_evd_dequeue.c \
Index: dapl/common/dapl_ep_post_recv_immed.c
===================================================================
--- dapl/common/dapl_ep_post_recv_immed.c (revision 0)
+++ dapl/common/dapl_ep_post_recv_immed.c (revision 0)
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2002-2003, Network Appliance, Inc. 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_ep_post_recv.c
+ *
+ * PURPOSE: Endpoint management
+ * Description: Interfaces in this file are completely described in
+ * the DAPL 1.1 API, Chapter 6, section 5
+ *
+ * $Id:$
+ **********************************************************************/
+
+#include "dapl.h"
+#include "dapl_cookie.h"
+#include "dapl_adapter_util.h"
+
+/*
+ * dapl_ep_post_recv_immed
+ *
+ * DAPL Requirements Version xxx, 6.5.11
+ *
+ * Request to receive data over the connection of ep handle into
+ * local_iov.
+ *
+ * Provide additional message buffer space for 32 bit immediate data.
+ *
+ * Input:
+ * ep_handle
+ * num_segments
+ * local_iov
+ * user_cookie
+ * completion_flags
+ *
+ * Output:
+ * None.
+ *
+ * Returns:
+ * DAT_SUCCESS
+ * DAT_INSUFFICIENT_RESOURCES
+ * DAT_INVALID_PARAMETER
+ * DAT_INVALID_STATE
+ * DAT_PROTECTION_VIOLATION
+ * DAT_PROVILEGES_VIOLATION
+ */
+DAT_RETURN
+dapl_ep_post_recv_immed (
+ IN DAT_EP_HANDLE ep_handle,
+ IN DAT_COUNT num_segments,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN DAT_COMPLETION_FLAGS completion_flags )
+{
+ DAPL_EP *ep_ptr;
+ DAPL_COOKIE *cookie;
+ DAT_RETURN dat_status;
+
+ dapl_dbg_log (DAPL_DBG_TYPE_API,
+ "dapl_ep_post_recv_immed(%p, %d, %p, %P, %x)\n",
+ ep_handle,
+ num_segments,
+ local_iov,
+ user_cookie.as_64,
+ completion_flags);
+ DAPL_CNTR (DCNT_POST_RECV);
+
+ if ( DAPL_BAD_HANDLE (ep_handle, DAPL_MAGIC_EP) )
+ {
+ dat_status = DAT_ERROR (DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+ goto bail;
+ }
+
+ ep_ptr = (DAPL_EP *) ep_handle;
+
+ /*
+ * Synchronization ok since this buffer is only used for receive
+ * requests, which aren't allowed to race with each other.
+ */
+ dat_status = dapls_dto_cookie_alloc (&ep_ptr->recv_buffer,
+ DAPL_DTO_TYPE_RECV_IMMED,
+ user_cookie,
+ &cookie);
+ if ( DAT_SUCCESS != dat_status)
+ {
+ goto bail;
+ }
+
+ /*
+ * Take reference before posting to avoid race conditions with
+ * completions
+ */
+ dapl_os_atomic_inc (&ep_ptr->recv_count);
+
+ /*
+ * Invoke provider specific routine to post DTO
+ */
+ dat_status = dapls_ib_post_recv_immed (ep_ptr, cookie, num_segments, local_iov);
+
+ if ( dat_status != DAT_SUCCESS )
+ {
+ dapl_os_atomic_dec (&ep_ptr->recv_count);
+ dapls_cookie_dealloc (&ep_ptr->recv_buffer, cookie);
+ }
+
+bail:
+ dapl_dbg_log (DAPL_DBG_TYPE_RTN,
+ "dapl_ep_post_recv_immed () returns 0x%x\n",
+ dat_status);
+
+ return dat_status;
+}
Index: dapl/common/dapl_ep_post_rdma_write.c
===================================================================
--- dapl/common/dapl_ep_post_rdma_write.c (revision 5065)
+++ dapl/common/dapl_ep_post_rdma_write.c (working copy)
@@ -78,7 +78,7 @@ dapl_ep_post_rdma_write (
DAT_RETURN dat_status;
dapl_dbg_log (DAPL_DBG_TYPE_API,
- "dapl_ep_post_rdma_write (%p, %d, %p, %p, %p, %x)\n",
+ "dapl_ep_post_rdma_write (%p, %d, %p, %P, %p, %x)\n",
ep_handle,
num_segments,
local_iov,
@@ -92,6 +92,9 @@ dapl_ep_post_rdma_write (
local_iov,
user_cookie,
remote_iov,
+#if DAT_IMMEDIATE_DATA
+ 0, 0,
+#endif
completion_flags,
DAPL_DTO_TYPE_RDMA_WRITE,
OP_RDMA_WRITE);
Index: dapl/common/dapl_ep_post_rdma_write_immed.c
===================================================================
--- dapl/common/dapl_ep_post_rdma_write_immed.c (revision 0)
+++ dapl/common/dapl_ep_post_rdma_write_immed.c (revision 0)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2002-2003, Network Appliance, Inc. 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_ep_post_rdma_write_immed.c
+ *
+ * PURPOSE: Endpoint management
+ * Description: Interfaces in this file are completely described in
+ * the DAPL 1.1 API, Chapter 6, section 5
+ *
+ * $Id:$
+ **********************************************************************/
+
+#include "dapl_ep_util.h"
+
+/*
+ * dapl_ep_post_rdma_write_immed
+ *
+ * DAPL Requirements Version xxx, 6.5.13
+ *
+ * Request the xfer of all data specified by the local_iov over the
+ * connection of ep handle Endpint into the remote_iov
+ *
+ * Input:
+ * ep_handle
+ * num_segments
+ * local_iov
+ * user_cookie
+ * remote_iov
+ * immed_data
+ * dto_flags
+ * compltion_flags
+ *
+ * Output:
+ * None.
+ *
+ * Returns:
+ * DAT_SUCCESS
+ * DAT_INSUFFICIENT_RESOURCES
+ * DAT_INVALID_PARAMETER
+ * DAT_INVALID_STATE
+ * DAT_LENGTH_ERROR
+ * DAT_PROTECTION_VIOLATION
+ * DAT_PRIVILEGES_VIOLATION
+ */
+DAT_RETURN
+dapl_ep_post_rdma_write_immed (
+ IN DAT_EP_HANDLE ep_handle,
+ IN DAT_COUNT num_segments,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN const DAT_RMR_TRIPLET *remote_iov,
+ IN DAT_UINT32 immed_data,
+ IN DAT_DTO_FLAGS dto_flags,
+ IN DAT_COMPLETION_FLAGS completion_flags )
+{
+ DAT_RETURN dat_status;
+
+ dapl_dbg_log (DAPL_DBG_TYPE_API,
+ "dapl_ep_post_rdma_write_immed (%p, %d, %p, %llx, %p, %x, %x, %x)\n",
+ ep_handle,
+ num_segments,
+ local_iov,
+ user_cookie.as_64,
+ remote_iov,
+ immed_data,
+ dto_flags,
+ completion_flags);
+ DAPL_CNTR(DCNT_POST_RDMA_WRITE_IMMED);
+
+ dat_status = dapl_ep_post_send_req(ep_handle,
+ num_segments,
+ local_iov,
+ user_cookie,
+ remote_iov,
+ immed_data,
+ dto_flags,
+ completion_flags,
+ DAPL_DTO_TYPE_RDMA_WRITE_IMMED,
+ OP_RDMA_WRITE_IMMED);
+
+ dapl_dbg_log (DAPL_DBG_TYPE_RTN,
+ "dapl_ep_post_rdma_write_immed () returns 0x%x",
+ dat_status);
+
+
+ return dat_status;
+}
Index: dapl/common/dapl_ia_query.c
===================================================================
--- dapl/common/dapl_ia_query.c (revision 5065)
+++ dapl/common/dapl_ia_query.c (working copy)
@@ -167,6 +167,14 @@ dapl_ia_query (
#if !defined(__KDAPL__)
provider_attr->pz_support = DAT_PZ_UNIQUE;
#endif /* !KDAPL */
+
+ /*
+ * Have provider set their own.
+ */
+#ifdef DAPL_PROVIDER_SPECIFIC_ATTR
+ dapls_set_provider_specific_attr(provider_attr);
+#endif
+
/*
* Set up evd_stream_merging_supported options. Note there is
* one bit per allowable combination, using the ordinal
Index: dapl/common/dapl_adapter_util.h
===================================================================
--- dapl/common/dapl_adapter_util.h (revision 5065)
+++ dapl/common/dapl_adapter_util.h (working copy)
@@ -256,6 +256,21 @@ dapls_ib_wait_object_wait (
IN u_int32_t timeout);
#endif
+#ifdef DAPL_PROVIDER_SPECIFIC_ATTR
+void
+dapls_set_provider_specific_attr(
+ IN DAT_PROVIDER_ATTR *provider_attr );
+#endif
+
+#ifdef DAT_EXTENSIONS
+void
+dapls_cqe_to_event_extension(
+ IN DAPL_EP *ep_ptr,
+ IN DAPL_COOKIE *cookie,
+ IN ib_work_completion_t *cqe_ptr,
+ OUT DAT_EVENT *event_ptr);
+#endif
+
/*
* Values for provider DAT_NAMED_ATTR
*/
@@ -272,6 +287,8 @@ dapls_ib_wait_object_wait (
#include "dapl_dummy_dto.h"
#elif OPENIB
#include "dapl_ib_dto.h"
+#elif DET
+#include "dapl_det_dto.h"
#endif
Index: dapl/common/dapl_ep_post_send.c
===================================================================
--- dapl/common/dapl_ep_post_send.c (revision 5065)
+++ dapl/common/dapl_ep_post_send.c (working copy)
@@ -75,7 +75,7 @@ dapl_ep_post_send (
DAT_RETURN dat_status;
dapl_dbg_log (DAPL_DBG_TYPE_API,
- "dapl_ep_post_send (%p, %d, %p, %p, %x)\n",
+ "dapl_ep_post_send (%p, %d, %p, %P, %x)\n",
ep_handle,
num_segments,
local_iov,
@@ -88,6 +88,9 @@ dapl_ep_post_send (
local_iov,
user_cookie,
&remote_iov,
+#if DAT_IMMEDIATE_DATA
+ 0, 0,
+#endif
completion_flags,
DAPL_DTO_TYPE_SEND,
OP_SEND);
Index: dapl/common/dapl_provider.c
===================================================================
--- dapl/common/dapl_provider.c (revision 5065)
+++ dapl/common/dapl_provider.c (working copy)
@@ -221,7 +221,19 @@ DAT_PROVIDER g_dapl_provider_template =
&dapl_srq_post_recv,
&dapl_srq_query,
&dapl_srq_resize,
- &dapl_srq_set_lw
+ &dapl_srq_set_lw,
+
+#ifdef DAT_IMMEDIATE_DATA
+ /* dat-2.0 */
+ &dapl_ep_post_send_immed,
+ &dapl_ep_post_recv_immed,
+ &dapl_ep_post_rdma_write_immed,
+#endif
+
+#ifdef DAT_EXTENSIONS
+ /* dat-2.0 */
+ &dapl_extensions
+#endif
};
#endif /* __KDAPL__ */
Index: dapl/common/dapl_ep_post_send_immed.c
===================================================================
--- dapl/common/dapl_ep_post_send_immed.c (revision 0)
+++ dapl/common/dapl_ep_post_send_immed.c (revision 0)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2002-2003, Network Appliance, Inc. 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_ep_post_send_immed.c
+ *
+ * PURPOSE: Endpoint management
+ * Description: Interfaces in this file are completely described in
+ * the DAPL 1.1 API, Chapter 6, section 5
+ *
+ * $Id:$
+ **********************************************************************/
+
+#include "dapl_ep_util.h"
+
+/*
+ * dapl_ep_post_send_immed
+ *
+ * DAPL Requirements Version xxx, 6.5.10
+ *
+ * Request a transfer of all the data from the local_iov over
+ * the connection of the ep handle Endpoint to the remote side.
+ *
+ * Input:
+ * ep_handle
+ * num_segments
+ * local_iov
+ * user_cookie
+ * immed_data
+ * dto_flags
+ * completion_flags
+ *
+ * Output:
+ * None
+ * Returns:
+ * DAT_SUCCESS
+ * DAT_INSUFFICIENT_RESOURCES
+ * DAT_INVALID_PARAMETER
+ * DAT_INVALID_STATE
+ * DAT_PROTECTION_VIOLATION
+ * DAT_PRIVILEGES_VIOLATION
+ */
+DAT_RETURN
+dapl_ep_post_send_immed (
+ IN DAT_EP_HANDLE ep_handle,
+ IN DAT_COUNT num_segments,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN DAT_UINT32 immed_data,
+ IN DAT_DTO_FLAGS dto_flags,
+ IN DAT_COMPLETION_FLAGS completion_flags )
+{
+ DAT_RMR_TRIPLET remote_iov = {0,0,0,0};
+ DAT_RETURN dat_status;
+
+ dapl_dbg_log (DAPL_DBG_TYPE_API,
+ "dapl_ep_post_send_immed (%p, %d, %p, %llx, %x, %x, %x)\n",
+ ep_handle,
+ num_segments,
+ local_iov,
+ user_cookie.as_64,
+ immed_data,
+ dto_flags,
+ completion_flags);
+ DAPL_CNTR(DCNT_POST_SEND_IMMED);
+
+ dat_status = dapl_ep_post_send_req(ep_handle,
+ num_segments,
+ local_iov,
+ user_cookie,
+ &remote_iov,
+ immed_data,
+ dto_flags,
+ completion_flags,
+ DAPL_DTO_TYPE_SEND_IMMED,
+ OP_SEND_IMMED);
+
+ dapl_dbg_log (DAPL_DBG_TYPE_RTN,
+ "dapl_ep_post_send () returns 0x%x\n",
+ dat_status);
+
+
+ return dat_status;
+}
Index: dapl/common/dapl_ep_util.c
===================================================================
--- dapl/common/dapl_ep_util.c (revision 5065)
+++ dapl/common/dapl_ep_util.c (working copy)
@@ -367,9 +367,13 @@ dapl_ep_post_send_req (
IN DAT_LMR_TRIPLET *local_iov,
IN DAT_DTO_COOKIE user_cookie,
IN const DAT_RMR_TRIPLET *remote_iov,
+#ifdef DAT_IMMEDIATE_DATA
+ IN DAT_UINT32 immed_data,
+ IN DAT_DTO_FLAGS dto_flags,
+#endif
IN DAT_COMPLETION_FLAGS completion_flags,
IN DAPL_DTO_TYPE dto_type,
- IN int op_type)
+ IN int op_type )
{
DAPL_EP *ep_ptr;
DAPL_COOKIE *cookie;
@@ -412,6 +416,10 @@ dapl_ep_post_send_req (
num_segments,
local_iov,
remote_iov,
+#ifdef DAT_IMMEDIATE_DATA
+ immed_data,
+ dto_flags,
+#endif
completion_flags );
if ( dat_status != DAT_SUCCESS )
Index: dapl/common/dapl_ep_util.h
===================================================================
--- dapl/common/dapl_ep_util.h (revision 5065)
+++ dapl/common/dapl_ep_util.h (working copy)
@@ -67,6 +67,10 @@ dapl_ep_post_send_req (
IN DAT_LMR_TRIPLET *local_iov,
IN DAT_DTO_COOKIE user_cookie,
IN const DAT_RMR_TRIPLET *remote_iov,
+#ifdef DAT_IMMEDIATE_DATA
+ IN DAT_UINT32 immed_data,
+ IN DAT_DTO_FLAGS dto_flags,
+#endif
IN DAT_COMPLETION_FLAGS completion_flags,
IN DAPL_DTO_TYPE dto_type,
IN int op_type );
Index: dapl/common/dapl_ep_post_rdma_read.c
===================================================================
--- dapl/common/dapl_ep_post_rdma_read.c (revision 5065)
+++ dapl/common/dapl_ep_post_rdma_read.c (working copy)
@@ -93,6 +93,9 @@ dapl_ep_post_rdma_read (
local_iov,
user_cookie,
remote_iov,
+#if DAT_IMMEDIATE_DATA
+ 0, 0,
+#endif
completion_flags,
DAPL_DTO_TYPE_RDMA_READ,
OP_RDMA_READ);
Index: dapl/common/dapl_evd_util.c
===================================================================
--- dapl/common/dapl_evd_util.c (revision 5065)
+++ dapl/common/dapl_evd_util.c (working copy)
@@ -502,6 +502,21 @@ dapli_evd_eh_print_cqe (
#ifdef DAPL_DBG
static char *optable[] =
{
+#ifdef OPENIB
+ /* different order for openib verbs */
+ "OP_RDMA_WRITE",
+ "OP_RDMA_WRITE_IMMED",
+ "OP_SEND",
+ "OP_SEND_IMMED",
+ "OP_RDMA_READ",
+ "OP_COMP_AND_SWAP",
+ "OP_FETCH_AND_ADD",
+ "OP_RECEIVE",
+ "OP_RECEIVE_IMMED",
+ "OP_RECEIVE_RDMA_IMMED",
+ "OP_BIND_MW",
+ "OP_INVALID",
+#else
"OP_SEND",
"OP_RDMA_READ",
"OP_RDMA_WRITE",
@@ -509,6 +524,7 @@ dapli_evd_eh_print_cqe (
"OP_FETCH_AND_ADD",
"OP_RECEIVE",
"OP_BIND_MW",
+#endif
0
};
@@ -1030,7 +1046,20 @@ dapli_evd_cqe_to_event (
{
DAPL_COOKIE_BUFFER *buffer;
+#ifdef DAT_EXTENSIONS
+ if ( DAPL_DTO_TYPE_EXTENSION == cookie->val.dto.type )
+ {
+ dapls_cqe_to_event_extension(ep_ptr, cookie, cqe_ptr, event_ptr);
+ break;
+ }
+#endif
+
+#if DAT_IMMEDIATE_DATA
+ if ( DAPL_DTO_TYPE_RECV == cookie->val.dto.type ||
+ DAPL_DTO_TYPE_RECV_IMMED == cookie->val.dto.type )
+#else
if ( DAPL_DTO_TYPE_RECV == cookie->val.dto.type )
+#endif
{
dapl_os_atomic_dec (&ep_ptr->recv_count);
buffer = &ep_ptr->recv_buffer;
@@ -1048,6 +1077,16 @@ dapli_evd_cqe_to_event (
cookie->val.dto.cookie;
event_ptr->event_data.dto_completion_event_data.status = dto_status;
+#ifdef DAT_IMMEDIATE_DATA
+ event_ptr->event_data.dto_completion_event_data.operation =
+ DAPL_GET_CQE_DTOS_OPTYPE(cqe_ptr);
+
+ if ( DAPL_GET_CQE_DTOS_OPTYPE(cqe_ptr) == DAT_RECEIVE_IMMED ||
+ DAPL_GET_CQE_DTOS_OPTYPE(cqe_ptr) == DAT_RECEIVE_RDMA_IMMED)
+ event_ptr->event_data.dto_completion_event_data.immed_data =
+ DAPL_GET_CQE_IMMED_DATA(cqe_ptr);
+#endif
+
#ifdef DAPL_DBG
if (dto_status == DAT_DTO_SUCCESS)
{
@@ -1055,18 +1094,42 @@ dapli_evd_cqe_to_event (
ibtype = DAPL_GET_CQE_OPTYPE (cqe_ptr);
- dapl_os_assert ((ibtype == OP_SEND &&
+ dapl_dbg_log(DAPL_DBG_TYPE_WARN,
+ " dapli_evd_cqe_to_event: OP type ib=%d, cookie=%d)\n",
+ ibtype, cookie->val.dto.type);
+#ifdef DAT_EXTENSIONS
+ if (cookie->val.dto.type != DAPL_DTO_TYPE_EXTENSION)
+#endif
+ dapl_os_assert ((ibtype == OP_SEND &&
cookie->val.dto.type == DAPL_DTO_TYPE_SEND)
- || (ibtype == OP_RECEIVE &&
- cookie->val.dto.type == DAPL_DTO_TYPE_RECV)
- || (ibtype == OP_RDMA_WRITE &&
- cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE)
- || (ibtype == OP_RDMA_READ &&
- cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_READ));
+#ifdef DAT_IMMEDIATE_DATA
+ || (ibtype == OP_RECEIVE &&
+ (cookie->val.dto.type == DAPL_DTO_TYPE_RECV ||
+ cookie->val.dto.type == DAPL_DTO_TYPE_RECV_IMMED))
+ || (ibtype == OP_RECEIVE_IMMED &&
+ cookie->val.dto.type == DAPL_DTO_TYPE_RECV_IMMED)
+ || (ibtype == OP_RECEIVE_RDMA_IMMED &&
+ cookie->val.dto.type == DAPL_DTO_TYPE_RECV_IMMED)
+ || (ibtype == OP_SEND_IMMED &&
+ cookie->val.dto.type == DAPL_DTO_TYPE_SEND_IMMED)
+ || (ibtype == OP_RDMA_WRITE_IMMED &&
+ cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE_IMMED)
+#else
+ || (ibtype == OP_RECEIVE &&
+ cookie->val.dto.type == DAPL_DTO_TYPE_RECV)
+#endif
+ || (ibtype == OP_RDMA_WRITE &&
+ cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE)
+ || (ibtype == OP_RDMA_READ &&
+ cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_READ));
}
#endif /* DAPL_DBG */
if ( cookie->val.dto.type == DAPL_DTO_TYPE_SEND ||
+#ifdef DAT_IMMEDIATE_DATA
+ cookie->val.dto.type == DAPL_DTO_TYPE_SEND_IMMED ||
+ cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE_IMMED ||
+#endif
cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE )
{
/* Get size from DTO; CQE value may be off. */
@@ -1113,6 +1176,7 @@ dapli_evd_cqe_to_event (
dapls_cookie_dealloc (&ep_ptr->req_buffer, cookie);
break;
}
+
default:
{
dapl_os_assert (!"Invalid Operation type");
Index: dapl/common/dapl_debug.c
===================================================================
--- dapl/common/dapl_debug.c (revision 5065)
+++ dapl/common/dapl_debug.c (working copy)
@@ -86,6 +86,11 @@ char *dapl_dbg_counter_names[] = {
"dapl_evd_not_found",
"dapls_timer_set",
"dapls_timer_cancel",
+#ifdef DAT_IMMEDIATE_DATA
+ "dapls_ep_post_send_immed",
+ "dapls_ep_post_recv_immed",
+ "dapls_ep_post_rdma_write_immed",
+#endif
};
void dapl_dump_cntr( int cntr )
Index: dapl/openib_cma/dapl_ib_dto.h
===================================================================
--- dapl/openib_cma/dapl_ib_dto.h (revision 5065)
+++ dapl/openib_cma/dapl_ib_dto.h (working copy)
@@ -35,7 +35,7 @@
*
* Description:
*
- * The uDAPL openib provider - DTO operations and CQE macros
+ * The OpenIB uCMA provider - DTO operations and CQE macros
*
****************************************************************************
* Source Control System Information
@@ -119,7 +119,6 @@ dapls_ib_post_recv (
return DAT_SUCCESS;
}
-
/*
* dapls_ib_post_send
*
@@ -133,6 +132,10 @@ dapls_ib_post_send (
IN DAT_COUNT segments,
IN DAT_LMR_TRIPLET *local_iov,
IN const DAT_RMR_TRIPLET *remote_iov,
+#ifdef DAT_IMMEDIATE_DATA
+ IN DAT_UINT32 immed_data,
+ IN DAT_DTO_FLAGS dto_flags,
+#endif
IN DAT_COMPLETION_FLAGS completion_flags)
{
dapl_dbg_log(DAPL_DBG_TYPE_EP,
@@ -191,8 +194,12 @@ dapls_ib_post_send (
if (cookie != NULL)
cookie->val.dto.size = total_len;
-
- if ((op_type == OP_RDMA_WRITE) || (op_type == OP_RDMA_READ)) {
+
+ if ((op_type == OP_RDMA_WRITE) ||
+#ifdef DAT_IMMEDIATE_DATA
+ (op_type == OP_RDMA_WRITE_IMMED) ||
+#endif
+ (op_type == OP_RDMA_READ)) {
wr.wr.rdma.remote_addr = remote_iov->target_address;
wr.wr.rdma.rkey = remote_iov->rmr_context;
dapl_dbg_log(DAPL_DBG_TYPE_EP,
@@ -200,6 +207,14 @@ dapls_ib_post_send (
wr.wr.rdma.rkey, wr.wr.rdma.remote_addr);
}
+#ifdef DAT_IMMEDIATE_DATA
+ if ((op_type == OP_SEND_IMMED) || (op_type == OP_RDMA_WRITE_IMMED)) {
+ dapl_dbg_log(DAPL_DBG_TYPE_EP,
+ " post_snd: IMMED=0x%x\n", immed_data);
+ wr.imm_data = immed_data;
+ }
+#endif
+
/* inline data for send or write ops */
if ((total_len <= ibt_ptr->max_inline_send) &&
((op_type == OP_SEND) || (op_type == OP_RDMA_WRITE)))
@@ -224,6 +239,182 @@ dapls_ib_post_send (
return DAT_SUCCESS;
}
+#ifdef DAT_IMMEDIATE_DATA
+
+STATIC _INLINE_ DAT_RETURN
+dapls_ib_post_recv_immed (
+ IN DAPL_EP *ep_ptr,
+ IN DAPL_COOKIE *cookie,
+ IN DAT_COUNT segments,
+ IN DAT_LMR_TRIPLET *local_iov )
+{
+ /* Nothing more to do, IB already provides space in descriptor */
+ return (dapls_ib_post_recv( ep_ptr, cookie, segments, local_iov));
+}
+
+/* map Work Completions to DAPL WR operations */
+STATIC _INLINE_ DAT_DTOS dapls_cqe_dtos_opcode(ib_work_completion_t *cqe_p)
+{
+ switch (cqe_p->opcode) {
+ case IBV_WC_SEND:
+ if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+ return (DAT_SEND_IMMED);
+ else
+ return (DAT_SEND);
+ case IBV_WC_RDMA_WRITE:
+ if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+ return (DAT_RDMA_WRITE_IMMED);
+ else
+ return (DAT_RDMA_WRITE);
+ case IBV_WC_RDMA_READ:
+ return (DAT_RDMA_READ);
+ case IBV_WC_BIND_MW:
+ return (DAT_BIND_MW);
+ case IBV_WC_RECV:
+ if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+ return (DAT_RECEIVE_IMMED);
+ else
+ return (DAT_RECEIVE);
+#ifdef DAT_EXTENSIONS
+ case IBV_WC_COMP_SWAP:
+ return (DAT_EXTENSION);
+ case IBV_WC_FETCH_ADD:
+ return (DAT_EXTENSION);
+#endif
+ case IBV_WC_RECV_RDMA_WITH_IMM:
+ return (DAT_RECEIVE_RDMA_IMMED);
+ default:
+ return (DAT_INVALID);
+ }
+}
+#define DAPL_GET_CQE_DTOS_OPTYPE(cqe_p) dapls_cqe_dtos_opcode(cqe_p)
+
+#endif
+
+#ifdef DAT_EXTENSIONS
+/*
+ * dapls_ib_post_ext_send
+ *
+ * Provider specific extended Post SEND function for atomics
+ * OP_COMP_AND_SWAP and OP_FETCH_AND_ADD
+ */
+STATIC _INLINE_ DAT_RETURN
+dapls_ib_post_ext_send (
+ IN DAPL_EP *ep_ptr,
+ IN ib_send_op_type_t op_type,
+ IN DAPL_COOKIE *cookie,
+ IN DAT_COUNT segments,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN const DAT_RMR_TRIPLET *remote_iov,
+ IN DAT_UINT64 compare_add,
+ IN DAT_UINT64 swap,
+ IN DAT_COMPLETION_FLAGS completion_flags)
+{
+ dapl_dbg_log(DAPL_DBG_TYPE_EP,
+ " post_snd: ep %p op %d ck %p sgs",
+ "%d l_iov %p r_iov %p f %d\n",
+ ep_ptr, op_type, cookie, segments, local_iov,
+ remote_iov, completion_flags);
+
+ ib_data_segment_t ds_array[DEFAULT_DS_ENTRIES];
+ ib_data_segment_t *ds_array_p;
+ struct ibv_send_wr wr;
+ struct ibv_send_wr *bad_wr;
+ DAT_COUNT i, total_len;
+
+ dapl_dbg_log(DAPL_DBG_TYPE_EP,
+ " post_snd: ep %p cookie %p segs %d l_iov %p\n",
+ ep_ptr, cookie, segments, local_iov);
+
+ if(segments <= DEFAULT_DS_ENTRIES)
+ ds_array_p = ds_array;
+ else
+ ds_array_p =
+ dapl_os_alloc(segments * sizeof(ib_data_segment_t));
+
+ if (NULL == ds_array_p)
+ return (DAT_INSUFFICIENT_RESOURCES);
+
+ /* setup the work request */
+ wr.next = 0;
+ wr.opcode = op_type;
+ wr.num_sge = 0;
+ wr.send_flags = 0;
+ wr.wr_id = (uint64_t)(uintptr_t)cookie;
+ wr.sg_list = ds_array_p;
+ total_len = 0;
+
+ for (i = 0; i < segments; i++ ) {
+ if ( !local_iov[i].segment_length )
+ continue;
+
+ ds_array_p->addr = (uint64_t) local_iov[i].virtual_address;
+ ds_array_p->length = local_iov[i].segment_length;
+ ds_array_p->lkey = local_iov[i].lmr_context;
+
+ dapl_dbg_log(DAPL_DBG_TYPE_EP,
+ " post_snd: lkey 0x%x va %p len %d\n",
+ ds_array_p->lkey, ds_array_p->addr,
+ ds_array_p->length );
+
+ total_len += ds_array_p->length;
+ wr.num_sge++;
+ ds_array_p++;
+ }
+
+ if (cookie != NULL)
+ cookie->val.dto.size = total_len;
+
+ switch (op_type) {
+ case OP_COMP_AND_SWAP:
+ /* OP_COMP_AND_SWAP has direct IBAL wr_type mapping */
+ dapl_dbg_log(DAPL_DBG_TYPE_EP,
+ " post_snd: OP_COMP_AND_SWAP=%lx,"
+ "%lx rkey 0x%x va %#016Lx\n",
+ compare_add, swap, remote_iov->rmr_context,
+ remote_iov->target_address);
+
+ wr.wr.atomic.compare_add = compare_add;
+ wr.wr.atomic.swap = swap;
+ wr.wr.atomic.remote_addr = remote_iov->target_address;
+ wr.wr.atomic.rkey = remote_iov->rmr_context;
+ break;
+ case OP_FETCH_AND_ADD:
+ /* OP_FETCH_AND_ADD has direct IBAL wr_type mapping */
+ dapl_dbg_log(DAPL_DBG_TYPE_EP,
+ " post_snd: OP_FETCH_AND_ADD=%lx,"
+ "%lx rkey 0x%x va %#016Lx\n",
+ compare_add, remote_iov->rmr_context,
+ remote_iov->target_address);
+
+ wr.wr.atomic.compare_add = compare_add;
+ wr.wr.atomic.remote_addr = remote_iov->target_address;
+ wr.wr.atomic.rkey = remote_iov->rmr_context;
+ break;
+ default:
+ break;
+ }
+
+ /* set completion flags in work request */
+ wr.send_flags |= (DAT_COMPLETION_SUPPRESS_FLAG &
+ completion_flags) ? 0 : IBV_SEND_SIGNALED;
+ wr.send_flags |= (DAT_COMPLETION_BARRIER_FENCE_FLAG &
+ completion_flags) ? IBV_SEND_FENCE : 0;
+ wr.send_flags |= (DAT_COMPLETION_SOLICITED_WAIT_FLAG &
+ completion_flags) ? IBV_SEND_SOLICITED : 0;
+
+ dapl_dbg_log(DAPL_DBG_TYPE_EP,
+ " post_snd: op 0x%x flags 0x%x sglist %p, %d\n",
+ wr.opcode, wr.send_flags, wr.sg_list, wr.num_sge);
+
+ if (ibv_post_send(ep_ptr->qp_handle->cm_id->qp, &wr, &bad_wr))
+ return( dapl_convert_errno(EFAULT,"ibv_recv") );
+
+ dapl_dbg_log(DAPL_DBG_TYPE_EP," post_snd: returned\n");
+ return DAT_SUCCESS;
+}
+#endif
+
STATIC _INLINE_ DAT_RETURN
dapls_ib_optional_prv_dat(
IN DAPL_CR *cr_ptr,
@@ -233,13 +424,17 @@ dapls_ib_optional_prv_dat(
return DAT_SUCCESS;
}
+/* map Work Completions to DAPL WR operations */
STATIC _INLINE_ int dapls_cqe_opcode(ib_work_completion_t *cqe_p)
{
switch (cqe_p->opcode) {
case IBV_WC_SEND:
return (OP_SEND);
case IBV_WC_RDMA_WRITE:
- return (OP_RDMA_WRITE);
+ if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+ return (OP_RDMA_WRITE_IMMED);
+ else
+ return (OP_RDMA_WRITE);
case IBV_WC_RDMA_READ:
return (OP_RDMA_READ);
case IBV_WC_COMP_SWAP:
@@ -249,14 +444,18 @@ STATIC _INLINE_ int dapls_cqe_opcode(ib_
case IBV_WC_BIND_MW:
return (OP_BIND_MW);
case IBV_WC_RECV:
- return (OP_RECEIVE);
+ if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+ return (OP_RECEIVE_IMMED);
+ else
+ return (OP_RECEIVE);
case IBV_WC_RECV_RDMA_WITH_IMM:
- return (OP_RECEIVE_IMM);
+ return (OP_RECEIVE_RDMA_IMMED);
default:
return (OP_INVALID);
}
}
+
#define DAPL_GET_CQE_OPTYPE(cqe_p) dapls_cqe_opcode(cqe_p)
#define DAPL_GET_CQE_WRID(cqe_p) ((ib_work_completion_t*)cqe_p)->wr_id
#define DAPL_GET_CQE_STATUS(cqe_p) ((ib_work_completion_t*)cqe_p)->status
Index: dapl/openib_cma/dapl_ib_util.c
===================================================================
--- dapl/openib_cma/dapl_ib_util.c (revision 5065)
+++ dapl/openib_cma/dapl_ib_util.c (working copy)
@@ -35,7 +35,7 @@
*
* Description:
*
- * The uDAPL openib provider - init, open, close, utilities, work thread
+ * The OpenIB uCMA provider - init, open, close, utilities, work thread
*
****************************************************************************
* Source Control System Information
@@ -64,7 +64,6 @@ static const char rcsid[] = "$Id: $";
#include <net/if.h> /* for struct ifreq */
#include <net/if_arp.h> /* for ARPHRD_INFINIBAND */
-
int g_dapl_loopback_connection = 0;
int g_ib_pipe[2];
ib_thread_state_t g_ib_thread_state = 0;
@@ -342,6 +341,7 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HC
struct timespec sleep, remain;
sleep.tv_sec = 0;
sleep.tv_nsec = 10000000; /* 10 ms */
+ write(g_ib_pipe[1], "w", sizeof "w");
dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
" ib_thread_destroy: wait on hca %p destroy\n");
nanosleep (&sleep, &remain);
@@ -727,7 +727,7 @@ void dapli_thread(void *arg)
int ret,idx,fds;
char rbuf[2];
- dapl_dbg_log (DAPL_DBG_TYPE_CM,
+ dapl_dbg_log (DAPL_DBG_TYPE_UTIL,
" ib_thread(%d,0x%x): ENTER: pipe %d ucma %d\n",
getpid(), g_ib_thread, g_ib_pipe[0], rdma_get_fd());
@@ -767,7 +767,7 @@ void dapli_thread(void *arg)
ufds[idx].revents = 0;
uhca[idx] = hca;
- dapl_dbg_log(DAPL_DBG_TYPE_CM,
+ dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
" ib_thread(%d) poll_fd: hca[%d]=%p, async=%d"
" pipe=%d cm=%d cq=d\n",
getpid(), hca, ufds[idx-1].fd,
@@ -783,14 +783,14 @@ void dapli_thread(void *arg)
dapl_os_unlock(&g_hca_lock);
ret = poll(ufds, fds, -1);
if (ret <= 0) {
- dapl_dbg_log(DAPL_DBG_TYPE_WARN,
+ dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
" ib_thread(%d): ERR %s poll\n",
getpid(),strerror(errno));
dapl_os_lock(&g_hca_lock);
continue;
}
- dapl_dbg_log(DAPL_DBG_TYPE_CM,
+ dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
" ib_thread(%d) poll_event: "
" async=0x%x pipe=0x%x cm=0x%x cq=0x%x\n",
getpid(), ufds[idx-1].revents, ufds[0].revents,
@@ -834,3 +834,54 @@ void dapli_thread(void *arg)
dapl_os_unlock(&g_hca_lock);
}
+#ifdef DAPL_PROVIDER_SPECIFIC_ATTR
+/*
+ * dapls_set_provider_specific_attr
+ *
+ * Input:
+ * attr_ptr Pointer provider attributes
+ *
+ * Output:
+ * none
+ *
+ * Returns:
+ * void
+ */
+DAT_NAMED_ATTR ib_attrs[] = {
+
+#ifdef DAT_EXTENSIONS
+ {
+ DAT_EXTENSION_ATTR,
+ DAT_EXTENSION_ATTR_TRUE
+ },
+ {
+ DAT_EXTENSION_ATTR_VERSION,
+ DAT_EXTENSION_ATTR_VERSION_VALUE
+ },
+ {
+ DAT_EXTENSION_ATTR_FETCH_AND_ADD,
+ DAT_EXTENSION_ATTR_TRUE
+ },
+ {
+ DAT_EXTENSION_ATTR_CMP_AND_SWAP,
+ DAT_EXTENSION_ATTR_TRUE
+ },
+#else
+ {
+ "DAT_EXTENSION_INTERFACE",
+ "FALSE"
+ },
+#endif
+};
+
+#define SPEC_ATTR_SIZE(x) ( sizeof(x)/sizeof(DAT_NAMED_ATTR) )
+
+void dapls_set_provider_specific_attr(
+ IN DAT_PROVIDER_ATTR *attr_ptr )
+{
+ attr_ptr->num_provider_specific_attr = SPEC_ATTR_SIZE(ib_attrs);
+ attr_ptr->provider_specific_attr = ib_attrs;
+}
+
+#endif
+
Index: dapl/openib_cma/dapl_ib_mem.c
===================================================================
--- dapl/openib_cma/dapl_ib_mem.c (revision 5065)
+++ dapl/openib_cma/dapl_ib_mem.c (working copy)
@@ -25,9 +25,9 @@
/**********************************************************************
*
- * MODULE: dapl_det_mem.c
+ * MODULE: dapl_ib_mem.c
*
- * PURPOSE: Intel DET APIs: Memory windows, registration,
+ * PURPOSE: OpenIB uCMA provider Memory windows, registration,
* and protection domain
*
* $Id: $
@@ -65,6 +65,10 @@ dapls_convert_privileges(IN DAT_MEM_PRIV
{
int access = 0;
+ dapl_dbg_log(DAPL_DBG_TYPE_WARN,
+ " dapls_convert_privileges: 0x%x\n",
+ privileges );
+
/*
* if (DAT_MEM_PRIV_LOCAL_READ_FLAG & privileges) do nothing
*/
@@ -72,12 +76,13 @@ dapls_convert_privileges(IN DAT_MEM_PRIV
access |= IBV_ACCESS_LOCAL_WRITE;
if (DAT_MEM_PRIV_REMOTE_WRITE_FLAG & privileges)
access |= IBV_ACCESS_REMOTE_WRITE;
- if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)
- access |= IBV_ACCESS_REMOTE_READ;
- if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)
- access |= IBV_ACCESS_REMOTE_READ;
- if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)
+ if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)
access |= IBV_ACCESS_REMOTE_READ;
+
+#ifdef DAT_EXTENSIONS
+ if (DAT_MEM_PRIV_EXT_REMOTE_ATOMIC & privileges)
+ access |= IBV_ACCESS_REMOTE_ATOMIC;
+#endif
return access;
}
Index: dapl/openib_cma/dapl_ib_extensions.c
===================================================================
--- dapl/openib_cma/dapl_ib_extensions.c (revision 0)
+++ dapl/openib_cma/dapl_ib_extensions.c (revision 0)
@@ -0,0 +1,374 @@
+/*
+ * 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_cmp_and_swap(
+ IN DAT_EP_HANDLE ep_handle,
+ IN DAT_UINT64 cmp_val,
+ IN DAT_UINT64 swap_val,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN const DAT_RMR_TRIPLET *remote_iov,
+ IN DAT_COMPLETION_FLAGS flags );
+
+DAT_RETURN
+dapli_post_fetch_and_add(
+ IN DAT_EP_HANDLE ep_handle,
+ IN DAT_UINT64 add_val,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN const DAT_RMR_TRIPLET *remote_iov,
+ 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_DTO_EXTENSION_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_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_DTO_EXTENSION_CMP_AND_SWAP:
+ 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_cmp_and_swap(ep,
+ dat_uint64a,
+ dat_uint64b,
+ lmr_p,
+ cookie,
+ rmr_p,
+ comp_flags );
+ break;
+
+ case DAT_DTO_EXTENSION_FETCH_AND_ADD:
+ 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_fetch_and_add(ep,
+ dat_uint64a,
+ lmr_p,
+ cookie,
+ rmr_p,
+ comp_flags );
+ break;
+
+ default:
+ dapl_dbg_log(DAPL_DBG_TYPE_ERR,
+ "unsupported extension(%d)\n", (int)ext_op);
+ }
+
+ return(status);
+}
+
+
+DAT_RETURN
+dapli_post_cmp_and_swap(IN DAT_EP_HANDLE ep_handle,
+ IN DAT_UINT64 cmp_val,
+ IN DAT_UINT64 swap_val,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN const DAT_RMR_TRIPLET *remote_iov,
+ IN DAT_COMPLETION_FLAGS flags )
+{
+ DAPL_EP *ep_ptr;
+ ib_qp_handle_t qp_ptr;
+ DAPL_COOKIE *cookie;
+ DAT_RETURN dat_status = DAT_SUCCESS;
+
+ dapl_dbg_log(DAPL_DBG_TYPE_API,
+ " post_cmp_and_swap: ep %p cmp_val %d "
+ "swap_val %d cookie 0x%x, r_iov %p, flags 0x%x\n",
+ ep_handle, (unsigned)cmp_val, (unsigned)swap_val,
+ (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));
+
+ if ((NULL == remote_iov) || (NULL == local_iov))
+ return DAT_INVALID_PARAMETER;
+
+ 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.
+ * only if completion is expected
+ */
+ if (!(DAT_COMPLETION_SUPPRESS_FLAG & flags)) {
+
+ 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_COMP_AND_SWAP,
+ cookie,
+ 1,
+ local_iov,
+ remote_iov,
+ cmp_val, /* compare or add */
+ swap_val, /* swap */
+ flags);
+
+ if (dat_status != DAT_SUCCESS) {
+ if ( cookie != NULL ) {
+ dapl_os_atomic_dec(&ep_ptr->req_count);
+ dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
+ }
+ }
+
+bail:
+ return dat_status;
+
+}
+
+DAT_RETURN
+dapli_post_fetch_and_add(IN DAT_EP_HANDLE ep_handle,
+ IN DAT_UINT64 add_val,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN const DAT_RMR_TRIPLET *remote_iov,
+ IN DAT_COMPLETION_FLAGS flags )
+{
+ DAPL_EP *ep_ptr;
+ DAPL_COOKIE *cookie;
+ DAT_RETURN dat_status = DAT_SUCCESS;
+
+ dapl_dbg_log (DAPL_DBG_TYPE_API,
+ " post_fetch_and_add: ep %p add_val %d local_iov"
+ "%p cookie 0x%x, r_iov %p, flags 0x%x\n",
+ ep_handle, (unsigned)add_val, local_iov,
+ (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));
+
+ if ((NULL == remote_iov) || (NULL == local_iov))
+ return DAT_INVALID_PARAMETER;
+
+ ep_ptr = (DAPL_EP *) ep_handle;
+
+ /*
+ * Synchronization ok since this buffer is only used for send
+ * requests, which aren't allowed to race with each other.
+ * only if completion is expected
+ */
+ if (!(DAT_COMPLETION_SUPPRESS_FLAG & flags)) {
+
+ 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_FETCH_AND_ADD,
+ cookie,
+ 1,
+ local_iov,
+ remote_iov,
+ add_val, /* compare or add */
+ 0, /* swap */
+ flags);
+
+ if (dat_status != DAT_SUCCESS) {
+ if (cookie != NULL ) {
+ 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;
+ DAPL_COOKIE_BUFFER *buffer;
+ DAT_DTO_COMPLETION_EVENT_DATA *dto_event =
+ &event_ptr->event_data.dto_completion_event_data;
+
+ dapl_dbg_log(DAPL_DBG_TYPE_EVD,
+ " cqe_to_event_ext: event_ptr %p dto_event %p\n",
+ event_ptr, dto_event);
+
+
+ if ( DAPL_DTO_TYPE_RECV == cookie->val.dto.type ||
+ DAPL_DTO_TYPE_RECV_IMMED == cookie->val.dto.type ) {
+ dapl_os_atomic_dec (&ep_ptr->recv_count);
+ buffer = &ep_ptr->recv_buffer;
+ }
+ else {
+ dapl_os_atomic_dec (&ep_ptr->req_count);
+ buffer = &ep_ptr->req_buffer;
+ }
+
+ /* update DTO event data and then the extension */
+ event_ptr->event_number = DAT_DTO_COMPLETION_EVENT;
+ dto_event->operation = DAT_EXTENSION;
+ dto_event->ep_handle = cookie->ep;
+ dto_event->user_cookie = cookie->val.dto.cookie;
+ dto_event->status = dapls_ib_get_dto_status(cqe_ptr);
+
+ if (dto_event->status != DAT_DTO_SUCCESS )
+ return;
+
+ /* get operation type from CQ work completion entry */
+ ibtype = DAPL_GET_CQE_OPTYPE(cqe_ptr);
+
+ switch (ibtype) {
+ 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 */
+ dto_event->extension.type = DAT_DTO_EXTENSION_CMP_AND_SWAP;
+ 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 */
+ dto_event->extension.type = DAT_DTO_EXTENSION_FETCH_AND_ADD;
+ break;
+
+ default:
+ dapl_dbg_log(DAPL_DBG_TYPE_DTO_COMP_ERR,
+ "Extension completion ERROR: unknown op = 0x%x\n",
+ ibtype);
+ }
+
+ if (cookie->val.dto.type == DAPL_DTO_TYPE_SEND ||
+ cookie->val.dto.type == DAPL_DTO_TYPE_SEND_IMMED ||
+ cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE_IMMED ||
+ cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE )
+ /* Get size from DTO; CQE value may be off. */
+ dto_event->transfered_length = cookie->val.dto.size;
+ else
+ dto_event->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);
+
+ dapls_cookie_dealloc(buffer, cookie);
+}
Index: dapl/openib_cma/dapl_ib_qp.c
===================================================================
--- dapl/openib_cma/dapl_ib_qp.c (revision 5065)
+++ dapl/openib_cma/dapl_ib_qp.c (working copy)
@@ -25,9 +25,9 @@
/**********************************************************************
*
- * MODULE: dapl_det_qp.c
+ * MODULE: dapl_ib_qp.c
*
- * PURPOSE: QP routines for access to DET Verbs
+ * PURPOSE: OpenIB uCMA QP routines
*
* $Id: $
**********************************************************************/
Index: dapl/openib_cma/dapl_ib_util.h
===================================================================
--- dapl/openib_cma/dapl_ib_util.h (revision 5065)
+++ dapl/openib_cma/dapl_ib_util.h (working copy)
@@ -35,7 +35,7 @@
*
* Description:
*
- * The uDAPL openib provider - definitions, prototypes,
+ * The OpenIB uCMA provider - definitions, prototypes,
*
****************************************************************************
* Source Control System Information
@@ -123,15 +123,16 @@ typedef struct ibv_comp_channel *ib_wait
/* DTO OPs, ordered for DAPL ENUM definitions */
#define OP_RDMA_WRITE IBV_WR_RDMA_WRITE
-#define OP_RDMA_WRITE_IMM IBV_WR_RDMA_WRITE_WITH_IMM
+#define OP_RDMA_WRITE_IMMED IBV_WR_RDMA_WRITE_WITH_IMM
#define OP_SEND IBV_WR_SEND
-#define OP_SEND_IMM IBV_WR_SEND_WITH_IMM
+#define OP_SEND_IMMED IBV_WR_SEND_WITH_IMM
#define OP_RDMA_READ IBV_WR_RDMA_READ
#define OP_COMP_AND_SWAP IBV_WR_ATOMIC_CMP_AND_SWP
#define OP_FETCH_AND_ADD IBV_WR_ATOMIC_FETCH_AND_ADD
-#define OP_RECEIVE 7 /* internal op */
-#define OP_RECEIVE_IMM 8 /* internel op */
-#define OP_BIND_MW 9 /* internal op */
+#define OP_RECEIVE 0x7 /* internal op */
+#define OP_RECEIVE_IMMED 0x8 /* internel op */
+#define OP_RECEIVE_RDMA_IMMED 0x9 /* internal op */
+#define OP_BIND_MW 0xa /* internal op */
#define OP_INVALID 0xff
/* Definitions to map QP state */
@@ -295,7 +296,8 @@ dapl_convert_errno( IN int err, IN const
if (!err) return DAT_SUCCESS;
#if DAPL_DBG
- if ((err != EAGAIN) && (err != ETIME) && (err != ETIMEDOUT))
+ if ((err != EAGAIN) && (err != ETIME) &&
+ (err != ETIMEDOUT) && (err != EINTR))
dapl_dbg_log (DAPL_DBG_TYPE_ERR," %s %s\n", str, strerror(err));
#endif
Index: dapl/openib_cma/dapl_ib_cq.c
===================================================================
--- dapl/openib_cma/dapl_ib_cq.c (revision 5065)
+++ dapl/openib_cma/dapl_ib_cq.c (working copy)
@@ -35,7 +35,7 @@
*
* Description:
*
- * The uDAPL openib provider - completion queue
+ * The OpenIB uCMA provider - completion queue
*
****************************************************************************
* Source Control System Information
@@ -498,7 +498,10 @@ dapls_ib_wait_object_wait(IN ib_wait_obj
if (timeout != DAT_TIMEOUT_INFINITE)
timeout_ms = timeout/1000;
- status = poll(&cq_fd, 1, timeout_ms);
+ /* restart syscall */
+ while ((status = poll(&cq_fd, 1, timeout_ms)) == -1 )
+ if (errno == EINTR)
+ continue;
/* returned event */
if (status > 0) {
@@ -511,6 +514,8 @@ dapls_ib_wait_object_wait(IN ib_wait_obj
/* timeout */
} else if (status == 0)
status = ETIMEDOUT;
+ else
+ status = errno;
dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
" cq_object_wait: RET evd %p ibv_cq %p ibv_ctx %p %s\n",
Index: dat/include/dat/udat.h
===================================================================
--- dat/include/dat/udat.h (revision 5065)
+++ dat/include/dat/udat.h (working copy)
@@ -1,31 +1,51 @@
/*
- * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
+ * Copyright (c) 2002-2004, Network Appliance, Inc. 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
- * in the file LICENSE.txt in the root directory. The license is also
- * available from the Open Source Initiative, see
+ * This Software is licensed under both of the following two licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0". The license is also
+ * 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 in the file
- * LICENSE2.txt in the root directory. The license is also available from
- * the Open Source Initiative, see
+ *
+ * OR
+ *
+ * 2) under the terms of the "The BSD License". The license is also 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 in the file LICENSE3.txt in the root directory. The
- * license is also 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.
- *
+ *
+ * Licensee has the right to choose either one of the above two licenses.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain both the above copyright
+ * notice and either one of the license notices.
+ *
* Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
+ * notice, either one of the license notices in the documentation
* and/or other materials provided with the distribution.
+ *
+ * Neither the name of Network Appliance, Inc. nor the names of other DAT
+ * Collaborative contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
*/
/****************************************************************
Index: dat/include/dat/dat_redirection.h
===================================================================
--- dat/include/dat/dat_redirection.h (revision 5065)
+++ dat/include/dat/dat_redirection.h (working copy)
@@ -59,10 +59,10 @@ typedef struct dat_provider DAT_PROVIDER
* This would allow a good compiler to avoid indirection overhead when
* making function calls.
*/
-
#define DAT_HANDLE_TO_PROVIDER(handle) (*(DAT_PROVIDER **)(handle))
#endif
+
#define DAT_IA_QUERY(ia, evd, ia_msk, ia_ptr, p_msk, p_ptr) \
(*DAT_HANDLE_TO_PROVIDER (ia)->ia_query_func) (\
(ia), \
@@ -395,6 +395,45 @@ typedef struct dat_provider DAT_PROVIDER
(lbuf), \
(cookie))
+#ifdef DAT_IMMEDIATE_DATA
+#define DAT_EP_POST_SEND_IMMED(ep, size, lbuf, cookie, immed, dflags, flags) \
+ (*DAT_HANDLE_TO_PROVIDER (ep)->ep_post_send_immed_func) (\
+ (ep), \
+ (size), \
+ (lbuf), \
+ (cookie), \
+ (immed), \
+ (dflags), \
+ (flags))
+
+#define DAT_EP_POST_RECV_IMMED(ep, size, lbuf, cookie, flags) \
+ (*DAT_HANDLE_TO_PROVIDER (ep)->ep_post_recv_immed_func) (\
+ (ep), \
+ (size), \
+ (lbuf), \
+ (cookie), \
+ (flags))
+
+#define DAT_EP_POST_RDMA_WRITE_IMMED(ep, size, lbuf, cookie, rbuf, immed, dflags, flags) \
+ (*DAT_HANDLE_TO_PROVIDER (ep)->ep_post_rdma_write_immed_func) (\
+ (ep), \
+ (size), \
+ (lbuf), \
+ (cookie), \
+ (rbuf), \
+ (immed), \
+ (dflags), \
+ (flags))
+#endif
+
+#ifdef DAT_EXTENSIONS
+#define DAT_EXTENSION(handle, op, args) \
+ (*DAT_HANDLE_TO_PROVIDER (handle)->extension_func) (\
+ (handle), \
+ (op), \
+ (args))
+#endif
+
/***************************************************************
*
* FUNCTION PROTOTYPES
@@ -720,4 +759,41 @@ typedef DAT_RETURN (*DAT_SRQ_POST_RECV_F
IN DAT_LMR_TRIPLET *, /* local_iov */
IN DAT_DTO_COOKIE ); /* user_cookie */
+#ifdef DAT_IMMEDIATE_DATA
+typedef DAT_RETURN (*DAT_EP_POST_SEND_IMMED_FUNC) (
+ IN DAT_EP_HANDLE, /* ep_handle */
+ IN DAT_COUNT, /* num_segments */
+ IN DAT_LMR_TRIPLET *, /* local_iov */
+ IN DAT_DTO_COOKIE, /* user_cookie */
+ IN DAT_UINT32, /* immediate data */
+ IN DAT_DTO_FLAGS, /* dto_flags */
+ IN DAT_COMPLETION_FLAGS ); /* completion_flags */
+
+typedef DAT_RETURN (*DAT_EP_POST_RECV_IMMED_FUNC) (
+ IN DAT_EP_HANDLE, /* ep_handle */
+ IN DAT_COUNT, /* num_segments */
+ IN DAT_LMR_TRIPLET *, /* local_iov */
+ IN DAT_DTO_COOKIE, /* user_cookie */
+ IN DAT_COMPLETION_FLAGS ); /* completion_flags */
+
+typedef DAT_RETURN (*DAT_EP_POST_RDMA_WRITE_IMMED_FUNC) (
+ IN DAT_EP_HANDLE, /* ep_handle */
+ IN DAT_COUNT, /* num_segments */
+ IN DAT_LMR_TRIPLET *, /* local_iov */
+ IN DAT_DTO_COOKIE, /* user_cookie */
+ IN const DAT_RMR_TRIPLET *,/* remote_iov */
+ IN DAT_UINT32, /* immediate data */
+ IN DAT_DTO_FLAGS, /* dto_flags */
+ IN DAT_COMPLETION_FLAGS ); /* completion_flags */
+#endif
+
+#ifdef DAT_EXTENSIONS
+#include <stdarg.h>
+typedef DAT_RETURN (*DAT_EXTENSION_FUNC) (
+ IN DAT_HANDLE, /* dat handle */
+ IN DAT_DTO_EXTENSION_OP, /* extension operation */
+ IN va_list ); /* va_list */
+#endif
+
+
#endif /* _DAT_REDIRECTION_H_ */
Index: dat/include/dat/dat.h
===================================================================
--- dat/include/dat/dat.h (revision 5065)
+++ dat/include/dat/dat.h (working copy)
@@ -119,6 +119,27 @@ typedef DAT_HANDLE DAT_RMR_HANDLE;
typedef DAT_HANDLE DAT_RSP_HANDLE;
typedef DAT_HANDLE DAT_SRQ_HANDLE;
+/* PROTOTYPE: immediate data and extensions */
+#ifdef DAT_IMMEDIATE_DATA
+typedef enum dat_dtos
+{
+ DAT_SEND,
+ DAT_SEND_IMMED,
+ DAT_RDMA_WRITE,
+ DAT_RDMA_WRITE_IMMED,
+ DAT_RDMA_READ,
+ DAT_RECEIVE,
+ DAT_RECEIVE_WITH_INVALIDATE,
+ DAT_RECEIVE_IMMED,
+ DAT_RECEIVE_RDMA_IMMED,
+ DAT_BIND_MW,
+#ifdef DAT_EXTENSIONS
+ DAT_EXTENSION,
+#endif
+ DAT_INVALID
+} DAT_DTOS;
+#endif
+
/* dat NULL handles */
#define DAT_HANDLE_NULL ((DAT_HANDLE)NULL)
@@ -176,6 +197,15 @@ typedef enum dat_psp_flags
DAT_PSP_PROVIDER_FLAG = 0x01 /* Provider creates an Endpoint */
} DAT_PSP_FLAGS;
+#ifdef DAT_IMMEDIATE_DATA
+typedef enum dat_dto_flags
+{
+ DAT_DTO_IMMED_FLAG = 0x1,
+ DAT_DTO_IMMED_CONFIRM_FLAG = 0x2
+
+} DAT_DTO_FLAGS;
+#endif
+
/*
* Memory Buffers
*
@@ -259,7 +289,6 @@ typedef struct dat_rmr_triplet
*/
/* Memory privileges */
-
typedef enum dat_mem_priv_flags
{
DAT_MEM_PRIV_NONE_FLAG = 0x00,
@@ -267,7 +296,11 @@ typedef enum dat_mem_priv_flags
DAT_MEM_PRIV_REMOTE_READ_FLAG = 0x02,
DAT_MEM_PRIV_LOCAL_WRITE_FLAG = 0x10,
DAT_MEM_PRIV_REMOTE_WRITE_FLAG = 0x20,
- DAT_MEM_PRIV_ALL_FLAG = 0x33
+ DAT_MEM_PRIV_MW_BIND_FLAG = 0x40,
+ DAT_MEM_PRIV_ALL_FLAG = 0x73,
+#ifdef DAT_EXTENSIONS
+ DAT_MEM_PRIV_EXTENSION = 0x10000
+#endif
} DAT_MEM_PRIV_FLAGS;
/* For backward compatibility with DAT-1.0, memory privileges values are
@@ -712,6 +745,10 @@ typedef enum dat_dto_completion_status
/* Completion group structs (six total) */
+#ifdef DAT_EXTENSIONS
+#include <dat/dat_extensions.h>
+#endif
+
/* DTO completion event data */
/* transfered_length is not defined if status is not DAT_SUCCESS */
typedef struct dat_dto_completion_event_data
@@ -719,7 +756,15 @@ typedef struct dat_dto_completion_event_
DAT_EP_HANDLE ep_handle;
DAT_DTO_COOKIE user_cookie;
DAT_DTO_COMPLETION_STATUS status;
- DAT_VLEN transfered_length;
+ DAT_VLEN transfered_length;
+#ifdef DAT_IMMEDIATE_DATA
+ DAT_DTOS operation;
+ DAT_RMR_CONTEXT rmr_context;
+ DAT_UINT32 immed_data;
+#endif
+#ifdef DAT_EXTENSIONS
+ DAT_DTO_EXTENSION_EVENT_DATA extension;
+#endif
} DAT_DTO_COMPLETION_EVENT_DATA;
/* RMR bind completion event data */
@@ -854,11 +899,11 @@ typedef enum dat_event_number
DAT_ASYNC_ERROR_EP_BROKEN = 0x08003,
DAT_ASYNC_ERROR_TIMED_OUT = 0x08004,
DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR = 0x08005,
- DAT_SOFTWARE_EVENT = 0x10001
+ DAT_SOFTWARE_EVENT = 0x10001,
+
} DAT_EVENT_NUMBER;
/* Union for event Data */
-
typedef union dat_event_data
{
DAT_DTO_COMPLETION_EVENT_DATA dto_completion_event_data;
@@ -1222,6 +1267,41 @@ extern DAT_RETURN dat_srq_set_lw (
IN DAT_SRQ_HANDLE, /* srq_handle */
IN DAT_COUNT); /* low_watermark */
+#ifdef DAT_IMMEDIATE_DATA
+extern DAT_RETURN dat_ep_post_send_immed (
+ IN DAT_EP_HANDLE, /* ep_handle */
+ IN DAT_COUNT, /* num_segments */
+ IN DAT_LMR_TRIPLET *, /* local_iov */
+ IN DAT_DTO_COOKIE, /* user_cookie */
+ IN DAT_UINT32, /* immediate data */
+ IN DAT_DTO_FLAGS, /* dto_flags */
+ IN DAT_COMPLETION_FLAGS ); /* completion_flags */
+
+extern DAT_RETURN dat_ep_post_recv_immed (
+ IN DAT_EP_HANDLE, /* ep_handle */
+ IN DAT_COUNT, /* num_segments */
+ IN DAT_LMR_TRIPLET *, /* local_iov */
+ IN DAT_DTO_COOKIE, /* user_cookie */
+ IN DAT_COMPLETION_FLAGS ); /* completion_flags */
+
+extern DAT_RETURN dat_ep_post_rdma_write_immed (
+ IN DAT_EP_HANDLE, /* ep_handle */
+ IN DAT_COUNT, /* num_segments */
+ IN DAT_LMR_TRIPLET *, /* local_iov */
+ IN DAT_DTO_COOKIE, /* user_cookie */
+ IN const DAT_RMR_TRIPLET *,/* remote_iov */
+ IN DAT_UINT32, /* immediate data */
+ IN DAT_DTO_FLAGS, /* dto_flags */
+ IN DAT_COMPLETION_FLAGS ); /* completion_flags */
+#endif
+
+#ifdef DAT_EXTENSIONS
+extern DAT_RETURN dat_extension(
+ IN DAT_HANDLE,
+ IN DAT_DTO_EXTENSION_OP,
+ IN ... );
+#endif
+
/*
* DAT registry functions.
*
Index: dat/include/dat/dat_error.h
===================================================================
--- dat/include/dat/dat_error.h (revision 5065)
+++ dat/include/dat/dat_error.h (working copy)
@@ -1,31 +1,51 @@
/*
- * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
+ * Copyright (c) 2002-2004, Network Appliance, Inc. 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
- * in the file LICENSE.txt in the root directory. The license is also
- * available from the Open Source Initiative, see
+ * This Software is licensed under both of the following two licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0". The license is also
+ * 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 in the file
- * LICENSE2.txt in the root directory. The license is also available from
- * the Open Source Initiative, see
+ *
+ * OR
+ *
+ * 2) under the terms of the "The BSD License". The license is also 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 in the file LICENSE3.txt in the root directory. The
- * license is also 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.
- *
+ *
+ * Licensee has the right to choose either one of the above two licenses.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain both the above copyright
+ * notice and either one of the license notices.
+ *
* Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
+ * notice, either one of the license notices in the documentation
* and/or other materials provided with the distribution.
+ *
+ * Neither the name of Network Appliance, Inc. nor the names of other DAT
+ * Collaborative contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
*/
/***********************************************************
@@ -47,17 +67,15 @@
/*
*
- * All return codes are actually a 3-way tuple:
- *
- * type: DAT_RETURN_CLASS DAT_RETURN_TYPE DAT_RETURN_SUBTYPE
- * bits: 31-30 29-16 15-0
+ * All return codes are actually a 4-way tuple:
*
- * 3 2 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | C | DAT_RETURN_TYPE | DAT_RETURN_SUBTYPE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * type: CLASS RETURN_TYPE EXTENSION_SUBTYPE SUBTYPE
+ * bits: 31-30 29-16 15-8 7-0
*
+ * +-------------------------------------------------------------------------+
+ * |3130 | 2928272625242322212019181716 | 15141312111009080 | 706054003020100|
+ * |CLAS | DAT_TYPE_STATUS | EXTENSION_SUBTYPE | SUBTYPE |
+ * +-------------------------------------------------------------------------+
*/
/*
@@ -70,8 +88,13 @@
* DAT Error bits
*/
#define DAT_TYPE_MASK 0x3fff0000 /* mask for DAT_TYPE_STATUS bits */
-#define DAT_SUBTYPE_MASK 0x0000FFFF /* mask for DAT_SUBTYPE_STATUS bits */
+#define DAT_SUBTYPE_MASK 0x000000FF /* mask for DAT_SUBTYPE_STATUS bits */
+#ifdef DAT_EXTENSIONS
+/* Mask and macro for new extension subtype bits */
+#define DAT_EXTENSION_SUBTYPE_MASK 0x0000FF00 /* mask for DAT_EXTENSION_SUBTYPE_STATUS bits */
+#define DAT_GET_EXTENSION_SUBTYPE(status) ((DAT_UINT32)(status) & DAT_EXTENSION_SUBTYPE_MASK)
+#endif
/*
* Determining the success of an operation is best done with a macro;
* each of these returns a boolean value.
Index: dat/include/dat/udat_redirection.h
===================================================================
--- dat/include/dat/udat_redirection.h (revision 5065)
+++ dat/include/dat/udat_redirection.h (working copy)
@@ -199,13 +199,12 @@ typedef DAT_RETURN (*DAT_EVD_SET_UNWAITA
typedef DAT_RETURN (*DAT_EVD_CLEAR_UNWAITABLE_FUNC) (
IN DAT_EVD_HANDLE); /* evd_handle */
-
#include <dat/dat_redirection.h>
struct dat_provider
{
const char * device_name;
- DAT_PVOID extension;
+ DAT_PVOID extension;
DAT_IA_OPEN_FUNC ia_open_func;
DAT_IA_QUERY_FUNC ia_query_func;
@@ -294,6 +293,19 @@ struct dat_provider
DAT_SRQ_QUERY_FUNC srq_query_func;
DAT_SRQ_RESIZE_FUNC srq_resize_func;
DAT_SRQ_SET_LW_FUNC srq_set_lw_func;
+
+#ifdef DAT_IMMEDIATE_DATA
+ /* udat-2.0 immediate data */
+ DAT_EP_POST_SEND_IMMED_FUNC ep_post_send_immed_func;
+ DAT_EP_POST_RECV_IMMED_FUNC ep_post_recv_immed_func;
+ DAT_EP_POST_RDMA_WRITE_IMMED_FUNC ep_post_rdma_write_immed_func;
+#endif
+
+#ifdef DAT_EXTENSIONS
+ /* udat-2.0 extensions */
+ DAT_EXTENSION_FUNC extension_func;
+#endif
+
};
#endif /* _UDAT_REDIRECTION_H_ */
Index: dat/include/dat/dat_extensions.h
===================================================================
--- dat/include/dat/dat_extensions.h (revision 0)
+++ dat/include/dat/dat_extensions.h (revision 0)
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2002-2005, Network Appliance, Inc. 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
+ * in the file LICENSE.txt in the root directory. The license is also
+ * 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 in the file
+ * LICENSE2.txt in the root directory. The license is also 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 in the file LICENSE3.txt in the root directory. The
+ * license is also 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.
+ */
+/**********************************************************************
+ *
+ * HEADER: dat_extensions.h
+ *
+ * PURPOSE: defines the extensions to the DAT API for uDAPL.
+ *
+ * Description: Header file for "uDAPL: User Direct Access Programming
+ * Library, Version: 1.2"
+ *
+ * Mapping rules:
+ * All global symbols are prepended with "DAT_" or "dat_"
+ * All DAT objects have an 'api' tag which, such as 'ep' or 'lmr'
+ * The method table is in the provider definition structure.
+ *
+ *
+ **********************************************************************/
+#ifndef _DAT_EXTENSIONS_H_
+
+extern int dat_extensions;
+
+/*
+ * Provider specific attribute strings for extension support
+ * returned with dat_ia_query() and
+ * DAT_PROVIDER_ATTR_MASK == DAT_PROVIDER_FIELD_PROVIDER_SPECIFIC_ATTR
+ *
+ * DAT_NAMED_ATTR name == extended operations and version,
+ * value == TRUE if extended operation is supported
+ * version_value = version number of extension API
+ */
+#define DAT_EXTENSION_ATTR "DAT_EXTENSION_INTERFACE"
+#define DAT_EXTENSION_ATTR_VERSION "DAT_EXTENSION_VERSION"
+#define DAT_EXTENSION_ATTR_FETCH_AND_ADD "DAT_EXTENSION_FETCH_AND_ADD"
+#define DAT_EXTENSION_ATTR_CMP_AND_SWAP "DAT_EXTENSION_CMP_AND_SWAP"
+#define DAT_EXTENSION_ATTR_TRUE "TRUE"
+#define DAT_EXTENSION_ATTR_FALSE "FALSE"
+#define DAT_EXTENSION_ATTR_VERSION_VALUE "2.0.1"
+
+
+/*
+ * DTO Extension OPERATIONS supported
+ */
+typedef enum dat_dto_extension_op
+{
+ DAT_DTO_EXTENSION_FETCH_AND_ADD,
+ DAT_DTO_EXTENSION_CMP_AND_SWAP
+
+} DAT_DTO_EXTENSION_OP;
+
+
+/*
+ * Definitions for extension subtype RETURN codes
+ *
+ * All DAT return codes are now a 4-way tuple with an 8-bit
+ * EXTENSION_SUBTYPE reserved to cover specific extension subtypes:
+ *
+ * type: CLASS RETURN_TYPE EXTENSION_SUBTYPE SUBTYPE
+ * bits: 31-30 29-16 15-8 7-0
+ *
+ * +-------------------------------------------------------------------------+
+ * |3130 | 2928272625242322212019181716 | 15141312111009080 | 706054003020100|
+ * |CLAS | DAT_TYPE_STATUS | EXTENSION_SUBTYPE | SUBTYPE |
+ * +-------------------------------------------------------------------------+
+ */
+typedef enum dat_return_extension_subtype
+{
+ /* NEW extension subtypes */
+ DAT_EXTENSION_ERR_1 = DAT_SUBTYPE_MASK+1,
+ DAT_EXTENSION_ERR_2,
+ DAT_EXTENSION_ERR_3
+
+} DAT_RETURN_EXTENSION_SUBTYPE;
+
+/* DAT_RETURN extension error to string */
+static __inline__ DAT_RETURN
+dat_strerror_extension (
+ IN DAT_RETURN value,
+ OUT const char **message )
+{
+ switch( DAT_GET_EXTENSION_SUBTYPE (value) ) {
+ case 0:
+ *message = " ";
+ return DAT_SUCCESS;
+ case DAT_EXTENSION_ERR_1:
+ *message = "DAT_EXTENSION_ERR_1";
+ return DAT_SUCCESS;
+ case DAT_EXTENSION_ERR_2:
+ *message = "DAT_EXTENSION_ERR_2";
+ return DAT_SUCCESS;
+ case DAT_EXTENSION_ERR_3:
+ *message = "DAT_EXTENSION_ERR_3";
+ return DAT_SUCCESS;
+ default:
+ *message = "unknown extension error";
+ return DAT_INVALID_PARAMETER;
+
+ }
+}
+
+/*
+ * Definition for memory privilege extension flags.
+ * New priviledes required for new atomic DTO type extensions.
+ * New Bit definitions MUST start at DAT_MEM_PRIV_EXTENSION
+ */
+typedef enum dat_mem_priv_extension_flags
+{
+ DAT_MEM_PRIV_EXT_START = DAT_MEM_PRIV_EXTENSION,
+ DAT_MEM_PRIV_EXT_REMOTE_ATOMIC = (DAT_MEM_PRIV_EXTENSION << 1),
+
+} DAT_MEM_PRIV_EXTENSION_FLAGS;
+
+
+/*
+ * DTO Extension event TYPES, DTO completion
+ */
+typedef enum dat_dto_extension_status
+{
+ DAT_DTO_EXTENSION_SUCCESS,
+ DAT_DTO_EXTENSION_ERR_GENERAL
+
+} DAT_DTO_EXTENSION_STATUS;
+
+
+/*
+ * DTO Extension completion event DATA types
+ */
+typedef struct dat_extension_dto_data
+{
+ DAT_UINT64 as_64;
+
+} DAT_DTO_EXTENSION_DATA;
+
+typedef struct dat_dto_extension_event_data
+{
+ DAT_DTO_EXTENSION_OP type;
+ DAT_DTO_EXTENSION_STATUS status;
+ union {
+ DAT_DTO_EXTENSION_DATA data;
+ } val;
+
+} DAT_DTO_EXTENSION_EVENT_DATA;
+
+
+/*
+ * Extended API with redirection via DAT extension function
+ */
+
+/*
+ * This asynchronous call is modeled after the InfiniBand atomic
+ * Fetch and Add operation. The add_value is added to the 64 bit
+ * value stored at the remote memory location specified in remote_iov
+ * and the result is stored in the local_iov.
+ */
+#define dat_ep_post_fetch_and_add(ep, add_val, lbuf, cookie, rbuf, flgs) \
+ dat_extension( ep, \
+ DAT_DTO_EXTENSION_FETCH_AND_ADD, \
+ (add_val), \
+ (lbuf), \
+ (cookie), \
+ (rbuf), \
+ (flgs))
+
+/*
+ * This asynchronous call is modeled after the InfiniBand atomic
+ * Compare and Swap operation. The cmp_value is compared to the 64 bit
+ * value stored at the remote memory location specified in remote_iov.
+ * If the two values are equal, the 64 bit swap_value is stored in
+ * the remote memory location. In all cases, the original 64 bit
+ * value stored in the remote memory location is copied to the local_iov.
+ */
+#define dat_ep_post_cmp_and_swap(ep, cmp_val, swap_val, lbuf, cookie, rbuf, flgs) \
+ dat_extension( ep, \
+ DAT_DTO_EXTENSION_CMP_AND_SWAP, \
+ (cmp_val), \
+ (swap_val), \
+ (lbuf), \
+ (cookie), \
+ (rbuf), \
+ (flgs))
+
+#endif /* _DAT_EXTENSIONS_H_ */
+
Index: dat/common/dat_api.c
===================================================================
--- dat/common/dat_api.c (revision 5065)
+++ dat/common/dat_api.c (working copy)
@@ -2,27 +2,27 @@
* Copyright (c) 2002-2005, Network Appliance, Inc. 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
* in the file LICENSE.txt in the root directory. The license is also
- * available from the Open Source Initiative, see
+ * 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 in the file
* LICENSE2.txt in the root directory. The license is also 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 in the file LICENSE3.txt in the root directory. The
* license is also 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.
@@ -35,7 +35,7 @@
* PURPOSE: DAT Provider and Consumer registry functions.
* Also provide small integers for IA_HANDLES
*
- * $Id: dat_api.c,v 1.10 2005/05/20 22:25:31 jlentini Exp $
+ * $Id: dat_api.c,v 1.5 2005/02/17 19:36:23 jlentini Exp $
**********************************************************************/
#include "dat_osd.h"
@@ -70,15 +70,16 @@ dats_handle_vector_init ( void )
{
DAT_RETURN dat_status;
int i;
+ int status;
dat_status = DAT_SUCCESS;
g_hv.handle_max = DAT_HANDLE_ENTRY_STEP;
- dat_status = dat_os_lock_init (&g_hv.handle_lock);
- if ( DAT_SUCCESS != dat_status )
+ status = dat_os_lock_init (&g_hv.handle_lock);
+ if ( DAT_SUCCESS != status )
{
- return dat_status;
+ return status;
}
g_hv.handle_array = dat_os_alloc (sizeof(void *) * DAT_HANDLE_ENTRY_STEP);
@@ -88,7 +89,7 @@ dats_handle_vector_init ( void )
goto bail;
}
- for (i = 0; i < g_hv.handle_max; i++)
+ for (i = g_hv.handle_max; i < g_hv.handle_max; i++)
{
g_hv.handle_array[i] = NULL;
}
@@ -112,11 +113,7 @@ dats_set_ia_handle (
void **h;
dat_os_lock (&g_hv.handle_lock);
-
- /*
- * Don't give out handle zero since that is DAT_HANDLE_NULL!
- */
- for (i = 1; i < g_hv.handle_max; i++)
+ for (i = 0; i < g_hv.handle_max; i++)
{
if (g_hv.handle_array[i] == NULL)
{
@@ -1142,6 +1139,105 @@ DAT_RETURN dat_srq_set_lw(
low_watermark);
}
+#ifdef DAT_IMMEDIATE_DATA
+DAT_RETURN dat_ep_post_rdma_write_immed (
+ IN DAT_EP_HANDLE ep_handle,
+ IN DAT_COUNT num_segments,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN const DAT_RMR_TRIPLET *remote_iov,
+ IN DAT_UINT32 immed_data,
+ IN DAT_DTO_FLAGS dto_flags,
+ IN DAT_COMPLETION_FLAGS completion_flags)
+{
+ if (ep_handle == NULL)
+ {
+ return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+ }
+ return DAT_EP_POST_RDMA_WRITE_IMMED(ep_handle,
+ num_segments,
+ local_iov,
+ user_cookie,
+ remote_iov,
+ immed_data,
+ dto_flags,
+ completion_flags);
+}
+
+DAT_RETURN dat_ep_post_send_immed (
+ IN DAT_EP_HANDLE ep_handle,
+ IN DAT_COUNT num_segments,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN DAT_UINT32 immed_data,
+ IN DAT_DTO_FLAGS dto_flags,
+ IN DAT_COMPLETION_FLAGS completion_flags)
+{
+ if (ep_handle == NULL)
+ {
+ return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+ }
+ return DAT_EP_POST_SEND_IMMED (ep_handle,
+ num_segments,
+ local_iov,
+ user_cookie,
+ immed_data,
+ dto_flags,
+ completion_flags);
+}
+
+DAT_RETURN dat_ep_post_recv_immed (
+ IN DAT_EP_HANDLE ep_handle,
+ IN DAT_COUNT num_segments,
+ IN DAT_LMR_TRIPLET *local_iov,
+ IN DAT_DTO_COOKIE user_cookie,
+ IN DAT_COMPLETION_FLAGS completion_flags)
+{
+ if (ep_handle == NULL)
+ {
+ return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+ }
+ return DAT_EP_POST_RECV_IMMED (ep_handle,
+ num_segments,
+ local_iov,
+ user_cookie,
+ completion_flags);
+}
+#endif
+
+#ifdef DAT_EXTENSIONS
+DAT_RETURN dat_extension(
+ IN DAT_HANDLE handle,
+ IN DAT_DTO_EXTENSION_OP ext_op,
+ IN ... )
+
+{
+ DAT_RETURN status;
+ va_list args;
+
+ if (handle == NULL)
+ {
+ return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+ }
+
+ /* verify provider extension support */
+ if (!dat_extensions)
+ {
+ return DAT_ERROR(DAT_NOT_IMPLEMENTED, 0);
+ }
+
+ va_start(args, ext_op);
+
+ status = DAT_EXTENSION(handle,
+ ext_op,
+ args);
+ va_end(args);
+
+ return status;
+}
+#endif
+
+
/*
* Local variables:
* c-indent-level: 4
Index: dat/udat/Makefile
===================================================================
--- dat/udat/Makefile (revision 5065)
+++ dat/udat/Makefile (working copy)
@@ -112,6 +112,13 @@ CFLAGS32 = -m32
endif
#
+# Prototype 2.0 DAT extensions and immediate data
+#
+CFLAGS += -DDAT_EXTENSIONS
+CFLAGS += -DDAT_IMMEDIATE_DATA
+
+
+#
# LD definitions
#
Index: dat/udat/udat.c
===================================================================
--- dat/udat/udat.c (revision 5065)
+++ dat/udat/udat.c (working copy)
@@ -2,27 +2,27 @@
* Copyright (c) 2002-2005, Network Appliance, Inc. 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
* in the file LICENSE.txt in the root directory. The license is also
- * available from the Open Source Initiative, see
+ * 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 in the file
* LICENSE2.txt in the root directory. The license is also 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 in the file LICENSE3.txt in the root directory. The
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ * copy of which is in the file LICENSE3.txt in the root directory. The
* license is also 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.
@@ -34,7 +34,7 @@
*
* PURPOSE: DAT Provider and Consumer registry functions.
*
- * $Id: udat.c,v 1.22 2005/03/24 05:58:35 jlentini Exp $
+ * $Id: udat.c,v 1.20 2005/02/11 20:17:05 jlentini Exp $
**********************************************************************/
#include <dat/udat.h>
@@ -66,6 +66,10 @@ udat_check_state ( void );
* *
*********************************************************************/
+/*
+ * Use a global to get an unresolved when run with pre-extension library
+ */
+int dat_extensions = 0;
/*
*
@@ -226,17 +230,48 @@ dat_ia_openv (
return dat_status;
}
- dat_status = (*ia_open_func) (name,
- async_event_qlen,
- async_event_handle,
- ia_handle);
+ dat_status = (*ia_open_func) (name,
+ async_event_qlen,
+ async_event_handle,
+ ia_handle);
+
+ /*
+ * See if provider supports extensions
+ */
if (dat_status == DAT_SUCCESS)
{
+ DAT_PROVIDER_ATTR p_attr;
+ int i;
+
return_handle = dats_set_ia_handle (*ia_handle);
if (return_handle >= 0)
{
*ia_handle = (DAT_IA_HANDLE)return_handle;
- }
+ }
+
+ if ( dat_ia_query( *ia_handle,
+ NULL,
+ 0,
+ NULL,
+ DAT_PROVIDER_FIELD_PROVIDER_SPECIFIC_ATTR,
+ &p_attr ) == DAT_SUCCESS )
+ {
+ for ( i = 0; i < p_attr.num_provider_specific_attr; i++ )
+ {
+ if ( (strcmp( p_attr.provider_specific_attr[i].name,
+ "DAT_EXTENSION_INTERFACE" ) == 0) &&
+ (strcmp( p_attr.provider_specific_attr[i].value,
+ "TRUE" ) == 0) )
+ {
+ dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
+ "DAT Registry: dat_ia_open () "
+ "DAPL Extension Interface supported!\n");
+
+ dat_extensions = 1;
+ break;
+ }
+ }
+ }
}
return dat_status;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/general/attachments/20060118/c782db72/attachment.html>
More information about the general
mailing list