From 8ec0a80b9779f1b46d248f827661b2c7c602ae1b Mon Sep 17 00:00:00 2001 From: Brian Gix Date: Mon, 22 Jun 2020 11:00:04 -0700 Subject: [PATCH] mesh: Fix memory leak when queuing OB pkts rapidly If a new packet for outbound delivery is queued during the last transmission of the only other packet being sent, the prior packet got forgotten and leaked. This fix correctly deletes the prior packet, but also makes sure it is given the proper oportunity for transmission. Change-Id: I1e05a8d55f9a8ee92b049be5bbcd24969a1b10d4 Signed-off-by: anuj.bhumiya --- mesh/mesh-io-generic.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/mesh/mesh-io-generic.c b/mesh/mesh-io-generic.c index 2e556fe..9252687 100644 --- a/mesh/mesh-io-generic.c +++ b/mesh/mesh-io-generic.c @@ -604,6 +604,9 @@ static void send_pkt(struct mesh_io_private *pvt, struct tx_pkt *tx, { struct bt_hci_cmd_le_set_adv_enable cmd; + if (pvt->tx && pvt->tx->delete) + l_free(pvt->tx); + pvt->tx = tx; pvt->interval = interval; @@ -618,7 +621,7 @@ static void send_pkt(struct mesh_io_private *pvt, struct tx_pkt *tx, set_send_adv_params, pvt, NULL); } -static void tx_timeout(struct l_timeout *timeout, void *user_data) +static void tx_to(struct l_timeout *timeout, void *user_data) { struct mesh_io_private *pvt = user_data; struct tx_pkt *tx; @@ -651,8 +654,9 @@ static void tx_timeout(struct l_timeout *timeout, void *user_data) send_pkt(pvt, tx, ms); if (count == 1) { - /* send_pkt will delete when done */ + /* Recalculate wakeup if we are responding to POLL */ tx = l_queue_peek_head(pvt->tx_pkts); + if (tx && tx->info.type == MESH_IO_TIMING_TYPE_POLL_RSP) { ms = instant_remaining_ms(tx->info.u.poll_rsp.instant + tx->info.u.poll_rsp.delay); @@ -664,8 +668,7 @@ static void tx_timeout(struct l_timeout *timeout, void *user_data) pvt->tx_timeout = timeout; l_timeout_modify_ms(timeout, ms); } else - pvt->tx_timeout = l_timeout_create_ms(ms, tx_timeout, - pvt, NULL); + pvt->tx_timeout = l_timeout_create_ms(ms, tx_to, pvt, NULL); } static void tx_worker(void *user_data) @@ -714,12 +717,11 @@ static void tx_worker(void *user_data) } if (!delay) - tx_timeout(pvt->tx_timeout, pvt); + tx_to(pvt->tx_timeout, pvt); else if (pvt->tx_timeout) l_timeout_modify_ms(pvt->tx_timeout, delay); else - pvt->tx_timeout = l_timeout_create_ms(delay, tx_timeout, - pvt, NULL); + pvt->tx_timeout = l_timeout_create_ms(delay, tx_to, pvt, NULL); } static bool send_tx(struct mesh_io *io, struct mesh_io_send_info *info, @@ -733,8 +735,6 @@ static bool send_tx(struct mesh_io *io, struct mesh_io_send_info *info, return false; tx = l_new(struct tx_pkt, 1); - if (!tx) - return false; memcpy(&tx->info, info, sizeof(tx->info)); memcpy(&tx->pkt, data, len); @@ -743,7 +743,11 @@ static bool send_tx(struct mesh_io *io, struct mesh_io_send_info *info, if (info->type == MESH_IO_TIMING_TYPE_POLL_RSP) l_queue_push_head(pvt->tx_pkts, tx); else { - sending = !l_queue_isempty(pvt->tx_pkts); + if (pvt->tx) + sending = true; + else + sending = !l_queue_isempty(pvt->tx_pkts); + l_queue_push_tail(pvt->tx_pkts, tx); } -- 2.7.4