From 68dee511aae1462679fdc42f3809b281fe5aa24b Mon Sep 17 00:00:00 2001 From: Xiongfeng Wang Date: Wed, 29 May 2019 11:38:58 +0800 Subject: [PATCH] pciehp: check timer pending status before schedule the work hulk inclusion category: bugfix bugzilla: 16100 CVE: NA ------------------------------------------------- Product department report the following issue. It occured only once. [ 316.954347] Internal error: Oops - BUG: 0 [#1] SMP [ 318.336890] Process irq/142-pciehp (pid: 891, stack limit = 0x000000005e206109) [ 318.351602] CPU: 70 PID: 891 Comm: irq/142-pciehp Kdump: loaded Tainted: G W OE 4.19.36- [ 318.377182] Hardware name: Huawei TaiShan 2280 V2/BC82AMDD, BIOS 0.14 05/23/2019 [ 318.392071] pstate: 60c00089 (nZCv daIf +PAN +UAO) [ 318.401705] pc : add_timer+0x38/0x40 [ 318.408878] lr : __queue_delayed_work+0x84/0x100 [ 318.418156] sp : ffff000035c8bcc0 [ 318.424800] x29: ffff000035c8bcc0 x28: 0000000000000070 [ 318.435481] x27: ffff80bef698dd00 x26: ffff000008169000 [ 318.446159] x25: ffff000009119000 x24: 00000000000002ee [ 318.456840] x23: ffff807eff41e600 x22: 00000000000002ee [ 318.467520] x21: 0000000000000400 x20: ffff807eff41e600 [ 318.478200] x19: ffffa07ef60c3458 x18: ffffffffffffffff [ 318.488880] x17: 0000000000000000 x16: 0000000000000000 [ 318.499560] x15: ffff000009119708 x14: 206e692070752f6e [ 318.514383] x13: 776f64206b6e696c x12: 2065736972707275 [ 318.529287] x11: 0000000000000000 x10: ffff00000911bae0 [ 318.544136] x9 : 0000000000000000 x8 : 00000000000009df [ 318.558884] x7 : ffff0000092eef80 x6 : ffffa07eff95e3b8 [ 318.573572] x5 : ffffa07eff95e3b8 x4 : 0000000000000000 [ 318.588298] x3 : 0000000100000bfc x2 : ffffa07ef60c3420 [ 318.603066] x1 : 000000010000090e x0 : ffffa07eff962a30 [ 318.617780] Call trace: [ 318.626714] add_timer+0x38/0x40 [ 318.637129] __queue_delayed_work+0x84/0x100 [ 318.649588] queue_delayed_work_on+0xbc/0xc8 [ 318.661993] pciehp_ist+0x1c0/0x2f8 [ 318.672745] irq_thread_fn+0x30/0x80 [ 318.683600] irq_thread+0x128/0x200 [ 318.694187] kthread+0x134/0x138 [ 318.704202] ret_from_fork+0x10/0x18 It is because when we schedule the work, the 'work.timer' is already pending. I can't figure out how it happened. Let's just set 'work.data' and return if that is the case. Since the timer is pending, 'pciehp_ist' will be called later, we don't need to queue the work again. Fixes: 764cafd9875e ("pciehp: fix a race between pciehp and removing operations by sysfs") Signed-off-by: Xiongfeng Wang Reviewed-by: Hanjun Guo Signed-off-by: Yang Yingliang --- drivers/pci/hotplug/pciehp_hpc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 600961c1e08b..a8298b483e9c 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -699,7 +699,12 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) */ atomic_long_set(&slot->work.work.data, DISABLE_SLOT); - schedule_delayed_work(&slot->work, 3 * HZ); + /* + * If 'work.timer' is pending, schedule the work will + * cause BUG_ON(). + */ + if (!timer_pending(&slot->work.timer)) + schedule_delayed_work(&slot->work, 3 * HZ); } } } else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) { @@ -721,7 +726,8 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) atomic_long_set(&slot->work.work.data, events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)); - schedule_delayed_work(&slot->work, 3 * HZ); + if (!timer_pending(&slot->work.timer)) + schedule_delayed_work(&slot->work, 3 * HZ); } } } -- GitLab