diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 475b2d0c0cf91..6cbd27d05fe3a 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -1573,11 +1573,18 @@ static struct net_pkt *context_alloc_pkt(struct net_context *context, { struct net_pkt *pkt; + /* We reference it once again to make sure context is not going + * to disappear while allocating a packet + */ + net_context_ref(context); + + k_mutex_unlock(&context->lock); + #if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) if (context->tx_slab) { pkt = net_pkt_alloc_from_slab(context->tx_slab(), timeout); if (!pkt) { - return NULL; + goto out; } net_pkt_set_iface(pkt, net_context_get_iface(context)); @@ -1588,18 +1595,30 @@ static struct net_pkt *context_alloc_pkt(struct net_context *context, net_context_get_ip_proto(context), timeout)) { net_pkt_unref(pkt); - return NULL; + pkt = NULL; } - return pkt; + goto out; } #endif pkt = net_pkt_alloc_with_buffer(net_context_get_iface(context), len, net_context_get_family(context), net_context_get_ip_proto(context), timeout); + if (!pkt) { + goto out; + } net_pkt_set_context(pkt, context); +out: + net_context_unref(context); + + k_mutex_lock(&context->lock, K_FOREVER); + + if (!net_context_is_used(context) && pkt) { + net_pkt_unref(pkt); + pkt = NULL; + } return pkt; } diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 4f26ff40cdcaf..fb5b56c554add 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -1926,9 +1926,10 @@ NET_CONN_CB(tcp_established) * ack # value can/should be sent, so we just force resend. */ resend_ack: + k_mutex_unlock(&context->lock); send_ack(context, &conn->remote_addr, true); - ret = NET_DROP; - goto unlock; + + return NET_DROP; } if (net_tcp_seq_cmp(sys_get_be32(tcp_hdr->seq),