From: Gustav Wiklander <gustavwi@xxxxxxxx> In the prepare_message callback the bus driver has the opportunity to split a transfer into smaller chunks. spi_map_msg is done after prepare_message. Function spi_res_release releases the splited transfers in the message. Therefore spi_res_release should be called after spi_map_msg. The previous try at this was commit c9ba7a16d0f1 which released the splited transfers after spi_finalize_current_message had been called. This introduced a race since the message struct could be out of scope because the spi_sync call got completed. Fixes this leak on spi bus driver spi-bcm2835.c when transfer size is greater than 65532: sg_alloc_table+0x28/0xc8 [ 76.674636][ T170] kmemleak: [<ffffffa542f938a4>] spi_map_buf+0xa4/0x300 [ 76.681838][ T170] kmemleak: [<ffffffa542f94648>] __spi_pump_messages+0x370/0x748 [ 76.689573][ T170] kmemleak: [<ffffffa542f94c24>] __spi_sync+0x1d4/0x270 [ 76.696863][ T170] kmemleak: [<ffffffa542f94cf4>] spi_sync+0x34/0x58 [ 76.703562][ T170] kmemleak: [<ffffffa4cd94a638>] spi_test_execute_msg+0x60/0x340 [spi_loopback_test] [ 76.713193][ T170] kmemleak: [<ffffffa4cd94ae60>] spi_test_run_iter+0x548/0x578 [spi_loopback_test] [ 76.722740][ T170] kmemleak: [<ffffffa4cd94af24>] spi_test_run_test+0x94/0x140 [spi_loopback_test] [ 76.732037][ T170] kmemleak: [<ffffffa4cd94b120>] spi_test_run_tests+0x150/0x180 [spi_loopback_test] [ 76.741498][ T170] kmemleak: [<ffffffa4cd94b1a0>] spi_loopback_test_probe+0x50/0xd0 [spi_loopback_test] [ 76.751392][ T170] kmemleak: [<ffffffa542f911f4>] spi_drv_probe+0x84/0xe0 Signed-off-by: Gustav Wiklander <gustavwi@xxxxxxxx> --- drivers/spi/spi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index dc12af018350..0cab239d8e7f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1327,8 +1327,6 @@ static int spi_transfer_one_message(struct spi_controller *ctlr, if (msg->status && ctlr->handle_err) ctlr->handle_err(ctlr, msg); - spi_res_release(ctlr, msg); - spi_finalize_current_message(ctlr); return ret; @@ -1725,6 +1723,13 @@ void spi_finalize_current_message(struct spi_controller *ctlr) spi_unmap_msg(ctlr, mesg); + /* In the prepare_messages callback the spi bus has the opportunity to + * split a transfer to smaller chunks. + * Release splited transfers here since spi_map_msg is done on the + * splited transfers. + */ + spi_res_release(ctlr, mesg); + if (ctlr->cur_msg_prepared && ctlr->unprepare_message) { ret = ctlr->unprepare_message(ctlr, mesg); if (ret) { -- 2.11.0