2007-12-21 09:02:00 +03:00
|
|
|
/* -*- Mode: C; c-basic-offset:4 ; -*- */
|
2005-07-01 01:28:35 +04:00
|
|
|
/*
|
2007-03-17 02:11:45 +03:00
|
|
|
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
2005-11-05 22:57:48 +03:00
|
|
|
* University Research and Technology
|
|
|
|
* Corporation. All rights reserved.
|
2008-02-18 20:39:30 +03:00
|
|
|
* Copyright (c) 2004-2008 The University of Tennessee and The University
|
2005-11-05 22:57:48 +03:00
|
|
|
* of Tennessee Research Foundation. All rights
|
|
|
|
* reserved.
|
2007-09-24 14:11:52 +04:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
2005-07-01 01:28:35 +04:00
|
|
|
* University of Stuttgart. All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2007-01-25 01:25:40 +03:00
|
|
|
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
2008-06-05 16:20:13 +04:00
|
|
|
* Copyright (c) 2006-2008 Mellanox Technologies. All rights reserved.
|
2007-07-25 19:03:34 +04:00
|
|
|
* Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights
|
2007-09-24 14:11:52 +04:00
|
|
|
* reserved.
|
|
|
|
* Copyright (c) 2006-2007 Voltaire All rights reserved.
|
2005-07-01 01:28:35 +04:00
|
|
|
* $COPYRIGHT$
|
2007-09-24 14:11:52 +04:00
|
|
|
*
|
2005-07-01 01:28:35 +04:00
|
|
|
* Additional copyrights may follow
|
2007-09-24 14:11:52 +04:00
|
|
|
*
|
2005-07-01 01:28:35 +04:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ompi_config.h"
|
|
|
|
#include <string.h>
|
2005-07-13 04:17:08 +04:00
|
|
|
#include <inttypes.h>
|
2008-06-09 18:53:58 +04:00
|
|
|
#include "orte/util/show_help.h"
|
2005-07-04 05:36:20 +04:00
|
|
|
#include "opal/util/if.h"
|
2008-04-18 00:43:56 +04:00
|
|
|
#include "opal/util/arch.h"
|
|
|
|
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "ompi/mca/pml/pml.h"
|
|
|
|
#include "ompi/mca/btl/btl.h"
|
|
|
|
#include "ompi/mca/btl/base/btl_base_error.h"
|
2008-10-16 19:09:00 +04:00
|
|
|
|
|
|
|
#if OPAL_ENABLE_FT == 1
|
|
|
|
#include "ompi/runtime/ompi_cr.h"
|
|
|
|
#endif
|
|
|
|
|
2005-07-01 01:28:35 +04:00
|
|
|
#include "btl_openib.h"
|
2008-01-21 15:11:18 +03:00
|
|
|
#include "btl_openib_frag.h"
|
2005-07-01 01:28:35 +04:00
|
|
|
#include "btl_openib_proc.h"
|
|
|
|
#include "btl_openib_endpoint.h"
|
2007-11-28 10:18:59 +03:00
|
|
|
#include "btl_openib_xrc.h"
|
2008-01-21 15:11:18 +03:00
|
|
|
#include "ompi/datatype/convertor.h"
|
|
|
|
#include "ompi/datatype/datatype.h"
|
|
|
|
#include "ompi/mca/mpool/base/base.h"
|
|
|
|
#include "ompi/mca/mpool/mpool.h"
|
2006-12-17 15:26:41 +03:00
|
|
|
#include "ompi/mca/mpool/rdma/mpool_rdma.h"
|
2008-03-24 02:10:15 +03:00
|
|
|
#include "orte/util/proc_info.h"
|
2008-01-21 15:11:18 +03:00
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
2005-10-02 22:58:57 +04:00
|
|
|
#include <math.h>
|
2007-01-04 01:35:41 +03:00
|
|
|
#include <inttypes.h>
|
2007-01-31 00:22:56 +03:00
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
|
|
#include <sys/time.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_RESOURCE_H
|
|
|
|
#include <sys/resource.h>
|
|
|
|
#endif
|
2008-02-28 04:57:57 +03:00
|
|
|
#include <unistd.h>
|
2007-01-31 00:22:56 +03:00
|
|
|
|
2005-07-01 01:28:35 +04:00
|
|
|
mca_btl_openib_module_t mca_btl_openib_module = {
|
|
|
|
{
|
|
|
|
&mca_btl_openib_component.super,
|
|
|
|
0, /* max size of first fragment */
|
|
|
|
0, /* min send fragment size */
|
|
|
|
0, /* max send fragment size */
|
2007-06-21 11:12:40 +04:00
|
|
|
0, /* btl_rdma_pipeline_send_length */
|
2007-05-17 11:54:27 +04:00
|
|
|
0, /* btl_rdma_pipeline_frag_size */
|
|
|
|
0, /* btl_min_rdma_pipeline_size */
|
2005-07-01 01:28:35 +04:00
|
|
|
0, /* exclusivity */
|
|
|
|
0, /* latency */
|
|
|
|
0, /* bandwidth */
|
2007-04-27 01:03:38 +04:00
|
|
|
0, /* TODO this should be PUT btl flags */
|
2005-07-01 01:28:35 +04:00
|
|
|
mca_btl_openib_add_procs,
|
|
|
|
mca_btl_openib_del_procs,
|
2008-01-21 15:11:18 +03:00
|
|
|
NULL,
|
2005-07-01 01:28:35 +04:00
|
|
|
mca_btl_openib_finalize,
|
2008-01-21 15:11:18 +03:00
|
|
|
/* we need alloc free, pack */
|
|
|
|
mca_btl_openib_alloc,
|
|
|
|
mca_btl_openib_free,
|
2005-07-01 01:28:35 +04:00
|
|
|
mca_btl_openib_prepare_src,
|
|
|
|
mca_btl_openib_prepare_dst,
|
|
|
|
mca_btl_openib_send,
|
2008-05-30 07:58:39 +04:00
|
|
|
NULL, /* send immediate */
|
2005-07-01 01:28:35 +04:00
|
|
|
mca_btl_openib_put,
|
2006-03-17 20:39:41 +03:00
|
|
|
mca_btl_openib_get,
|
2006-08-18 02:02:01 +04:00
|
|
|
mca_btl_base_dump,
|
|
|
|
NULL, /* mpool */
|
2007-03-17 02:11:45 +03:00
|
|
|
mca_btl_openib_register_error_cb, /* error call back registration */
|
|
|
|
mca_btl_openib_ft_event
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-10-16 19:09:00 +04:00
|
|
|
#if OPAL_ENABLE_FT == 1
|
|
|
|
static int ft_event_btl_openib_finalize(struct mca_btl_base_module_t* btl);
|
|
|
|
#endif
|
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
static void show_init_error(const char *file, int line,
|
|
|
|
const char *func, const char *dev)
|
2007-01-25 01:25:40 +03:00
|
|
|
{
|
|
|
|
if (ENOMEM == errno) {
|
2007-01-31 00:22:56 +03:00
|
|
|
int ret;
|
|
|
|
struct rlimit limit;
|
|
|
|
char *str_limit = NULL;
|
|
|
|
|
|
|
|
ret = getrlimit(RLIMIT_MEMLOCK, &limit);
|
|
|
|
if (0 != ret) {
|
|
|
|
asprintf(&str_limit, "Unknown");
|
|
|
|
} else if (limit.rlim_cur == RLIM_INFINITY) {
|
|
|
|
asprintf(&str_limit, "unlimited");
|
|
|
|
} else {
|
2007-02-01 22:07:04 +03:00
|
|
|
asprintf(&str_limit, "%ld", (long)limit.rlim_cur);
|
2007-01-31 00:22:56 +03:00
|
|
|
}
|
|
|
|
|
This commit represents a bunch of work on a Mercurial side branch. As
such, the commit message back to the master SVN repository is fairly
long.
= ORTE Job-Level Output Messages =
Add two new interfaces that should be used for all new code throughout
the ORTE and OMPI layers (we already make the search-and-replace on
the existing ORTE / OMPI layers):
* orte_output(): (and corresponding friends ORTE_OUTPUT,
orte_output_verbose, etc.) This function sends the output directly
to the HNP for processing as part of a job-specific output
channel. It supports all the same outputs as opal_output()
(syslog, file, stdout, stderr), but for stdout/stderr, the output
is sent to the HNP for processing and output. More on this below.
* orte_show_help(): This function is a drop-in-replacement for
opal_show_help(), with two differences in functionality:
1. the rendered text help message output is sent to the HNP for
display (rather than outputting directly into the process' stderr
stream)
1. the HNP detects duplicate help messages and does not display them
(so that you don't see the same error message N times, once from
each of your N MPI processes); instead, it counts "new" instances
of the help message and displays a message every ~5 seconds when
there are new ones ("I got X new copies of the help message...")
opal_show_help and opal_output still exist, but they only output in
the current process. The intent for the new orte_* functions is that
they can apply job-level intelligence to the output. As such, we
recommend that all new ORTE and OMPI code use the new orte_*
functions, not thei opal_* functions.
=== New code ===
For ORTE and OMPI programmers, here's what you need to do differently
in new code:
* Do not include opal/util/show_help.h or opal/util/output.h.
Instead, include orte/util/output.h (this one header file has
declarations for both the orte_output() series of functions and
orte_show_help()).
* Effectively s/opal_output/orte_output/gi throughout your code.
Note that orte_output_open() takes a slightly different argument
list (as a way to pass data to the filtering stream -- see below),
so you if explicitly call opal_output_open(), you'll need to
slightly adapt to the new signature of orte_output_open().
* Literally s/opal_show_help/orte_show_help/. The function signature
is identical.
=== Notes ===
* orte_output'ing to stream 0 will do similar to what
opal_output'ing did, so leaving a hard-coded "0" as the first
argument is safe.
* For systems that do not use ORTE's RML or the HNP, the effect of
orte_output_* and orte_show_help will be identical to their opal
counterparts (the additional information passed to
orte_output_open() will be lost!). Indeed, the orte_* functions
simply become trivial wrappers to their opal_* counterparts. Note
that we have not tested this; the code is simple but it is quite
possible that we mucked something up.
= Filter Framework =
Messages sent view the new orte_* functions described above and
messages output via the IOF on the HNP will now optionally be passed
through a new "filter" framework before being output to
stdout/stderr. The "filter" OPAL MCA framework is intended to allow
preprocessing to messages before they are sent to their final
destinations. The first component that was written in the filter
framework was to create an XML stream, segregating all the messages
into different XML tags, etc. This will allow 3rd party tools to read
the stdout/stderr from the HNP and be able to know exactly what each
text message is (e.g., a help message, another OMPI infrastructure
message, stdout from the user process, stderr from the user process,
etc.).
Filtering is not active by default. Filter components must be
specifically requested, such as:
{{{
$ mpirun --mca filter xml ...
}}}
There can only be one filter component active.
= New MCA Parameters =
The new functionality described above introduces two new MCA
parameters:
* '''orte_base_help_aggregate''': Defaults to 1 (true), meaning that
help messages will be aggregated, as described above. If set to 0,
all help messages will be displayed, even if they are duplicates
(i.e., the original behavior).
* '''orte_base_show_output_recursions''': An MCA parameter to help
debug one of the known issues, described below. It is likely that
this MCA parameter will disappear before v1.3 final.
= Known Issues =
* The XML filter component is not complete. The current output from
this component is preliminary and not real XML. A bit more work
needs to be done to configure.m4 search for an appropriate XML
library/link it in/use it at run time.
* There are possible recursion loops in the orte_output() and
orte_show_help() functions -- e.g., if RML send calls orte_output()
or orte_show_help(). We have some ideas how to fix these, but
figured that it was ok to commit before feature freeze with known
issues. The code currently contains sub-optimal workarounds so
that this will not be a problem, but it would be good to actually
solve the problem rather than have hackish workarounds before v1.3 final.
This commit was SVN r18434.
2008-05-14 00:00:55 +04:00
|
|
|
orte_show_help("help-mpi-btl-openib.txt", "init-fail-no-mem",
|
2008-03-24 02:10:15 +03:00
|
|
|
true, orte_process_info.nodename,
|
2007-01-31 00:22:56 +03:00
|
|
|
file, line, func, dev, str_limit);
|
|
|
|
|
|
|
|
if (NULL != str_limit) free(str_limit);
|
2007-01-25 01:25:40 +03:00
|
|
|
} else {
|
This commit represents a bunch of work on a Mercurial side branch. As
such, the commit message back to the master SVN repository is fairly
long.
= ORTE Job-Level Output Messages =
Add two new interfaces that should be used for all new code throughout
the ORTE and OMPI layers (we already make the search-and-replace on
the existing ORTE / OMPI layers):
* orte_output(): (and corresponding friends ORTE_OUTPUT,
orte_output_verbose, etc.) This function sends the output directly
to the HNP for processing as part of a job-specific output
channel. It supports all the same outputs as opal_output()
(syslog, file, stdout, stderr), but for stdout/stderr, the output
is sent to the HNP for processing and output. More on this below.
* orte_show_help(): This function is a drop-in-replacement for
opal_show_help(), with two differences in functionality:
1. the rendered text help message output is sent to the HNP for
display (rather than outputting directly into the process' stderr
stream)
1. the HNP detects duplicate help messages and does not display them
(so that you don't see the same error message N times, once from
each of your N MPI processes); instead, it counts "new" instances
of the help message and displays a message every ~5 seconds when
there are new ones ("I got X new copies of the help message...")
opal_show_help and opal_output still exist, but they only output in
the current process. The intent for the new orte_* functions is that
they can apply job-level intelligence to the output. As such, we
recommend that all new ORTE and OMPI code use the new orte_*
functions, not thei opal_* functions.
=== New code ===
For ORTE and OMPI programmers, here's what you need to do differently
in new code:
* Do not include opal/util/show_help.h or opal/util/output.h.
Instead, include orte/util/output.h (this one header file has
declarations for both the orte_output() series of functions and
orte_show_help()).
* Effectively s/opal_output/orte_output/gi throughout your code.
Note that orte_output_open() takes a slightly different argument
list (as a way to pass data to the filtering stream -- see below),
so you if explicitly call opal_output_open(), you'll need to
slightly adapt to the new signature of orte_output_open().
* Literally s/opal_show_help/orte_show_help/. The function signature
is identical.
=== Notes ===
* orte_output'ing to stream 0 will do similar to what
opal_output'ing did, so leaving a hard-coded "0" as the first
argument is safe.
* For systems that do not use ORTE's RML or the HNP, the effect of
orte_output_* and orte_show_help will be identical to their opal
counterparts (the additional information passed to
orte_output_open() will be lost!). Indeed, the orte_* functions
simply become trivial wrappers to their opal_* counterparts. Note
that we have not tested this; the code is simple but it is quite
possible that we mucked something up.
= Filter Framework =
Messages sent view the new orte_* functions described above and
messages output via the IOF on the HNP will now optionally be passed
through a new "filter" framework before being output to
stdout/stderr. The "filter" OPAL MCA framework is intended to allow
preprocessing to messages before they are sent to their final
destinations. The first component that was written in the filter
framework was to create an XML stream, segregating all the messages
into different XML tags, etc. This will allow 3rd party tools to read
the stdout/stderr from the HNP and be able to know exactly what each
text message is (e.g., a help message, another OMPI infrastructure
message, stdout from the user process, stderr from the user process,
etc.).
Filtering is not active by default. Filter components must be
specifically requested, such as:
{{{
$ mpirun --mca filter xml ...
}}}
There can only be one filter component active.
= New MCA Parameters =
The new functionality described above introduces two new MCA
parameters:
* '''orte_base_help_aggregate''': Defaults to 1 (true), meaning that
help messages will be aggregated, as described above. If set to 0,
all help messages will be displayed, even if they are duplicates
(i.e., the original behavior).
* '''orte_base_show_output_recursions''': An MCA parameter to help
debug one of the known issues, described below. It is likely that
this MCA parameter will disappear before v1.3 final.
= Known Issues =
* The XML filter component is not complete. The current output from
this component is preliminary and not real XML. A bit more work
needs to be done to configure.m4 search for an appropriate XML
library/link it in/use it at run time.
* There are possible recursion loops in the orte_output() and
orte_show_help() functions -- e.g., if RML send calls orte_output()
or orte_show_help(). We have some ideas how to fix these, but
figured that it was ok to commit before feature freeze with known
issues. The code currently contains sub-optimal workarounds so
that this will not be a problem, but it would be good to actually
solve the problem rather than have hackish workarounds before v1.3 final.
This commit was SVN r18434.
2008-05-14 00:00:55 +04:00
|
|
|
orte_show_help("help-mpi-btl-openib.txt", "init-fail-create-q",
|
2008-03-24 02:10:15 +03:00
|
|
|
true, orte_process_info.nodename,
|
2007-01-25 01:25:40 +03:00
|
|
|
file, line, func, strerror(errno), errno, dev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-09 13:05:41 +03:00
|
|
|
static inline struct ibv_cq *ibv_create_cq_compat(struct ibv_context *context,
|
|
|
|
int cqe, void *cq_context, struct ibv_comp_channel *channel,
|
|
|
|
int comp_vector)
|
|
|
|
{
|
|
|
|
#if OMPI_IBV_CREATE_CQ_ARGS == 3
|
|
|
|
return ibv_create_cq(context, cqe, channel);
|
|
|
|
#else
|
2008-01-21 15:11:18 +03:00
|
|
|
return ibv_create_cq(context, cqe, cq_context, channel, comp_vector);
|
2008-01-09 13:05:41 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-07-23 04:28:59 +04:00
|
|
|
static int adjust_cq(mca_btl_openib_device_t *device, const int cq)
|
2008-01-09 13:05:41 +03:00
|
|
|
{
|
2008-07-23 04:28:59 +04:00
|
|
|
uint32_t cq_size = device->cq_size[cq];
|
2008-01-09 13:05:41 +03:00
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
/* make sure we don't exceed the maximum CQ size and that we
|
|
|
|
* don't size the queue smaller than otherwise requested
|
2008-01-09 13:05:41 +03:00
|
|
|
*/
|
|
|
|
if(cq_size < mca_btl_openib_component.ib_cq_size[cq])
|
|
|
|
cq_size = mca_btl_openib_component.ib_cq_size[cq];
|
|
|
|
|
2008-07-23 04:28:59 +04:00
|
|
|
if(cq_size > (uint32_t)device->ib_dev_attr.max_cqe)
|
|
|
|
cq_size = device->ib_dev_attr.max_cqe;
|
2008-01-09 13:05:41 +03:00
|
|
|
|
2008-07-23 04:28:59 +04:00
|
|
|
if(NULL == device->ib_cq[cq]) {
|
|
|
|
device->ib_cq[cq] = ibv_create_cq_compat(device->ib_dev_context, cq_size,
|
2008-01-09 13:05:41 +03:00
|
|
|
#if OMPI_ENABLE_PROGRESS_THREADS == 1
|
2008-07-23 04:28:59 +04:00
|
|
|
device, device->ib_channel,
|
2008-01-09 13:05:41 +03:00
|
|
|
#else
|
|
|
|
NULL, NULL,
|
|
|
|
#endif
|
|
|
|
0);
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2008-07-23 04:28:59 +04:00
|
|
|
if (NULL == device->ib_cq[cq]) {
|
2008-01-09 13:05:41 +03:00
|
|
|
show_init_error(__FILE__, __LINE__, "ibv_create_cq",
|
2008-07-23 04:28:59 +04:00
|
|
|
ibv_get_device_name(device->ib_dev));
|
2008-01-09 13:05:41 +03:00
|
|
|
return OMPI_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if OMPI_ENABLE_PROGRESS_THREADS == 1
|
2008-07-23 04:28:59 +04:00
|
|
|
if(ibv_req_notify_cq(device->ib_cq[cq], 0)) {
|
2008-01-09 13:05:41 +03:00
|
|
|
show_init_error(__FILE__, __LINE__, "ibv_req_notify_cq",
|
2008-07-23 04:28:59 +04:00
|
|
|
ibv_get_device_name(device->ib_dev));
|
2008-01-09 13:05:41 +03:00
|
|
|
return OMPI_ERROR;
|
|
|
|
}
|
|
|
|
|
2008-07-23 04:28:59 +04:00
|
|
|
OPAL_THREAD_LOCK(&device->device_lock);
|
|
|
|
if (!device->progress) {
|
2008-01-09 13:05:41 +03:00
|
|
|
int rc;
|
2008-07-23 04:28:59 +04:00
|
|
|
device->progress = true;
|
|
|
|
if(OPAL_SUCCESS != (rc = opal_thread_start(&device->thread))) {
|
2008-01-09 13:05:41 +03:00
|
|
|
BTL_ERROR(("Unable to create progress thread, retval=%d", rc));
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
2008-07-23 04:28:59 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&device->device_lock);
|
2008-01-09 13:05:41 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#ifdef HAVE_IBV_RESIZE_CQ
|
|
|
|
else if (cq_size > mca_btl_openib_component.ib_cq_size[cq]){
|
|
|
|
int rc;
|
2008-07-23 04:28:59 +04:00
|
|
|
rc = ibv_resize_cq(device->ib_cq[cq], cq_size);
|
2008-01-21 15:11:18 +03:00
|
|
|
/* For ConnectX the resize CQ is not implemented and verbs returns -ENOSYS
|
2008-01-09 13:05:41 +03:00
|
|
|
* but should return ENOSYS. So it is reason for abs */
|
|
|
|
if(rc && ENOSYS != abs(rc)) {
|
|
|
|
BTL_ERROR(("cannot resize completion queue, error: %d", rc));
|
|
|
|
return OMPI_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
/*
|
|
|
|
* create both the high and low priority completion queues
|
2008-01-09 13:05:41 +03:00
|
|
|
* and the shared receive queue (if requested)
|
2008-01-21 15:11:18 +03:00
|
|
|
*/
|
2008-01-09 13:05:41 +03:00
|
|
|
static int create_srq(mca_btl_openib_module_t *openib_btl)
|
|
|
|
{
|
|
|
|
int qp;
|
|
|
|
|
|
|
|
/* create the SRQ's */
|
2008-01-21 15:11:18 +03:00
|
|
|
for(qp = 0; qp < mca_btl_openib_component.num_qps; qp++) {
|
|
|
|
struct ibv_srq_init_attr attr;
|
2008-01-09 13:05:41 +03:00
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
if(!BTL_OPENIB_QP_TYPE_PP(qp)) {
|
|
|
|
attr.attr.max_wr = mca_btl_openib_component.qp_infos[qp].rd_num +
|
2008-01-09 13:05:41 +03:00
|
|
|
mca_btl_openib_component.qp_infos[qp].u.srq_qp.sd_max;
|
2008-06-11 20:31:39 +04:00
|
|
|
attr.attr.max_sge = 1;
|
2008-01-09 13:05:41 +03:00
|
|
|
openib_btl->qps[qp].u.srq_qp.rd_posted = 0;
|
|
|
|
#if HAVE_XRC
|
|
|
|
if(BTL_OPENIB_QP_TYPE_XRC(qp)) {
|
|
|
|
openib_btl->qps[qp].u.srq_qp.srq =
|
2008-07-23 04:28:59 +04:00
|
|
|
ibv_create_xrc_srq(openib_btl->device->ib_pd,
|
|
|
|
openib_btl->device->xrc_domain,
|
|
|
|
openib_btl->device->ib_cq[qp_cq_prio(qp)], &attr);
|
2008-01-09 13:05:41 +03:00
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
openib_btl->qps[qp].u.srq_qp.srq =
|
2008-07-23 04:28:59 +04:00
|
|
|
ibv_create_srq(openib_btl->device->ib_pd, &attr);
|
2008-01-09 13:05:41 +03:00
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
if (NULL == openib_btl->qps[qp].u.srq_qp.srq) {
|
2008-01-09 13:05:41 +03:00
|
|
|
show_init_error(__FILE__, __LINE__, "ibv_create_srq",
|
2008-07-23 04:28:59 +04:00
|
|
|
ibv_get_device_name(openib_btl->device->ib_dev));
|
2008-01-21 15:11:18 +03:00
|
|
|
return OMPI_ERROR;
|
2008-01-09 13:05:41 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2008-01-09 13:05:41 +03:00
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
static int mca_btl_openib_size_queues(struct mca_btl_openib_module_t* openib_btl, size_t nprocs)
|
2008-01-09 13:05:41 +03:00
|
|
|
{
|
|
|
|
uint32_t send_cqes, recv_cqes;
|
|
|
|
int rc = OMPI_SUCCESS, qp;
|
2008-07-23 04:28:59 +04:00
|
|
|
mca_btl_openib_device_t *device = openib_btl->device;
|
2008-01-09 13:05:41 +03:00
|
|
|
|
|
|
|
/* figure out reasonable sizes for completion queues */
|
2008-01-21 15:11:18 +03:00
|
|
|
for(qp = 0; qp < mca_btl_openib_component.num_qps; qp++) {
|
2008-01-09 13:05:41 +03:00
|
|
|
if(BTL_OPENIB_QP_TYPE_SRQ(qp)) {
|
|
|
|
send_cqes = mca_btl_openib_component.qp_infos[qp].u.srq_qp.sd_max;
|
|
|
|
recv_cqes = mca_btl_openib_component.qp_infos[qp].rd_num;
|
|
|
|
} else {
|
|
|
|
send_cqes = (mca_btl_openib_component.qp_infos[qp].rd_num +
|
|
|
|
mca_btl_openib_component.qp_infos[qp].u.pp_qp.rd_rsv) * nprocs;
|
|
|
|
recv_cqes = send_cqes;
|
|
|
|
}
|
2008-07-23 04:28:59 +04:00
|
|
|
openib_btl->device->cq_size[qp_cq_prio(qp)] += recv_cqes;
|
|
|
|
openib_btl->device->cq_size[BTL_OPENIB_LP_CQ] += send_cqes;
|
2008-01-09 13:05:41 +03:00
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2008-07-23 04:28:59 +04:00
|
|
|
rc = adjust_cq(device, BTL_OPENIB_HP_CQ);
|
2008-10-15 14:37:20 +04:00
|
|
|
if (OMPI_SUCCESS != rc) {
|
2008-01-09 13:05:41 +03:00
|
|
|
goto out;
|
2008-10-15 14:37:20 +04:00
|
|
|
}
|
2008-01-09 13:05:41 +03:00
|
|
|
|
2008-07-23 04:28:59 +04:00
|
|
|
rc = adjust_cq(device, BTL_OPENIB_LP_CQ);
|
2008-10-15 14:37:20 +04:00
|
|
|
if (OMPI_SUCCESS != rc) {
|
2008-01-09 13:05:41 +03:00
|
|
|
goto out;
|
2008-10-15 14:37:20 +04:00
|
|
|
}
|
2008-01-09 13:05:41 +03:00
|
|
|
|
2008-10-15 14:37:20 +04:00
|
|
|
if (0 == openib_btl->num_peers) {
|
2008-01-21 15:11:18 +03:00
|
|
|
rc = create_srq(openib_btl);
|
2008-10-15 14:37:20 +04:00
|
|
|
}
|
2008-01-09 13:05:41 +03:00
|
|
|
|
|
|
|
openib_btl->num_peers += nprocs;
|
2008-10-15 14:37:20 +04:00
|
|
|
out:
|
2008-01-09 13:05:41 +03:00
|
|
|
return rc;
|
|
|
|
}
|
2007-01-25 01:25:40 +03:00
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
/*
|
|
|
|
* add a proc to this btl module
|
2005-07-20 19:17:18 +04:00
|
|
|
* creates an endpoint that is setup on the
|
|
|
|
* first send to the endpoint
|
2008-01-21 15:11:18 +03:00
|
|
|
*/
|
2005-07-01 01:28:35 +04:00
|
|
|
int mca_btl_openib_add_procs(
|
2008-01-21 15:11:18 +03:00
|
|
|
struct mca_btl_base_module_t* btl,
|
|
|
|
size_t nprocs,
|
|
|
|
struct ompi_proc_t **ompi_procs,
|
|
|
|
struct mca_btl_base_endpoint_t** peers,
|
2005-07-01 01:28:35 +04:00
|
|
|
ompi_bitmap_t* reachable)
|
|
|
|
{
|
2005-07-12 17:38:54 +04:00
|
|
|
mca_btl_openib_module_t* openib_btl = (mca_btl_openib_module_t*)btl;
|
2007-01-04 01:35:41 +03:00
|
|
|
int i,j, rc;
|
2007-01-13 01:42:20 +03:00
|
|
|
int rem_subnet_id_port_cnt;
|
|
|
|
int lcl_subnet_id_port_cnt = 0;
|
2007-01-08 20:20:09 +03:00
|
|
|
int btl_rank = 0;
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
mca_btl_base_endpoint_t* endpoint;
|
2008-05-02 15:52:33 +04:00
|
|
|
ompi_btl_openib_connect_base_module_t *local_cpc;
|
|
|
|
ompi_btl_openib_connect_base_module_data_t *remote_cpc_data;
|
2008-01-21 15:11:18 +03:00
|
|
|
|
|
|
|
for(j=0; j < mca_btl_openib_component.ib_num_btls; j++){
|
2007-05-09 01:47:21 +04:00
|
|
|
if(mca_btl_openib_component.openib_btls[j]->port_info.subnet_id
|
2008-01-21 15:11:18 +03:00
|
|
|
== openib_btl->port_info.subnet_id) {
|
|
|
|
if(openib_btl == mca_btl_openib_component.openib_btls[j]) {
|
2007-06-13 15:15:58 +04:00
|
|
|
btl_rank = lcl_subnet_id_port_cnt;
|
2007-01-13 01:42:20 +03:00
|
|
|
}
|
2007-06-14 14:27:11 +04:00
|
|
|
lcl_subnet_id_port_cnt++;
|
2007-01-13 01:42:20 +03:00
|
|
|
}
|
|
|
|
}
|
2007-06-14 14:27:11 +04:00
|
|
|
|
2007-11-28 10:18:59 +03:00
|
|
|
#if HAVE_XRC
|
|
|
|
if(MCA_BTL_XRC_ENABLED &&
|
|
|
|
NULL == mca_btl_openib_component.ib_addr_table.ht_table) {
|
|
|
|
if(OPAL_SUCCESS != opal_hash_table_init(
|
|
|
|
&mca_btl_openib_component.ib_addr_table, nprocs)) {
|
2008-05-02 15:52:33 +04:00
|
|
|
BTL_ERROR(("XRC internal error. Failed to allocate ib_table"));
|
2007-11-28 10:18:59 +03:00
|
|
|
return OMPI_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-05-02 15:52:33 +04:00
|
|
|
for (i = 0; i < (int) nprocs; i++) {
|
2005-07-01 01:28:35 +04:00
|
|
|
struct ompi_proc_t* ompi_proc = ompi_procs[i];
|
|
|
|
mca_btl_openib_proc_t* ib_proc;
|
2008-05-02 15:52:33 +04:00
|
|
|
int remote_matching_port;
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2008-06-09 18:53:58 +04:00
|
|
|
opal_output(-1, "add procs: adding proc %d", i);
|
2008-06-21 02:08:00 +04:00
|
|
|
|
2008-06-25 18:50:59 +04:00
|
|
|
#if defined(HAVE_STRUCT_IBV_DEVICE_TRANSPORT_TYPE)
|
2008-06-21 02:08:00 +04:00
|
|
|
/* Most current iWARP adapters (June 2008) cannot handle
|
|
|
|
talking to other processes on the same host (!) -- so mark
|
|
|
|
them as unreachable (need to use sm). So for the moment,
|
|
|
|
we'll just mark any local peer on an iWARP NIC as
|
|
|
|
unreachable. See trac ticket #1352. */
|
2008-07-23 04:28:59 +04:00
|
|
|
if (IBV_TRANSPORT_IWARP == openib_btl->device->ib_dev->transport_type &&
|
2008-06-21 02:08:00 +04:00
|
|
|
0 != (ompi_proc->proc_flags && OMPI_PROC_FLAG_LOCAL)) {
|
|
|
|
continue;
|
|
|
|
}
|
2008-06-25 18:50:59 +04:00
|
|
|
#endif
|
2008-06-21 02:08:00 +04:00
|
|
|
|
2005-07-01 01:28:35 +04:00
|
|
|
if(NULL == (ib_proc = mca_btl_openib_proc_create(ompi_proc))) {
|
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
|
|
|
|
2008-05-02 15:52:33 +04:00
|
|
|
/* check if the remote proc has any ports that:
|
|
|
|
- on the same subnet as the local proc, and
|
|
|
|
- on that subnet, has a CPC in common with the local proc
|
|
|
|
*/
|
|
|
|
remote_matching_port = -1;
|
|
|
|
rem_subnet_id_port_cnt = 0;
|
|
|
|
BTL_VERBOSE(("got %d port_infos ", ib_proc->proc_port_count));
|
|
|
|
for (j = 0; j < (int) ib_proc->proc_port_count; j++){
|
2008-06-27 00:23:56 +04:00
|
|
|
BTL_VERBOSE(("got a subnet %016" PRIx64,
|
2008-05-02 15:52:33 +04:00
|
|
|
ib_proc->proc_ports[j].pm_port_info.subnet_id));
|
|
|
|
if (ib_proc->proc_ports[j].pm_port_info.subnet_id ==
|
|
|
|
openib_btl->port_info.subnet_id) {
|
|
|
|
BTL_VERBOSE(("Got a matching subnet!"));
|
|
|
|
if (rem_subnet_id_port_cnt == btl_rank) {
|
|
|
|
remote_matching_port = j;
|
|
|
|
}
|
|
|
|
rem_subnet_id_port_cnt++;
|
2007-01-04 01:35:41 +03:00
|
|
|
}
|
|
|
|
}
|
2008-01-15 02:22:03 +03:00
|
|
|
|
2008-05-02 15:52:33 +04:00
|
|
|
if (0 == rem_subnet_id_port_cnt) {
|
|
|
|
/* no use trying to communicate with this endpoint */
|
|
|
|
BTL_VERBOSE(("No matching subnet id/CPC was found, moving on.. "));
|
|
|
|
continue;
|
2008-01-15 02:22:03 +03:00
|
|
|
}
|
|
|
|
|
2008-05-02 15:52:33 +04:00
|
|
|
/* If this process has multiple ports on a single subnet ID,
|
|
|
|
and the report proc also has multiple ports on this same
|
|
|
|
subnet ID, the default connection pattern is:
|
|
|
|
|
|
|
|
LOCAL REMOTE PEER
|
|
|
|
1st port on subnet X <--> 1st port on subnet X
|
|
|
|
2nd port on subnet X <--> 2nd port on subnet X
|
|
|
|
3nd port on subnet X <--> 3nd port on subnet X
|
|
|
|
...etc.
|
|
|
|
|
|
|
|
Note that the port numbers may not be contiguous, and they
|
|
|
|
may not be the same on either side. Hence the "1st", "2nd",
|
|
|
|
"3rd, etc. notation, above.
|
|
|
|
|
|
|
|
Hence, if the local "rank" of this module's port on the
|
|
|
|
subnet ID is greater than the total number of ports on the
|
|
|
|
peer on this same subnet, then we have no match. So skip
|
|
|
|
this connection. */
|
|
|
|
if (rem_subnet_id_port_cnt < lcl_subnet_id_port_cnt &&
|
|
|
|
btl_rank >= rem_subnet_id_port_cnt) {
|
|
|
|
BTL_VERBOSE(("Not enough remote ports on this subnet id, moving on.. "));
|
2007-01-04 01:35:41 +03:00
|
|
|
continue;
|
|
|
|
}
|
2007-04-27 01:03:38 +04:00
|
|
|
|
2008-05-02 15:52:33 +04:00
|
|
|
/* Now that we have verified that we're on the same subnet and
|
|
|
|
the remote peer has enough ports, see if that specific port
|
|
|
|
on the peer has a matching CPC. */
|
|
|
|
assert(btl_rank <= ib_proc->proc_port_count);
|
|
|
|
assert(remote_matching_port != -1);
|
|
|
|
if (OMPI_SUCCESS !=
|
|
|
|
ompi_btl_openib_connect_base_find_match(openib_btl,
|
|
|
|
&(ib_proc->proc_ports[remote_matching_port]),
|
|
|
|
&local_cpc,
|
|
|
|
&remote_cpc_data)) {
|
2007-01-04 01:35:41 +03:00
|
|
|
continue;
|
|
|
|
}
|
2008-05-02 15:52:33 +04:00
|
|
|
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&ib_proc->proc_lock);
|
2005-07-01 01:28:35 +04:00
|
|
|
|
2007-04-27 01:03:38 +04:00
|
|
|
/* The btl_proc datastructure is shared by all IB BTL
|
2008-01-21 15:11:18 +03:00
|
|
|
* instances that are trying to reach this destination.
|
2005-07-01 01:28:35 +04:00
|
|
|
* Cache the peer instance on the btl_proc.
|
|
|
|
*/
|
2007-01-04 01:35:41 +03:00
|
|
|
endpoint = OBJ_NEW(mca_btl_openib_endpoint_t);
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
assert(((opal_object_t*)endpoint)->obj_reference_count == 1);
|
2007-01-04 01:35:41 +03:00
|
|
|
if(NULL == endpoint) {
|
2005-08-16 17:22:08 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ib_proc->proc_lock);
|
2005-07-01 01:28:35 +04:00
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-11-28 10:18:59 +03:00
|
|
|
#if HAVE_XRC
|
|
|
|
if (MCA_BTL_XRC_ENABLED) {
|
2007-11-28 12:57:48 +03:00
|
|
|
int rem_port_cnt = 0;
|
2007-12-03 12:49:53 +03:00
|
|
|
for(j = 0; j < (int) ib_proc->proc_port_count; j++) {
|
2008-05-02 15:52:33 +04:00
|
|
|
if(ib_proc->proc_ports[j].pm_port_info.subnet_id ==
|
2007-11-28 12:57:48 +03:00
|
|
|
openib_btl->port_info.subnet_id) {
|
2007-12-03 12:49:53 +03:00
|
|
|
if (rem_port_cnt == btl_rank)
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
rem_port_cnt ++;
|
2007-11-28 12:57:48 +03:00
|
|
|
}
|
|
|
|
}
|
2007-12-03 12:49:53 +03:00
|
|
|
|
2007-11-28 12:57:48 +03:00
|
|
|
assert(rem_port_cnt == btl_rank);
|
2008-01-16 00:14:48 +03:00
|
|
|
/* Push the subnet/lid/jobid to xrc hash */
|
2007-11-28 10:18:59 +03:00
|
|
|
rc = mca_btl_openib_ib_address_add_new(
|
2008-05-02 15:52:33 +04:00
|
|
|
ib_proc->proc_ports[j].pm_port_info.lid,
|
|
|
|
ib_proc->proc_ports[j].pm_port_info.subnet_id,
|
2008-01-16 00:14:48 +03:00
|
|
|
ompi_proc->proc_name.jobid, endpoint);
|
2007-11-28 10:18:59 +03:00
|
|
|
if (OMPI_SUCCESS != rc ) {
|
|
|
|
OPAL_THREAD_UNLOCK(&ib_proc->proc_lock);
|
|
|
|
return OMPI_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2008-05-02 15:52:33 +04:00
|
|
|
mca_btl_openib_endpoint_init(openib_btl, endpoint,
|
|
|
|
local_cpc,
|
|
|
|
&(ib_proc->proc_ports[remote_matching_port]),
|
|
|
|
remote_cpc_data);
|
|
|
|
|
2007-01-04 01:35:41 +03:00
|
|
|
rc = mca_btl_openib_proc_insert(ib_proc, endpoint);
|
2008-05-02 15:52:33 +04:00
|
|
|
if (OMPI_SUCCESS != rc) {
|
2007-01-04 01:35:41 +03:00
|
|
|
OBJ_RELEASE(endpoint);
|
2005-08-14 23:03:09 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ib_proc->proc_lock);
|
2005-07-01 01:28:35 +04:00
|
|
|
continue;
|
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2008-07-23 04:28:59 +04:00
|
|
|
endpoint->index = opal_pointer_array_add(openib_btl->device->endpoints, (void*)endpoint);
|
2007-12-21 09:02:00 +03:00
|
|
|
if( 0 > endpoint->index ) {
|
|
|
|
OBJ_RELEASE(endpoint);
|
|
|
|
OPAL_THREAD_UNLOCK(&ib_proc->proc_lock);
|
|
|
|
continue;
|
|
|
|
}
|
2008-05-02 15:52:33 +04:00
|
|
|
|
|
|
|
/* Tell the selected CPC that it won. NOTE: This call is
|
|
|
|
outside of / separate from mca_btl_openib_endpoint_init()
|
|
|
|
because this function likely needs the endpoint->index. */
|
|
|
|
if (NULL != local_cpc->cbm_endpoint_init) {
|
|
|
|
rc = local_cpc->cbm_endpoint_init(endpoint);
|
|
|
|
if (OMPI_SUCCESS != rc) {
|
|
|
|
OBJ_RELEASE(endpoint);
|
|
|
|
OPAL_THREAD_UNLOCK(&ib_proc->proc_lock);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-07-01 01:28:35 +04:00
|
|
|
ompi_bitmap_set_bit(reachable, i);
|
2005-08-14 23:03:09 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&ib_proc->proc_lock);
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-01-04 01:35:41 +03:00
|
|
|
peers[i] = endpoint;
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
2007-01-04 01:35:41 +03:00
|
|
|
|
2007-07-18 17:49:15 +04:00
|
|
|
return mca_btl_openib_size_queues(openib_btl, nprocs);
|
2006-07-31 21:24:39 +04:00
|
|
|
}
|
2006-07-30 04:58:40 +04:00
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
/*
|
|
|
|
* delete the proc as reachable from this btl module
|
2005-07-20 19:17:18 +04:00
|
|
|
*/
|
2008-01-21 15:11:18 +03:00
|
|
|
int mca_btl_openib_del_procs(struct mca_btl_base_module_t* btl,
|
|
|
|
size_t nprocs,
|
|
|
|
struct ompi_proc_t **procs,
|
2005-07-01 01:28:35 +04:00
|
|
|
struct mca_btl_base_endpoint_t ** peers)
|
|
|
|
{
|
2007-05-09 01:47:21 +04:00
|
|
|
int i,ep_index;
|
|
|
|
mca_btl_openib_module_t* openib_btl = (mca_btl_openib_module_t*) btl;
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
mca_btl_openib_endpoint_t* endpoint;
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-05-09 01:47:21 +04:00
|
|
|
for (i=0 ; i < (int) nprocs ; i++) {
|
|
|
|
mca_btl_base_endpoint_t* del_endpoint = peers[i];
|
|
|
|
for(ep_index=0;
|
2008-07-23 04:28:59 +04:00
|
|
|
ep_index < opal_pointer_array_get_size(openib_btl->device->endpoints);
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
ep_index++) {
|
2008-01-21 15:11:18 +03:00
|
|
|
endpoint =
|
2008-07-23 04:28:59 +04:00
|
|
|
opal_pointer_array_get_item(openib_btl->device->endpoints,
|
2007-08-20 16:28:25 +04:00
|
|
|
ep_index);
|
|
|
|
if(!endpoint || endpoint->endpoint_btl != openib_btl) {
|
2007-05-09 01:47:21 +04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (endpoint == del_endpoint) {
|
2008-05-02 15:52:33 +04:00
|
|
|
BTL_VERBOSE(("in del_procs %d, setting another endpoint to null",
|
2007-10-15 21:53:02 +04:00
|
|
|
ep_index));
|
2008-07-23 04:28:59 +04:00
|
|
|
opal_pointer_array_set_item(openib_btl->device->endpoints,
|
2007-08-20 16:28:25 +04:00
|
|
|
ep_index, NULL);
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
assert(((opal_object_t*)endpoint)->obj_reference_count == 1);
|
2008-05-02 15:52:33 +04:00
|
|
|
mca_btl_openib_proc_remove(procs[i], endpoint);
|
2007-05-09 01:47:21 +04:00
|
|
|
OBJ_RELEASE(endpoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
|
2005-07-01 01:28:35 +04:00
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
/*
|
2006-08-17 00:21:38 +04:00
|
|
|
*Register callback function for error handling..
|
2008-01-21 15:11:18 +03:00
|
|
|
*/
|
2006-08-17 00:21:38 +04:00
|
|
|
int mca_btl_openib_register_error_cb(
|
2008-01-21 15:11:18 +03:00
|
|
|
struct mca_btl_base_module_t* btl,
|
2006-08-17 00:21:38 +04:00
|
|
|
mca_btl_base_module_error_cb_fn_t cbfunc)
|
|
|
|
{
|
2008-01-21 15:11:18 +03:00
|
|
|
|
|
|
|
mca_btl_openib_module_t* openib_btl = (mca_btl_openib_module_t*) btl;
|
2006-08-17 00:21:38 +04:00
|
|
|
openib_btl->error_cb = cbfunc; /* stash for later */
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-12-09 17:02:32 +03:00
|
|
|
static inline mca_btl_base_descriptor_t *
|
2007-12-09 17:08:55 +03:00
|
|
|
ib_frag_alloc(mca_btl_openib_module_t *btl, size_t size, uint8_t order,
|
|
|
|
uint32_t flags)
|
2007-12-09 17:02:32 +03:00
|
|
|
{
|
|
|
|
int qp, rc;
|
|
|
|
ompi_free_list_item_t* item = NULL;
|
|
|
|
|
|
|
|
for(qp = 0; qp < mca_btl_openib_component.num_qps; qp++) {
|
|
|
|
if(mca_btl_openib_component.qp_infos[qp].size >= size) {
|
2008-07-23 04:28:59 +04:00
|
|
|
OMPI_FREE_LIST_GET(&btl->device->qps[qp].send_free, item, rc);
|
2007-12-09 17:02:32 +03:00
|
|
|
if(item)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(NULL == item)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* not all upper layer users set this */
|
|
|
|
to_base_frag(item)->segment.seg_len = size;
|
|
|
|
to_base_frag(item)->base.order = order;
|
2007-12-09 17:08:55 +03:00
|
|
|
to_base_frag(item)->base.des_flags = flags;
|
2007-12-09 17:02:32 +03:00
|
|
|
|
|
|
|
assert(to_send_frag(item)->qp_idx <= order);
|
|
|
|
return &to_base_frag(item)->base;
|
|
|
|
}
|
|
|
|
|
2007-12-09 17:05:13 +03:00
|
|
|
/* check if pending fragment has enough space for coalescing */
|
|
|
|
static mca_btl_openib_send_frag_t *check_coalescing(opal_list_t *frag_list,
|
|
|
|
opal_mutex_t *lock, mca_btl_base_endpoint_t *ep, size_t size)
|
|
|
|
{
|
|
|
|
mca_btl_openib_send_frag_t *frag = NULL;
|
|
|
|
|
|
|
|
if(opal_list_is_empty(frag_list))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
OPAL_THREAD_LOCK(lock);
|
|
|
|
if(!opal_list_is_empty(frag_list)) {
|
|
|
|
int qp;
|
|
|
|
size_t total_length;
|
|
|
|
opal_list_item_t *i = opal_list_get_first(frag_list);
|
|
|
|
frag = to_send_frag(i);
|
|
|
|
if(to_com_frag(frag)->endpoint != ep ||
|
|
|
|
MCA_BTL_OPENIB_FRAG_CONTROL == openib_frag_type(frag)) {
|
|
|
|
OPAL_THREAD_UNLOCK(lock);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
total_length = size + frag->coalesced_length +
|
|
|
|
to_base_frag(frag)->segment.seg_len +
|
|
|
|
sizeof(mca_btl_openib_header_coalesced_t);
|
|
|
|
|
|
|
|
qp = to_base_frag(frag)->base.order;
|
|
|
|
|
|
|
|
if(total_length <= mca_btl_openib_component.qp_infos[qp].size)
|
|
|
|
opal_list_remove_first(frag_list);
|
|
|
|
else
|
|
|
|
frag = NULL;
|
|
|
|
}
|
|
|
|
OPAL_THREAD_UNLOCK(lock);
|
|
|
|
|
|
|
|
return frag;
|
|
|
|
}
|
|
|
|
|
2005-07-01 01:28:35 +04:00
|
|
|
/**
|
|
|
|
* Allocate a segment.
|
|
|
|
*
|
|
|
|
* @param btl (IN) BTL module
|
|
|
|
* @param size (IN) Request segment size.
|
2008-01-21 15:11:18 +03:00
|
|
|
* @param size (IN) Size of segment to allocate
|
|
|
|
*
|
|
|
|
* When allocating a segment we pull a pre-alllocated segment
|
2005-07-20 19:17:18 +04:00
|
|
|
* from one of two free lists, an eager list and a max list
|
2005-07-01 01:28:35 +04:00
|
|
|
*/
|
|
|
|
mca_btl_base_descriptor_t* mca_btl_openib_alloc(
|
|
|
|
struct mca_btl_base_module_t* btl,
|
2007-12-09 17:05:13 +03:00
|
|
|
struct mca_btl_base_endpoint_t* ep,
|
2007-05-24 23:51:26 +04:00
|
|
|
uint8_t order,
|
2007-12-09 17:08:01 +03:00
|
|
|
size_t size,
|
|
|
|
uint32_t flags)
|
2005-07-01 01:28:35 +04:00
|
|
|
{
|
2007-12-09 17:05:13 +03:00
|
|
|
mca_btl_openib_module_t *obtl = (mca_btl_openib_module_t*)btl;
|
|
|
|
int qp = frag_size_to_order(obtl, size);
|
|
|
|
mca_btl_openib_send_frag_t *sfrag = NULL;
|
|
|
|
mca_btl_openib_coalesced_frag_t *cfrag;
|
|
|
|
|
|
|
|
assert(qp != MCA_BTL_NO_ORDER);
|
|
|
|
|
2008-02-18 20:39:30 +03:00
|
|
|
if(mca_btl_openib_component.use_message_coalescing &&
|
|
|
|
(flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP)) {
|
2007-12-09 17:08:55 +03:00
|
|
|
int prio = !(flags & MCA_BTL_DES_FLAGS_PRIORITY);
|
|
|
|
sfrag = check_coalescing(&ep->qps[qp].qp->pending_frags[prio],
|
2007-12-09 17:05:13 +03:00
|
|
|
&ep->qps[qp].qp->lock, ep, size);
|
|
|
|
|
|
|
|
if(NULL == sfrag) {
|
|
|
|
if(BTL_OPENIB_QP_TYPE_PP(qp)) {
|
2007-12-09 17:08:55 +03:00
|
|
|
sfrag = check_coalescing(&ep->qps[qp].pending_frags[prio],
|
2007-12-09 17:05:13 +03:00
|
|
|
&ep->endpoint_lock, ep, size);
|
|
|
|
} else {
|
|
|
|
sfrag = check_coalescing(
|
2007-12-09 17:08:55 +03:00
|
|
|
&obtl->qps[qp].u.srq_qp.pending_frags[prio],
|
2007-12-09 17:05:13 +03:00
|
|
|
&obtl->ib_lock, ep, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(NULL == sfrag)
|
2007-12-09 17:08:55 +03:00
|
|
|
return ib_frag_alloc((mca_btl_openib_module_t*)btl, size, order, flags);
|
2007-12-09 17:05:13 +03:00
|
|
|
|
|
|
|
/* begin coalescing message */
|
2008-01-09 13:26:21 +03:00
|
|
|
cfrag = alloc_coalesced_frag();
|
2007-12-09 17:05:13 +03:00
|
|
|
cfrag->send_frag = sfrag;
|
|
|
|
|
|
|
|
/* fix up new coalescing header if this is the first coalesced frag */
|
|
|
|
if(sfrag->hdr != sfrag->chdr) {
|
|
|
|
mca_btl_openib_control_header_t *ctrl_hdr;
|
|
|
|
mca_btl_openib_header_coalesced_t *clsc_hdr;
|
|
|
|
uint8_t org_tag;
|
|
|
|
|
|
|
|
org_tag = sfrag->hdr->tag;
|
|
|
|
sfrag->hdr = sfrag->chdr;
|
|
|
|
ctrl_hdr = (mca_btl_openib_control_header_t*)(sfrag->hdr + 1);
|
|
|
|
clsc_hdr = (mca_btl_openib_header_coalesced_t*)(ctrl_hdr + 1);
|
|
|
|
sfrag->hdr->tag = MCA_BTL_TAG_BTL;
|
|
|
|
ctrl_hdr->type = MCA_BTL_OPENIB_CONTROL_COALESCED;
|
|
|
|
clsc_hdr->tag = org_tag;
|
|
|
|
clsc_hdr->size = to_base_frag(sfrag)->segment.seg_len;
|
|
|
|
clsc_hdr->alloc_size = to_base_frag(sfrag)->segment.seg_len;
|
2007-12-09 17:10:25 +03:00
|
|
|
if(ep->nbo)
|
|
|
|
BTL_OPENIB_HEADER_COALESCED_HTON(*clsc_hdr);
|
2007-12-09 17:05:13 +03:00
|
|
|
sfrag->coalesced_length = sizeof(mca_btl_openib_control_header_t) +
|
|
|
|
sizeof(mca_btl_openib_header_coalesced_t);
|
2008-01-21 15:11:18 +03:00
|
|
|
to_com_frag(sfrag)->sg_entry.addr = (uint64_t)(uintptr_t)sfrag->hdr;
|
2007-12-09 17:05:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
cfrag->hdr = (mca_btl_openib_header_coalesced_t*)
|
|
|
|
(((unsigned char*)(sfrag->hdr + 1)) + sfrag->coalesced_length +
|
|
|
|
to_base_frag(sfrag)->segment.seg_len);
|
|
|
|
cfrag->hdr->alloc_size = size;
|
|
|
|
|
|
|
|
/* point coalesced frag pointer into a data buffer */
|
|
|
|
to_base_frag(cfrag)->segment.seg_addr.pval = cfrag->hdr + 1;
|
|
|
|
to_base_frag(cfrag)->segment.seg_len = size;
|
|
|
|
|
|
|
|
/* save coalesced fragment on a main fragment; we will need it after send
|
|
|
|
* completion to free it and to call upper layer callback */
|
|
|
|
opal_list_append(&sfrag->coalesced_frags, (opal_list_item_t*)cfrag);
|
|
|
|
sfrag->coalesced_length += (size+sizeof(mca_btl_openib_header_coalesced_t));
|
|
|
|
|
2008-02-19 15:26:45 +03:00
|
|
|
to_base_frag(cfrag)->base.des_flags = flags;
|
|
|
|
|
2007-12-09 17:05:13 +03:00
|
|
|
return &to_base_frag(cfrag)->base;
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
/**
|
|
|
|
* Return a segment
|
|
|
|
*
|
|
|
|
* Return the segment to the appropriate
|
|
|
|
* preallocated segment list
|
|
|
|
*/
|
2005-07-01 01:28:35 +04:00
|
|
|
int mca_btl_openib_free(
|
2008-01-21 15:11:18 +03:00
|
|
|
struct mca_btl_base_module_t* btl,
|
|
|
|
mca_btl_base_descriptor_t* des)
|
2005-07-01 01:28:35 +04:00
|
|
|
{
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
/* is this fragment pointing at user memory? */
|
2007-11-28 10:11:14 +03:00
|
|
|
if(MCA_BTL_OPENIB_FRAG_SEND_USER == openib_frag_type(des) ||
|
|
|
|
MCA_BTL_OPENIB_FRAG_RECV_USER == openib_frag_type(des)) {
|
|
|
|
mca_btl_openib_com_frag_t* frag = to_com_frag(des);
|
|
|
|
|
|
|
|
if(frag->registration != NULL) {
|
|
|
|
btl->btl_mpool->mpool_deregister(btl->btl_mpool,
|
|
|
|
(mca_mpool_base_registration_t*)frag->registration);
|
|
|
|
frag->registration = NULL;
|
|
|
|
}
|
2006-06-01 06:32:18 +04:00
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-11-28 10:11:14 +03:00
|
|
|
/* reset those field on free so we will not have to do it on alloc */
|
|
|
|
to_base_frag(des)->base.des_flags = 0;
|
2007-12-09 17:05:13 +03:00
|
|
|
switch(openib_frag_type(des)) {
|
|
|
|
case MCA_BTL_OPENIB_FRAG_RECV:
|
|
|
|
case MCA_BTL_OPENIB_FRAG_RECV_USER:
|
|
|
|
to_base_frag(des)->base.des_src = NULL;
|
|
|
|
to_base_frag(des)->base.des_src_cnt = 0;
|
|
|
|
break;
|
|
|
|
case MCA_BTL_OPENIB_FRAG_SEND:
|
|
|
|
to_send_frag(des)->hdr = (mca_btl_openib_header_t*)
|
|
|
|
(((unsigned char*)to_send_frag(des)->chdr) +
|
|
|
|
sizeof(mca_btl_openib_header_coalesced_t) +
|
|
|
|
sizeof(mca_btl_openib_control_header_t));
|
2007-12-09 17:15:35 +03:00
|
|
|
to_com_frag(des)->sg_entry.addr =
|
|
|
|
(uint64_t)(uintptr_t)to_send_frag(des)->hdr;
|
2007-12-09 17:05:13 +03:00
|
|
|
to_send_frag(des)->coalesced_length = 0;
|
|
|
|
assert(!opal_list_get_size(&to_send_frag(des)->coalesced_frags));
|
|
|
|
/* fall throug */
|
|
|
|
case MCA_BTL_OPENIB_FRAG_SEND_USER:
|
|
|
|
to_base_frag(des)->base.des_dst = NULL;
|
|
|
|
to_base_frag(des)->base.des_dst_cnt = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2007-11-28 10:11:14 +03:00
|
|
|
}
|
|
|
|
MCA_BTL_IB_FRAG_RETURN(des);
|
2008-01-21 15:11:18 +03:00
|
|
|
|
|
|
|
return OMPI_SUCCESS;
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-01-21 15:11:18 +03:00
|
|
|
* register user buffer or pack
|
|
|
|
* data into pre-registered buffer and return a
|
2005-07-20 19:17:18 +04:00
|
|
|
* descriptor that can be
|
2005-07-01 01:28:35 +04:00
|
|
|
* used for send/put.
|
|
|
|
*
|
|
|
|
* @param btl (IN) BTL module
|
|
|
|
* @param peer (IN) BTL peer addressing
|
2008-01-21 15:11:18 +03:00
|
|
|
*
|
|
|
|
* prepare source's behavior depends on the following:
|
|
|
|
* Has a valid memory registration been passed to prepare_src?
|
|
|
|
* if so we attempt to use the pre-registered user-buffer, if the memory registration
|
|
|
|
* is too small (only a portion of the user buffer) then we must reregister the user buffer
|
|
|
|
* Has the user requested the memory to be left pinned?
|
|
|
|
* if so we insert the memory registration into a memory tree for later lookup, we
|
|
|
|
* may also remove a previous registration if a MRU (most recently used) list of
|
2007-04-27 01:03:38 +04:00
|
|
|
* registrations is full, this prevents resources from being exhausted.
|
2008-01-21 15:11:18 +03:00
|
|
|
* Is the requested size larger than the btl's max send size?
|
|
|
|
* if so and we aren't asked to leave the registration pinned, then we register the memory if
|
|
|
|
* the users buffer is contiguous
|
|
|
|
* Otherwise we choose from two free lists of pre-registered memory in which to pack the data into.
|
|
|
|
*
|
2005-07-01 01:28:35 +04:00
|
|
|
*/
|
|
|
|
mca_btl_base_descriptor_t* mca_btl_openib_prepare_src(
|
|
|
|
struct mca_btl_base_module_t* btl,
|
|
|
|
struct mca_btl_base_endpoint_t* endpoint,
|
2008-01-21 15:11:18 +03:00
|
|
|
mca_mpool_base_registration_t* registration,
|
2005-07-01 01:28:35 +04:00
|
|
|
struct ompi_convertor_t* convertor,
|
2007-05-24 23:51:26 +04:00
|
|
|
uint8_t order,
|
2005-07-01 01:28:35 +04:00
|
|
|
size_t reserve,
|
2007-12-09 17:08:01 +03:00
|
|
|
size_t* size,
|
|
|
|
uint32_t flags)
|
2005-07-01 01:28:35 +04:00
|
|
|
{
|
2006-12-17 15:26:41 +03:00
|
|
|
mca_btl_openib_module_t *openib_btl;
|
|
|
|
mca_btl_openib_reg_t *openib_reg;
|
2007-11-28 10:11:14 +03:00
|
|
|
mca_btl_openib_com_frag_t *frag = NULL;
|
2006-12-17 15:26:41 +03:00
|
|
|
struct iovec iov;
|
|
|
|
uint32_t iov_count = 1;
|
|
|
|
size_t max_data = *size;
|
|
|
|
int rc;
|
2005-07-01 01:28:35 +04:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
openib_btl = (mca_btl_openib_module_t*)btl;
|
2005-07-20 19:17:18 +04:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
if(ompi_convertor_need_buffers(convertor) == false && 0 == reserve) {
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
/* GMS bloody HACK! */
|
2006-12-17 15:26:41 +03:00
|
|
|
if(registration != NULL || max_data > btl->btl_max_send_size) {
|
2008-01-09 13:26:21 +03:00
|
|
|
frag = alloc_send_user_frag();
|
2006-12-17 15:26:41 +03:00
|
|
|
if(NULL == frag) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
iov.iov_len = max_data;
|
|
|
|
iov.iov_base = NULL;
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
ompi_convertor_pack(convertor, &iov, &iov_count, &max_data);
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
*size = max_data;
|
|
|
|
|
|
|
|
if(NULL == registration) {
|
|
|
|
rc = btl->btl_mpool->mpool_register(btl->btl_mpool,
|
|
|
|
iov.iov_base, max_data, 0, ®istration);
|
|
|
|
if(OMPI_SUCCESS != rc || NULL == registration) {
|
2007-11-28 10:11:14 +03:00
|
|
|
MCA_BTL_IB_FRAG_RETURN(frag);
|
2006-12-17 15:26:41 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* keep track of the registration we did */
|
2007-11-28 10:11:14 +03:00
|
|
|
to_com_frag(frag)->registration =
|
|
|
|
(mca_btl_openib_reg_t*)registration;
|
2006-12-17 15:26:41 +03:00
|
|
|
}
|
|
|
|
openib_reg = (mca_btl_openib_reg_t*)registration;
|
2005-07-01 01:28:35 +04:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
frag->sg_entry.length = max_data;
|
|
|
|
frag->sg_entry.lkey = openib_reg->mr->lkey;
|
2007-12-09 17:15:35 +03:00
|
|
|
frag->sg_entry.addr = (uint64_t)(uintptr_t)iov.iov_base;
|
2006-12-17 15:26:41 +03:00
|
|
|
|
2007-11-28 10:11:14 +03:00
|
|
|
to_base_frag(frag)->base.order = order;
|
2008-02-18 20:39:30 +03:00
|
|
|
to_base_frag(frag)->base.des_flags = flags;
|
2007-11-28 10:11:14 +03:00
|
|
|
to_base_frag(frag)->segment.seg_len = max_data;
|
|
|
|
to_base_frag(frag)->segment.seg_addr.pval = iov.iov_base;
|
|
|
|
to_base_frag(frag)->segment.seg_key.key32[0] =
|
|
|
|
(uint32_t)frag->sg_entry.lkey;
|
2008-01-21 15:11:18 +03:00
|
|
|
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
assert(MCA_BTL_NO_ORDER == order);
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
BTL_VERBOSE(("frag->sg_entry.lkey = %lu .addr = %llu "
|
|
|
|
"frag->segment.seg_key.key32[0] = %lu",
|
|
|
|
frag->sg_entry.lkey, frag->sg_entry.addr,
|
2007-11-28 10:11:14 +03:00
|
|
|
frag->sg_entry.lkey));
|
|
|
|
|
|
|
|
return &to_base_frag(frag)->base;
|
2006-12-17 15:26:41 +03:00
|
|
|
}
|
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
|
|
|
assert(MCA_BTL_NO_ORDER == order);
|
|
|
|
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
if(max_data + reserve > btl->btl_max_send_size) {
|
|
|
|
max_data = btl->btl_max_send_size - reserve;
|
2006-12-17 15:26:41 +03:00
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-12-09 17:05:13 +03:00
|
|
|
frag = (mca_btl_openib_com_frag_t*)(reserve ?
|
2007-12-11 16:10:52 +03:00
|
|
|
mca_btl_openib_alloc(btl, endpoint, order, max_data + reserve,
|
|
|
|
flags) :
|
|
|
|
ib_frag_alloc(openib_btl, max_data, order, flags));
|
2007-12-09 17:02:32 +03:00
|
|
|
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
if(NULL == frag)
|
|
|
|
return NULL;
|
2005-07-01 01:28:35 +04:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
iov.iov_len = max_data;
|
2007-12-09 17:02:32 +03:00
|
|
|
iov.iov_base = (unsigned char*)to_base_frag(frag)->segment.seg_addr.pval +
|
|
|
|
reserve;
|
2006-12-17 15:26:41 +03:00
|
|
|
rc = ompi_convertor_pack(convertor, &iov, &iov_count, &max_data);
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-11-28 10:11:14 +03:00
|
|
|
*size = max_data;
|
|
|
|
|
2007-12-11 16:10:52 +03:00
|
|
|
/* not all upper layer users set this */
|
|
|
|
to_base_frag(frag)->segment.seg_len = max_data + reserve;
|
|
|
|
|
2007-11-28 10:11:14 +03:00
|
|
|
return &to_base_frag(frag)->base;
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2005-07-20 21:43:31 +04:00
|
|
|
* Prepare the dst buffer
|
2005-07-01 01:28:35 +04:00
|
|
|
*
|
|
|
|
* @param btl (IN) BTL module
|
|
|
|
* @param peer (IN) BTL peer addressing
|
2008-01-21 15:11:18 +03:00
|
|
|
* prepare dest's behavior depends on the following:
|
|
|
|
* Has a valid memory registration been passed to prepare_src?
|
|
|
|
* if so we attempt to use the pre-registered user-buffer, if the memory registration
|
|
|
|
* is to small (only a portion of the user buffer) then we must reregister the user buffer
|
|
|
|
* Has the user requested the memory to be left pinned?
|
|
|
|
* if so we insert the memory registration into a memory tree for later lookup, we
|
|
|
|
* may also remove a previous registration if a MRU (most recently used) list of
|
2007-04-27 01:03:38 +04:00
|
|
|
* registrations is full, this prevents resources from being exhausted.
|
2005-07-01 01:28:35 +04:00
|
|
|
*/
|
|
|
|
mca_btl_base_descriptor_t* mca_btl_openib_prepare_dst(
|
|
|
|
struct mca_btl_base_module_t* btl,
|
|
|
|
struct mca_btl_base_endpoint_t* endpoint,
|
2006-12-17 15:26:41 +03:00
|
|
|
mca_mpool_base_registration_t* registration,
|
2005-07-01 01:28:35 +04:00
|
|
|
struct ompi_convertor_t* convertor,
|
2007-05-24 23:51:26 +04:00
|
|
|
uint8_t order,
|
2005-07-01 01:28:35 +04:00
|
|
|
size_t reserve,
|
2007-12-09 17:08:01 +03:00
|
|
|
size_t* size,
|
|
|
|
uint32_t flags)
|
2005-07-01 01:28:35 +04:00
|
|
|
{
|
2006-12-17 15:26:41 +03:00
|
|
|
mca_btl_openib_module_t *openib_btl;
|
2007-11-28 10:11:14 +03:00
|
|
|
mca_btl_openib_com_frag_t *frag;
|
2006-12-17 15:26:41 +03:00
|
|
|
mca_btl_openib_reg_t *openib_reg;
|
|
|
|
int rc;
|
2007-11-28 10:11:14 +03:00
|
|
|
void *buffer;
|
2005-07-01 01:28:35 +04:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
openib_btl = (mca_btl_openib_module_t*)btl;
|
2008-01-09 13:26:21 +03:00
|
|
|
|
|
|
|
frag = alloc_recv_user_frag();
|
2006-12-17 15:26:41 +03:00
|
|
|
if(NULL == frag) {
|
|
|
|
return NULL;
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-11-28 10:11:14 +03:00
|
|
|
ompi_convertor_get_current_pointer(convertor, &buffer);
|
2005-07-01 01:28:35 +04:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
if(NULL == registration){
|
|
|
|
/* we didn't get a memory registration passed in, so we have to
|
|
|
|
* register the region ourselves
|
2008-01-21 15:11:18 +03:00
|
|
|
*/
|
2007-11-28 10:11:14 +03:00
|
|
|
rc = btl->btl_mpool->mpool_register(btl->btl_mpool, buffer, *size, 0,
|
|
|
|
®istration);
|
2006-12-17 15:26:41 +03:00
|
|
|
if(OMPI_SUCCESS != rc || NULL == registration) {
|
2007-11-28 10:11:14 +03:00
|
|
|
MCA_BTL_IB_FRAG_RETURN(frag);
|
2005-12-22 19:05:28 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
2006-12-17 15:26:41 +03:00
|
|
|
/* keep track of the registration we did */
|
|
|
|
frag->registration = (mca_btl_openib_reg_t*)registration;
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
2006-12-17 15:26:41 +03:00
|
|
|
openib_reg = (mca_btl_openib_reg_t*)registration;
|
2005-07-01 01:28:35 +04:00
|
|
|
|
2006-12-17 15:26:41 +03:00
|
|
|
frag->sg_entry.length = *size;
|
|
|
|
frag->sg_entry.lkey = openib_reg->mr->lkey;
|
2007-12-09 17:15:35 +03:00
|
|
|
frag->sg_entry.addr = (uint64_t)(uintptr_t)buffer;
|
2006-12-17 15:26:41 +03:00
|
|
|
|
2007-11-28 10:11:14 +03:00
|
|
|
to_base_frag(frag)->segment.seg_addr.pval = buffer;
|
|
|
|
to_base_frag(frag)->segment.seg_len = *size;
|
|
|
|
to_base_frag(frag)->segment.seg_key.key32[0] = openib_reg->mr->rkey;
|
|
|
|
to_base_frag(frag)->base.order = order;
|
2007-12-09 17:08:55 +03:00
|
|
|
to_base_frag(frag)->base.des_flags = flags;
|
2006-12-17 15:26:41 +03:00
|
|
|
|
|
|
|
BTL_VERBOSE(("frag->sg_entry.lkey = %lu .addr = %llu "
|
|
|
|
"frag->segment.seg_key.key32[0] = %lu",
|
|
|
|
frag->sg_entry.lkey, frag->sg_entry.addr,
|
2007-11-28 10:11:14 +03:00
|
|
|
openib_reg->mr->rkey));
|
2006-12-17 15:26:41 +03:00
|
|
|
|
2007-11-28 10:11:14 +03:00
|
|
|
return &to_base_frag(frag)->base;
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int mca_btl_openib_finalize(struct mca_btl_base_module_t* btl)
|
|
|
|
{
|
2008-01-21 15:11:18 +03:00
|
|
|
mca_btl_openib_module_t* openib_btl;
|
2007-05-09 01:47:21 +04:00
|
|
|
mca_btl_openib_endpoint_t* endpoint;
|
2007-12-23 15:29:34 +03:00
|
|
|
int ep_index, i;
|
2007-11-28 10:14:34 +03:00
|
|
|
int qp, rc = OMPI_SUCCESS;
|
2008-01-21 15:11:18 +03:00
|
|
|
|
|
|
|
openib_btl = (mca_btl_openib_module_t*) btl;
|
2005-07-20 19:17:18 +04:00
|
|
|
|
2008-10-16 19:09:00 +04:00
|
|
|
/* Sanity check */
|
|
|
|
if( mca_btl_openib_component.ib_num_btls <= 0 ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-05-09 01:47:21 +04:00
|
|
|
/* Release all QPs */
|
2008-10-06 04:46:02 +04:00
|
|
|
for (ep_index=0;
|
|
|
|
ep_index < opal_pointer_array_get_size(openib_btl->device->endpoints);
|
|
|
|
ep_index++) {
|
2008-07-23 04:28:59 +04:00
|
|
|
endpoint=opal_pointer_array_get_item(openib_btl->device->endpoints,
|
2008-10-06 04:46:02 +04:00
|
|
|
ep_index);
|
2007-05-09 01:47:21 +04:00
|
|
|
if(!endpoint) {
|
2008-05-02 15:52:33 +04:00
|
|
|
BTL_VERBOSE(("In finalize, got another null endpoint"));
|
2007-05-09 01:47:21 +04:00
|
|
|
continue;
|
|
|
|
}
|
2008-10-06 04:46:02 +04:00
|
|
|
if(endpoint->endpoint_btl != openib_btl) {
|
2007-08-20 16:28:25 +04:00
|
|
|
continue;
|
2008-10-06 04:46:02 +04:00
|
|
|
}
|
2008-07-23 04:28:59 +04:00
|
|
|
for(i = 0; i < openib_btl->device->eager_rdma_buffers_count; i++) {
|
|
|
|
if(openib_btl->device->eager_rdma_buffers[i] == endpoint) {
|
|
|
|
openib_btl->device->eager_rdma_buffers[i] = NULL;
|
2007-12-23 16:58:31 +03:00
|
|
|
OBJ_RELEASE(endpoint);
|
|
|
|
}
|
|
|
|
}
|
2007-05-09 01:47:21 +04:00
|
|
|
OBJ_RELEASE(endpoint);
|
|
|
|
}
|
2008-05-02 15:52:33 +04:00
|
|
|
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
/* Release SRQ resources */
|
2008-01-21 15:11:18 +03:00
|
|
|
for(qp = 0; qp < mca_btl_openib_component.num_qps; qp++) {
|
2007-11-28 10:20:26 +03:00
|
|
|
if(!BTL_OPENIB_QP_TYPE_PP(qp)) {
|
2007-11-28 10:18:59 +03:00
|
|
|
MCA_BTL_OPENIB_CLEAN_PENDING_FRAGS(
|
2007-11-28 10:12:44 +03:00
|
|
|
&openib_btl->qps[qp].u.srq_qp.pending_frags[0]);
|
2007-11-28 10:18:59 +03:00
|
|
|
MCA_BTL_OPENIB_CLEAN_PENDING_FRAGS(
|
2007-11-28 10:12:44 +03:00
|
|
|
&openib_btl->qps[qp].u.srq_qp.pending_frags[1]);
|
2007-11-28 10:18:59 +03:00
|
|
|
if (ibv_destroy_srq(openib_btl->qps[qp].u.srq_qp.srq)){
|
|
|
|
BTL_VERBOSE(("Failed to close SRQ %d", qp));
|
2007-12-23 16:58:31 +03:00
|
|
|
rc = OMPI_ERROR;
|
2007-11-28 10:18:59 +03:00
|
|
|
}
|
|
|
|
OBJ_DESTRUCT(&openib_btl->qps[qp].u.srq_qp.pending_frags[0]);
|
|
|
|
OBJ_DESTRUCT(&openib_btl->qps[qp].u.srq_qp.pending_frags[1]);
|
2007-05-09 01:47:21 +04:00
|
|
|
}
|
|
|
|
}
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
|
2008-10-06 04:46:02 +04:00
|
|
|
/* Finalize the CPC modules on this openib module */
|
|
|
|
for (i = 0; i < openib_btl->num_cpcs; ++i) {
|
|
|
|
if (NULL != openib_btl->cpcs[i]->cbm_finalize) {
|
|
|
|
openib_btl->cpcs[i]->cbm_finalize(openib_btl, openib_btl->cpcs[i]);
|
|
|
|
}
|
|
|
|
free(openib_btl->cpcs[i]);
|
|
|
|
}
|
|
|
|
free(openib_btl->cpcs);
|
|
|
|
|
2008-07-23 04:28:59 +04:00
|
|
|
/* Release device if there are no more users */
|
2008-10-06 04:46:02 +04:00
|
|
|
if (!(--openib_btl->device->btls)) {
|
2008-07-23 04:28:59 +04:00
|
|
|
OBJ_RELEASE(openib_btl->device);
|
2007-05-09 01:47:21 +04:00
|
|
|
}
|
2007-11-28 10:14:34 +03:00
|
|
|
|
2008-10-06 04:46:02 +04:00
|
|
|
/* Remove the btl from component list */
|
|
|
|
if ( mca_btl_openib_component.ib_num_btls > 1 ) {
|
|
|
|
for(i = 0; i < mca_btl_openib_component.ib_num_btls; i++){
|
|
|
|
if (mca_btl_openib_component.openib_btls[i] == openib_btl){
|
|
|
|
mca_btl_openib_component.openib_btls[i] =
|
|
|
|
mca_btl_openib_component.openib_btls[mca_btl_openib_component.ib_num_btls-1];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mca_btl_openib_component.ib_num_btls--;
|
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
OBJ_DESTRUCT(&openib_btl->ib_lock);
|
2007-05-09 01:47:21 +04:00
|
|
|
free(openib_btl);
|
|
|
|
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
BTL_VERBOSE(("Success in closing BTL resources"));
|
2005-07-01 01:28:35 +04:00
|
|
|
|
2007-11-28 10:14:34 +03:00
|
|
|
return rc;
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2008-01-21 15:11:18 +03:00
|
|
|
* Initiate a send.
|
2005-07-01 01:28:35 +04:00
|
|
|
*/
|
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
int mca_btl_openib_send(
|
2005-07-01 01:28:35 +04:00
|
|
|
struct mca_btl_base_module_t* btl,
|
2007-12-09 17:05:13 +03:00
|
|
|
struct mca_btl_base_endpoint_t* ep,
|
|
|
|
struct mca_btl_base_descriptor_t* des,
|
2005-07-01 01:28:35 +04:00
|
|
|
mca_btl_base_tag_t tag)
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2005-07-01 01:28:35 +04:00
|
|
|
{
|
2007-12-09 17:05:13 +03:00
|
|
|
mca_btl_openib_send_frag_t *frag;
|
|
|
|
|
|
|
|
assert(openib_frag_type(des) == MCA_BTL_OPENIB_FRAG_SEND ||
|
|
|
|
openib_frag_type(des) == MCA_BTL_OPENIB_FRAG_COALESCED);
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-12-09 17:05:13 +03:00
|
|
|
if(openib_frag_type(des) == MCA_BTL_OPENIB_FRAG_COALESCED) {
|
|
|
|
to_coalesced_frag(des)->hdr->tag = tag;
|
|
|
|
to_coalesced_frag(des)->hdr->size = des->des_src->seg_len;
|
2007-12-09 17:10:25 +03:00
|
|
|
if(ep->nbo)
|
|
|
|
BTL_OPENIB_HEADER_COALESCED_HTON(*to_coalesced_frag(des)->hdr);
|
2007-12-09 17:05:13 +03:00
|
|
|
frag = to_coalesced_frag(des)->send_frag;
|
|
|
|
} else {
|
|
|
|
frag = to_send_frag(des);
|
2008-01-21 15:11:18 +03:00
|
|
|
to_com_frag(des)->endpoint = ep;
|
2007-12-09 17:05:13 +03:00
|
|
|
frag->hdr->tag = tag;
|
|
|
|
}
|
2007-11-28 10:11:14 +03:00
|
|
|
|
2007-12-09 17:05:13 +03:00
|
|
|
return mca_btl_openib_endpoint_send(ep, frag);
|
2005-07-01 01:28:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-08-18 21:08:27 +04:00
|
|
|
* RDMA WRITE local buffer to remote buffer address.
|
2005-07-01 01:28:35 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
int mca_btl_openib_put( mca_btl_base_module_t* btl,
|
2007-11-28 10:16:52 +03:00
|
|
|
mca_btl_base_endpoint_t* ep,
|
2005-07-01 01:28:35 +04:00
|
|
|
mca_btl_base_descriptor_t* descriptor)
|
|
|
|
{
|
2008-01-21 15:11:18 +03:00
|
|
|
struct ibv_send_wr* bad_wr;
|
|
|
|
mca_btl_openib_out_frag_t* frag = to_out_frag(descriptor);
|
2007-11-28 10:11:14 +03:00
|
|
|
int qp = descriptor->order;
|
|
|
|
uint64_t rem_addr = descriptor->des_dst->seg_addr.lval;
|
|
|
|
uint32_t rkey = descriptor->des_dst->seg_key.key32[0];
|
|
|
|
|
|
|
|
assert(openib_frag_type(frag) == MCA_BTL_OPENIB_FRAG_SEND_USER ||
|
|
|
|
openib_frag_type(frag) == MCA_BTL_OPENIB_FRAG_SEND);
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
|
2007-11-28 10:16:52 +03:00
|
|
|
if(ep->endpoint_state != MCA_BTL_IB_CONNECTED) {
|
|
|
|
int rc;
|
|
|
|
OPAL_THREAD_LOCK(&ep->endpoint_lock);
|
|
|
|
rc = check_endpoint_state(ep, descriptor, &ep->pending_put_frags);
|
2007-11-28 12:38:49 +03:00
|
|
|
OPAL_THREAD_UNLOCK(&ep->endpoint_lock);
|
2007-12-09 17:14:11 +03:00
|
|
|
if(OMPI_ERR_RESOURCE_BUSY == rc)
|
2007-11-28 10:16:52 +03:00
|
|
|
return OMPI_SUCCESS;
|
|
|
|
if(OMPI_SUCCESS != rc)
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
if(MCA_BTL_NO_ORDER == qp)
|
|
|
|
qp = mca_btl_openib_component.rdma_qp;
|
2006-01-13 02:42:44 +03:00
|
|
|
|
|
|
|
/* check for a send wqe */
|
2007-11-28 10:16:52 +03:00
|
|
|
if (qp_get_wqe(ep, qp) < 0) {
|
|
|
|
qp_put_wqe(ep, qp);
|
|
|
|
OPAL_THREAD_LOCK(&ep->endpoint_lock);
|
|
|
|
opal_list_append(&ep->pending_put_frags, (opal_list_item_t*)frag);
|
|
|
|
OPAL_THREAD_UNLOCK(&ep->endpoint_lock);
|
2007-11-28 10:11:14 +03:00
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
2006-01-13 02:42:44 +03:00
|
|
|
/* post descriptor */
|
2007-08-29 01:23:44 +04:00
|
|
|
#if OMPI_ENABLE_HETEROGENEOUS_SUPPORT
|
2008-04-18 00:43:56 +04:00
|
|
|
if((ep->endpoint_proc->proc_ompi->proc_arch & OPAL_ARCH_ISBIGENDIAN)
|
|
|
|
!= (ompi_proc_local()->proc_arch & OPAL_ARCH_ISBIGENDIAN)) {
|
2007-11-28 10:11:14 +03:00
|
|
|
rem_addr = opal_swap_bytes8(rem_addr);
|
|
|
|
rkey = opal_swap_bytes4(rkey);
|
2005-10-21 06:21:45 +04:00
|
|
|
}
|
2007-11-28 10:11:14 +03:00
|
|
|
#endif
|
|
|
|
frag->sr_desc.wr.rdma.remote_addr = rem_addr;
|
|
|
|
frag->sr_desc.wr.rdma.rkey = rkey;
|
|
|
|
|
|
|
|
to_com_frag(frag)->sg_entry.addr =
|
2008-01-21 15:11:18 +03:00
|
|
|
(uint64_t)(uintptr_t)descriptor->des_src->seg_addr.pval;
|
|
|
|
to_com_frag(frag)->sg_entry.length = descriptor->des_src->seg_len;
|
2007-11-28 10:16:52 +03:00
|
|
|
to_com_frag(frag)->endpoint = ep;
|
2007-11-28 10:18:59 +03:00
|
|
|
#if HAVE_XRC
|
|
|
|
if (MCA_BTL_XRC_ENABLED && BTL_OPENIB_QP_TYPE_XRC(qp))
|
|
|
|
frag->sr_desc.xrc_remote_srq_num=ep->rem_info.rem_srqs[qp].rem_srq_num;
|
|
|
|
#endif
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-11-28 10:11:14 +03:00
|
|
|
descriptor->order = qp;
|
|
|
|
/* Setting opcode on a frag constructor isn't enough since prepare_src
|
2008-01-21 15:11:18 +03:00
|
|
|
* may return send_frag instead of put_frag */
|
2007-11-28 10:11:14 +03:00
|
|
|
frag->sr_desc.opcode = IBV_WR_RDMA_WRITE;
|
2008-06-19 12:40:39 +04:00
|
|
|
frag->sr_desc.send_flags = ib_send_flags(descriptor->des_src->seg_len, &(ep->qps[qp]));
|
2007-11-28 10:16:52 +03:00
|
|
|
if(ibv_post_send(ep->qps[qp].qp->lcl_qp, &frag->sr_desc, &bad_wr))
|
2007-11-28 10:11:14 +03:00
|
|
|
return OMPI_ERROR;
|
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
return OMPI_SUCCESS;
|
2005-08-18 21:08:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* RDMA READ remote buffer to local buffer address.
|
|
|
|
*/
|
|
|
|
|
2007-11-28 10:16:52 +03:00
|
|
|
int mca_btl_openib_get(mca_btl_base_module_t* btl,
|
|
|
|
mca_btl_base_endpoint_t* ep,
|
2005-08-18 21:08:27 +04:00
|
|
|
mca_btl_base_descriptor_t* descriptor)
|
|
|
|
{
|
2008-01-21 15:11:18 +03:00
|
|
|
struct ibv_send_wr* bad_wr;
|
|
|
|
mca_btl_openib_get_frag_t* frag = to_get_frag(descriptor);
|
2007-11-28 10:11:14 +03:00
|
|
|
int qp = descriptor->order;
|
|
|
|
uint64_t rem_addr = descriptor->des_src->seg_addr.lval;
|
|
|
|
uint32_t rkey = descriptor->des_src->seg_key.key32[0];
|
|
|
|
|
|
|
|
assert(openib_frag_type(frag) == MCA_BTL_OPENIB_FRAG_RECV_USER);
|
2005-11-10 23:15:02 +03:00
|
|
|
|
2007-11-28 10:16:52 +03:00
|
|
|
if(ep->endpoint_state != MCA_BTL_IB_CONNECTED) {
|
|
|
|
int rc;
|
|
|
|
OPAL_THREAD_LOCK(&ep->endpoint_lock);
|
|
|
|
rc = check_endpoint_state(ep, descriptor, &ep->pending_get_frags);
|
|
|
|
OPAL_THREAD_UNLOCK(&ep->endpoint_lock);
|
2007-12-09 17:14:11 +03:00
|
|
|
if(OMPI_ERR_RESOURCE_BUSY == rc)
|
2007-11-28 10:16:52 +03:00
|
|
|
return OMPI_SUCCESS;
|
|
|
|
if(OMPI_SUCCESS != rc)
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
if(MCA_BTL_NO_ORDER == qp)
|
|
|
|
qp = mca_btl_openib_component.rdma_qp;
|
|
|
|
|
2006-01-13 02:42:44 +03:00
|
|
|
/* check for a send wqe */
|
2007-11-28 10:16:52 +03:00
|
|
|
if (qp_get_wqe(ep, qp) < 0) {
|
|
|
|
qp_put_wqe(ep, qp);
|
|
|
|
OPAL_THREAD_LOCK(&ep->endpoint_lock);
|
|
|
|
opal_list_append(&ep->pending_get_frags, (opal_list_item_t*)frag);
|
|
|
|
OPAL_THREAD_UNLOCK(&ep->endpoint_lock);
|
2006-01-13 02:42:44 +03:00
|
|
|
return OMPI_SUCCESS;
|
2007-11-28 10:11:14 +03:00
|
|
|
}
|
2005-11-10 23:15:02 +03:00
|
|
|
|
2006-01-13 02:42:44 +03:00
|
|
|
/* check for a get token */
|
2007-11-28 10:16:52 +03:00
|
|
|
if(OPAL_THREAD_ADD32(&ep->get_tokens,-1) < 0) {
|
|
|
|
qp_put_wqe(ep, qp);
|
|
|
|
OPAL_THREAD_ADD32(&ep->get_tokens,1);
|
|
|
|
OPAL_THREAD_LOCK(&ep->endpoint_lock);
|
|
|
|
opal_list_append(&ep->pending_get_frags, (opal_list_item_t*)frag);
|
|
|
|
OPAL_THREAD_UNLOCK(&ep->endpoint_lock);
|
2006-01-13 02:42:44 +03:00
|
|
|
return OMPI_SUCCESS;
|
2007-11-28 10:11:14 +03:00
|
|
|
}
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-08-29 01:23:44 +04:00
|
|
|
#if OMPI_ENABLE_HETEROGENEOUS_SUPPORT
|
2008-04-18 00:43:56 +04:00
|
|
|
if((ep->endpoint_proc->proc_ompi->proc_arch & OPAL_ARCH_ISBIGENDIAN)
|
|
|
|
!= (ompi_proc_local()->proc_arch & OPAL_ARCH_ISBIGENDIAN)) {
|
2008-01-21 15:11:18 +03:00
|
|
|
rem_addr = opal_swap_bytes8(rem_addr);
|
|
|
|
rkey = opal_swap_bytes4(rkey);
|
2005-10-21 06:21:45 +04:00
|
|
|
}
|
2007-11-28 10:11:14 +03:00
|
|
|
#endif
|
2008-01-21 15:11:18 +03:00
|
|
|
frag->sr_desc.wr.rdma.remote_addr = rem_addr;
|
2007-11-28 10:11:14 +03:00
|
|
|
frag->sr_desc.wr.rdma.rkey = rkey;
|
2005-07-01 01:28:35 +04:00
|
|
|
|
2007-11-28 10:11:14 +03:00
|
|
|
to_com_frag(frag)->sg_entry.addr =
|
2008-01-21 15:11:18 +03:00
|
|
|
(uint64_t)(uintptr_t)descriptor->des_dst->seg_addr.pval;
|
|
|
|
to_com_frag(frag)->sg_entry.length = descriptor->des_dst->seg_len;
|
2007-11-28 10:16:52 +03:00
|
|
|
to_com_frag(frag)->endpoint = ep;
|
2008-01-21 15:11:18 +03:00
|
|
|
|
2007-11-28 10:18:59 +03:00
|
|
|
#if HAVE_XRC
|
|
|
|
if (MCA_BTL_XRC_ENABLED && BTL_OPENIB_QP_TYPE_XRC(qp))
|
|
|
|
frag->sr_desc.xrc_remote_srq_num=ep->rem_info.rem_srqs[qp].rem_srq_num;
|
|
|
|
#endif
|
2007-11-28 10:11:14 +03:00
|
|
|
descriptor->order = qp;
|
2007-11-28 10:16:52 +03:00
|
|
|
if(ibv_post_send(ep->qps[qp].qp->lcl_qp, &frag->sr_desc, &bad_wr))
|
2007-11-28 10:11:14 +03:00
|
|
|
return OMPI_ERROR;
|
This commit brings in two major things:
1. Galen's fine-grain control of queue pair resources in the openib
BTL.
1. Pasha's new implementation of asychronous HCA event handling.
Pasha's new implementation doesn't take much explanation, but the new
"multifrag" stuff does.
Note that "svn merge" was not used to bring this new code from the
/tmp/ib_multifrag branch -- something Bad happened in the periodic
trunk pulls on that branch making an actual merge back to the trunk
effectively impossible (i.e., lots and lots of arbitrary conflicts and
artifical changes). :-(
== Fine-grain control of queue pair resources ==
Galen's fine-grain control of queue pair resources to the OpenIB BTL
(thanks to Gleb for fixing broken code and providing additional
functionality, Pasha for finding broken code, and Jeff for doing all
the svn work and regression testing).
Prior to this commit, the OpenIB BTL created two queue pairs: one for
eager size fragments and one for max send size fragments. When the
use of the shared receive queue (SRQ) was specified (via "-mca
btl_openib_use_srq 1"), these QPs would use a shared receive queue for
receive buffers instead of the default per-peer (PP) receive queues
and buffers. One consequence of this design is that receive buffer
utilization (the size of the data received as a percentage of the
receive buffer used for the data) was quite poor for a number of
applications.
The new design allows multiple QPs to be specified at runtime. Each
QP can be setup to use PP or SRQ receive buffers as well as giving
fine-grained control over receive buffer size, number of receive
buffers to post, when to replenish the receive queue (low water mark)
and for SRQ QPs, the number of outstanding sends can also be
specified. The following is an example of the syntax to describe QPs
to the OpenIB BTL using the new MCA parameter btl_openib_receive_queues:
{{{
-mca btl_openib_receive_queues \
"P,128,16,4;S,1024,256,128,32;S,4096,256,128,32;S,65536,256,128,32"
}}}
Each QP description is delimited by ";" (semicolon) with individual
fields of the QP description delimited by "," (comma). The above
example therefore describes 4 QPs.
The first QP is:
P,128,16,4
Meaning: per-peer receive buffer QPs are indicated by a starting field
of "P"; the first QP (shown above) is therefore a per-peer based QP.
The second field indicates the size of the receive buffer in bytes
(128 bytes). The third field indicates the number of receive buffers
to allocate to the QP (16). The fourth field indicates the low
watermark for receive buffers at which time the BTL will repost
receive buffers to the QP (4).
The second QP is:
S,1024,256,128,32
Shared receive queue based QPs are indicated by a starting field of
"S"; the second QP (shown above) is therefore a shared receive queue
based QP. The second, third and fourth fields are the same as in the
per-peer based QP. The fifth field is the number of outstanding sends
that are allowed at a given time on the QP (32). This provides a
"good enough" mechanism of flow control for some regular communication
patterns.
QPs MUST be specified in ascending receive buffer size order. This
requirement may be removed prior to 1.3 release.
This commit was SVN r15474.
2007-07-18 05:15:59 +04:00
|
|
|
|
2008-01-21 15:11:18 +03:00
|
|
|
return OMPI_SUCCESS;
|
2007-11-28 10:11:14 +03:00
|
|
|
}
|
2007-03-17 02:11:45 +03:00
|
|
|
|
2008-10-16 19:09:00 +04:00
|
|
|
#if OPAL_ENABLE_FT == 0
|
2007-03-17 02:11:45 +03:00
|
|
|
int mca_btl_openib_ft_event(int state) {
|
2008-10-16 19:09:00 +04:00
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
int mca_btl_openib_ft_event(int state) {
|
|
|
|
int i;
|
|
|
|
|
2007-03-17 02:11:45 +03:00
|
|
|
if(OPAL_CRS_CHECKPOINT == state) {
|
2008-10-16 19:09:00 +04:00
|
|
|
/* Continue must reconstruct the routes (including modex), since we
|
|
|
|
* have to tear down the devices completely. */
|
|
|
|
ompi_cr_continue_like_restart = true;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* To keep the node from crashing we need to call ibv_close_device
|
|
|
|
* before the checkpoint is taken. To do this we need to tear
|
|
|
|
* everything down, and rebuild it all on continue/restart. :(
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Shutdown all modules
|
|
|
|
* - Do this backwards since the openib_finalize function also loops
|
|
|
|
* over this variable.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < mca_btl_openib_component.ib_num_btls; ++i ) {
|
|
|
|
ft_event_btl_openib_finalize( &(mca_btl_openib_component.openib_btls[i])->super);
|
|
|
|
}
|
|
|
|
ompi_btl_openib_connect_base_finalize();
|
2007-03-17 02:11:45 +03:00
|
|
|
}
|
|
|
|
else if(OPAL_CRS_CONTINUE == state) {
|
2008-10-16 19:09:00 +04:00
|
|
|
; /* Cleared by forcing the modex, no work needed */
|
2007-03-17 02:11:45 +03:00
|
|
|
}
|
|
|
|
else if(OPAL_CRS_RESTART == state) {
|
|
|
|
;
|
|
|
|
}
|
|
|
|
else if(OPAL_CRS_TERM == state ) {
|
|
|
|
;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
2008-10-16 19:09:00 +04:00
|
|
|
|
|
|
|
static int ft_event_btl_openib_finalize(struct mca_btl_base_module_t* btl) {
|
|
|
|
mca_btl_openib_module_t* openib_btl;
|
|
|
|
mca_btl_openib_endpoint_t* endpoint;
|
|
|
|
int ep_index, i;
|
|
|
|
int qp, rc = OMPI_SUCCESS;
|
|
|
|
|
|
|
|
openib_btl = (mca_btl_openib_module_t*) btl;
|
|
|
|
|
|
|
|
/* Release all QPs */
|
|
|
|
for(ep_index=0;
|
|
|
|
ep_index < opal_pointer_array_get_size(openib_btl->device->endpoints);
|
|
|
|
ep_index++) {
|
|
|
|
endpoint=opal_pointer_array_get_item(openib_btl->device->endpoints,
|
|
|
|
ep_index);
|
|
|
|
if(!endpoint) {
|
|
|
|
BTL_VERBOSE(("In finalize, got another null endpoint"));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(endpoint->endpoint_btl != openib_btl)
|
|
|
|
continue;
|
|
|
|
for(i = 0; i < openib_btl->device->eager_rdma_buffers_count; i++) {
|
|
|
|
if(openib_btl->device->eager_rdma_buffers[i] == endpoint) {
|
|
|
|
openib_btl->device->eager_rdma_buffers[i] = NULL;
|
|
|
|
OBJ_RELEASE(endpoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
OBJ_RELEASE(endpoint);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Finalize the CPC modules on this openib module */
|
|
|
|
for (i = 0; i < openib_btl->num_cpcs; ++i) {
|
|
|
|
if (NULL != openib_btl->cpcs[i]->cbm_finalize) {
|
|
|
|
openib_btl->cpcs[i]->cbm_finalize(openib_btl, openib_btl->cpcs[i]);
|
|
|
|
}
|
|
|
|
free(openib_btl->cpcs[i]);
|
|
|
|
}
|
|
|
|
free(openib_btl->cpcs);
|
|
|
|
|
|
|
|
/* Release SRQ resources */
|
|
|
|
for(qp = 0; qp < mca_btl_openib_component.num_qps; qp++) {
|
|
|
|
if(!BTL_OPENIB_QP_TYPE_PP(qp)) {
|
|
|
|
MCA_BTL_OPENIB_CLEAN_PENDING_FRAGS(
|
|
|
|
&openib_btl->qps[qp].u.srq_qp.pending_frags[0]);
|
|
|
|
MCA_BTL_OPENIB_CLEAN_PENDING_FRAGS(
|
|
|
|
&openib_btl->qps[qp].u.srq_qp.pending_frags[1]);
|
|
|
|
if (ibv_destroy_srq(openib_btl->qps[qp].u.srq_qp.srq)){
|
|
|
|
BTL_VERBOSE(("Failed to close SRQ %d", qp));
|
|
|
|
rc = OMPI_ERROR;
|
|
|
|
}
|
|
|
|
OBJ_DESTRUCT(&openib_btl->qps[qp].u.srq_qp.pending_frags[0]);
|
|
|
|
OBJ_DESTRUCT(&openib_btl->qps[qp].u.srq_qp.pending_frags[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Release device if there are no more users */
|
|
|
|
if(!(--openib_btl->device->btls)) {
|
|
|
|
OBJ_RELEASE(openib_btl->device);
|
|
|
|
}
|
|
|
|
mca_btl_openib_component.devices_count = 0;
|
|
|
|
mca_btl_openib_component.ib_num_btls = 0;
|
|
|
|
OBJ_DESTRUCT(&mca_btl_openib_component.ib_procs);
|
|
|
|
|
|
|
|
BTL_VERBOSE(("Success in closing BTL resources"));
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* OPAL_ENABLE_FT */
|