提交 8a53c6db 编写于 作者: X Xiongfeng Wang 提交者: Xie XiuQi

pciehp: use delayed_work private data to pass pending events

euler inclusion
category: bugfix
bugzilla: NA
CVE: NA
---------------------------

We use 'work_struct' private data to pass the pending events when we
schedule a 'delayed_work' in the following commit.
764cafd9875e ("pciehp: fix a race between pciehp and removing operations
by sysfs")
But workqueue framework will use this member, such as workqueue core
function 'set_work_pool_and_keep_pending()'. This patch add a new member
in 'struct delayed_work' and use this member to pass the pending events.
This patch also add more debug info.

Fixes: 764cafd9875e ("pciehp: fix a race between pciehp and removing
operations by sysfs")
Signed-off-by: NXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: NYao Hongbo <yaohongbo@huawei.com>
Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 e56c9e3e
...@@ -145,8 +145,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) ...@@ -145,8 +145,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work)
{ {
struct slot *p_slot = container_of(work, struct slot, work.work); struct slot *p_slot = container_of(work, struct slot, work.work);
struct controller *ctrl = p_slot->ctrl; struct controller *ctrl = p_slot->ctrl;
int events = atomic_long_read(&work->data) & (PCI_EXP_SLTSTA_PDC | int events = p_slot->work.data;
PCI_EXP_SLTSTA_DLLSC | DISABLE_SLOT);
mutex_lock(&p_slot->lock); mutex_lock(&p_slot->lock);
switch (p_slot->state) { switch (p_slot->state) {
...@@ -188,7 +187,7 @@ void pciehp_handle_button_press(struct slot *p_slot) ...@@ -188,7 +187,7 @@ void pciehp_handle_button_press(struct slot *p_slot)
/* blink green LED and turn off amber */ /* blink green LED and turn off amber */
pciehp_green_led_blink(p_slot); pciehp_green_led_blink(p_slot);
pciehp_set_attention_status(p_slot, 0); pciehp_set_attention_status(p_slot, 0);
atomic_long_set(&p_slot->work.work.data, 0); p_slot->work.data = 0;
schedule_delayed_work(&p_slot->work, 5 * HZ); schedule_delayed_work(&p_slot->work, 5 * HZ);
break; break;
case BLINKINGOFF_STATE: case BLINKINGOFF_STATE:
......
...@@ -693,18 +693,22 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) ...@@ -693,18 +693,22 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
slot->state == BLINKINGON_STATE) slot->state == BLINKINGON_STATE)
pciehp_handle_disable_request(slot); pciehp_handle_disable_request(slot);
else { else {
ctrl_info(ctrl, "Slot(%s): DISABLE_SLOT event in remove or rescan process!\n",
slot_name(slot));
/* /*
* we use the work_struct private data to store * we use the work_struct private data to store
* the event type * the event type
*/ */
atomic_long_set(&slot->work.work.data, slot->work.data = DISABLE_SLOT;
DISABLE_SLOT);
/* /*
* If 'work.timer' is pending, schedule the work will * If 'work.timer' is pending, schedule the work will
* cause BUG_ON(). * cause BUG_ON().
*/ */
if (!timer_pending(&slot->work.timer)) if (!timer_pending(&slot->work.timer))
schedule_delayed_work(&slot->work, 3 * HZ); schedule_delayed_work(&slot->work, 3 * HZ);
else
ctrl_info(ctrl, "Slot(%s): Didn't schedule delayed_work because timer is pending!\n",
slot_name(slot));
} }
} }
} else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) { } else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) {
...@@ -723,11 +727,12 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) ...@@ -723,11 +727,12 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
*/ */
ctrl_info(ctrl, "Slot(%s): Surprise link down/up in remove or rescan process!\n", ctrl_info(ctrl, "Slot(%s): Surprise link down/up in remove or rescan process!\n",
slot_name(slot)); slot_name(slot));
atomic_long_set(&slot->work.work.data, slot->work.data = events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
events & (PCI_EXP_SLTSTA_PDC |
PCI_EXP_SLTSTA_DLLSC));
if (!timer_pending(&slot->work.timer)) if (!timer_pending(&slot->work.timer))
schedule_delayed_work(&slot->work, 3 * HZ); schedule_delayed_work(&slot->work, 3 * HZ);
else
ctrl_info(ctrl, "Slot(%s): Didn't schedule delayed_work because timer is pending!\n",
slot_name(slot));
} }
} }
} }
......
...@@ -125,6 +125,8 @@ struct delayed_work { ...@@ -125,6 +125,8 @@ struct delayed_work {
/* target workqueue and CPU ->timer uses to queue ->work */ /* target workqueue and CPU ->timer uses to queue ->work */
struct workqueue_struct *wq; struct workqueue_struct *wq;
int cpu; int cpu;
/* delayed_work private data, only used in pciehp now */
unsigned long data;
KABI_RESERVE(1) KABI_RESERVE(1)
KABI_RESERVE(2) KABI_RESERVE(2)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册