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