[PATCH v8 45/45] PCI/hotplug: PowerPC PowerNV PCI hotplug driver
Gavin Shan
gwshan at linux.vnet.ibm.com
Fri Apr 15 11:39:10 AEST 2016
On Fri, Apr 15, 2016 at 10:47:52AM +1000, Alistair Popple wrote:
>Hi Gavin,
>
>I was reading through this to understand how it all works and noticed a couple
>of things, comments below.
>
Alistair, thanks for your time on review.
>
>On Wed, 17 Feb 2016 14:44:28 Gavin Shan wrote:
>
><snip>
>
>> +
>> +static void pnv_php_handle_poweron(struct pnv_php_slot *php_slot)
>> +{
>> + void *fdt, *fdt1, *dt;
>> + int confirm = PNV_PHP_POWER_CONFIRMED_SUCCESS;
>> + int ret;
>> +
>> + /* We don't know the FDT blob size. We try to get it through
>> + * maximal memory chunk and then copy it to another chunk that
>> + * fits the real size.
>> + */
>> + fdt1 = kzalloc(0x10000, GFP_KERNEL);
>> + if (!fdt1)
>> + goto error;
>> +
>> + ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000);
>> + if (ret)
>> + goto free_fdt1;
>> +
>> + fdt = kzalloc(fdt_totalsize(fdt1), GFP_KERNEL);
>> + if (!fdt)
>> + goto free_fdt1;
>> +
>> + /* Unflatten device tree blob */
>> + memcpy(fdt, fdt1, fdt_totalsize(fdt1));
>> + dt = of_fdt_unflatten_tree(fdt, php_slot->dn, NULL);
>> + if (!dt) {
>> + dev_warn(&php_slot->pdev->dev, "Cannot unflatten FDT\n");
>> + goto free_fdt;
>> + }
>> +
>> + /* Initialize and apply the changeset */
>> + of_changeset_init(&php_slot->ocs);
>> + ret = pnv_php_populate_changeset(&php_slot->ocs, php_slot->dn);
>> + if (ret) {
>> + dev_warn(&php_slot->pdev->dev, "Error %d populating changeset\n",
>> + ret);
>> + goto free_dt;
>> + }
>> +
>> + php_slot->dn->child = NULL;
>> + ret = of_changeset_apply(&php_slot->ocs);
>> + if (ret) {
>> + dev_warn(&php_slot->pdev->dev, "Error %d applying changeset\n",
>> + ret);
>> + goto destroy_changeset;
>> + }
>> +
>> + /* Add device node firmware data */
>> + pnv_php_add_pdns(php_slot);
>> + php_slot->fdt = fdt;
>> + php_slot->dt = dt;
>> + goto out;
>
>Doesn't this leak memory from fdt1? I can't see where it gets freed in this
>case.
>
You're right that @fdt1 should be released here. I'll fix it in
next revision.
>> +destroy_changeset:
>> + of_changeset_destroy(&php_slot->ocs);
>> +free_dt:
>> + kfree(dt);
>> + php_slot->dn->child = NULL;
>> +free_fdt:
>> + kfree(fdt);
>> +free_fdt1:
>> + kfree(fdt1);
>> +error:
>> + confirm = PNV_PHP_POWER_CONFIRMED_FAIL;
>> +out:
>> + /* Confirm status change */
>> + php_slot->power_state_confirmed = confirm;
>> + wake_up_interruptible(&php_slot->queue);
>> +}
>> +
>
><snip>
>
>> +
>> +static void __exit pnv_php_exit(void)
>> +{
>> + struct device_node *dn;
>> +
>> + for_each_compatible_node(dn, NULL, "ibm,ioda-phb")
>> + pnv_php_unregister(dn);
>> + for_each_compatible_node(dn, NULL, "ibm,ioda2-phb")
>> + pnv_php_unregister(dn);
>> +
>> + pnv_pci_hotplug_notifier_unregister(&php_msg_nb);
>
>Do you flush the workqueues anywhere? Usually you would stop work being queued
>and call something like flush_workqueue() to ensure no work is still
>running/queued before unloading the module.
>
Good question. Yeah, I'll flush the workqueue before the module is going
to be unloaded.
Thanks,
Gavin
>- Alistair
>
>> +}
>> +
>> +module_init(pnv_php_init);
>> +module_exit(pnv_php_exit);
>> +
>> +MODULE_VERSION(DRIVER_VERSION);
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_AUTHOR(DRIVER_AUTHOR);
>> +MODULE_DESCRIPTION(DRIVER_DESC);
>>
>
More information about the Linuxppc-dev
mailing list