Commit 262303fe authored by Kenji Kaneshige's avatar Kenji Kaneshige Committed by Greg Kroah-Hartman

pciehp: fix wait command completion

This patch fixes this problem that pciehp driver will sleep
unnecessarily long when waiting for command completion. With this
patch, modprobe pciehp driver becomes very faster as follows for
instance.

  o Without this patch
    # time /sbin/modprobe pciehp

    real    0m4.976s
    user    0m0.000s
    sys     0m0.004s

  o With this patch
    # time /sbin/modprobe pciehp

    real    0m0.640s
    user    0m0.000s
    sys     0m0.004s
Signed-off-by: default avatarKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: default avatarKristen Carlson Accardi <kristen.c.accardi@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 44ef4cef
...@@ -100,6 +100,7 @@ struct controller { ...@@ -100,6 +100,7 @@ struct controller {
u16 vendor_id; u16 vendor_id;
u8 cap_base; u8 cap_base;
struct timer_list poll_timer; struct timer_list poll_timer;
volatile int cmd_busy;
}; };
#define INT_BUTTON_IGNORE 0 #define INT_BUTTON_IGNORE 0
......
...@@ -251,20 +251,21 @@ static void start_int_poll_timer(struct controller *ctrl, int sec) ...@@ -251,20 +251,21 @@ static void start_int_poll_timer(struct controller *ctrl, int sec)
static inline int pcie_wait_cmd(struct controller *ctrl) static inline int pcie_wait_cmd(struct controller *ctrl)
{ {
DECLARE_WAITQUEUE(wait, current); int retval = 0;
unsigned int msecs = pciehp_poll_mode ? 2500 : 1000;
add_wait_queue(&ctrl->queue, &wait); unsigned long timeout = msecs_to_jiffies(msecs);
if (!pciehp_poll_mode) int rc;
/* Sleep for up to 1 second */
msleep_interruptible(1000);
else
msleep_interruptible(2500);
remove_wait_queue(&ctrl->queue, &wait); rc = wait_event_interruptible_timeout(ctrl->queue,
if (signal_pending(current)) !ctrl->cmd_busy, timeout);
return -EINTR; if (!rc)
dbg("Command not completed in 1000 msec\n");
else if (rc < 0) {
retval = -EINTR;
info("Command was interrupted by a signal\n");
}
return 0; return retval;
} }
static int pcie_write_cmd(struct slot *slot, u16 cmd) static int pcie_write_cmd(struct slot *slot, u16 cmd)
...@@ -291,6 +292,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) ...@@ -291,6 +292,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
__FUNCTION__); __FUNCTION__);
} }
ctrl->cmd_busy = 1;
retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE));
if (retval) { if (retval) {
err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
...@@ -773,6 +775,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) ...@@ -773,6 +775,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
/* /*
* Command Complete Interrupt Pending * Command Complete Interrupt Pending
*/ */
ctrl->cmd_busy = 0;
wake_up_interruptible(&ctrl->queue); wake_up_interruptible(&ctrl->queue);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment