Skip to content
This repository was archived by the owner on Dec 26, 2023. It is now read-only.

Commit 1f22a2b

Browse files
dnejezchlebcarlescufi
authored andcommitted
net: tcp: Fix possible deadlock in tcp_conn_unref()
This reverts commit e7489d8. And fixes the deadlock by allowing only 1 thread to actualy clean up the connection when the ref_count is 0. Signed-off-by: Daniel Nejezchleb <[email protected]>
1 parent bf45055 commit 1f22a2b

File tree

1 file changed

+4
-7
lines changed

1 file changed

+4
-7
lines changed

subsys/net/ip/tcp.c

+4-7
Original file line numberDiff line numberDiff line change
@@ -377,15 +377,15 @@ static int tcp_conn_unref(struct tcp *conn)
377377
}
378378
#endif /* CONFIG_NET_TEST_PROTOCOL */
379379

380-
k_mutex_lock(&tcp_lock, K_FOREVER);
381-
382380
ref_count = atomic_dec(&conn->ref_count) - 1;
383-
if (ref_count) {
381+
if (ref_count != 0) {
384382
tp_out(net_context_get_family(conn->context), conn->iface,
385383
"TP_TRACE", "event", "CONN_DELETE");
386-
goto unlock;
384+
return ref_count;
387385
}
388386

387+
k_mutex_lock(&tcp_lock, K_FOREVER);
388+
389389
/* If there is any pending data, pass that to application */
390390
while ((pkt = k_fifo_get(&conn->recv_data, K_NO_WAIT)) != NULL) {
391391
if (net_context_packet_received(
@@ -403,10 +403,8 @@ static int tcp_conn_unref(struct tcp *conn)
403403
}
404404

405405
if (conn->context->recv_cb) {
406-
k_mutex_unlock(&tcp_lock);
407406
conn->context->recv_cb(conn->context, NULL, NULL, NULL,
408407
-ECONNRESET, conn->recv_user_data);
409-
k_mutex_lock(&tcp_lock, K_FOREVER);
410408
}
411409

412410
conn->context->tcp = NULL;
@@ -431,7 +429,6 @@ static int tcp_conn_unref(struct tcp *conn)
431429

432430
k_mem_slab_free(&tcp_conns_slab, (void **)&conn);
433431

434-
unlock:
435432
k_mutex_unlock(&tcp_lock);
436433
out:
437434
return ref_count;

0 commit comments

Comments
 (0)