Skip to content

Commit 14ad768

Browse files
M-Vaittinenjwrdegoede
authored andcommitted
extcon: extcon-max14577: Fix potential work-queue cancellation race
The extcon IRQ schedules a work item. IRQ is requested using devm while WQ is cancelld at remove(). This mixing of devm and manual unwinding has potential case where the WQ has been emptied (.remove() was ran) but devm unwinding of IRQ was not yet done. It is possible the IRQ is triggered at this point scheduling new work item to the already flushed queue. Use new devm_work_autocancel() to remove the remove() and to kill the bug. Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Chanwoo Choi <cw00.choi@samsung.com> Link: https://lore.kernel.org/r/ee8545f59ae3a93f0a70f640ecbd7e31cfadbcb9.1623146580.git.matti.vaittinen@fi.rohmeurope.com Signed-off-by: Hans de Goede <hdegoede@redhat.com>
1 parent 7a2c4cc commit 14ad768

1 file changed

Lines changed: 5 additions & 11 deletions

File tree

drivers/extcon/extcon-max14577.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// Chanwoo Choi <cw00.choi@samsung.com>
77
// Krzysztof Kozlowski <krzk@kernel.org>
88

9+
#include <linux/devm-helpers.h>
910
#include <linux/kernel.h>
1011
#include <linux/module.h>
1112
#include <linux/i2c.h>
@@ -673,7 +674,10 @@ static int max14577_muic_probe(struct platform_device *pdev)
673674
platform_set_drvdata(pdev, info);
674675
mutex_init(&info->mutex);
675676

676-
INIT_WORK(&info->irq_work, max14577_muic_irq_work);
677+
ret = devm_work_autocancel(&pdev->dev, &info->irq_work,
678+
max14577_muic_irq_work);
679+
if (ret)
680+
return ret;
677681

678682
switch (max14577->dev_type) {
679683
case MAXIM_DEVICE_TYPE_MAX77836:
@@ -766,15 +770,6 @@ static int max14577_muic_probe(struct platform_device *pdev)
766770
return ret;
767771
}
768772

769-
static int max14577_muic_remove(struct platform_device *pdev)
770-
{
771-
struct max14577_muic_info *info = platform_get_drvdata(pdev);
772-
773-
cancel_work_sync(&info->irq_work);
774-
775-
return 0;
776-
}
777-
778773
static const struct platform_device_id max14577_muic_id[] = {
779774
{ "max14577-muic", MAXIM_DEVICE_TYPE_MAX14577, },
780775
{ "max77836-muic", MAXIM_DEVICE_TYPE_MAX77836, },
@@ -797,7 +792,6 @@ static struct platform_driver max14577_muic_driver = {
797792
.of_match_table = of_max14577_muic_dt_match,
798793
},
799794
.probe = max14577_muic_probe,
800-
.remove = max14577_muic_remove,
801795
.id_table = max14577_muic_id,
802796
};
803797

0 commit comments

Comments
 (0)