Skip to content

Commit 67b1623

Browse files
authored
Merge pull request #3719 from yosefe/topic/ucm-fix-event-test-when-not-installed-v1.6.x
Port fixes to v1.6.x: UCM events test, client/server example
2 parents 43afe2e + bd027f1 commit 67b1623

File tree

6 files changed

+115
-66
lines changed

6 files changed

+115
-66
lines changed

NEWS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
##
88
#
99

10-
## 1.6.0-rc2 (June 13, 2019)
10+
## 1.6.0-rc3 (June 19, 2019)
1111
Features:
1212
- Modular architecture for UCT transports
1313
- ROCm transport re-design: support for managed memory, direct copy, ROCm GDR
@@ -33,6 +33,8 @@ Bugfixes:
3333
- Fix data race in UCP proxy endpoint
3434
- Static checker fixes
3535
- Fallback to ibv_create_cq() if ibv_create_cq_ex() returns ENOSYS
36+
- Fix malloc hooks test
37+
- Fix checking return status in ucp_client_server example
3638

3739
Tested configurations:
3840
- RDMA: MLNX_OFED 4.5, distribution inbox drivers, rdma-core 22.1

src/ucm/event/event.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,22 @@ void ucm_event_handler_remove(ucm_event_handler_t *handler)
459459
ucm_event_leave();
460460
}
461461

462+
static int ucm_events_to_native_events(int events)
463+
{
464+
int native_events;
465+
466+
native_events = events & ~(UCM_EVENT_VM_MAPPED | UCM_EVENT_VM_UNMAPPED |
467+
UCM_EVENT_MEM_TYPE_ALLOC | UCM_EVENT_MEM_TYPE_FREE);
468+
if (events & UCM_EVENT_VM_MAPPED) {
469+
native_events |= UCM_NATIVE_EVENT_VM_MAPPED;
470+
}
471+
if (events & UCM_EVENT_VM_UNMAPPED) {
472+
native_events |= UCM_NATIVE_EVENT_VM_UNMAPPED;
473+
}
474+
475+
return native_events;
476+
}
477+
462478
static ucs_status_t ucm_event_install(int events)
463479
{
464480
static ucs_init_once_t init_once = UCS_INIT_ONCE_INIITIALIZER;
@@ -472,14 +488,7 @@ static ucs_status_t ucm_event_install(int events)
472488
}
473489

474490
/* Replace aggregate events with the native events which make them */
475-
native_events = events & ~(UCM_EVENT_VM_MAPPED | UCM_EVENT_VM_UNMAPPED |
476-
UCM_EVENT_MEM_TYPE_ALLOC | UCM_EVENT_MEM_TYPE_FREE);
477-
if (events & UCM_EVENT_VM_MAPPED) {
478-
native_events |= UCM_NATIVE_EVENT_VM_MAPPED;
479-
}
480-
if (events & UCM_EVENT_VM_UNMAPPED) {
481-
native_events |= UCM_NATIVE_EVENT_VM_UNMAPPED;
482-
}
491+
native_events = ucm_events_to_native_events(events);
483492

484493
/* TODO lock */
485494
status = ucm_mmap_install(native_events);
@@ -590,9 +599,7 @@ void ucm_unset_event_handler(int events, ucm_event_callback_t cb, void *arg)
590599

591600
ucs_status_t ucm_test_events(int events)
592601
{
593-
int out_events;
594-
595-
return ucm_mmap_test_events(events, &out_events);
602+
return ucm_mmap_test_installed_events(ucm_events_to_native_events(events));
596603
}
597604

