Skip to content

Commit d387b8a

Browse files
tvegas1bureddy
authored andcommitted
Avoid deadlock by unlocking on close path before receiving signal on socket.
A run can fail to return because on both nodes, one thread is holding the lock pending on receive, which prevents a close send. Visible with 8 gpus, 2 nodes.
1 parent 8a2ef11 commit d387b8a

1 file changed

Lines changed: 19 additions & 19 deletions

File tree

src/ucx_plugin.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -350,34 +350,34 @@ static ncclResult_t ucx_get_ctx_and_worker(int dev, ucp_context_h *ctx,
350350
}
351351

352352
static ncclResult_t nccl_ucx_free_worker(ucp_worker_h worker) {
353-
int i;
354-
int dummy;
353+
int i, dummy, count;
355354
struct ep_list *ep, *cur;
356355

357356
pthread_mutex_lock(&nccl_ucx_lock);
358357
for(i = 0; i < ncclNIbDevs; i++) {
359-
if (worker == workers[i].worker) {
360-
workers[i].count--;
361-
if (workers[i].count == 0){
362-
ep = workers[i].eps;
363-
while(ep){
364-
cur = ep;
365-
NCCLCHECK(ncclSocketRecv(ep->sock, &dummy, sizeof(int)));
366-
ep = ep->next;
367-
close(cur->sock->fd);
368-
free(cur);
369-
}
370-
ucp_worker_destroy(workers[i].worker);
371-
ucp_cleanup(workers[i].ctx);
372-
workers[i].eps = NULL;
373-
workers[i].worker = NULL;
374-
workers[i].ctx = NULL;
375-
}
358+
if (workers[i].count > 0 && worker == workers[i].worker) {
359+
count = --workers[i].count;
376360
break;
377361
}
378362
}
379363
pthread_mutex_unlock(&nccl_ucx_lock);
380364

365+
if (i < ncclNIbDevs && count == 0) {
366+
ep = workers[i].eps;
367+
while(ep){
368+
cur = ep;
369+
NCCLCHECK(ncclSocketRecv(ep->sock, &dummy, sizeof(int)));
370+
ep = ep->next;
371+
close(cur->sock->fd);
372+
free(cur);
373+
}
374+
ucp_worker_destroy(workers[i].worker);
375+
ucp_cleanup(workers[i].ctx);
376+
workers[i].eps = NULL;
377+
workers[i].worker = NULL;
378+
workers[i].ctx = NULL;
379+
}
380+
381381
return ncclSuccess;
382382
}
383383

0 commit comments

Comments
 (0)