On Mon, Nov 16, 2020 at 3:03 PM Lukas Wunner <lukas@xxxxxxxxx> wrote: > > On Mon, Nov 16, 2020 at 11:23:43AM -0800, Andrey Smirnov wrote: > > On Mon, Nov 16, 2020 at 12:44 AM Lukas Wunner <lukas@xxxxxxxxx> wrote: > > > If the call to devm_spi_register_master() fails on probe of the GPIO SPI > > > driver, the spi_master struct is erroneously not freed: > > > > > > After allocating the spi_master, its reference count is 1. The driver > > > unconditionally decrements the reference count on unbind using a devm > > > action. Before calling devm_spi_register_master(), the driver > > > unconditionally increments the reference count because on success, > > > that function will decrement the reference count on unbind. However on > > > failure, devm_spi_register_master() does *not* decrement the reference > > > count, so the spi_master is leaked. > > > > Not sure I fully understand this. On failure > > devm_spi_register_master() will return a negative error code which > > should result in probe failure and release of devres resource, right? > > Yes, but that just decrements the refcount from 2 to 1: > > /* refcount initialized to 1 */ > master = spi_alloc_master(dev, sizeof(*spi_gpio)); > > ... > > /* refcount incremented to 2 */ > return devm_spi_register_master(&pdev->dev, spi_master_get(master)); > > ... > > /* on failure of devm_spi_register_master(), refcount decremented to 1 > by devres action */ > spi_gpio_put() > > > > > The issue was introduced by commits 8b797490b4db ("spi: gpio: Make sure > > > spi_master_put() is called in every error path") and 79567c1a321e ("spi: > > > gpio: Use devm_spi_register_master()"), which sought to plug leaks > > > introduced by 9b00bc7b901f ("spi: spi-gpio: Rewrite to use GPIO > > > descriptors") but missed this remaining leak. > > > > That extra spi_master_get() that might be problematic was present in > > the code before 8b797490b4db ("spi: gpio: Make sure spi_master_put() > > is called in every error path") and I think was first introduced in > > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers?h=v5.9-rc4&id=702a4879ec337463f858c8ab467482cce260bf18 > > > > Or am I missing something? > > The extra spi_master_get() was introduced by 79567c1a321e. > I don't see it in spi-gpio.c before that commit. > > Its quite possible that I missed something myself, nobody's perfect. > But just from code inspection it seems wrong the way it is right now. > > Shout if I failed to explain it properly and I'll try again. :) > Before 79567c1a321e extra spi_master_get() was a part of spi_bitbang_start(). Ah, OK, it had it's own local spi_master_put() on failure, which I lost when inlinging that function. My bad. Good to see that the with devm_spi_alloc_master() cleanup path is sane and easy to read once again. > Thanks, > > Lukas