598605
UCS_STATIC_INIT {

src/ucm/mmap/install.c

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <ucm/util/reloc.h>
1818
#include <ucm/util/sys.h>
1919
#include <ucm/bistro/bistro.h>
20+
#include <ucs/sys/preprocessor.h>
2021
#include <ucs/sys/math.h>
2122
#include <ucs/sys/checker.h>
2223
#include <ucs/arch/bitops.h>
@@ -37,6 +38,8 @@
3738
do { \
3839
(_data)->fired_events = 0; \
3940
_call; \
41+
ucm_trace("after %s: fired events = 0x%x", UCS_PP_MAKE_STRING(_call), \
42+
(_data)->fired_events); \
4043
(_data)->out_events &= ~((_event) & (_mask)) | (_data)->fired_events; \
4144
} while(0)
4245

@@ -74,6 +77,9 @@ static ucm_mmap_func_t ucm_mmap_funcs[] = {
7477
{ {NULL, NULL}, 0}
7578
};
7679

80+
static pthread_mutex_t ucm_mmap_install_mutex = PTHREAD_MUTEX_INITIALIZER;
81+
static int ucm_mmap_installed_events = 0; /* events that were reported as installed */
82+
7783
static void ucm_mmap_event_test_callback(ucm_event_type_t event_type,
7884
ucm_event_t *event, void *fired_events)
7985
{
@@ -89,6 +95,8 @@ static void ucm_mmap_event_test_callback(ucm_event_type_t event_type,
8995
static void
9096
ucm_fire_mmap_events_internal(int events, ucm_mmap_test_events_data_t *data)
9197
{
98+
size_t sbrk_size;
99+
int sbrk_mask;
92100
int shmid;
93101
void *p;
94102

@@ -129,10 +137,18 @@ ucm_fire_mmap_events_internal(int events, ucm_mmap_test_events_data_t *data)
129137
}
130138

131139
if (events & (UCM_EVENT_SBRK|UCM_EVENT_VM_MAPPED|UCM_EVENT_VM_UNMAPPED)) {
132-
UCM_FIRE_EVENT(events, UCM_EVENT_SBRK|UCM_EVENT_VM_MAPPED,
133-
data, (void)sbrk(ucm_get_page_size()));
134-
UCM_FIRE_EVENT(events, UCM_EVENT_SBRK|UCM_EVENT_VM_UNMAPPED,
135-
data, (void)sbrk(-ucm_get_page_size()));
140+
if (RUNNING_ON_VALGRIND) {
141+
/* on valgrind, doing a non-trivial sbrk() causes heap corruption */
142+
sbrk_size = 0;
143+
sbrk_mask = UCM_EVENT_SBRK;
144+
} else {
145+
sbrk_size = ucm_get_page_size();
146+
sbrk_mask = UCM_EVENT_SBRK|UCM_EVENT_VM_MAPPED|UCM_EVENT_VM_UNMAPPED;
147+
}
148+
UCM_FIRE_EVENT(events, (UCM_EVENT_SBRK|UCM_EVENT_VM_MAPPED) & sbrk_mask,
149+
data, (void)sbrk(sbrk_size));
150+
UCM_FIRE_EVENT(events, (UCM_EVENT_SBRK|UCM_EVENT_VM_UNMAPPED) & sbrk_mask,
151+
data, (void)sbrk(-sbrk_size));
136152
}
137153

138154
if (events & UCM_EVENT_MADVISE) {
@@ -157,7 +173,8 @@ void ucm_fire_mmap_events(int events)
157173
ucm_fire_mmap_events_internal(events, &data);
158174
}
159175

160-
ucs_status_t ucm_mmap_test_events(int events, int *out_events)
176+
/* Called with lock held */
177+
static ucs_status_t ucm_mmap_test_events(int events)
161178
{
162179
ucm_event_handler_t handler;
163180
ucm_mmap_test_events_data_t data;
@@ -172,32 +189,27 @@ ucs_status_t ucm_mmap_test_events(int events, int *out_events)
172189
ucm_fire_mmap_events_internal(events, &data);
173190
ucm_event_handler_remove(&handler);
174191

175-
*out_events = data.out_events;
176-
177-
ucm_debug("mmap test: got 0x%x out of 0x%x", *out_events, events);
192+
ucm_debug("mmap test: got 0x%x out of 0x%x", data.out_events, events);
178193

179194
/* Return success if we caught all wanted events */
180-
if (!ucs_test_all_flags(*out_events, events)) {
195+
if (!ucs_test_all_flags(data.out_events, events)) {
181196
return UCS_ERR_UNSUPPORTED;
182197
}
183198

184199
return UCS_OK;
185200
}
186201

187-
/* Called with lock held */
188-
static ucs_status_t ucm_mmap_test(int events)
202+
ucs_status_t ucm_mmap_test_installed_events(int events)
189203
{
190-
static int installed_events = 0;
191-
int out_events = 0; /* GCC bug: it reports compilation fail if not initialized */
192204
ucs_status_t status;
193205

194-
if (ucs_test_all_flags(installed_events, events)) {
195-
/* All requested events are already installed */
196-
return UCS_OK;
197-
}
198-
199-
status = ucm_mmap_test_events(events, &out_events);
200-
installed_events |= out_events;
206+
/*
207+
* return UCS_OK iff all installed events are actually working
208+
* we don't check the status of events which were not successfully installed
209+
*/
210+
pthread_mutex_lock(&ucm_mmap_install_mutex);
211+
status = ucm_mmap_test_events(events & ucm_mmap_installed_events);
212+
pthread_mutex_unlock(&ucm_mmap_install_mutex);
201213

202214
return status;
203215
}
@@ -250,14 +262,18 @@ static ucs_status_t ucs_mmap_install_reloc(int events)
250262

251263
ucs_status_t ucm_mmap_install(int events)
252264
{
253-
static pthread_mutex_t install_mutex = PTHREAD_MUTEX_INITIALIZER;
254265
ucs_status_t status;
255266

256-
pthread_mutex_lock(&install_mutex);
267+
pthread_mutex_lock(&ucm_mmap_install_mutex);
257268

258-
status = ucm_mmap_test(events);
259-
if (status == UCS_OK) {
260-
goto out_unlock;
269+
if (ucs_test_all_flags(ucm_mmap_installed_events, events)) {
270+
/* if we already installed these events, check that they are still
271+
* working, and if not - reinstall them.
272+
*/
273+
status = ucm_mmap_test_events(events);
274+
if (status == UCS_OK) {
275+
goto out_unlock;
276+
}
261277
}
262278

263279
status = ucs_mmap_install_reloc(events);
@@ -266,9 +282,17 @@ ucs_status_t ucm_mmap_install(int events)
266282
goto out_unlock;
267283
}
268284

269-
status = ucm_mmap_test(events);
285+
status = ucm_mmap_test_events(events);
286+
if (status != UCS_OK) {
287+
ucm_debug("failed to install mmap events");
288+
goto out_unlock;
289+
}
290+
291+
/* status == UCS_OK */
292+
ucm_mmap_installed_events |= events;
293+
ucm_debug("mmap installed events = 0x%x", ucm_mmap_installed_events);
270294

271295
out_unlock:
272-
pthread_mutex_unlock(&install_mutex);
296+
pthread_mutex_unlock(&ucm_mmap_install_mutex);
273297
return status;
274298
}

src/ucm/mmap/mmap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ int ucm_override_brk(void *addr);
3434
void *ucm_brk_syscall(void *addr);
3535
int ucm_override_madvise(void *addr, size_t length, int advice);
3636
void ucm_fire_mmap_events(int events);
37-
ucs_status_t ucm_mmap_test_events(int events, int *out_events);
37+
ucs_status_t ucm_mmap_test_installed_events(int events);
3838

3939
static UCS_F_ALWAYS_INLINE ucm_mmap_hook_mode_t ucm_mmap_hook_mode(void)
4040
{

test/examples/ucp_client_server.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ static int start_client(ucp_worker_h ucp_worker, const char *ip,
202202
static void print_result(int is_server, char *recv_message)
203203
{
204204
if (is_server) {
205+
printf("UCX data message was received\n");
205206
printf("\n\n----- UCP TEST SUCCESS -------\n\n");
206207
printf("%s", recv_message);
207208
printf("\n\n------------------------------\n\n");
@@ -213,15 +214,32 @@ static void print_result(int is_server, char *recv_message)
213214
}
214215
}
215216

216-
static void request_wait(ucp_worker_h ucp_worker, test_req_t *request)
217+
/**
218+
* Progress the request until it completes.
219+
*/
220+
static ucs_status_t request_wait(ucp_worker_h ucp_worker, test_req_t *request)
217221
{
222+
ucs_status_t status;
223+
224+
/* if operation was completed immediately */
225+
if (request == NULL) {
226+
return UCS_OK;
227+
}
228+
229+
if (UCS_PTR_IS_ERR(request)) {
230+
return UCS_PTR_STATUS(request);
231+
}
232+
218233
while (request->complete == 0) {
219234
ucp_worker_progress(ucp_worker);
220235
}
236+
status = ucp_request_check_status(request);
221237

222238
/* This request may be reused so initialize it for next time */
223239
request->complete = 0;
224240
ucp_request_free(request);
241+
242+
return status;
225243
}
226244

227245
/**
@@ -235,39 +253,31 @@ static int send_recv_stream(ucp_worker_h ucp_worker, ucp_ep_h ep, int is_server)
235253
test_req_t *request;
236254
size_t length;
237255
int ret = 0;
256+
ucs_status_t status;
238257

239258
if (!is_server) {
240259
/* Client sends a message to the server using the stream API */
241260
request = ucp_stream_send_nb(ep, test_message, 1,
242261
ucp_dt_make_contig(TEST_STRING_LEN),
243262
stream_send_cb, 0);
244-
if (UCS_PTR_IS_ERR(request)) {
245-
fprintf(stderr, "unable to send UCX message (%s)\n",
246-
ucs_status_string(UCS_PTR_STATUS(request)));
247-
ret = -1;
248-
goto out;
249-
} else if (UCS_PTR_STATUS(request) != UCS_OK) {
250-
request_wait(ucp_worker, request);
251-
}
252263
} else {
253264
/* Server receives a message from the client using the stream API */
254265
request = ucp_stream_recv_nb(ep, &recv_message, 1,
255266
ucp_dt_make_contig(TEST_STRING_LEN),
256-
stream_recv_cb, &length , 0);
257-
if (UCS_PTR_IS_ERR(request)) {
258-
fprintf(stderr, "unable to receive UCX message (%s)\n",
259-
ucs_status_string(UCS_PTR_STATUS(request)));
260-
ret = -1;
261-
goto out;
262-
} else {
263-
request_wait(ucp_worker, request);
264-
printf("UCX data message was received\n");
265-
}
267+
stream_recv_cb, &length,
268+
UCP_STREAM_RECV_FLAG_WAITALL);
266269
}
267270

268-
print_result(is_server, recv_message);
271+
status = request_wait(ucp_worker, request);
272+
if (status != UCS_OK){
273+
fprintf(stderr, "unable to %s UCX message (%s)\n",
274+
is_server ? "receive": "send",
275+
ucs_status_string(status));
276+
ret = -1;
277+
} else {
278+
print_result(is_server, recv_message);
279+
}
269280

270-
out:
271281
return ret;
272282
}
273283

test/gtest/ucm/malloc_hook.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ UCS_TEST_F(malloc_hook, test_event_failed) {
10071007
UCS_TEST_SKIP_R("skipping on non-BISTRO hooks");
10081008
}
10091009

1010-
status = event.set(UCM_EVENT_MUNMAP);
1010+
status = event.set(UCM_EVENT_MUNMAP | UCM_EVENT_VM_UNMAPPED);
10111011
ASSERT_UCS_OK(status);
10121012

10131013
/* set hook to mmap call */
@@ -1021,7 +1021,7 @@ UCS_TEST_F(malloc_hook, test_event_failed) {
10211021
status = ucm_test_events(UCM_EVENT_VM_UNMAPPED);
10221022
EXPECT_TRUE(status == UCS_ERR_UNSUPPORTED);
10231023

1024-
/* restore original mmap body */
1024+
/* restore original munmap body */
10251025
status = ucm_bistro_restore(rp);
10261026
ASSERT_UCS_OK(status);
10271027
}
@@ -1040,21 +1040,27 @@ UCS_TEST_F(malloc_hook, test_event_unmap) {
10401040
UCS_TEST_SKIP_R("skipping on non-BISTRO hooks");
10411041
}
10421042

1043-
status = event.set(UCM_EVENT_MUNMAP);
1043+
status = event.set(UCM_EVENT_MMAP | UCM_EVENT_MUNMAP | UCM_EVENT_VM_UNMAPPED);
10441044
ASSERT_UCS_OK(status);
10451045

10461046
/* set hook to mmap call */
10471047
status = ucm_bistro_patch(symbol, (void*)bistro_hook<1>::munmap, &rp);
10481048
ASSERT_UCS_OK(status);
10491049
EXPECT_NE((intptr_t)rp, NULL);
10501050

1051+
/* munmap should be broken */
10511052
status = ucm_test_events(UCM_EVENT_MUNMAP);
10521053
EXPECT_TRUE(status == UCS_ERR_UNSUPPORTED);
10531054

1054-
status = ucm_test_events(UCM_EVENT_VM_UNMAPPED);
1055+
/* vm_unmap should be broken as well, because munmap is broken */
1056+
status = ucm_test_events(UCM_EVENT_MUNMAP);
1057+
EXPECT_TRUE(status == UCS_ERR_UNSUPPORTED);
1058+
1059+
/* mmap should still work */
1060+
status = ucm_test_events(UCM_EVENT_MMAP);
10551061
EXPECT_TRUE(status == UCS_OK);
10561062

1057-
/* restore original mmap body */
1063+
/* restore original munmap body */
10581064
status = ucm_bistro_restore(rp);
10591065
ASSERT_UCS_OK(status);
10601066
}

0 commit comments

Comments
 (0)