Thread (17 messages) flat view 17 messages, 4 authors, 2020-11-23

Re: [PATCH v4 01/11] firmware: raspberrypi: Keep count of all consumers

From: Nicolas Saenz Julienne <hidden>
Date: 2020-11-23 17:20:00
Also in: linux-arm-kernel, linux-clk, linux-gpio, linux-input, linux-pwm, lkml

On Thu, 2020-11-12 at 23:26 -0800, Dmitry Torokhov wrote:
On Thu, Nov 12, 2020 at 07:52:14PM +0200, Andy Shevchenko wrote:
quoted
On Thu, Nov 12, 2020 at 6:40 PM Nicolas Saenz Julienne
[off-list ref] wrote:
quoted
When unbinding the firmware device we need to make sure it has no
consumers left. Otherwise we'd leave them with a firmware handle
pointing at freed memory.

Keep a reference count of all consumers and introduce rpi_firmware_put()
which will permit automatically decrease the reference count upon
unbinding consumer drivers.
...
quoted
 /**
- * rpi_firmware_get - Get pointer to rpi_firmware structure.
  * @firmware_node:    Pointer to the firmware Device Tree node.
  *
+ * The reference to rpi_firmware has to be released with rpi_firmware_put().
+ *
  * Returns NULL is the firmware device is not ready.
  */
 struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
 {
        struct platform_device *pdev = of_find_device_by_node(firmware_node);
+       struct rpi_firmware *fw;

        if (!pdev)
                return NULL;

-       return platform_get_drvdata(pdev);
+       fw = platform_get_drvdata(pdev);
+       if (!fw)
+               return NULL;
+
+       if (!kref_get_unless_zero(&fw->consumers))
+               return NULL;
Hi Andy, Dimitry,
quoted
Don't we have a more traditional way of doing this, i.e.
try_module_get() coupled with get_device() ?
get_device() will make sure that device is there, but gives no
assurances that device is bound to a driver, so it will not help with
the racy access to firmware via platform_get_drvdata() call.
I also looked at using get/put_device() just as a means for refcounting (i.e.
replacing fw->consumers), but I can't make it work either. I'd need a way to
hook up into one of the struct device_ktype release() functions. AFAIK it's not
possible for private uses like this.

IIUC the way to do this would be to bypass platform device and create a special
device class/bus for RPi's firmware dependent devices (I could pretty much copy
SCMI's implementation), but I fear that's overkill.

So, for now I'll stick with the kref based implementation, I'll be happy to
change it if you find a better solution. :)

Regards,
Nicolas

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help