Skip to content

Commit

Permalink
pciehp: fix wait command completion
Browse files Browse the repository at this point in the history
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: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Kenji Kaneshige authored and Greg Kroah-Hartman committed Feb 7, 2007
1 parent 44ef4ce commit 262303f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
1 change: 1 addition & 0 deletions drivers/pci/hotplug/pciehp.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ struct controller {
u16 vendor_id;
u8 cap_base;
struct timer_list poll_timer;
volatile int cmd_busy;
};

#define INT_BUTTON_IGNORE 0
Expand Down
27 changes: 15 additions & 12 deletions drivers/pci/hotplug/pciehp_hpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,21 @@ static void start_int_poll_timer(struct controller *ctrl, int sec)

static inline int pcie_wait_cmd(struct controller *ctrl)
{
DECLARE_WAITQUEUE(wait, current);

add_wait_queue(&ctrl->queue, &wait);
if (!pciehp_poll_mode)
/* Sleep for up to 1 second */
msleep_interruptible(1000);
else
msleep_interruptible(2500);
int retval = 0;
unsigned int msecs = pciehp_poll_mode ? 2500 : 1000;
unsigned long timeout = msecs_to_jiffies(msecs);
int rc;

remove_wait_queue(&ctrl->queue, &wait);
if (signal_pending(current))
return -EINTR;
rc = wait_event_interruptible_timeout(ctrl->queue,
!ctrl->cmd_busy, timeout);
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)
Expand All @@ -291,6 +292,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
__FUNCTION__);
}

ctrl->cmd_busy = 1;
retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE));
if (retval) {
err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
Expand Down Expand Up @@ -773,6 +775,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
/*
* Command Complete Interrupt Pending
*/
ctrl->cmd_busy = 0;
wake_up_interruptible(&ctrl->queue);
}

Expand Down

0 comments on commit 262303f

Please sign in to comment.