提交 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)
{
struct slot *p_slot = container_of(work, struct slot, work.work);
struct controller *ctrl = p_slot->ctrl;
int events = atomic_long_read(&work->data) & (PCI_EXP_SLTSTA_PDC |
PCI_EXP_SLTSTA_DLLSC | DISABLE_SLOT);
int events = p_slot->work.data;
mutex_lock(&p_slot->lock);
switch (p_slot->state) {
......@@ -188,7 +187,7 @@ void pciehp_handle_button_press(struct slot *p_slot)
/* blink green LED and turn off amber */
pciehp_green_led_blink(p_slot);
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);
break;
case BLINKINGOFF_STATE:
......
......@@ -693,18 +693,22 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
slot->state == BLINKINGON_STATE)
pciehp_handle_disable_request(slot);
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
* the event type
*/
atomic_long_set(&slot->work.work.data,
DISABLE_SLOT);
slot->work.data = DISABLE_SLOT;
/*
* 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
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)) {
......@@ -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",
slot_name(slot));
atomic_long_set(&slot->work.work.data,
events & (PCI_EXP_SLTSTA_PDC |
PCI_EXP_SLTSTA_DLLSC));
slot->work.data = events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
if (!timer_pending(&slot->work.timer))
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 {
/* target workqueue and CPU ->timer uses to queue ->work */
struct workqueue_struct *wq;
int cpu;
/* delayed_work private data, only used in pciehp now */
unsigned long data;
KABI_RESERVE(1)
KABI_RESERVE(2)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册