* [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue to avoid deadlock
@ 2012-10-31 7:10 Yijing Wang
2012-10-31 9:20 ` Kaneshige, Kenji
2012-11-07 10:47 ` Kaneshige, Kenji
0 siblings, 2 replies; 5+ messages in thread
From: Yijing Wang @ 2012-10-31 7:10 UTC (permalink / raw)
To: Bjorn Helgaas, Yinghai Lu, Kenji Kaneshige, Rafael, Rusty Russell,
Mauro Carvalho Chehab, Oliver Neukum
Cc: linux-pci, Hanjun Guo, jiang.liu, Yijing Wang
Currently, pciehp use global pciehp_wq to handle hotplug event from hardware.
Hot remove path will be blocked if a hotplug slot connected a IO-BOX(composed of PCIe
Switch and some slots which support hotplug, eg.PLX8696). The hot removed work was queued
into pciehp_wq. But in the hot-remove path, pciehp driver would flush pciehp_wq when
the pcie port(support pciehp) was removed. In this case the hot-remove path blocked.
This patch remove the global pciehp_wq and create a new workqueue for every slot to
avoid above problem.
-+-[0000:40]-+-00.0-[0000:41]--
| +-01.0-[0000:42]--+-00.0 Intel Corporation 82576 Gigabit Network Connection
| | \-00.1 Intel Corporation 82576 Gigabit Network Connection
| +-03.0-[0000:43]----00.0 LSI Logic / Symbios Logic SAS1064ET PCI-Express Fusion-MPT SAS
| +-04.0-[0000:44]--
| +-05.0-[0000:45]--
| +-07.0-[0000:46-4f]----00.0-[0000:47-4f]--+-04.0-[0000:48-49]----00.0-[0000:49]--
| |(hotplug slot) +-08.0-[0000:4a]--
| | +-09.0-[0000:4b]--
| | +-10.0-[0000:4c]--
| | +-11.0-[0000:4d]--
| | +-14.0-[0000:4e]--
| | \-15.0-[0000:4f]--+-00.0 Intel Corporation 82576 Gigabit Network Connection
| | (hotplug slot) \-00.1 Intel Corporation 82576 Gigabit Network Connection
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
drivers/pci/hotplug/pciehp.h | 2 +-
drivers/pci/hotplug/pciehp_core.c | 11 ++---------
drivers/pci/hotplug/pciehp_ctrl.c | 8 ++++----
drivers/pci/hotplug/pciehp_hpc.c | 14 ++++++++++++--
4 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 26ffd3e..2c113de 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -44,7 +44,6 @@ extern bool pciehp_poll_mode;
extern int pciehp_poll_time;
extern bool pciehp_debug;
extern bool pciehp_force;
-extern struct workqueue_struct *pciehp_wq;
#define dbg(format, arg...) \
do { \
@@ -78,6 +77,7 @@ struct slot {
struct hotplug_slot *hotplug_slot;
struct delayed_work work; /* work for button event */
struct mutex lock;
+ struct workqueue_struct *wq;
};
struct event_info {
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 916bf4f..0914211 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -42,7 +42,6 @@ bool pciehp_debug;
bool pciehp_poll_mode;
int pciehp_poll_time;
bool pciehp_force;
-struct workqueue_struct *pciehp_wq;
#define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
@@ -340,18 +339,13 @@ static int __init pcied_init(void)
{
int retval = 0;
- pciehp_wq = alloc_workqueue("pciehp", 0, 0);
- if (!pciehp_wq)
- return -ENOMEM;
-
pciehp_firmware_init();
retval = pcie_port_service_register(&hpdriver_portdrv);
dbg("pcie_port_service_register = %d\n", retval);
info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
- if (retval) {
- destroy_workqueue(pciehp_wq);
+ if (retval)
dbg("Failure to register service\n");
- }
+
return retval;
}
@@ -359,7 +353,6 @@ static void __exit pcied_cleanup(void)
{
dbg("unload_pciehpd()\n");
pcie_port_service_unregister(&hpdriver_portdrv);
- destroy_workqueue(pciehp_wq);
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
}
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 27f4429..38f0186 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -49,7 +49,7 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
info->p_slot = p_slot;
INIT_WORK(&info->work, interrupt_event_handler);
- queue_work(pciehp_wq, &info->work);
+ queue_work(p_slot->wq, &info->work);
return 0;
}
@@ -344,7 +344,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work)
kfree(info);
goto out;
}
- queue_work(pciehp_wq, &info->work);
+ queue_work(p_slot->wq, &info->work);
out:
mutex_unlock(&p_slot->lock);
}
@@ -377,7 +377,7 @@ static void handle_button_press_event(struct slot *p_slot)
if (ATTN_LED(ctrl))
pciehp_set_attention_status(p_slot, 0);
- queue_delayed_work(pciehp_wq, &p_slot->work, 5*HZ);
+ queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ);
break;
case BLINKINGOFF_STATE:
case BLINKINGON_STATE:
@@ -439,7 +439,7 @@ static void handle_surprise_event(struct slot *p_slot)
else
p_slot->state = POWERON_STATE;
- queue_work(pciehp_wq, &info->work);
+ queue_work(p_slot->wq, &info->work);
}
static void interrupt_event_handler(struct work_struct *work)
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 13b2eaf..8e5e571 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -773,23 +773,33 @@ static void pcie_shutdown_notification(struct controller *ctrl)
static int pcie_init_slot(struct controller *ctrl)
{
struct slot *slot;
+ char name[32];
slot = kzalloc(sizeof(*slot), GFP_KERNEL);
if (!slot)
return -ENOMEM;
-
+
+ snprintf(name, sizeof(name), "pciehpd_%s",
+ pci_name(ctrl->pcie->port));
+ slot->wq = create_singlethread_workqueue(name);
+ if (!slot->wq)
+ goto abort;
slot->ctrl = ctrl;
mutex_init(&slot->lock);
INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
ctrl->slot = slot;
return 0;
+abort:
+ kfree(slot);
+ return -1;
}
static void pcie_cleanup_slot(struct controller *ctrl)
{
struct slot *slot = ctrl->slot;
cancel_delayed_work(&slot->work);
- flush_workqueue(pciehp_wq);
+ flush_workqueue(slot->wq);
+ destroy_workqueue(slot->wq);
kfree(slot);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* RE: [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue to avoid deadlock
2012-10-31 7:10 [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue to avoid deadlock Yijing Wang
@ 2012-10-31 9:20 ` Kaneshige, Kenji
2012-10-31 9:33 ` Yijing Wang
2012-11-07 10:47 ` Kaneshige, Kenji
1 sibling, 1 reply; 5+ messages in thread
From: Kaneshige, Kenji @ 2012-10-31 9:20 UTC (permalink / raw)
To: Yijing Wang, Bjorn Helgaas, Yinghai Lu, Rafael, Rusty Russell,
Mauro Carvalho Chehab, Oliver Neukum
Cc: linux-pci@vger.kernel.org, Hanjun Guo, jiang.liu@huawei.com
Let me confirm the problem. My understanding of the problem is below.
Is my understanding correct?
- Your hardware has nested PCIe hotplug slots like below.
--<slot A>--<Slot B>
- Hot-removal request (attention button event) comes to <slot A>
- Pciehp driver queue the hot-removal work
- This hot-removal work try to remove <slot B>
- To remove <slot B>, pciehp flush the pciehp_wq, but it never finishes
because hot-removal work is in progress. ===> deadlock
Regards,
Kenji Kaneshige
> -----Original Message-----
> From: Yijing Wang [mailto:wangyijing@huawei.com]
> Sent: Wednesday, October 31, 2012 4:11 PM
> To: Bjorn Helgaas; Yinghai Lu; Kaneshige, Kenji/金重 憲治; Rafael; Rusty
> Russell; Mauro Carvalho Chehab; Oliver Neukum
> Cc: linux-pci@vger.kernel.org; Hanjun Guo; jiang.liu@huawei.com; Yijing
> Wang
> Subject: [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue
> to avoid deadlock
>
> Currently, pciehp use global pciehp_wq to handle hotplug event from
> hardware.
> Hot remove path will be blocked if a hotplug slot connected a IO-BOX(composed
> of PCIe
> Switch and some slots which support hotplug, eg.PLX8696). The hot removed
> work was queued
> into pciehp_wq. But in the hot-remove path, pciehp driver would flush
> pciehp_wq when
> the pcie port(support pciehp) was removed. In this case the hot-remove path
> blocked.
> This patch remove the global pciehp_wq and create a new workqueue for every
> slot to
> avoid above problem.
>
> -+-[0000:40]-+-00.0-[0000:41]--
> | +-01.0-[0000:42]--+-00.0 Intel Corporation 82576 Gigabit
> Network Connection
> | | \-00.1 Intel Corporation 82576 Gigabit
> Network Connection
> | +-03.0-[0000:43]----00.0 LSI Logic / Symbios Logic
> SAS1064ET PCI-Express Fusion-MPT SAS
> | +-04.0-[0000:44]--
> | +-05.0-[0000:45]--
> |
> +-07.0-[0000:46-4f]----00.0-[0000:47-4f]--+-04.0-[0000:48-49]----00.0-
> [0000:49]--
> | |(hotplug slot)
> +-08.0-[0000:4a]--
> | |
> +-09.0-[0000:4b]--
> | |
> +-10.0-[0000:4c]--
> | |
> +-11.0-[0000:4d]--
> | |
> +-14.0-[0000:4e]--
> | |
> \-15.0-[0000:4f]--+-00.0 Intel Corporation 82576 Gigabit Network
> Connection
> | | (hotplug slot)
> \-00.1 Intel Corporation 82576 Gigabit Network Connection
>
>
> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
> ---
> drivers/pci/hotplug/pciehp.h | 2 +-
> drivers/pci/hotplug/pciehp_core.c | 11 ++---------
> drivers/pci/hotplug/pciehp_ctrl.c | 8 ++++----
> drivers/pci/hotplug/pciehp_hpc.c | 14 ++++++++++++--
> 4 files changed, 19 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
> index 26ffd3e..2c113de 100644
> --- a/drivers/pci/hotplug/pciehp.h
> +++ b/drivers/pci/hotplug/pciehp.h
> @@ -44,7 +44,6 @@ extern bool pciehp_poll_mode;
> extern int pciehp_poll_time;
> extern bool pciehp_debug;
> extern bool pciehp_force;
> -extern struct workqueue_struct *pciehp_wq;
>
> #define dbg(format, arg...)
> \
> do {
> \
> @@ -78,6 +77,7 @@ struct slot {
> struct hotplug_slot *hotplug_slot;
> struct delayed_work work; /* work for button event */
> struct mutex lock;
> + struct workqueue_struct *wq;
> };
>
> struct event_info {
> diff --git a/drivers/pci/hotplug/pciehp_core.c
> b/drivers/pci/hotplug/pciehp_core.c
> index 916bf4f..0914211 100644
> --- a/drivers/pci/hotplug/pciehp_core.c
> +++ b/drivers/pci/hotplug/pciehp_core.c
> @@ -42,7 +42,6 @@ bool pciehp_debug;
> bool pciehp_poll_mode;
> int pciehp_poll_time;
> bool pciehp_force;
> -struct workqueue_struct *pciehp_wq;
>
> #define DRIVER_VERSION "0.4"
> #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg
> Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
> @@ -340,18 +339,13 @@ static int __init pcied_init(void)
> {
> int retval = 0;
>
> - pciehp_wq = alloc_workqueue("pciehp", 0, 0);
> - if (!pciehp_wq)
> - return -ENOMEM;
> -
> pciehp_firmware_init();
> retval = pcie_port_service_register(&hpdriver_portdrv);
> dbg("pcie_port_service_register = %d\n", retval);
> info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
> - if (retval) {
> - destroy_workqueue(pciehp_wq);
> + if (retval)
> dbg("Failure to register service\n");
> - }
> +
> return retval;
> }
>
> @@ -359,7 +353,6 @@ static void __exit pcied_cleanup(void)
> {
> dbg("unload_pciehpd()\n");
> pcie_port_service_unregister(&hpdriver_portdrv);
> - destroy_workqueue(pciehp_wq);
> info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
> }
>
> diff --git a/drivers/pci/hotplug/pciehp_ctrl.c
> b/drivers/pci/hotplug/pciehp_ctrl.c
> index 27f4429..38f0186 100644
> --- a/drivers/pci/hotplug/pciehp_ctrl.c
> +++ b/drivers/pci/hotplug/pciehp_ctrl.c
> @@ -49,7 +49,7 @@ static int queue_interrupt_event(struct slot *p_slot,
> u32 event_type)
> info->p_slot = p_slot;
> INIT_WORK(&info->work, interrupt_event_handler);
>
> - queue_work(pciehp_wq, &info->work);
> + queue_work(p_slot->wq, &info->work);
>
> return 0;
> }
> @@ -344,7 +344,7 @@ void pciehp_queue_pushbutton_work(struct work_struct
> *work)
> kfree(info);
> goto out;
> }
> - queue_work(pciehp_wq, &info->work);
> + queue_work(p_slot->wq, &info->work);
> out:
> mutex_unlock(&p_slot->lock);
> }
> @@ -377,7 +377,7 @@ static void handle_button_press_event(struct slot
> *p_slot)
> if (ATTN_LED(ctrl))
> pciehp_set_attention_status(p_slot, 0);
>
> - queue_delayed_work(pciehp_wq, &p_slot->work, 5*HZ);
> + queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ);
> break;
> case BLINKINGOFF_STATE:
> case BLINKINGON_STATE:
> @@ -439,7 +439,7 @@ static void handle_surprise_event(struct slot *p_slot)
> else
> p_slot->state = POWERON_STATE;
>
> - queue_work(pciehp_wq, &info->work);
> + queue_work(p_slot->wq, &info->work);
> }
>
> static void interrupt_event_handler(struct work_struct *work)
> diff --git a/drivers/pci/hotplug/pciehp_hpc.c
> b/drivers/pci/hotplug/pciehp_hpc.c
> index 13b2eaf..8e5e571 100644
> --- a/drivers/pci/hotplug/pciehp_hpc.c
> +++ b/drivers/pci/hotplug/pciehp_hpc.c
> @@ -773,23 +773,33 @@ static void pcie_shutdown_notification(struct
> controller *ctrl)
> static int pcie_init_slot(struct controller *ctrl)
> {
> struct slot *slot;
> + char name[32];
>
> slot = kzalloc(sizeof(*slot), GFP_KERNEL);
> if (!slot)
> return -ENOMEM;
> -
> +
> + snprintf(name, sizeof(name), "pciehpd_%s",
> + pci_name(ctrl->pcie->port));
> + slot->wq = create_singlethread_workqueue(name);
> + if (!slot->wq)
> + goto abort;
> slot->ctrl = ctrl;
> mutex_init(&slot->lock);
> INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
> ctrl->slot = slot;
> return 0;
> +abort:
> + kfree(slot);
> + return -1;
> }
>
> static void pcie_cleanup_slot(struct controller *ctrl)
> {
> struct slot *slot = ctrl->slot;
> cancel_delayed_work(&slot->work);
> - flush_workqueue(pciehp_wq);
> + flush_workqueue(slot->wq);
> + destroy_workqueue(slot->wq);
> kfree(slot);
> }
>
> --
> 1.7.1
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue to avoid deadlock
2012-10-31 9:20 ` Kaneshige, Kenji
@ 2012-10-31 9:33 ` Yijing Wang
0 siblings, 0 replies; 5+ messages in thread
From: Yijing Wang @ 2012-10-31 9:33 UTC (permalink / raw)
To: Kaneshige, Kenji
Cc: Bjorn Helgaas, Yinghai Lu, Rafael, Rusty Russell,
Mauro Carvalho Chehab, Oliver Neukum, linux-pci@vger.kernel.org,
Hanjun Guo, jiang.liu@huawei.com
On 2012/10/31 17:20, Kaneshige, Kenji wrote:
> Let me confirm the problem. My understanding of the problem is below.
> Is my understanding correct?
>
Yes,exactly.
> - Your hardware has nested PCIe hotplug slots like below.
>
> --<slot A>--<Slot B>
>
> - Hot-removal request (attention button event) comes to <slot A>
> - Pciehp driver queue the hot-removal work
> - This hot-removal work try to remove <slot B>
> - To remove <slot B>, pciehp flush the pciehp_wq, but it never finishes
> because hot-removal work is in progress. ===> deadlock
>
> Regards,
> Kenji Kaneshige
>
>
>
>> -----Original Message-----
>> From: Yijing Wang [mailto:wangyijing@huawei.com]
>> Sent: Wednesday, October 31, 2012 4:11 PM
>> To: Bjorn Helgaas; Yinghai Lu; Kaneshige, Kenji/金重 憲治; Rafael; Rusty
>> Russell; Mauro Carvalho Chehab; Oliver Neukum
>> Cc: linux-pci@vger.kernel.org; Hanjun Guo; jiang.liu@huawei.com; Yijing
>> Wang
>> Subject: [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue
>> to avoid deadlock
>>
>> Currently, pciehp use global pciehp_wq to handle hotplug event from
>> hardware.
>> Hot remove path will be blocked if a hotplug slot connected a IO-BOX(composed
>> of PCIe
>> Switch and some slots which support hotplug, eg.PLX8696). The hot removed
>> work was queued
>> into pciehp_wq. But in the hot-remove path, pciehp driver would flush
>> pciehp_wq when
>> the pcie port(support pciehp) was removed. In this case the hot-remove path
>> blocked.
>> This patch remove the global pciehp_wq and create a new workqueue for every
>> slot to
>> avoid above problem.
>>
>> -+-[0000:40]-+-00.0-[0000:41]--
>> | +-01.0-[0000:42]--+-00.0 Intel Corporation 82576 Gigabit
>> Network Connection
>> | | \-00.1 Intel Corporation 82576 Gigabit
>> Network Connection
>> | +-03.0-[0000:43]----00.0 LSI Logic / Symbios Logic
>> SAS1064ET PCI-Express Fusion-MPT SAS
>> | +-04.0-[0000:44]--
>> | +-05.0-[0000:45]--
>> |
>> +-07.0-[0000:46-4f]----00.0-[0000:47-4f]--+-04.0-[0000:48-49]----00.0-
>> [0000:49]--
>> | |(hotplug slot)
>> +-08.0-[0000:4a]--
>> | |
>> +-09.0-[0000:4b]--
>> | |
>> +-10.0-[0000:4c]--
>> | |
>> +-11.0-[0000:4d]--
>> | |
>> +-14.0-[0000:4e]--
>> | |
>> \-15.0-[0000:4f]--+-00.0 Intel Corporation 82576 Gigabit Network
>> Connection
>> | | (hotplug slot)
>> \-00.1 Intel Corporation 82576 Gigabit Network Connection
>>
>>
>> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
>> ---
>> drivers/pci/hotplug/pciehp.h | 2 +-
>> drivers/pci/hotplug/pciehp_core.c | 11 ++---------
>> drivers/pci/hotplug/pciehp_ctrl.c | 8 ++++----
>> drivers/pci/hotplug/pciehp_hpc.c | 14 ++++++++++++--
>> 4 files changed, 19 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
>> index 26ffd3e..2c113de 100644
>> --- a/drivers/pci/hotplug/pciehp.h
>> +++ b/drivers/pci/hotplug/pciehp.h
>> @@ -44,7 +44,6 @@ extern bool pciehp_poll_mode;
>> extern int pciehp_poll_time;
>> extern bool pciehp_debug;
>> extern bool pciehp_force;
>> -extern struct workqueue_struct *pciehp_wq;
>>
>> #define dbg(format, arg...)
>> \
>> do {
>> \
>> @@ -78,6 +77,7 @@ struct slot {
>> struct hotplug_slot *hotplug_slot;
>> struct delayed_work work; /* work for button event */
>> struct mutex lock;
>> + struct workqueue_struct *wq;
>> };
>>
>> struct event_info {
>> diff --git a/drivers/pci/hotplug/pciehp_core.c
>> b/drivers/pci/hotplug/pciehp_core.c
>> index 916bf4f..0914211 100644
>> --- a/drivers/pci/hotplug/pciehp_core.c
>> +++ b/drivers/pci/hotplug/pciehp_core.c
>> @@ -42,7 +42,6 @@ bool pciehp_debug;
>> bool pciehp_poll_mode;
>> int pciehp_poll_time;
>> bool pciehp_force;
>> -struct workqueue_struct *pciehp_wq;
>>
>> #define DRIVER_VERSION "0.4"
>> #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg
>> Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
>> @@ -340,18 +339,13 @@ static int __init pcied_init(void)
>> {
>> int retval = 0;
>>
>> - pciehp_wq = alloc_workqueue("pciehp", 0, 0);
>> - if (!pciehp_wq)
>> - return -ENOMEM;
>> -
>> pciehp_firmware_init();
>> retval = pcie_port_service_register(&hpdriver_portdrv);
>> dbg("pcie_port_service_register = %d\n", retval);
>> info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
>> - if (retval) {
>> - destroy_workqueue(pciehp_wq);
>> + if (retval)
>> dbg("Failure to register service\n");
>> - }
>> +
>> return retval;
>> }
>>
>> @@ -359,7 +353,6 @@ static void __exit pcied_cleanup(void)
>> {
>> dbg("unload_pciehpd()\n");
>> pcie_port_service_unregister(&hpdriver_portdrv);
>> - destroy_workqueue(pciehp_wq);
>> info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
>> }
>>
>> diff --git a/drivers/pci/hotplug/pciehp_ctrl.c
>> b/drivers/pci/hotplug/pciehp_ctrl.c
>> index 27f4429..38f0186 100644
>> --- a/drivers/pci/hotplug/pciehp_ctrl.c
>> +++ b/drivers/pci/hotplug/pciehp_ctrl.c
>> @@ -49,7 +49,7 @@ static int queue_interrupt_event(struct slot *p_slot,
>> u32 event_type)
>> info->p_slot = p_slot;
>> INIT_WORK(&info->work, interrupt_event_handler);
>>
>> - queue_work(pciehp_wq, &info->work);
>> + queue_work(p_slot->wq, &info->work);
>>
>> return 0;
>> }
>> @@ -344,7 +344,7 @@ void pciehp_queue_pushbutton_work(struct work_struct
>> *work)
>> kfree(info);
>> goto out;
>> }
>> - queue_work(pciehp_wq, &info->work);
>> + queue_work(p_slot->wq, &info->work);
>> out:
>> mutex_unlock(&p_slot->lock);
>> }
>> @@ -377,7 +377,7 @@ static void handle_button_press_event(struct slot
>> *p_slot)
>> if (ATTN_LED(ctrl))
>> pciehp_set_attention_status(p_slot, 0);
>>
>> - queue_delayed_work(pciehp_wq, &p_slot->work, 5*HZ);
>> + queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ);
>> break;
>> case BLINKINGOFF_STATE:
>> case BLINKINGON_STATE:
>> @@ -439,7 +439,7 @@ static void handle_surprise_event(struct slot *p_slot)
>> else
>> p_slot->state = POWERON_STATE;
>>
>> - queue_work(pciehp_wq, &info->work);
>> + queue_work(p_slot->wq, &info->work);
>> }
>>
>> static void interrupt_event_handler(struct work_struct *work)
>> diff --git a/drivers/pci/hotplug/pciehp_hpc.c
>> b/drivers/pci/hotplug/pciehp_hpc.c
>> index 13b2eaf..8e5e571 100644
>> --- a/drivers/pci/hotplug/pciehp_hpc.c
>> +++ b/drivers/pci/hotplug/pciehp_hpc.c
>> @@ -773,23 +773,33 @@ static void pcie_shutdown_notification(struct
>> controller *ctrl)
>> static int pcie_init_slot(struct controller *ctrl)
>> {
>> struct slot *slot;
>> + char name[32];
>>
>> slot = kzalloc(sizeof(*slot), GFP_KERNEL);
>> if (!slot)
>> return -ENOMEM;
>> -
>> +
>> + snprintf(name, sizeof(name), "pciehpd_%s",
>> + pci_name(ctrl->pcie->port));
>> + slot->wq = create_singlethread_workqueue(name);
>> + if (!slot->wq)
>> + goto abort;
>> slot->ctrl = ctrl;
>> mutex_init(&slot->lock);
>> INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
>> ctrl->slot = slot;
>> return 0;
>> +abort:
>> + kfree(slot);
>> + return -1;
>> }
>>
>> static void pcie_cleanup_slot(struct controller *ctrl)
>> {
>> struct slot *slot = ctrl->slot;
>> cancel_delayed_work(&slot->work);
>> - flush_workqueue(pciehp_wq);
>> + flush_workqueue(slot->wq);
>> + destroy_workqueue(slot->wq);
>> kfree(slot);
>> }
>>
>> --
>> 1.7.1
>>
>
>
> .
>
--
Thanks!
Yijing
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue to avoid deadlock
2012-10-31 7:10 [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue to avoid deadlock Yijing Wang
2012-10-31 9:20 ` Kaneshige, Kenji
@ 2012-11-07 10:47 ` Kaneshige, Kenji
2012-11-08 1:16 ` Yijing Wang
1 sibling, 1 reply; 5+ messages in thread
From: Kaneshige, Kenji @ 2012-11-07 10:47 UTC (permalink / raw)
To: Yijing Wang, Bjorn Helgaas, Yinghai Lu, Rafael, Rusty Russell,
Mauro Carvalho Chehab, Oliver Neukum
Cc: linux-pci@vger.kernel.org, Hanjun Guo, jiang.liu@huawei.com
Hi Yijing,
I have some comments. Sorry for the delay.
<snip.>
> --- a/drivers/pci/hotplug/pciehp_hpc.c
> +++ b/drivers/pci/hotplug/pciehp_hpc.c
> @@ -773,23 +773,33 @@ static void pcie_shutdown_notification(struct controller *ctrl)
> static int pcie_init_slot(struct controller *ctrl)
> {
> struct slot *slot;
> + char name[32];
>
> slot = kzalloc(sizeof(*slot), GFP_KERNEL);
> if (!slot)
> return -ENOMEM;
> -
> +
> + snprintf(name, sizeof(name), "pciehpd_%s",
> + pci_name(ctrl->pcie->port));
The name of the threads seems to be cut off.
$ ps aux | grep pciehp
root 125 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:00]
root 126 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:00]
root 127 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:0b]
root 128 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:0b]
root 129 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:0b]
root 130 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:0b]
root 131 0.0 0.0 0 0 ? S< 18:55 0:00 [pciehpd_0000:1a]
root 132 0.0 0.0 0 0 ? S< 18:55 0:00 [pciehpd_0000:1a]
root 133 0.0 0.0 0 0 ? S< 18:55 0:00 [pciehpd_0000:1a]
root 134 0.0 0.0 0 0 ? S< 18:55 0:00 [pciehpd_0000:1a]
How about using slot name for the thread name?
<snip.>
>
> static void pcie_cleanup_slot(struct controller *ctrl)
> {
> struct slot *slot = ctrl->slot;
> cancel_delayed_work(&slot->work);
> - flush_workqueue(pciehp_wq);
> + flush_workqueue(slot->wq);
> + destroy_workqueue(slot->wq);
> kfree(slot);
> }
I think flush_workqueue() call is no longer required because
it is done in destroy_workqueue() code path.
Regards,
Kenji Kaneshige
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue to avoid deadlock
2012-11-07 10:47 ` Kaneshige, Kenji
@ 2012-11-08 1:16 ` Yijing Wang
0 siblings, 0 replies; 5+ messages in thread
From: Yijing Wang @ 2012-11-08 1:16 UTC (permalink / raw)
To: Kaneshige, Kenji
Cc: Bjorn Helgaas, Yinghai Lu, Rafael, Rusty Russell,
Mauro Carvalho Chehab, Oliver Neukum, linux-pci@vger.kernel.org,
Hanjun Guo, jiang.liu@huawei.com
On 2012/11/7 18:47, Kaneshige, Kenji wrote:
> Hi Yijing,
>
> I have some comments. Sorry for the delay.
>
> <snip.>
>
Hi Kaneshige,
Thanks for your review and comments very much!
I will update this patch and using slot name instead of device name, it's really a good suggestion.
Also I will remove the redundant flush_workqueue().
Thanks!
Yijing.
>> --- a/drivers/pci/hotplug/pciehp_hpc.c
>> +++ b/drivers/pci/hotplug/pciehp_hpc.c
>> @@ -773,23 +773,33 @@ static void pcie_shutdown_notification(struct controller *ctrl)
>> static int pcie_init_slot(struct controller *ctrl)
>> {
>> struct slot *slot;
>> + char name[32];
>>
>> slot = kzalloc(sizeof(*slot), GFP_KERNEL);
>> if (!slot)
>> return -ENOMEM;
>> -
>> +
>> + snprintf(name, sizeof(name), "pciehpd_%s",
>> + pci_name(ctrl->pcie->port));
>
> The name of the threads seems to be cut off.
>
> $ ps aux | grep pciehp
> root 125 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:00]
> root 126 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:00]
> root 127 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:0b]
> root 128 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:0b]
> root 129 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:0b]
> root 130 0.0 0.0 0 0 ? S< 18:54 0:00 [pciehpd_0000:0b]
> root 131 0.0 0.0 0 0 ? S< 18:55 0:00 [pciehpd_0000:1a]
> root 132 0.0 0.0 0 0 ? S< 18:55 0:00 [pciehpd_0000:1a]
> root 133 0.0 0.0 0 0 ? S< 18:55 0:00 [pciehpd_0000:1a]
> root 134 0.0 0.0 0 0 ? S< 18:55 0:00 [pciehpd_0000:1a]
>
> How about using slot name for the thread name?
>
> <snip.>
>
>>
>> static void pcie_cleanup_slot(struct controller *ctrl)
>> {
>> struct slot *slot = ctrl->slot;
>> cancel_delayed_work(&slot->work);
>> - flush_workqueue(pciehp_wq);
>> + flush_workqueue(slot->wq);
>> + destroy_workqueue(slot->wq);
>> kfree(slot);
>> }
>
> I think flush_workqueue() call is no longer required because
> it is done in destroy_workqueue() code path.
>
> Regards,
> Kenji Kaneshige
>
>
> .
>
--
Thanks!
Yijing
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-11-08 1:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-31 7:10 [RFC][PATCH] PCI, pciehp: make every slot have its own workqueue to avoid deadlock Yijing Wang
2012-10-31 9:20 ` Kaneshige, Kenji
2012-10-31 9:33 ` Yijing Wang
2012-11-07 10:47 ` Kaneshige, Kenji
2012-11-08 1:16 ` Yijing Wang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.