#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <gpxe/iobuf.h>
#include <gpxe/xfer.h>
#include <gpxe/process.h>
#include <gpxe/infiniband.h>
#include <gpxe/ib_cm.h>
#include <gpxe/ib_cmrc.h>
Go to the source code of this file.
Data Structures | |
| struct | ib_cmrc_connection |
| An Infiniband Communication-Managed Reliable Connection. More... | |
Defines | |
| #define | IB_CMRC_NUM_SEND_WQES 4 |
| CMRC number of send WQEs. | |
| #define | IB_CMRC_NUM_RECV_WQES 2 |
| CMRC number of receive WQEs. | |
| #define | IB_CMRC_NUM_CQES 8 |
| CMRC number of completion queue entries. | |
Functions | |
| FILE_LICENCE (BSD2) | |
| static void | ib_cmrc_shutdown (struct process *process) |
| Shut down CMRC connection gracefully. | |
| static void | ib_cmrc_close (struct ib_cmrc_connection *cmrc, int rc) |
| Close CMRC connection. | |
| static void | ib_cmrc_changed (struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct ib_connection *conn __unused, int rc_cm, void *private_data, size_t private_data_len) |
| Handle change of CMRC connection status. | |
| static void | ib_cmrc_complete_send (struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct io_buffer *iobuf, int rc) |
| Handle CMRC send completion. | |
| static void | ib_cmrc_complete_recv (struct ib_device *ibdev __unused, struct ib_queue_pair *qp, struct ib_address_vector *av __unused, struct io_buffer *iobuf, int rc) |
| Handle CMRC receive completion. | |
| static int | ib_cmrc_xfer_deliver_iob (struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta __unused) |
| Send data via CMRC. | |
| static size_t | ib_cmrc_xfer_window (struct xfer_interface *xfer) |
| Check CMRC flow control window. | |
| static void | ib_cmrc_xfer_close (struct xfer_interface *xfer, int rc) |
| Close CMRC data-transfer interface. | |
| int | ib_cmrc_open (struct xfer_interface *xfer, struct ib_device *ibdev, struct ib_gid *dgid, struct ib_gid_half *service_id) |
| Open CMRC connection. | |
Variables | |
| static struct ib_connection_operations | ib_cmrc_conn_op |
| CMRC connection operations. | |
| static struct ib_completion_queue_operations | ib_cmrc_completion_ops |
| Infiniband CMRC completion operations. | |
| static struct xfer_interface_operations | ib_cmrc_xfer_operations |
| CMRC data transfer interface operations. | |
Definition in file ib_cmrc.c.
| #define IB_CMRC_NUM_SEND_WQES 4 |
CMRC number of send WQEs.
This is a policy decision.
Definition at line 54 of file ib_cmrc.c.
Referenced by ib_cmrc_open().
| #define IB_CMRC_NUM_RECV_WQES 2 |
CMRC number of receive WQEs.
This is a policy decision.
Definition at line 60 of file ib_cmrc.c.
Referenced by ib_cmrc_open().
| #define IB_CMRC_NUM_CQES 8 |
CMRC number of completion queue entries.
This is a policy decision
Definition at line 66 of file ib_cmrc.c.
Referenced by ib_cmrc_open().
| FILE_LICENCE | ( | BSD2 | ) |
| static void ib_cmrc_shutdown | ( | struct process * | process | ) | [static] |
Shut down CMRC connection gracefully.
| process | Process |
This shutdown process will run some time after the call to ib_cmrc_close(), after control has returned out of the Infiniband core, and will shut down the Infiniband interfaces cleanly.
The shutdown process holds an implicit reference on the CMRC connection, ensuring that the structure is not freed before the shutdown process has run.
Definition at line 110 of file ib_cmrc.c.
References ib_cmrc_connection::conn, container_of, ib_cmrc_connection::cq, DBGC, ib_close(), ib_destroy_conn(), ib_destroy_cq(), ib_destroy_qp(), ib_cmrc_connection::ibdev, process_del(), ib_cmrc_connection::qp, ref_put(), ib_cmrc_connection::refcnt, ib_cmrc_connection::shutdown, and shutdown().
Referenced by ib_cmrc_open().
00110 { 00111 struct ib_cmrc_connection *cmrc = 00112 container_of ( process, struct ib_cmrc_connection, shutdown ); 00113 00114 DBGC ( cmrc, "CMRC %p shutting down\n", cmrc ); 00115 00116 /* Shut down Infiniband interface */ 00117 ib_destroy_conn ( cmrc->ibdev, cmrc->qp, cmrc->conn ); 00118 ib_destroy_qp ( cmrc->ibdev, cmrc->qp ); 00119 ib_destroy_cq ( cmrc->ibdev, cmrc->cq ); 00120 ib_close ( cmrc->ibdev ); 00121 00122 /* Remove process from run queue */ 00123 process_del ( &cmrc->shutdown ); 00124 00125 /* Drop the remaining reference */ 00126 ref_put ( &cmrc->refcnt ); 00127 }
| static void ib_cmrc_close | ( | struct ib_cmrc_connection * | cmrc, | |
| int | rc | |||
| ) | [static] |
Close CMRC connection.
| cmrc | Communication-Managed Reliable Connection | |
| rc | Reason for close |
Definition at line 135 of file ib_cmrc.c.
References process_add(), ib_cmrc_connection::shutdown, ib_cmrc_connection::xfer, and xfer_close().
Referenced by ib_cmrc_changed(), ib_cmrc_complete_recv(), ib_cmrc_complete_send(), ib_cmrc_xfer_close(), and ib_cmrc_xfer_deliver_iob().
00135 { 00136 00137 /* Close data transfer interface */ 00138 xfer_nullify ( &cmrc->xfer ); 00139 xfer_close ( &cmrc->xfer, rc ); 00140 00141 /* Schedule shutdown process */ 00142 process_add ( &cmrc->shutdown ); 00143 }
| static void ib_cmrc_changed | ( | struct ib_device *ibdev | __unused, | |
| struct ib_queue_pair * | qp, | |||
| struct ib_connection *conn | __unused, | |||
| int | rc_cm, | |||
| void * | private_data, | |||
| size_t | private_data_len | |||
| ) | [static] |
Handle change of CMRC connection status.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| conn | Connection | |
| rc_cm | Connection status code | |
| private_data | Private data, if available | |
| private_data_len | Length of private data |
Definition at line 155 of file ib_cmrc.c.
References ib_cmrc_connection::connected, DBGC, DBGC2, DBGC2_HDA, ib_cmrc_close(), ib_qp_get_ownerdata(), strerror(), ib_cmrc_connection::xfer, and xfer_deliver_raw().
00158 { 00159 struct ib_cmrc_connection *cmrc = ib_qp_get_ownerdata ( qp ); 00160 int rc_xfer; 00161 00162 /* Record connection status */ 00163 if ( rc_cm == 0 ) { 00164 DBGC ( cmrc, "CMRC %p connected\n", cmrc ); 00165 cmrc->connected = 1; 00166 } else { 00167 DBGC ( cmrc, "CMRC %p disconnected: %s\n", 00168 cmrc, strerror ( rc_cm ) ); 00169 cmrc->connected = 0; 00170 } 00171 00172 /* Pass up any private data */ 00173 DBGC2 ( cmrc, "CMRC %p received private data:\n", cmrc ); 00174 DBGC2_HDA ( cmrc, 0, private_data, private_data_len ); 00175 if ( private_data && 00176 ( rc_xfer = xfer_deliver_raw ( &cmrc->xfer, private_data, 00177 private_data_len ) ) != 0 ) { 00178 DBGC ( cmrc, "CMRC %p could not deliver private data: %s\n", 00179 cmrc, strerror ( rc_xfer ) ); 00180 ib_cmrc_close ( cmrc, rc_xfer ); 00181 return; 00182 } 00183 00184 /* If we are disconnected, close the upper connection */ 00185 if ( rc_cm != 0 ) { 00186 ib_cmrc_close ( cmrc, rc_cm ); 00187 return; 00188 } 00189 }
| static void ib_cmrc_complete_send | ( | struct ib_device *ibdev | __unused, | |
| struct ib_queue_pair * | qp, | |||
| struct io_buffer * | iobuf, | |||
| int | rc | |||
| ) | [static] |
Handle CMRC send completion.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| iobuf | I/O buffer | |
| rc | Completion status code |
Definition at line 204 of file ib_cmrc.c.
References DBGC, free_iob(), ib_cmrc_close(), ib_qp_get_ownerdata(), and strerror().
00206 { 00207 struct ib_cmrc_connection *cmrc = ib_qp_get_ownerdata ( qp ); 00208 00209 /* Free the completed I/O buffer */ 00210 free_iob ( iobuf ); 00211 00212 /* Close the connection on any send errors */ 00213 if ( rc != 0 ) { 00214 DBGC ( cmrc, "CMRC %p send error: %s\n", 00215 cmrc, strerror ( rc ) ); 00216 ib_cmrc_close ( cmrc, rc ); 00217 return; 00218 } 00219 }
| static void ib_cmrc_complete_recv | ( | struct ib_device *ibdev | __unused, | |
| struct ib_queue_pair * | qp, | |||
| struct ib_address_vector *av | __unused, | |||
| struct io_buffer * | iobuf, | |||
| int | rc | |||
| ) | [static] |
Handle CMRC receive completion.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| av | Address vector, or NULL | |
| iobuf | I/O buffer | |
| rc | Completion status code |
Definition at line 230 of file ib_cmrc.c.
References io_buffer::data, DBGC, DBGC2, DBGC2_HDA, free_iob(), ib_cmrc_close(), ib_qp_get_ownerdata(), iob_len(), strerror(), ib_cmrc_connection::xfer, and xfer_deliver_iob().
00233 { 00234 struct ib_cmrc_connection *cmrc = ib_qp_get_ownerdata ( qp ); 00235 00236 /* Close the connection on any receive errors */ 00237 if ( rc != 0 ) { 00238 DBGC ( cmrc, "CMRC %p receive error: %s\n", 00239 cmrc, strerror ( rc ) ); 00240 free_iob ( iobuf ); 00241 ib_cmrc_close ( cmrc, rc ); 00242 return; 00243 } 00244 00245 DBGC2 ( cmrc, "CMRC %p received:\n", cmrc ); 00246 DBGC2_HDA ( cmrc, 0, iobuf->data, iob_len ( iobuf ) ); 00247 00248 /* Pass up data */ 00249 if ( ( rc = xfer_deliver_iob ( &cmrc->xfer, iobuf ) ) != 0 ) { 00250 DBGC ( cmrc, "CMRC %p could not deliver data: %s\n", 00251 cmrc, strerror ( rc ) ); 00252 ib_cmrc_close ( cmrc, rc ); 00253 return; 00254 } 00255 }
| static int ib_cmrc_xfer_deliver_iob | ( | struct xfer_interface * | xfer, | |
| struct io_buffer * | iobuf, | |||
| struct xfer_metadata *meta | __unused | |||
| ) | [static] |
Send data via CMRC.
| xfer | Data transfer interface | |
| iobuf | Datagram I/O buffer | |
| meta | Data transfer metadata |
| rc | Return status code |
Definition at line 271 of file ib_cmrc.c.
References ib_cmrc_connection::conn, ib_cmrc_connection::connected, container_of, io_buffer::data, DBGC, ib_cmrc_connection::dgid, EIO, ENOMEM, free_iob(), ib_cmrc_close(), ib_create_conn(), ib_post_send(), ib_cmrc_connection::ibdev, iob_disown, iob_len(), NULL, ib_cmrc_connection::qp, ib_cmrc_connection::service_id, and strerror().
00273 { 00274 struct ib_cmrc_connection *cmrc = 00275 container_of ( xfer, struct ib_cmrc_connection, xfer ); 00276 int rc; 00277 00278 /* If no connection has yet been attempted, send this datagram 00279 * as the CM REQ private data. Otherwise, send it via the QP. 00280 */ 00281 if ( ! cmrc->connected ) { 00282 00283 /* Abort if we have already sent a CM connection request */ 00284 if ( cmrc->conn ) { 00285 DBGC ( cmrc, "CMRC %p attempt to send before " 00286 "connection is complete\n", cmrc ); 00287 rc = -EIO; 00288 goto out; 00289 } 00290 00291 /* Send via CM connection request */ 00292 cmrc->conn = ib_create_conn ( cmrc->ibdev, cmrc->qp, 00293 &cmrc->dgid, &cmrc->service_id, 00294 iobuf->data, iob_len ( iobuf ), 00295 &ib_cmrc_conn_op ); 00296 if ( ! cmrc->conn ) { 00297 DBGC ( cmrc, "CMRC %p could not connect\n", cmrc ); 00298 rc = -ENOMEM; 00299 goto out; 00300 } 00301 00302 } else { 00303 00304 /* Send via QP */ 00305 if ( ( rc = ib_post_send ( cmrc->ibdev, cmrc->qp, NULL, 00306 iob_disown ( iobuf ) ) ) != 0 ) { 00307 DBGC ( cmrc, "CMRC %p could not send: %s\n", 00308 cmrc, strerror ( rc ) ); 00309 goto out; 00310 } 00311 00312 } 00313 return 0; 00314 00315 out: 00316 /* Free the I/O buffer if necessary */ 00317 free_iob ( iobuf ); 00318 00319 /* Close the connection on any errors */ 00320 if ( rc != 0 ) 00321 ib_cmrc_close ( cmrc, rc ); 00322 00323 return rc; 00324 }
| static size_t ib_cmrc_xfer_window | ( | struct xfer_interface * | xfer | ) | [static] |
Check CMRC flow control window.
| xfer | Data transfer interface |
| len | Length of window |
Definition at line 332 of file ib_cmrc.c.
References ib_cmrc_connection::connected, container_of, and IB_MAX_PAYLOAD_SIZE.
00332 { 00333 struct ib_cmrc_connection *cmrc = 00334 container_of ( xfer, struct ib_cmrc_connection, xfer ); 00335 00336 /* We indicate a window only when we are successfully 00337 * connected. 00338 */ 00339 return ( cmrc->connected ? IB_MAX_PAYLOAD_SIZE : 0 ); 00340 }
| static void ib_cmrc_xfer_close | ( | struct xfer_interface * | xfer, | |
| int | rc | |||
| ) | [static] |
Close CMRC data-transfer interface.
| xfer | Data transfer interface | |
| rc | Reason for close |
Definition at line 348 of file ib_cmrc.c.
References container_of, DBGC, ib_cmrc_close(), and strerror().
00348 { 00349 struct ib_cmrc_connection *cmrc = 00350 container_of ( xfer, struct ib_cmrc_connection, xfer ); 00351 00352 DBGC ( cmrc, "CMRC %p closed: %s\n", cmrc, strerror ( rc ) ); 00353 ib_cmrc_close ( cmrc, rc ); 00354 }
| int ib_cmrc_open | ( | struct xfer_interface * | xfer, | |
| struct ib_device * | ibdev, | |||
| struct ib_gid * | dgid, | |||
| struct ib_gid_half * | service_id | |||
| ) |
Open CMRC connection.
| xfer | Data transfer interface | |
| ibdev | Infiniband device | |
| dgid | Destination GID | |
| service_id | Service ID |
| rc | Returns status code |
Definition at line 375 of file ib_cmrc.c.
References ib_cmrc_connection::cq, DBGC, ib_cmrc_connection::dgid, ENOMEM, ib_close(), IB_CMRC_NUM_CQES, IB_CMRC_NUM_RECV_WQES, IB_CMRC_NUM_SEND_WQES, ib_cmrc_shutdown(), ib_create_cq(), ib_create_qp(), ib_destroy_cq(), ib_destroy_qp(), ib_open(), ib_qp_set_ownerdata(), IB_QPT_RC, ib_cmrc_connection::ibdev, memcpy, process_init_stopped(), ib_cmrc_connection::qp, ib_queue_pair::qpn, ref_put(), ib_cmrc_connection::refcnt, ib_cmrc_connection::service_id, ib_cmrc_connection::shutdown, strerror(), ib_cmrc_connection::xfer, xfer_init(), and zalloc().
Referenced by ib_srp_connect().
00376 { 00377 struct ib_cmrc_connection *cmrc; 00378 int rc; 00379 00380 /* Allocate and initialise structure */ 00381 cmrc = zalloc ( sizeof ( *cmrc ) ); 00382 if ( ! cmrc ) { 00383 rc = -ENOMEM; 00384 goto err_alloc; 00385 } 00386 xfer_init ( &cmrc->xfer, &ib_cmrc_xfer_operations, &cmrc->refcnt ); 00387 cmrc->ibdev = ibdev; 00388 memcpy ( &cmrc->dgid, dgid, sizeof ( cmrc->dgid ) ); 00389 memcpy ( &cmrc->service_id, service_id, sizeof ( cmrc->service_id ) ); 00390 process_init_stopped ( &cmrc->shutdown, ib_cmrc_shutdown, 00391 &cmrc->refcnt ); 00392 00393 /* Open Infiniband device */ 00394 if ( ( rc = ib_open ( ibdev ) ) != 0 ) { 00395 DBGC ( cmrc, "CMRC %p could not open device: %s\n", 00396 cmrc, strerror ( rc ) ); 00397 goto err_open; 00398 } 00399 00400 /* Create completion queue */ 00401 cmrc->cq = ib_create_cq ( ibdev, IB_CMRC_NUM_CQES, 00402 &ib_cmrc_completion_ops ); 00403 if ( ! cmrc->cq ) { 00404 DBGC ( cmrc, "CMRC %p could not create completion queue\n", 00405 cmrc ); 00406 rc = -ENOMEM; 00407 goto err_create_cq; 00408 } 00409 00410 /* Create queue pair */ 00411 cmrc->qp = ib_create_qp ( ibdev, IB_QPT_RC, IB_CMRC_NUM_SEND_WQES, 00412 cmrc->cq, IB_CMRC_NUM_RECV_WQES, cmrc->cq ); 00413 if ( ! cmrc->qp ) { 00414 DBGC ( cmrc, "CMRC %p could not create queue pair\n", cmrc ); 00415 rc = -ENOMEM; 00416 goto err_create_qp; 00417 } 00418 ib_qp_set_ownerdata ( cmrc->qp, cmrc ); 00419 DBGC ( cmrc, "CMRC %p using QPN %lx\n", cmrc, cmrc->qp->qpn ); 00420 00421 /* Attach to parent interface, transfer reference (implicitly) 00422 * to our shutdown process, and return. 00423 */ 00424 xfer_plug_plug ( &cmrc->xfer, xfer ); 00425 return 0; 00426 00427 ib_destroy_qp ( ibdev, cmrc->qp ); 00428 err_create_qp: 00429 ib_destroy_cq ( ibdev, cmrc->cq ); 00430 err_create_cq: 00431 ib_close ( ibdev ); 00432 err_open: 00433 ref_put ( &cmrc->refcnt ); 00434 err_alloc: 00435 return rc; 00436 }
struct ib_connection_operations ib_cmrc_conn_op [static] |
struct ib_completion_queue_operations ib_cmrc_completion_ops [static] |
Initial value:
{
.complete_send = ib_cmrc_complete_send,
.complete_recv = ib_cmrc_complete_recv,
}
struct xfer_interface_operations ib_cmrc_xfer_operations [static] |
Initial value:
{
.close = ib_cmrc_xfer_close,
.vredirect = ignore_xfer_vredirect,
.window = ib_cmrc_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = ib_cmrc_xfer_deliver_iob,
.deliver_raw = xfer_deliver_as_iob,
}
1.5.7.1