diff --git a/drivers/block/swim.c b/drivers/block/swim.c index b5afd49..7d09955 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -332,7 +332,7 @@ static inline void swim_motor(struct swim __iomem *base, if (swim_readbit(base, MOTOR_ON)) break; current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_min_hrtimeout(); } } else if (action == OFF) { swim_action(base, MOTOR_OFF); @@ -351,7 +351,7 @@ static inline void swim_eject(struct swim __iomem *base) if (!swim_readbit(base, DISK_IN)) break; current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_min_hrtimeout(); } swim_select(base, RELAX); } @@ -375,7 +375,7 @@ static inline int swim_step(struct swim __iomem *base) for (wait = 0; wait < HZ; wait++) { current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_min_hrtimeout(); swim_select(base, RELAX); if (!swim_readbit(base, STEP)) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 683c2b6..75502f8 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -883,7 +883,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) * then host can communicate with new baudrate to controller */ set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS)); + schedule_msec_hrtimeout((BAUDRATE_SETTLE_TIMEOUT_MS)); set_current_state(TASK_INTERRUPTIBLE); return 0; diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index d8619998..75866dd 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2952,7 +2952,7 @@ static void cleanup_smi_msgs(ipmi_smi_t intf) /* Current message first, to preserve order */ while (intf->curr_msg && !list_empty(&intf->waiting_rcv_msgs)) { /* Wait for the message to clear out. */ - schedule_timeout(1); + schedule_min_hrtimeout(); } /* No need for locks, the interface is down. */ diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 5673fff..8bb6345 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -1190,7 +1190,7 @@ static int ssif_remove(struct i2c_client *client) /* make sure the driver is not looking for flags any more. */ while (ssif_info->ssif_state != SSIF_NORMAL) - schedule_timeout(1); + schedule_min_hrtimeout(); ssif_info->stopping = true; del_timer_sync(&ssif_info->retry_timer); diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 94006f9..8078a74 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c @@ -198,7 +198,7 @@ scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos) add_wait_queue(&sd->sd_rq, &wait); spin_unlock_irqrestore(&sd->sd_rlock, flags); - schedule_timeout(msecs_to_jiffies(SCDRV_TIMEOUT)); + schedule_msec_hrtimeout((SCDRV_TIMEOUT)); remove_wait_queue(&sd->sd_rq, &wait); if (signal_pending(current)) { @@ -294,7 +294,7 @@ scdrv_write(struct file *file, const char __user *buf, add_wait_queue(&sd->sd_wq, &wait); spin_unlock_irqrestore(&sd->sd_wlock, flags); - schedule_timeout(msecs_to_jiffies(SCDRV_TIMEOUT)); + schedule_msec_hrtimeout((SCDRV_TIMEOUT)); remove_wait_queue(&sd->sd_wq, &wait); if (signal_pending(current)) { diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 1f266d7..9565702f 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -280,7 +280,7 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv, if (gmbus2 & (GMBUS_SATOER | gmbus2_status)) break; - schedule_timeout(1); + schedule_min_hrtimeout(); } finish_wait(&dev_priv->gmbus_wait_queue, &wait); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index b6a0806..b5b02cf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c @@ -235,7 +235,7 @@ static int vmw_fifo_wait_noirq(struct vmw_private *dev_priv, DRM_ERROR("SVGA device lockup.\n"); break; } - schedule_timeout(1); + schedule_min_hrtimeout(); if (interruptible && signal_pending(current)) { ret = -ERESTARTSYS; break; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c index 0c7e172..4c1555c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c @@ -156,7 +156,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, break; } if (lazy) - schedule_timeout(1); + schedule_min_hrtimeout(); else if ((++count & 0x0F) == 0) { /** * FIXME: Use schedule_hr_timeout here for diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index 15aa49d..991e8a7 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -238,7 +238,7 @@ static ssize_t acc_show_power(struct device *dev, prev_ptsc[cu] = data->cpu_sw_pwr_ptsc[cu]; } - leftover = schedule_timeout_interruptible(msecs_to_jiffies(data->power_period)); + leftover = schedule_msec_hrtimeout_interruptible((data->power_period)); if (leftover) return 0; diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 04598ae..a8c095d 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -282,11 +282,7 @@ static void tsl2563_wait_adc(struct tsl2563_chip *chip) default: delay = 402; } - /* - * TODO: Make sure that we wait at least required delay but why we - * have to extend it one tick more? - */ - schedule_timeout_interruptible(msecs_to_jiffies(delay) + 2); + schedule_msec_hrtimeout_interruptible(delay + 1); } static int tsl2563_adjust_gainlevel(struct tsl2563_chip *chip, u16 adc) diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c index 503b7c4..d790a90 100644 --- a/drivers/media/i2c/msp3400-driver.c +++ b/drivers/media/i2c/msp3400-driver.c @@ -184,7 +184,7 @@ static int msp_read(struct i2c_client *client, int dev, int addr) break; v4l_warn(client, "I/O error #%d (read 0x%02x/0x%02x)\n", err, dev, addr); - schedule_timeout_interruptible(msecs_to_jiffies(10)); + schedule_msec_hrtimeout_interruptible((10)); } if (err == 3) { v4l_warn(client, "resetting chip, sound will go off.\n"); @@ -225,7 +225,7 @@ static int msp_write(struct i2c_client *client, int dev, int addr, int val) break; v4l_warn(client, "I/O error #%d (write 0x%02x/0x%02x)\n", err, dev, addr); - schedule_timeout_interruptible(msecs_to_jiffies(10)); + schedule_msec_hrtimeout_interruptible((10)); } if (err == 3) { v4l_warn(client, "resetting chip, sound will go off.\n"); diff --git a/drivers/media/pci/cx18/cx18-gpio.c b/drivers/media/pci/cx18/cx18-gpio.c index 38dc6b8..3cd3098 100644 --- a/drivers/media/pci/cx18/cx18-gpio.c +++ b/drivers/media/pci/cx18/cx18-gpio.c @@ -95,11 +95,11 @@ static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi, /* Assert */ gpio_update(cx, mask, ~active_lo); - schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs)); + schedule_msec_hrtimeout_uninterruptible((assert_msecs)); /* Deassert */ gpio_update(cx, mask, ~active_hi); - schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs)); + schedule_msec_hrtimeout_uninterruptible((recovery_msecs)); } /* diff --git a/drivers/media/pci/ivtv/ivtv-gpio.c b/drivers/media/pci/ivtv/ivtv-gpio.c index f752f39..23372af6 100644 --- a/drivers/media/pci/ivtv/ivtv-gpio.c +++ b/drivers/media/pci/ivtv/ivtv-gpio.c @@ -117,7 +117,7 @@ void ivtv_reset_ir_gpio(struct ivtv *itv) curout = (curout & ~0xF) | 1; write_reg(curout, IVTV_REG_GPIO_OUT); /* We could use something else for smaller time */ - schedule_timeout_interruptible(msecs_to_jiffies(1)); + schedule_msec_hrtimeout_interruptible((1)); curout |= 2; write_reg(curout, IVTV_REG_GPIO_OUT); curdir &= ~0x80; @@ -137,11 +137,11 @@ int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value) curout = read_reg(IVTV_REG_GPIO_OUT); curout &= ~(1 << itv->card->xceive_pin); write_reg(curout, IVTV_REG_GPIO_OUT); - schedule_timeout_interruptible(msecs_to_jiffies(1)); + schedule_msec_hrtimeout_interruptible((1)); curout |= 1 << itv->card->xceive_pin; write_reg(curout, IVTV_REG_GPIO_OUT); - schedule_timeout_interruptible(msecs_to_jiffies(1)); + schedule_msec_hrtimeout_interruptible((1)); return 0; } diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 2dc4b20..8e061cf 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -1151,7 +1151,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std) TASK_UNINTERRUPTIBLE); if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100) break; - schedule_timeout(msecs_to_jiffies(25)); + schedule_msec_hrtimeout((25)); } finish_wait(&itv->vsync_waitq, &wait); mutex_lock(&itv->serialize_lock); diff --git a/drivers/media/pci/ivtv/ivtv-streams.c b/drivers/media/pci/ivtv/ivtv-streams.c index d27c6df..e9ffc4e 100644 --- a/drivers/media/pci/ivtv/ivtv-streams.c +++ b/drivers/media/pci/ivtv/ivtv-streams.c @@ -834,7 +834,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && time_before(jiffies, then + msecs_to_jiffies(2000))) { - schedule_timeout(msecs_to_jiffies(10)); + schedule_msec_hrtimeout((10)); } /* To convert jiffies to ms, we must multiply by 1000 diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index c2927fd..bdee269 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -382,7 +382,7 @@ static int vidioc_s_hw_freq_seek(struct file *file, void *priv, retval = -ENODATA; break; } - if (schedule_timeout_interruptible(msecs_to_jiffies(10))) { + if (schedule_msec_hrtimeout_interruptible((10))) { retval = -ERESTARTSYS; break; } diff --git a/drivers/media/radio/radio-tea5777.c b/drivers/media/radio/radio-tea5777.c index 83fe7ab..aaae5fa 100644 --- a/drivers/media/radio/radio-tea5777.c +++ b/drivers/media/radio/radio-tea5777.c @@ -249,7 +249,7 @@ static int radio_tea5777_update_read_reg(struct radio_tea5777 *tea, int wait) } if (wait) { - if (schedule_timeout_interruptible(msecs_to_jiffies(wait))) + if (schedule_msec_hrtimeout_interruptible((wait))) return -ERESTARTSYS; } diff --git a/drivers/media/radio/tea575x.c b/drivers/media/radio/tea575x.c index 4dc2067..29f4416 100644 --- a/drivers/media/radio/tea575x.c +++ b/drivers/media/radio/tea575x.c @@ -416,7 +416,7 @@ int snd_tea575x_s_hw_freq_seek(struct file *file, struct snd_tea575x *tea, for (;;) { if (time_after(jiffies, timeout)) break; - if (schedule_timeout_interruptible(msecs_to_jiffies(10))) { + if (schedule_msec_hrtimeout_interruptible((10))) { /* some signal arrived, stop search */ tea->val &= ~TEA575X_BIT_SEARCH; snd_tea575x_set_freq(tea); diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index 9ab9ec4..a72685d 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c @@ -253,7 +253,7 @@ unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync) break; /* yield to other processes */ set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + schedule_min_hrtimeout(); } return UCB_ADC_DAT(val); diff --git a/drivers/misc/panel.c b/drivers/misc/panel.c index 6030ac5..f0c1a101 100644 --- a/drivers/misc/panel.c +++ b/drivers/misc/panel.c @@ -760,7 +760,7 @@ static void long_sleep(int ms) if (in_interrupt()) mdelay(ms); else - schedule_timeout_interruptible(msecs_to_jiffies(ms)); + schedule_msec_hrtimeout_interruptible((ms)); } /* diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c index 128d561..38e68e9 100644 --- a/drivers/misc/sgi-xp/xpc_channel.c +++ b/drivers/misc/sgi-xp/xpc_channel.c @@ -837,7 +837,7 @@ xpc_allocate_msg_wait(struct xpc_channel *ch) atomic_inc(&ch->n_on_msg_allocate_wq); prepare_to_wait(&ch->msg_allocate_wq, &wait, TASK_INTERRUPTIBLE); - ret = schedule_timeout(1); + ret = schedule_min_hrtimeout(); finish_wait(&ch->msg_allocate_wq, &wait); atomic_dec(&ch->n_on_msg_allocate_wq); diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index ddabce7..67fb5ce 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -944,7 +944,7 @@ static void cfhsi_wake_down(struct work_struct *work) break; set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + schedule_min_hrtimeout(); retry--; } diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index 838545c..34f8972 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -250,7 +250,7 @@ static int pcan_usb_write_mode(struct peak_usb_device *dev, u8 onoff) } else { /* the PCAN-USB needs time to init */ set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(PCAN_USB_STARTUP_TIMEOUT)); + schedule_msec_hrtimeout((PCAN_USB_STARTUP_TIMEOUT)); } return err; diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 6a9d474..a9939ed 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2361,7 +2361,7 @@ static void lan78xx_terminate_urbs(struct lan78xx_net *dev) while (!skb_queue_empty(&dev->rxq) && !skb_queue_empty(&dev->txq) && !skb_queue_empty(&dev->done)) { - schedule_timeout(msecs_to_jiffies(UNLINK_TIMEOUT_MS)); + schedule_msec_hrtimeout((UNLINK_TIMEOUT_MS)); set_current_state(TASK_UNINTERRUPTIBLE); netif_dbg(dev, ifdown, dev->net, "waited for %d urb completions\n", temp); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 3bfb592..4dfe132 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -769,7 +769,7 @@ static void wait_skb_queue_empty(struct sk_buff_head *q) spin_lock_irqsave(&q->lock, flags); while (!skb_queue_empty(q)) { spin_unlock_irqrestore(&q->lock, flags); - schedule_timeout(msecs_to_jiffies(UNLINK_TIMEOUT_MS)); + schedule_msec_hrtimeout((UNLINK_TIMEOUT_MS)); set_current_state(TASK_UNINTERRUPTIBLE); spin_lock_irqsave(&q->lock, flags); } diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index bfa542c..c6759c5 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -830,7 +830,7 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv, * doesn't seem to have as many firmware restart cycles... * * As a test, we're sticking in a 1/100s delay here */ - schedule_timeout_uninterruptible(msecs_to_jiffies(10)); + schedule_msec_hrtimeout_uninterruptible((10)); return 0; @@ -1281,7 +1281,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv) IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n"); i = 5000; do { - schedule_timeout_uninterruptible(msecs_to_jiffies(40)); + schedule_msec_hrtimeout_uninterruptible((40)); /* Todo... wait for sync command ... */ read_register(priv->net_dev, IPW_REG_INTA, &inta); diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c index 6a50f20..8e1dd94 100644 --- a/drivers/ntb/test/ntb_perf.c +++ b/drivers/ntb/test/ntb_perf.c @@ -306,7 +306,7 @@ static int perf_move_data(struct pthr_ctx *pctx, char __iomem *dst, char *src, if (unlikely((jiffies - last_sleep) > 5 * HZ)) { last_sleep = jiffies; set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + schedule_min_hrtimeout(); } if (unlikely(kthread_should_stop())) diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c index f9fd4b3..00ad2f3 100644 --- a/drivers/parport/ieee1284.c +++ b/drivers/parport/ieee1284.c @@ -215,7 +215,7 @@ int parport_wait_peripheral(struct parport *port, /* parport_wait_event didn't time out, but the * peripheral wasn't actually ready either. * Wait for another 10ms. */ - schedule_timeout_interruptible(msecs_to_jiffies(10)); + schedule_msec_hrtimeout_interruptible((10)); } } diff --git a/drivers/parport/ieee1284_ops.c b/drivers/parport/ieee1284_ops.c index 2e21af4..da5f240 100644 --- a/drivers/parport/ieee1284_ops.c +++ b/drivers/parport/ieee1284_ops.c @@ -536,7 +536,7 @@ size_t parport_ieee1284_ecp_read_data (struct parport *port, /* Yield the port for a while. */ if (count && dev->port->irq != PARPORT_IRQ_NONE) { parport_release (dev); - schedule_timeout_interruptible(msecs_to_jiffies(40)); + schedule_msec_hrtimeout_interruptible((40)); parport_claim_or_block (dev); } else diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 55663b3..0363fed 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -812,7 +812,7 @@ static int ips_adjust(void *data) ips_gpu_lower(ips); sleep: - schedule_timeout_interruptible(msecs_to_jiffies(IPS_ADJUST_PERIOD)); + schedule_msec_hrtimeout_interruptible((IPS_ADJUST_PERIOD)); } while (!kthread_should_stop()); dev_dbg(&ips->dev->dev, "ips-adjust thread stopped\n"); @@ -991,7 +991,7 @@ static int ips_monitor(void *data) seqno_timestamp = get_jiffies_64(); old_cpu_power = thm_readl(THM_CEC); - schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD)); + schedule_msec_hrtimeout_interruptible((IPS_SAMPLE_PERIOD)); /* Collect an initial average */ for (i = 0; i < IPS_SAMPLE_COUNT; i++) { @@ -1018,7 +1018,7 @@ static int ips_monitor(void *data) mchp_samples[i] = mchp; } - schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD)); + schedule_msec_hrtimeout_interruptible((IPS_SAMPLE_PERIOD)); if (kthread_should_stop()) break; } @@ -1045,7 +1045,7 @@ static int ips_monitor(void *data) * us to reduce the sample frequency if the CPU and GPU are idle. */ old_cpu_power = thm_readl(THM_CEC); - schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD)); + schedule_msec_hrtimeout_interruptible((IPS_SAMPLE_PERIOD)); last_sample_period = IPS_SAMPLE_PERIOD; setup_deferrable_timer_on_stack(&timer, monitor_timeout, diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c index fa247de..f1a28d8 100644 --- a/drivers/rtc/rtc-wm8350.c +++ b/drivers/rtc/rtc-wm8350.c @@ -121,7 +121,7 @@ static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm) /* Wait until confirmation of stopping */ do { rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); - schedule_timeout_uninterruptible(msecs_to_jiffies(1)); + schedule_msec_hrtimeout_uninterruptible((1)); } while (--retries && !(rtc_ctrl & WM8350_RTC_STS)); if (!retries) { @@ -204,7 +204,7 @@ static int wm8350_rtc_stop_alarm(struct wm8350 *wm8350) /* Wait until confirmation of stopping */ do { rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); - schedule_timeout_uninterruptible(msecs_to_jiffies(1)); + schedule_msec_hrtimeout_uninterruptible((1)); } while (retries-- && !(rtc_ctrl & WM8350_RTC_ALMSTS)); if (!(rtc_ctrl & WM8350_RTC_ALMSTS)) @@ -227,7 +227,7 @@ static int wm8350_rtc_start_alarm(struct wm8350 *wm8350) /* Wait until confirmation */ do { rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); - schedule_timeout_uninterruptible(msecs_to_jiffies(1)); + schedule_msec_hrtimeout_uninterruptible((1)); } while (retries-- && rtc_ctrl & WM8350_RTC_ALMSTS); if (rtc_ctrl & WM8350_RTC_ALMSTS) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index d9fd2f8..ea44afd 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -217,7 +217,7 @@ int fnic_fw_reset_handler(struct fnic *fnic) /* wait for io cmpl */ while (atomic_read(&fnic->in_flight)) - schedule_timeout(msecs_to_jiffies(1)); + schedule_msec_hrtimeout((1)); spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); @@ -2193,7 +2193,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, } } - schedule_timeout(msecs_to_jiffies(2 * fnic->config.ed_tov)); + schedule_msec_hrtimeout((2 * fnic->config.ed_tov)); /* walk again to check, if IOs are still pending in fw */ if (fnic_is_abts_pending(fnic, lr_sc)) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index d197aa1..8e2fd7b 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5105,7 +5105,7 @@ lpfc_reset_flush_io_context(struct lpfc_vport *vport, uint16_t tgt_id, tgt_id, lun_id, context); later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; while (time_after(later, jiffies) && cnt) { - schedule_timeout_uninterruptible(msecs_to_jiffies(20)); + schedule_msec_hrtimeout_uninterruptible((20)); cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context); } if (cnt) { diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c index abada16..0bf30dc 100644 --- a/drivers/scsi/snic/snic_scsi.c +++ b/drivers/scsi/snic/snic_scsi.c @@ -2356,7 +2356,7 @@ snic_reset(struct Scsi_Host *shost, struct scsi_cmnd *sc) /* Wait for all the IOs that are entered in Qcmd */ while (atomic_read(&snic->ios_inflight)) - schedule_timeout(msecs_to_jiffies(1)); + schedule_msec_hrtimeout((1)); ret = snic_issue_hba_reset(snic, sc); if (ret) { diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 0f97d7b..1e1dccb 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -4611,7 +4611,7 @@ static int cs5529_wait_for_idle(struct comedi_device *dev) if ((status & NI67XX_CAL_STATUS_BUSY) == 0) break; set_current_state(TASK_INTERRUPTIBLE); - if (schedule_timeout(1)) + if (schedule_min_hrtimeout()) return -EIO; } if (i == timeout) { diff --git a/drivers/staging/lustre/lnet/lnet/lib-eq.c b/drivers/staging/lustre/lnet/lnet/lib-eq.c index d05c6cc..3f62b6f 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-eq.c +++ b/drivers/staging/lustre/lnet/lnet/lib-eq.c @@ -328,7 +328,7 @@ __must_hold(&the_lnet.ln_eq_wait_lock) schedule(); } else { now = jiffies; - schedule_timeout(msecs_to_jiffies(tms)); + schedule_msec_hrtimeout((tms)); tms -= jiffies_to_msecs(jiffies - now); if (tms < 0) /* no more wait but may have new event */ tms = 0; diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index 25d095a..38a38cc 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -534,7 +534,7 @@ static int rtsx_polling_thread(void *__dev) for (;;) { set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(POLLING_INTERVAL)); + schedule_msec_hrtimeout((POLLING_INTERVAL)); /* lock the device pointers */ mutex_lock(&(dev->dev_mutex)); diff --git a/drivers/staging/speakup/speakup_acntpc.c b/drivers/staging/speakup/speakup_acntpc.c index efb791b..fd02fb2 100644 --- a/drivers/staging/speakup/speakup_acntpc.c +++ b/drivers/staging/speakup/speakup_acntpc.c @@ -204,7 +204,7 @@ static void do_catch_up(struct spk_synth *synth) full_time_val = full_time->u.n.value; spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (synth_full()) { - schedule_timeout(msecs_to_jiffies(full_time_val)); + schedule_msec_hrtimeout((full_time_val)); continue; } set_current_state(TASK_RUNNING); @@ -232,7 +232,7 @@ static void do_catch_up(struct spk_synth *synth) jiffy_delta_val = jiffy_delta->u.n.value; delay_time_val = delay_time->u.n.value; spin_unlock_irqrestore(&speakup_info.spinlock, flags); - schedule_timeout(msecs_to_jiffies(delay_time_val)); + schedule_msec_hrtimeout((delay_time_val)); jiff_max = jiffies+jiffy_delta_val; } } diff --git a/drivers/staging/speakup/speakup_apollo.c b/drivers/staging/speakup/speakup_apollo.c index 3cbc8a7..3c17854 100644 --- a/drivers/staging/speakup/speakup_apollo.c +++ b/drivers/staging/speakup/speakup_apollo.c @@ -172,7 +172,7 @@ static void do_catch_up(struct spk_synth *synth) outb(UART_MCR_DTR, speakup_info.port_tts + UART_MCR); outb(UART_MCR_DTR | UART_MCR_RTS, speakup_info.port_tts + UART_MCR); - schedule_timeout(msecs_to_jiffies(full_time_val)); + schedule_msec_hrtimeout((full_time_val)); continue; } if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) { diff --git a/drivers/staging/speakup/speakup_decext.c b/drivers/staging/speakup/speakup_decext.c index 1a5cf3d..fa2b4e1 100644 --- a/drivers/staging/speakup/speakup_decext.c +++ b/drivers/staging/speakup/speakup_decext.c @@ -186,7 +186,7 @@ static void do_catch_up(struct spk_synth *synth) if (ch == '\n') ch = 0x0D; if (synth_full() || !spk_serial_out(ch)) { - schedule_timeout(msecs_to_jiffies(delay_time_val)); + schedule_msec_hrtimeout((delay_time_val)); continue; } set_current_state(TASK_RUNNING); diff --git a/drivers/staging/speakup/speakup_decpc.c b/drivers/staging/speakup/speakup_decpc.c index d6479bd..f7554bf 100644 --- a/drivers/staging/speakup/speakup_decpc.c +++ b/drivers/staging/speakup/speakup_decpc.c @@ -403,7 +403,7 @@ static void do_catch_up(struct spk_synth *synth) if (ch == '\n') ch = 0x0D; if (dt_sendchar(ch)) { - schedule_timeout(msecs_to_jiffies(delay_time_val)); + schedule_msec_hrtimeout((delay_time_val)); continue; } set_current_state(TASK_RUNNING); diff --git a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c index 7646567..639192e 100644 --- a/drivers/staging/speakup/speakup_dectlk.c +++ b/drivers/staging/speakup/speakup_dectlk.c @@ -251,7 +251,7 @@ static void do_catch_up(struct spk_synth *synth) if (ch == '\n') ch = 0x0D; if (synth_full_val || !spk_serial_out(ch)) { - schedule_timeout(msecs_to_jiffies(delay_time_val)); + schedule_msec_hrtimeout((delay_time_val)); continue; } set_current_state(TASK_RUNNING); diff --git a/drivers/staging/speakup/speakup_dtlk.c b/drivers/staging/speakup/speakup_dtlk.c index 38aa401..1640519 100644 --- a/drivers/staging/speakup/speakup_dtlk.c +++ b/drivers/staging/speakup/speakup_dtlk.c @@ -217,7 +217,7 @@ static void do_catch_up(struct spk_synth *synth) delay_time_val = delay_time->u.n.value; spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (synth_full()) { - schedule_timeout(msecs_to_jiffies(delay_time_val)); + schedule_msec_hrtimeout((delay_time_val)); continue; } set_current_state(TASK_RUNNING); @@ -233,7 +233,7 @@ static void do_catch_up(struct spk_synth *synth) delay_time_val = delay_time->u.n.value; jiffy_delta_val = jiffy_delta->u.n.value; spin_unlock_irqrestore(&speakup_info.spinlock, flags); - schedule_timeout(msecs_to_jiffies(delay_time_val)); + schedule_msec_hrtimeout((delay_time_val)); jiff_max = jiffies + jiffy_delta_val; } } diff --git a/drivers/staging/speakup/speakup_keypc.c b/drivers/staging/speakup/speakup_keypc.c index 5e2170b..30b5df7 100644 --- a/drivers/staging/speakup/speakup_keypc.c +++ b/drivers/staging/speakup/speakup_keypc.c @@ -206,7 +206,7 @@ spin_lock_irqsave(&speakup_info.spinlock, flags); full_time_val = full_time->u.n.value; spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (synth_full()) { - schedule_timeout(msecs_to_jiffies(full_time_val)); + schedule_msec_hrtimeout((full_time_val)); continue; } set_current_state(TASK_RUNNING); @@ -239,7 +239,7 @@ spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; delay_time_val = delay_time->u.n.value; spin_unlock_irqrestore(&speakup_info.spinlock, flags); - schedule_timeout(msecs_to_jiffies(delay_time_val)); + schedule_msec_hrtimeout((delay_time_val)); jiff_max = jiffies+jiffy_delta_val; } } diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c index 4f462c3..66af521 100644 --- a/drivers/staging/speakup/synth.c +++ b/drivers/staging/speakup/synth.c @@ -119,7 +119,7 @@ void spk_do_catch_up(struct spk_synth *synth) if (ch == '\n') ch = synth->procspeech; if (!spk_serial_out(ch)) { - schedule_timeout(msecs_to_jiffies(full_time_val)); + schedule_msec_hrtimeout((full_time_val)); continue; } if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) { diff --git a/drivers/staging/unisys/visorbus/periodic_work.c b/drivers/staging/unisys/visorbus/periodic_work.c index 00b1527..b930287 100644 --- a/drivers/staging/unisys/visorbus/periodic_work.c +++ b/drivers/staging/unisys/visorbus/periodic_work.c @@ -192,7 +192,7 @@ bool visor_periodic_work_stop(struct periodic_work *pw) } if (pw->is_scheduled) { write_unlock(&pw->lock); - schedule_timeout_interruptible(msecs_to_jiffies(10)); + schedule_msec_hrtimeout_interruptible((10)); write_lock(&pw->lock); } else { pw->want_to_stop = false; diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index a28388d..9bee76c 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -507,7 +507,7 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout) } set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&devdata->priv_lock, flags); - wait += schedule_timeout(msecs_to_jiffies(10)); + wait += schedule_msec_hrtimeout((10)); spin_lock_irqsave(&devdata->priv_lock, flags); } @@ -518,7 +518,7 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout) while (1) { set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&devdata->priv_lock, flags); - schedule_timeout(msecs_to_jiffies(10)); + schedule_msec_hrtimeout((10)); spin_lock_irqsave(&devdata->priv_lock, flags); if (atomic_read(&devdata->usage)) break; @@ -650,7 +650,7 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout) } set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&devdata->priv_lock, flags); - wait += schedule_timeout(msecs_to_jiffies(10)); + wait += schedule_msec_hrtimeout((10)); spin_lock_irqsave(&devdata->priv_lock, flags); } diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 62bf4fe..058bdd1 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -446,7 +446,7 @@ static int tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) pr_debug("sleeping for ring space\n"); spin_unlock_irq(&udev->cmdr_lock); - ret = schedule_timeout(msecs_to_jiffies(TCMU_TIME_OUT)); + ret = schedule_msec_hrtimeout((TCMU_TIME_OUT)); finish_wait(&udev->wait_cmdr, &__wait); if (!ret) { pr_warn("tcmu: command timed out\n"); diff --git a/drivers/video/fbdev/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c index a4ee65b..cf38bcb 100644 --- a/drivers/video/fbdev/omap/hwa742.c +++ b/drivers/video/fbdev/omap/hwa742.c @@ -926,7 +926,7 @@ static void hwa742_resume(void) if (hwa742_read_reg(HWA742_PLL_DIV_REG) & (1 << 7)) break; set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(5)); + schedule_msec_hrtimeout((5)); } hwa742_set_update_mode(hwa742.update_mode_before_suspend); } diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c index 2c0487f..022b8f4 100644 --- a/drivers/video/fbdev/pxafb.c +++ b/drivers/video/fbdev/pxafb.c @@ -1287,7 +1287,7 @@ static int pxafb_smart_thread(void *arg) mutex_unlock(&fbi->ctrlr_lock); set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(30)); + schedule_msec_hrtimeout((30)); } pr_debug("%s(): task ending\n", __func__); diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index 5297678..87bd28f 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c @@ -129,7 +129,7 @@ static int afs_vlocation_access_vl_by_id(struct afs_vlocation *vl, if (vl->upd_busy_cnt > 1) { /* second+ BUSY - sleep a little bit */ set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); + schedule_min_hrtimeout(); } continue; } diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 665da8f..85d9b5a 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -5945,7 +5945,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) if (flush != BTRFS_RESERVE_NO_FLUSH && btrfs_transaction_in_commit(root->fs_info)) - schedule_timeout(1); + schedule_min_hrtimeout(); if (delalloc_lock) mutex_lock(&BTRFS_I(inode)->delalloc_mutex); diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 359ee86..12955ed 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c @@ -89,7 +89,7 @@ again: btrfs_release_path(path); root->ino_cache_progress = last; up_read(&fs_info->commit_root_sem); - schedule_timeout(1); + schedule_min_hrtimeout(); goto again; } else continue; diff --git a/include/linux/sched.h b/include/linux/sched.h index 7b9e719..62dd304 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -437,6 +437,12 @@ extern signed long schedule_timeout_interruptible(signed long timeout); extern signed long schedule_timeout_killable(signed long timeout); extern signed long schedule_timeout_uninterruptible(signed long timeout); extern signed long schedule_timeout_idle(signed long timeout); + +extern signed long schedule_msec_hrtimeout(signed long timeout); +extern signed long schedule_min_hrtimeout(void); +extern signed long schedule_msec_hrtimeout_interruptible(signed long timeout); +extern signed long schedule_msec_hrtimeout_uninterruptible(signed long timeout); + asmlinkage void schedule(void); extern void schedule_preempt_disabled(void); diff --git a/kernel/sched/MuQSS.c b/kernel/sched/MuQSS.c index f66a3da..a8480fc 100644 --- a/kernel/sched/MuQSS.c +++ b/kernel/sched/MuQSS.c @@ -137,7 +137,7 @@ void print_scheduler_version(void) { - printk(KERN_INFO "MuQSS CPU scheduler v0.120 by Con Kolivas.\n"); + printk(KERN_INFO "MuQSS CPU scheduler v0.135 by Con Kolivas.\n"); } /* @@ -752,6 +752,13 @@ static inline bool task_queued(struct task_struct *p) static void enqueue_task(struct rq *rq, struct task_struct *p, int flags); static inline void resched_if_idle(struct rq *rq); +/* Dodgy workaround till we figure out where the softirqs are going */ +static inline void do_pending_softirq(struct rq *rq, struct task_struct *next) +{ + if (unlikely(next == rq->idle && local_softirq_pending() && !in_interrupt())) + do_softirq_own_stack(); +} + static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) { #ifdef CONFIG_SMP @@ -806,7 +813,11 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) raw_spin_unlock(&prev->pi_lock); } #endif - raw_spin_unlock_irq(&rq->lock); + rq_unlock(rq); + + do_pending_softirq(rq, current); + + local_irq_enable(); } static inline bool deadline_before(u64 deadline, u64 time) @@ -2548,7 +2559,7 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev, * past. prev == current is still correct but we need to recalculate this_rq * because prev may have moved to another CPU. */ -static struct rq *finish_task_switch(struct task_struct *prev) +static void finish_task_switch(struct task_struct *prev) __releases(rq->lock) { struct rq *rq = this_rq(); @@ -2601,7 +2612,6 @@ static struct rq *finish_task_switch(struct task_struct *prev) kprobe_flush_task(prev); put_task_struct(prev); } - return rq; } /** @@ -2609,10 +2619,7 @@ static struct rq *finish_task_switch(struct task_struct *prev) * @prev: the thread we just switched away from. */ asmlinkage __visible void schedule_tail(struct task_struct *prev) - __releases(rq->lock) { - struct rq *rq; - /* * New tasks start with FORK_PREEMPT_COUNT, see there and * finish_task_switch() for details. @@ -2622,7 +2629,7 @@ asmlinkage __visible void schedule_tail(struct task_struct *prev) * PREEMPT_COUNT kernels). */ - rq = finish_task_switch(prev); + finish_task_switch(prev); preempt_enable(); if (current->set_child_tid) @@ -2632,7 +2639,7 @@ asmlinkage __visible void schedule_tail(struct task_struct *prev) /* * context_switch - switch to the new MM and the new thread's register state. */ -static __always_inline struct rq * +static __always_inline void context_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next) { @@ -2672,7 +2679,7 @@ context_switch(struct rq *rq, struct task_struct *prev, switch_to(prev, next, prev); barrier(); - return finish_task_switch(prev); + finish_task_switch(prev); } /* @@ -3492,6 +3499,12 @@ static inline struct task_struct * is locked so entries will always be accurate. */ if (!sched_interactive) { + /* + * Don't reschedule balance across nodes unless the CPU + * is idle. + */ + if (edt != idle && rq->cpu_locality[other_rq->cpu] > 3) + break; if (entries <= best_entries) continue; } else if (!entries) @@ -3516,8 +3529,8 @@ static inline struct task_struct key = other_rq->node.next[0]->key; /* Reevaluate key after locking */ if (unlikely(key >= best_key)) { - if (i) - unlock_rq(other_rq); + /* This will always be when rq != other_rq */ + unlock_rq(other_rq); continue; } @@ -3791,13 +3804,8 @@ static void __sched notrace __schedule(bool preempt) struct task_struct *to_wakeup; to_wakeup = wq_worker_sleeping(prev); - if (to_wakeup) { - /* This shouldn't happen, but does */ - if (WARN_ONCE((to_wakeup == prev), "Waking up prev as worker\n")) - deactivate = false; - else - try_to_wake_up_local(to_wakeup); - } + if (to_wakeup) + try_to_wake_up_local(to_wakeup); } } switch_count = &prev->nvcsw; @@ -3846,10 +3854,12 @@ static void __sched notrace __schedule(bool preempt) ++*switch_count; trace_sched_switch(preempt, prev, next); - rq = context_switch(rq, prev, next); /* unlocks the rq */ + context_switch(rq, prev, next); /* unlocks the rq */ } else { check_siblings(rq); - rq_unlock_irq(rq); + rq_unlock(rq); + do_pending_softirq(rq, next); + local_irq_enable(); } } diff --git a/kernel/sched/MuQSS.h b/kernel/sched/MuQSS.h index f9510d7..3565a7d 100644 --- a/kernel/sched/MuQSS.h +++ b/kernel/sched/MuQSS.h @@ -1,5 +1,6 @@ #include #include +#include #include #include #include "cpuacct.h" @@ -325,4 +326,18 @@ static inline void cpufreq_trigger(u64 time, unsigned long util) #define arch_scale_freq_invariant() (false) #endif +/* + * This should only be called when current == rq->idle. Dodgy workaround for + * when softirqs are pending and we are in the idle loop. Setting current to + * resched will kick us out of the idle loop and the softirqs will be serviced + * on our next pass through schedule(). + */ +static inline bool softirq_pending(int cpu) +{ + if (likely(!local_softirq_pending())) + return false; + set_tsk_need_resched(current); + return true; +} + #endif /* MUQSS_SCHED_H */ diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 060b76d..51264e6 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -208,6 +208,8 @@ static void cpu_idle_loop(void) int cpu = smp_processor_id(); while (1) { + bool pending = false; + /* * If the arch has a polling bit, we maintain an invariant: * @@ -219,7 +221,10 @@ static void cpu_idle_loop(void) __current_set_polling(); quiet_vmstat(); - tick_nohz_idle_enter(); + if (unlikely(softirq_pending(cpu))) + pending = true; + else + tick_nohz_idle_enter(); while (!need_resched()) { check_pgt_cache(); @@ -259,7 +264,8 @@ static void cpu_idle_loop(void) * not have had an IPI to fold the state for us. */ preempt_set_need_resched(); - tick_nohz_idle_exit(); + if (!pending) + tick_nohz_idle_exit(); __current_clr_polling(); /* diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index c64fc51..cdefab6 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1813,3 +1813,8 @@ static inline void cpufreq_trigger_update(u64 time) {} #else /* arch_scale_freq_capacity */ #define arch_scale_freq_invariant() (false) #endif + +static inline bool softirq_pending(int cpu) +{ + return false; +} diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 9ba7c82..53291d7 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -1788,3 +1788,65 @@ int __sched schedule_hrtimeout(ktime_t *expires, return schedule_hrtimeout_range(expires, 0, mode); } EXPORT_SYMBOL_GPL(schedule_hrtimeout); + +/* + * As per schedule_hrtimeout but taskes a millisecond value and returns how + * many milliseconds are left. + */ +signed long __sched schedule_msec_hrtimeout(signed long timeout) +{ + struct hrtimer_sleeper t; + ktime_t expires; + int delta, secs; + + if (!timeout) { + __set_current_state(TASK_RUNNING); + return 0; + } + + secs = timeout / 1000; + delta = (timeout % 1000) * NSEC_PER_MSEC; + expires = ktime_set(secs, delta); + + hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_set_expires_range_ns(&t.timer, expires, delta); + + hrtimer_init_sleeper(&t, current); + + hrtimer_start_expires(&t.timer, HRTIMER_MODE_REL); + + if (likely(t.task)) + schedule(); + + hrtimer_cancel(&t.timer); + destroy_hrtimer_on_stack(&t.timer); + + __set_current_state(TASK_RUNNING); + + expires = hrtimer_expires_remaining(&t.timer); + timeout = ktime_to_ms(expires); + return timeout < 0 ? 0 : timeout; +} + +EXPORT_SYMBOL(schedule_msec_hrtimeout); + +signed long __sched schedule_min_hrtimeout(void) +{ + return schedule_msec_hrtimeout(1); +} + +EXPORT_SYMBOL(schedule_min_hrtimeout); + +signed long __sched schedule_msec_hrtimeout_interruptible(signed long timeout) +{ + __set_current_state(TASK_INTERRUPTIBLE); + return schedule_msec_hrtimeout(timeout); +} +EXPORT_SYMBOL(schedule_msec_hrtimeout_interruptible); + +signed long __sched schedule_msec_hrtimeout_uninterruptible(signed long timeout) +{ + __set_current_state(TASK_UNINTERRUPTIBLE); + return schedule_msec_hrtimeout(timeout); +} +EXPORT_SYMBOL(schedule_msec_hrtimeout_uninterruptible); diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 32bf6f7..7651d47 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1454,7 +1454,7 @@ static unsigned long __next_timer_interrupt(struct timer_base *base) * Check, if the next hrtimer event is before the next timer wheel * event: */ -static u64 cmp_next_hrtimer_event(u64 basem, u64 expires) +static u64 cmp_next_hrtimer_event(struct timer_base *base, u64 basem, u64 expires) { u64 nextevt = hrtimer_get_next_event(); @@ -1472,6 +1472,9 @@ static u64 cmp_next_hrtimer_event(u64 basem, u64 expires) if (nextevt <= basem) return basem; + if (nextevt < expires && nextevt - basem <= TICK_NSEC) + base->is_idle = false; + /* * Round up to the next jiffie. High resolution timers are * off, so the hrtimers are expired in the tick and we need to @@ -1531,7 +1534,7 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) } spin_unlock(&base->lock); - return cmp_next_hrtimer_event(basem, expires); + return cmp_next_hrtimer_event(base, basem, expires); } /** @@ -1742,6 +1745,17 @@ signed long __sched schedule_timeout(signed long timeout) expire = timeout + jiffies; + if (timeout == 1 && hrtimer_resolution < NSEC_PER_SEC / HZ) { + /* + * Special case 1 as being a request for the minimum timeout + * and use highres timers to timeout after 1ms to workaround + * the granularity of low Hz tick timers. + */ + if (!schedule_min_hrtimeout()) + return 0; + goto out_timeout; + } + setup_timer_on_stack(&timer, process_timeout, (unsigned long)current); __mod_timer(&timer, expire, false); schedule(); @@ -1749,10 +1763,10 @@ signed long __sched schedule_timeout(signed long timeout) /* Remove the timer from the object tracker */ destroy_timer_on_stack(&timer); - +out_timeout: timeout = expire - jiffies; - out: +out: return timeout < 0 ? 0 : timeout; } EXPORT_SYMBOL(schedule_timeout); @@ -1873,7 +1887,13 @@ void __init init_timers(void) */ void msleep(unsigned int msecs) { - unsigned long timeout = msecs_to_jiffies(msecs) + 1; + unsigned long timeout; + + if (likely(hrtimer_resolution < NSEC_PER_SEC / HZ)) { + while (msecs) + msecs = schedule_msec_hrtimeout_uninterruptible(msecs); + } + timeout = msecs_to_jiffies(msecs) + 1; while (timeout) timeout = schedule_timeout_uninterruptible(timeout); @@ -1887,7 +1907,14 @@ EXPORT_SYMBOL(msleep); */ unsigned long msleep_interruptible(unsigned int msecs) { - unsigned long timeout = msecs_to_jiffies(msecs) + 1; + unsigned long timeout; + + if (likely(hrtimer_resolution < NSEC_PER_SEC / HZ)) { + while (msecs && !signal_pending(current)) + msecs = schedule_msec_hrtimeout_interruptible(msecs); + return msecs; + } + timeout = msecs_to_jiffies(msecs) + 1; while (timeout && !signal_pending(current)) timeout = schedule_timeout_interruptible(timeout); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index bbd118b..80d4e11 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1992,7 +1992,7 @@ static void pktgen_mark_device(const struct pktgen_net *pn, const char *ifname) mutex_unlock(&pktgen_thread_lock); pr_debug("%s: waiting for %s to disappear....\n", __func__, ifname); - schedule_timeout_interruptible(msecs_to_jiffies(msec_per_try)); + schedule_msec_hrtimeout_interruptible((msec_per_try)); mutex_lock(&pktgen_thread_lock); if (++i >= max_tries) { diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 17ae926..e0dcffd 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -2016,7 +2016,7 @@ static void snd_m3_ac97_reset(struct snd_m3 *chip) outw(0, io + GPIO_DATA); outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION); - schedule_timeout_uninterruptible(msecs_to_jiffies(delay1)); + schedule_msec_hrtimeout_uninterruptible((delay1)); outw(GPO_PRIMARY_AC97, io + GPIO_DATA); udelay(5); @@ -2024,7 +2024,7 @@ static void snd_m3_ac97_reset(struct snd_m3 *chip) outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A); outw(~0, io + GPIO_MASK); - schedule_timeout_uninterruptible(msecs_to_jiffies(delay2)); + schedule_msec_hrtimeout_uninterruptible((delay2)); if (! snd_m3_try_read_vendor(chip)) break; diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 1be2bab..75e7f6c 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -419,7 +419,7 @@ static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable) hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2); snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff); if (enable) { - schedule_timeout_uninterruptible(msecs_to_jiffies(10)); + schedule_msec_hrtimeout_uninterruptible((10)); /* config one-bit depop parameter */ rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x307f); snd_soc_update_bits(codec, RT5631_HP_OUT_VOL, @@ -529,7 +529,7 @@ static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable) hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2); snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff); if (enable) { - schedule_timeout_uninterruptible(msecs_to_jiffies(10)); + schedule_msec_hrtimeout_uninterruptible((10)); /* config depop sequence parameter */ rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f); diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index ffbf3df..cb8473d 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -236,10 +236,10 @@ static void wm8350_pga_work(struct work_struct *work) out2->ramp == WM8350_RAMP_UP) { /* delay is longer over 0dB as increases are larger */ if (i >= WM8350_OUTn_0dB) - schedule_timeout_interruptible(msecs_to_jiffies + schedule_msec_hrtimeout_interruptible( (2)); else - schedule_timeout_interruptible(msecs_to_jiffies + schedule_msec_hrtimeout_interruptible( (1)); } else udelay(50); /* doesn't matter if we delay longer */ @@ -1123,7 +1123,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, (platform->dis_out4 << 6)); /* wait for discharge */ - schedule_timeout_interruptible(msecs_to_jiffies + schedule_msec_hrtimeout_interruptible( (platform-> cap_discharge_msecs)); @@ -1139,7 +1139,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, WM8350_VBUFEN); /* wait for vmid */ - schedule_timeout_interruptible(msecs_to_jiffies + schedule_msec_hrtimeout_interruptible( (platform-> vmid_charge_msecs)); @@ -1190,7 +1190,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1); /* wait */ - schedule_timeout_interruptible(msecs_to_jiffies + schedule_msec_hrtimeout_interruptible( (platform-> vmid_discharge_msecs)); @@ -1208,7 +1208,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, pm1 | WM8350_OUTPUT_DRAIN_EN); /* wait */ - schedule_timeout_interruptible(msecs_to_jiffies + schedule_msec_hrtimeout_interruptible( (platform->drain_msecs)); pm1 &= ~WM8350_BIASEN; diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 5d8dca88..4b4d455 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -1112,7 +1112,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, /* Need to let things settle before stopping the clock * to ensure that restart works, see "Stopping the * master clock" in the datasheet. */ - schedule_timeout_interruptible(msecs_to_jiffies(1)); + schedule_msec_hrtimeout_interruptible((1)); snd_soc_write(codec, WM8900_REG_POWER2, WM8900_REG_POWER2_SYSCLK_ENA); break; diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 9849643..30af3b2 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -199,7 +199,7 @@ static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, /* Gracefully shut down the voice interface. */ snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0200); - schedule_timeout_interruptible(msecs_to_jiffies(1)); + schedule_msec_hrtimeout_interruptible((1)); snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0f00); snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x1000, 0x1000); @@ -868,7 +868,7 @@ static int wm9713_set_pll(struct snd_soc_codec *codec, wm9713->pll_in = freq_in; /* wait 10ms AC97 link frames for the link to stabilise */ - schedule_timeout_interruptible(msecs_to_jiffies(10)); + schedule_msec_hrtimeout_interruptible((10)); return 0; } diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d908ff8..dd8d84b 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -134,7 +134,7 @@ static void dapm_assert_locked(struct snd_soc_dapm_context *dapm) static void pop_wait(u32 pop_time) { if (pop_time) - schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); + schedule_msec_hrtimeout_uninterruptible((pop_time)); } static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...) diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index 41aa335..4834687 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -131,7 +131,7 @@ static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm, if (!alive) break; set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); + schedule_min_hrtimeout(); } while (--timeout > 0); if (alive) dev_err(line6pcm->line6->ifcdev,