Merge pull request #580 from tkordenbrock/topic/mtl.add.status.to.short.recv.blocks
mtl-portals4: add status to short recv blocks to coordinate out of or…
Этот коммит содержится в:
Коммит
bbeaf41a52
@ -83,15 +83,16 @@ struct mca_mtl_portals4_module_t {
|
||||
overflow list on the recv_idx portal table. */
|
||||
ptl_handle_me_t long_overflow_me_h;
|
||||
|
||||
/** List of active short receive blocks. Active means that the ME
|
||||
was posted to the overflow list and the UNLINK event has not
|
||||
yet been received. */
|
||||
opal_list_t active_recv_short_blocks;
|
||||
/** List of short receive blocks. */
|
||||
opal_list_t recv_short_blocks;
|
||||
|
||||
/** List of short receive blocks waiting for FREE event. Blocks
|
||||
are added to this list when the UNLINK event has been
|
||||
received and removed when the FREE event is received. */
|
||||
opal_list_t waiting_recv_short_blocks;
|
||||
/** Number of active short receive blocks. Active means that the ME
|
||||
was posted to the overflow list, the LINK event has been received but the UNLINK or the FREE event has not
|
||||
yet been received. */
|
||||
uint32_t active_recv_short_blocks;
|
||||
|
||||
/** Mutex to protect opal_list */
|
||||
opal_mutex_t short_block_mutex;
|
||||
|
||||
/** number of send-side operations started */
|
||||
uint64_t opcount;
|
||||
|
@ -41,22 +41,113 @@ ompi_mtl_portals4_recv_block_progress(ptl_event_t *ev,
|
||||
(ompi_mtl_portals4_recv_short_request_t*) ptl_base_request;
|
||||
ompi_mtl_portals4_recv_short_block_t *block = ptl_request->block;
|
||||
|
||||
if (PTL_EVENT_AUTO_FREE == ev->type) {
|
||||
if (OPAL_UNLIKELY(block->release_on_free)) {
|
||||
opal_list_remove_item(&ompi_mtl_portals4.waiting_recv_short_blocks,
|
||||
&block->base);
|
||||
ompi_mtl_portals4_recv_short_block_free(block);
|
||||
} else {
|
||||
ompi_mtl_portals4_activate_block(block);
|
||||
}
|
||||
} else if (PTL_EVENT_AUTO_UNLINK == ev->type) {
|
||||
opal_list_remove_item(&ompi_mtl_portals4.active_recv_short_blocks,
|
||||
&block->base);
|
||||
opal_list_append(&ompi_mtl_portals4.waiting_recv_short_blocks,
|
||||
&block->base);
|
||||
} else {
|
||||
OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output,
|
||||
"OVERFLOW EVENT %d, hdr_data = %lx", ev->type, (long unsigned) ev->hdr_data));
|
||||
switch (ev->type) {
|
||||
case PTL_EVENT_AUTO_FREE:
|
||||
#ifdef OMPI_ENABLE_THREAD_MULTIPLE
|
||||
OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
switch (block->status) {
|
||||
case BLOCK_STATUS_ACTIVATED: /* May be encountered with multi threading */
|
||||
block->status = BLOCK_STATUS_WAITING_UNLINK;
|
||||
ompi_mtl_portals4.active_recv_short_blocks--;
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
OPAL_OUTPUT_VERBOSE((10, ompi_mtl_base_framework.framework_output,
|
||||
"mtl:portals4 PTL_EVENT_AUTO_FREE received before PTL_EVENT_AUTO_UNLINK"));
|
||||
break;
|
||||
|
||||
case BLOCK_STATUS_WAITING_FREE: /* Normal case */
|
||||
if (OPAL_UNLIKELY(block->release_on_free)) {
|
||||
opal_list_remove_item(&ompi_mtl_portals4.recv_short_blocks,
|
||||
&block->base);
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
ompi_mtl_portals4_recv_short_block_free(block);
|
||||
} else {
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
ompi_mtl_portals4_activate_block(block);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
|
||||
"%s:%d: Bad status (%d) when receiving PTL_EVENT_AUTO_FREE",
|
||||
__FILE__, __LINE__, block->status);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (OPAL_UNLIKELY(block->release_on_free)) {
|
||||
opal_list_remove_item(&ompi_mtl_portals4.recv_short_blocks,
|
||||
&block->base);
|
||||
ompi_mtl_portals4_recv_short_block_free(block);
|
||||
} else {
|
||||
ompi_mtl_portals4_activate_block(block);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PTL_EVENT_AUTO_UNLINK:
|
||||
#ifdef OMPI_ENABLE_THREAD_MULTIPLE
|
||||
OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
switch (block->status) {
|
||||
case BLOCK_STATUS_ACTIVATED: /* Normal case */
|
||||
block->status = BLOCK_STATUS_WAITING_FREE;
|
||||
ompi_mtl_portals4.active_recv_short_blocks--;
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
break;
|
||||
|
||||
case BLOCK_STATUS_WAITING_UNLINK: /* May be encountered with multi threading */
|
||||
if (OPAL_UNLIKELY(block->release_on_free)) {
|
||||
opal_list_remove_item(&ompi_mtl_portals4.recv_short_blocks,
|
||||
&block->base);
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
ompi_mtl_portals4_recv_short_block_free(block);
|
||||
} else {
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
OPAL_OUTPUT_VERBOSE((10, ompi_mtl_base_framework.framework_output,
|
||||
"mtl:portals4 PTL_EVENT_AUTO_UNLINK received after PTL_EVENT_AUTO_FREE"));
|
||||
ompi_mtl_portals4_activate_block(block);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
|
||||
"%s:%d: Bad status (%d) when receiving PTL_EVENT_AUTO_UNLINK",
|
||||
__FILE__, __LINE__, block->status);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
block->status = BLOCK_STATUS_WAITING_FREE;
|
||||
ompi_mtl_portals4.active_recv_short_blocks--;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PTL_EVENT_LINK:
|
||||
#ifdef OMPI_ENABLE_THREAD_MULTIPLE
|
||||
OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
switch (block->status) {
|
||||
case BLOCK_STATUS_WAITING_LINK:
|
||||
block->status = BLOCK_STATUS_ACTIVATED;
|
||||
ompi_mtl_portals4.active_recv_short_blocks++;
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
break;
|
||||
|
||||
default:
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
|
||||
"%s:%d: Bad status (%d) when receiving PTL_EVENT_LINK",
|
||||
__FILE__, __LINE__, block->status);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
block->status = BLOCK_STATUS_ACTIVATED;
|
||||
ompi_mtl_portals4.active_recv_short_blocks++;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output,
|
||||
"Other EVENT %d, hdr_data = %lx", ev->type, (long unsigned) ev->hdr_data));
|
||||
break;
|
||||
}
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
@ -70,6 +161,7 @@ ompi_mtl_portals4_recv_short_block_alloc(bool release_on_free)
|
||||
|
||||
block = OBJ_NEW(ompi_mtl_portals4_recv_short_block_t);
|
||||
block->start = malloc(ompi_mtl_portals4.recv_short_size);
|
||||
block->status = BLOCK_STATUS_INACTIVE;
|
||||
if (block->start == NULL) return NULL;
|
||||
|
||||
block->me_h = PTL_INVALID_HANDLE;
|
||||
@ -109,8 +201,6 @@ ompi_mtl_portals4_activate_block(ompi_mtl_portals4_recv_short_block_t *block)
|
||||
ptl_me_t me;
|
||||
int ret;
|
||||
|
||||
opal_list_remove_item(&ompi_mtl_portals4.waiting_recv_short_blocks, &block->base);
|
||||
|
||||
ignore_bits = MTL_PORTALS4_CONTEXT_MASK | MTL_PORTALS4_SOURCE_MASK | MTL_PORTALS4_TAG_MASK;
|
||||
|
||||
me.start = block->start;
|
||||
@ -132,6 +222,10 @@ ompi_mtl_portals4_activate_block(ompi_mtl_portals4_recv_short_block_t *block)
|
||||
me.match_bits = match_bits;
|
||||
me.ignore_bits = ignore_bits;
|
||||
|
||||
OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
block->status = BLOCK_STATUS_WAITING_LINK;
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
|
||||
ret = PtlMEAppend(ompi_mtl_portals4.ni_h,
|
||||
ompi_mtl_portals4.recv_idx,
|
||||
&me,
|
||||
@ -140,8 +234,6 @@ ompi_mtl_portals4_activate_block(ompi_mtl_portals4_recv_short_block_t *block)
|
||||
&block->me_h);
|
||||
if (OPAL_LIKELY(ret == PTL_OK)) {
|
||||
ret = OMPI_SUCCESS;
|
||||
opal_list_append(&ompi_mtl_portals4.active_recv_short_blocks,
|
||||
&block->base);
|
||||
} else {
|
||||
ret = ompi_mtl_portals4_get_error(ret);
|
||||
}
|
||||
@ -155,8 +247,8 @@ ompi_mtl_portals4_recv_short_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
OBJ_CONSTRUCT(&(ompi_mtl_portals4.active_recv_short_blocks), opal_list_t);
|
||||
OBJ_CONSTRUCT(&(ompi_mtl_portals4.waiting_recv_short_blocks), opal_list_t);
|
||||
OBJ_CONSTRUCT(&ompi_mtl_portals4.short_block_mutex, opal_mutex_t);
|
||||
OBJ_CONSTRUCT(&(ompi_mtl_portals4.recv_short_blocks), opal_list_t);
|
||||
|
||||
/* create the recv blocks */
|
||||
for (i = 0 ; i < ompi_mtl_portals4.recv_short_num ; ++i) {
|
||||
@ -165,7 +257,7 @@ ompi_mtl_portals4_recv_short_init(void)
|
||||
if (OPAL_UNLIKELY(NULL == block)) {
|
||||
return OMPI_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
opal_list_append(&ompi_mtl_portals4.waiting_recv_short_blocks,
|
||||
opal_list_append(&ompi_mtl_portals4.recv_short_blocks,
|
||||
&block->base);
|
||||
ompi_mtl_portals4_activate_block(block);
|
||||
}
|
||||
@ -179,16 +271,13 @@ ompi_mtl_portals4_recv_short_fini(void)
|
||||
{
|
||||
opal_list_item_t *item;
|
||||
|
||||
while (NULL != (item = opal_list_remove_first(&ompi_mtl_portals4.active_recv_short_blocks))) {
|
||||
ompi_mtl_portals4_recv_short_block_t *block =
|
||||
(ompi_mtl_portals4_recv_short_block_t*) item;
|
||||
ompi_mtl_portals4_recv_short_block_free(block);
|
||||
}
|
||||
while (NULL != (item = opal_list_remove_first(&ompi_mtl_portals4.waiting_recv_short_blocks))) {
|
||||
OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
while (NULL != (item = opal_list_remove_first(&ompi_mtl_portals4.recv_short_blocks))) {
|
||||
ompi_mtl_portals4_recv_short_block_t *block =
|
||||
(ompi_mtl_portals4_recv_short_block_t*) item;
|
||||
ompi_mtl_portals4_recv_short_block_free(block);
|
||||
}
|
||||
OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
@ -197,7 +286,7 @@ ompi_mtl_portals4_recv_short_fini(void)
|
||||
int
|
||||
ompi_mtl_portals4_recv_short_link(int count)
|
||||
{
|
||||
int active = opal_list_get_size(&ompi_mtl_portals4.active_recv_short_blocks);
|
||||
int active = ompi_mtl_portals4.active_recv_short_blocks;
|
||||
int i;
|
||||
|
||||
if (active < count) {
|
||||
@ -207,8 +296,6 @@ ompi_mtl_portals4_recv_short_link(int count)
|
||||
if (NULL == block) {
|
||||
return OMPI_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
opal_list_append(&ompi_mtl_portals4.waiting_recv_short_blocks,
|
||||
&block->base);
|
||||
ompi_mtl_portals4_activate_block(block);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,21 @@ struct ompi_mtl_portals4_recv_short_block_t {
|
||||
ptl_handle_me_t me_h;
|
||||
struct ompi_mtl_portals4_recv_short_request_t request;
|
||||
bool release_on_free;
|
||||
char status; /* see Note after */
|
||||
};
|
||||
/* Note: Even if portals4 may guarantee that PTL_EVENT_AUTO_UNLINK comes before
|
||||
* PTL_EVENT_AUTO_FREE, we are not sure that this is the case in a
|
||||
* multi-threaded environment : A thread catching the PTL_EVENT_AUTO_UNLINK
|
||||
* may be preceded by another catching the PTL_EVENT_AUTO_FREE even if this
|
||||
* event comes after. That is why we introduce the status field with the
|
||||
* following STATUSES. */
|
||||
|
||||
#define BLOCK_STATUS_INACTIVE 0 /* The block has just been malloc'ed */
|
||||
#define BLOCK_STATUS_WAITING_LINK 1 /* The PtlMEAppend has been called. Now wait for PTL_EVENT_LINK */
|
||||
#define BLOCK_STATUS_ACTIVATED 2 /* PTL_EVENT_LINK has been received, the block is operational */
|
||||
#define BLOCK_STATUS_WAITING_FREE 3 /* The PTL_EVENT_AUTO_UNLINK has been received, now wait for a PTL_EVENT_AUTO_FREE */
|
||||
#define BLOCK_STATUS_WAITING_UNLINK 4 /* The PTL_EVENT_AUTO_FREE has been received, now wait for a PTL_EVENT_AUTO_UNLINK (rare) */
|
||||
|
||||
typedef struct ompi_mtl_portals4_recv_short_block_t ompi_mtl_portals4_recv_short_block_t;
|
||||
OBJ_CLASS_DECLARATION(ompi_mtl_portals4_recv_short_block_t);
|
||||
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user