* [PATCH 3/3] cfq-iosched: Convert to use highres timers [not found] <1459783781-25537-1-git-send-email-jack@suse.cz> @ 2016-04-04 15:29 ` Jan Kara 2016-04-18 18:26 ` Jeff Moyer 0 siblings, 1 reply; 5+ messages in thread From: Jan Kara @ 2016-04-04 15:29 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block, Jeff Moyer, Jan Kara From: Jan Kara <jack@suse.com> Signed-off-by: Jan Kara <jack@suse.com> --- block/cfq-iosched.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index c7f1a70dd8f7..9e3ec4bbb81d 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -362,7 +362,7 @@ struct cfq_data { /* * idle window management */ - struct timer_list idle_slice_timer; + struct hrtimer idle_slice_timer; struct work_struct unplug_work; struct cfq_queue *active_queue; @@ -2619,7 +2619,7 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq, static inline void cfq_del_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - del_timer(&cfqd->idle_slice_timer); + hrtimer_try_to_cancel(&cfqd->idle_slice_timer); cfqg_stats_update_idle_time(cfqq->cfqg); } @@ -2981,7 +2981,8 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) else sl = cfqd->cfq_slice_idle; - mod_timer(&cfqd->idle_slice_timer, now + sl); + hrtimer_start(&cfqd->idle_slice_timer, ns_to_ktime(sl), + HRTIMER_MODE_REL); cfqg_stats_set_start_idle_time(cfqq->cfqg); cfq_log_cfqq(cfqd, cfqq, "arm_idle: %llu group_idle: %d", sl, group_idle ? 1 : 0); @@ -3300,7 +3301,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) * flight or is idling for a new request, allow either of these * conditions to happen (or time out) before selecting a new queue. */ - if (timer_pending(&cfqd->idle_slice_timer)) { + if (hrtimer_active(&cfqd->idle_slice_timer)) { cfqq = NULL; goto keep_queue; } @@ -4445,9 +4446,10 @@ static void cfq_kick_queue(struct work_struct *work) /* * Timer running if the active_queue is currently idling inside its time slice */ -static void cfq_idle_slice_timer(unsigned long data) +static enum hrtimer_restart cfq_idle_slice_timer(struct hrtimer *timer) { - struct cfq_data *cfqd = (struct cfq_data *) data; + struct cfq_data *cfqd = container_of(timer, struct cfq_data, + idle_slice_timer); struct cfq_queue *cfqq; unsigned long flags; int timed_out = 1; @@ -4496,11 +4498,12 @@ out_kick: cfq_schedule_dispatch(cfqd); out_cont: spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); + return HRTIMER_NORESTART; } static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) { - del_timer_sync(&cfqd->idle_slice_timer); + hrtimer_cancel(&cfqd->idle_slice_timer); cancel_work_sync(&cfqd->unplug_work); } @@ -4596,9 +4599,9 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e) cfqg_put(cfqd->root_group); spin_unlock_irq(q->queue_lock); - init_timer(&cfqd->idle_slice_timer); + hrtimer_init(&cfqd->idle_slice_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); cfqd->idle_slice_timer.function = cfq_idle_slice_timer; - cfqd->idle_slice_timer.data = (unsigned long) cfqd; INIT_WORK(&cfqd->unplug_work, cfq_kick_queue); -- 2.6.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 3/3] cfq-iosched: Convert to use highres timers 2016-04-04 15:29 ` [PATCH 3/3] cfq-iosched: Convert to use highres timers Jan Kara @ 2016-04-18 18:26 ` Jeff Moyer 2016-05-31 15:42 ` Jan Kara 0 siblings, 1 reply; 5+ messages in thread From: Jeff Moyer @ 2016-04-18 18:26 UTC (permalink / raw) To: Jan Kara; +Cc: Jens Axboe, linux-block, Jan Kara Jan Kara <jack@suse.cz> writes: > From: Jan Kara <jack@suse.com> > > Signed-off-by: Jan Kara <jack@suse.com> Sorry for the late reply. This all looks good, Jan, thanks! Reviewed-by: Jeff Moyer <jmoyer@redhat.com> > --- > block/cfq-iosched.c | 21 ++++++++++++--------- > 1 file changed, 12 insertions(+), 9 deletions(-) > > diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c > index c7f1a70dd8f7..9e3ec4bbb81d 100644 > --- a/block/cfq-iosched.c > +++ b/block/cfq-iosched.c > @@ -362,7 +362,7 @@ struct cfq_data { > /* > * idle window management > */ > - struct timer_list idle_slice_timer; > + struct hrtimer idle_slice_timer; > struct work_struct unplug_work; > > struct cfq_queue *active_queue; > @@ -2619,7 +2619,7 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq, > > static inline void cfq_del_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq) > { > - del_timer(&cfqd->idle_slice_timer); > + hrtimer_try_to_cancel(&cfqd->idle_slice_timer); > cfqg_stats_update_idle_time(cfqq->cfqg); > } > > @@ -2981,7 +2981,8 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) > else > sl = cfqd->cfq_slice_idle; > > - mod_timer(&cfqd->idle_slice_timer, now + sl); > + hrtimer_start(&cfqd->idle_slice_timer, ns_to_ktime(sl), > + HRTIMER_MODE_REL); > cfqg_stats_set_start_idle_time(cfqq->cfqg); > cfq_log_cfqq(cfqd, cfqq, "arm_idle: %llu group_idle: %d", sl, > group_idle ? 1 : 0); > @@ -3300,7 +3301,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) > * flight or is idling for a new request, allow either of these > * conditions to happen (or time out) before selecting a new queue. > */ > - if (timer_pending(&cfqd->idle_slice_timer)) { > + if (hrtimer_active(&cfqd->idle_slice_timer)) { > cfqq = NULL; > goto keep_queue; > } > @@ -4445,9 +4446,10 @@ static void cfq_kick_queue(struct work_struct *work) > /* > * Timer running if the active_queue is currently idling inside its time slice > */ > -static void cfq_idle_slice_timer(unsigned long data) > +static enum hrtimer_restart cfq_idle_slice_timer(struct hrtimer *timer) > { > - struct cfq_data *cfqd = (struct cfq_data *) data; > + struct cfq_data *cfqd = container_of(timer, struct cfq_data, > + idle_slice_timer); > struct cfq_queue *cfqq; > unsigned long flags; > int timed_out = 1; > @@ -4496,11 +4498,12 @@ out_kick: > cfq_schedule_dispatch(cfqd); > out_cont: > spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); > + return HRTIMER_NORESTART; > } > > static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) > { > - del_timer_sync(&cfqd->idle_slice_timer); > + hrtimer_cancel(&cfqd->idle_slice_timer); > cancel_work_sync(&cfqd->unplug_work); > } > > @@ -4596,9 +4599,9 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e) > cfqg_put(cfqd->root_group); > spin_unlock_irq(q->queue_lock); > > - init_timer(&cfqd->idle_slice_timer); > + hrtimer_init(&cfqd->idle_slice_timer, CLOCK_MONOTONIC, > + HRTIMER_MODE_REL); > cfqd->idle_slice_timer.function = cfq_idle_slice_timer; > - cfqd->idle_slice_timer.data = (unsigned long) cfqd; > > INIT_WORK(&cfqd->unplug_work, cfq_kick_queue); ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 3/3] cfq-iosched: Convert to use highres timers 2016-04-18 18:26 ` Jeff Moyer @ 2016-05-31 15:42 ` Jan Kara 2016-05-31 21:01 ` Jens Axboe 0 siblings, 1 reply; 5+ messages in thread From: Jan Kara @ 2016-05-31 15:42 UTC (permalink / raw) To: Jens Axboe; +Cc: Jan Kara, Jeff Moyer, linux-block, Jan Kara On Mon 18-04-16 14:26:46, Jeff Moyer wrote: > Jan Kara <jack@suse.cz> writes: > > > From: Jan Kara <jack@suse.com> > > > > Signed-off-by: Jan Kara <jack@suse.com> > > Sorry for the late reply. This all looks good, Jan, thanks! > > Reviewed-by: Jeff Moyer <jmoyer@redhat.com> Jens, what do you think about this patch set? It seems to have fallen through the cracks... Honza > > > > --- > > block/cfq-iosched.c | 21 ++++++++++++--------- > > 1 file changed, 12 insertions(+), 9 deletions(-) > > > > diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c > > index c7f1a70dd8f7..9e3ec4bbb81d 100644 > > --- a/block/cfq-iosched.c > > +++ b/block/cfq-iosched.c > > @@ -362,7 +362,7 @@ struct cfq_data { > > /* > > * idle window management > > */ > > - struct timer_list idle_slice_timer; > > + struct hrtimer idle_slice_timer; > > struct work_struct unplug_work; > > > > struct cfq_queue *active_queue; > > @@ -2619,7 +2619,7 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq, > > > > static inline void cfq_del_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq) > > { > > - del_timer(&cfqd->idle_slice_timer); > > + hrtimer_try_to_cancel(&cfqd->idle_slice_timer); > > cfqg_stats_update_idle_time(cfqq->cfqg); > > } > > > > @@ -2981,7 +2981,8 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) > > else > > sl = cfqd->cfq_slice_idle; > > > > - mod_timer(&cfqd->idle_slice_timer, now + sl); > > + hrtimer_start(&cfqd->idle_slice_timer, ns_to_ktime(sl), > > + HRTIMER_MODE_REL); > > cfqg_stats_set_start_idle_time(cfqq->cfqg); > > cfq_log_cfqq(cfqd, cfqq, "arm_idle: %llu group_idle: %d", sl, > > group_idle ? 1 : 0); > > @@ -3300,7 +3301,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) > > * flight or is idling for a new request, allow either of these > > * conditions to happen (or time out) before selecting a new queue. > > */ > > - if (timer_pending(&cfqd->idle_slice_timer)) { > > + if (hrtimer_active(&cfqd->idle_slice_timer)) { > > cfqq = NULL; > > goto keep_queue; > > } > > @@ -4445,9 +4446,10 @@ static void cfq_kick_queue(struct work_struct *work) > > /* > > * Timer running if the active_queue is currently idling inside its time slice > > */ > > -static void cfq_idle_slice_timer(unsigned long data) > > +static enum hrtimer_restart cfq_idle_slice_timer(struct hrtimer *timer) > > { > > - struct cfq_data *cfqd = (struct cfq_data *) data; > > + struct cfq_data *cfqd = container_of(timer, struct cfq_data, > > + idle_slice_timer); > > struct cfq_queue *cfqq; > > unsigned long flags; > > int timed_out = 1; > > @@ -4496,11 +4498,12 @@ out_kick: > > cfq_schedule_dispatch(cfqd); > > out_cont: > > spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); > > + return HRTIMER_NORESTART; > > } > > > > static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) > > { > > - del_timer_sync(&cfqd->idle_slice_timer); > > + hrtimer_cancel(&cfqd->idle_slice_timer); > > cancel_work_sync(&cfqd->unplug_work); > > } > > > > @@ -4596,9 +4599,9 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e) > > cfqg_put(cfqd->root_group); > > spin_unlock_irq(q->queue_lock); > > > > - init_timer(&cfqd->idle_slice_timer); > > + hrtimer_init(&cfqd->idle_slice_timer, CLOCK_MONOTONIC, > > + HRTIMER_MODE_REL); > > cfqd->idle_slice_timer.function = cfq_idle_slice_timer; > > - cfqd->idle_slice_timer.data = (unsigned long) cfqd; > > > > INIT_WORK(&cfqd->unplug_work, cfq_kick_queue); -- Jan Kara <jack@suse.com> SUSE Labs, CR ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 3/3] cfq-iosched: Convert to use highres timers 2016-05-31 15:42 ` Jan Kara @ 2016-05-31 21:01 ` Jens Axboe 0 siblings, 0 replies; 5+ messages in thread From: Jens Axboe @ 2016-05-31 21:01 UTC (permalink / raw) To: Jan Kara; +Cc: Jeff Moyer, linux-block, Jan Kara On 05/31/2016 09:42 AM, Jan Kara wrote: > On Mon 18-04-16 14:26:46, Jeff Moyer wrote: >> Jan Kara <jack@suse.cz> writes: >> >>> From: Jan Kara <jack@suse.com> >>> >>> Signed-off-by: Jan Kara <jack@suse.com> >> >> Sorry for the late reply. This all looks good, Jan, thanks! >> >> Reviewed-by: Jeff Moyer <jmoyer@redhat.com> > > Jens, what do you think about this patch set? It seems to have fallen > through the cracks... I think it did. Looks good to me, I'll get it applied. Thanks Jan. -- Jens Axboe ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 0/3 v2] cfq: High precision slice tuning @ 2016-06-08 13:11 Jan Kara 2016-06-08 13:11 ` [PATCH 3/3] cfq-iosched: Convert to use highres timers Jan Kara 0 siblings, 1 reply; 5+ messages in thread From: Jan Kara @ 2016-06-08 13:11 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block, Jeff Moyer, Jan Kara Hi, since Jens didn't merge the patches yet, I'm sending v2 of the series. Since v1 I have added Jeff's Reviewed-by tag and also fixed two 32-bit issues (possible overflow when computing cfq_latency_target and 64-bit division using '/' in choose_wl_class_and_type()). Jens, please merge these patches. Thanks! Honza --- Intro to the series This series contains patches which convert CFQ to internally use nanoseconds instead of jiffies (based on patch from Jeff), use high resultion timers, and provide interfaces to tune slice length in microseconds instead of miliseconds. Currently, since CFQ uses jiffies interally, the precision of slice length is in the order of microseconds (e.g., 4 ms for SUSE kernels). In some cases it would be desirable to tune the slice length to 1 ms or even somewhat lower - especially in cases where the idling is necessary only to avoid starving processes doing dependent IO. There giving process 1 ms to submit more IO is usually more than enough. I have been running some IO benchmarks (dbench, postmark, tiobench) with these patches and didn't see any negative effect. I have also checked that tuning slice lenght down to 0.5 ms basically removes negative performance effect of isolating dbench process in a blkio cgroup in my setup. The optimal length of timeslice obviously depends on the setup and workload and it is not goal of this patch set to argue about the time slice lenght. Mostly I just wanted to demonstrate that tuning the timeslice length down helps some workloads and we don't want to disable idling completely. ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/3] cfq-iosched: Convert to use highres timers 2016-06-08 13:11 [PATCH 0/3 v2] cfq: High precision slice tuning Jan Kara @ 2016-06-08 13:11 ` Jan Kara 0 siblings, 0 replies; 5+ messages in thread From: Jan Kara @ 2016-06-08 13:11 UTC (permalink / raw) To: Jens Axboe; +Cc: linux-block, Jeff Moyer, Jan Kara From: Jan Kara <jack@suse.com> Reviewed-by: Jeff Moyer <jmoyer@redhat.com> Signed-off-by: Jan Kara <jack@suse.com> --- block/cfq-iosched.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index afba86813f2a..dab606852e24 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -362,7 +362,7 @@ struct cfq_data { /* * idle window management */ - struct timer_list idle_slice_timer; + struct hrtimer idle_slice_timer; struct work_struct unplug_work; struct cfq_queue *active_queue; @@ -2619,7 +2619,7 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq, static inline void cfq_del_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - del_timer(&cfqd->idle_slice_timer); + hrtimer_try_to_cancel(&cfqd->idle_slice_timer); cfqg_stats_update_idle_time(cfqq->cfqg); } @@ -2981,7 +2981,8 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) else sl = cfqd->cfq_slice_idle; - mod_timer(&cfqd->idle_slice_timer, now + sl); + hrtimer_start(&cfqd->idle_slice_timer, ns_to_ktime(sl), + HRTIMER_MODE_REL); cfqg_stats_set_start_idle_time(cfqq->cfqg); cfq_log_cfqq(cfqd, cfqq, "arm_idle: %llu group_idle: %d", sl, group_idle ? 1 : 0); @@ -3300,7 +3301,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) * flight or is idling for a new request, allow either of these * conditions to happen (or time out) before selecting a new queue. */ - if (timer_pending(&cfqd->idle_slice_timer)) { + if (hrtimer_active(&cfqd->idle_slice_timer)) { cfqq = NULL; goto keep_queue; } @@ -4445,9 +4446,10 @@ static void cfq_kick_queue(struct work_struct *work) /* * Timer running if the active_queue is currently idling inside its time slice */ -static void cfq_idle_slice_timer(unsigned long data) +static enum hrtimer_restart cfq_idle_slice_timer(struct hrtimer *timer) { - struct cfq_data *cfqd = (struct cfq_data *) data; + struct cfq_data *cfqd = container_of(timer, struct cfq_data, + idle_slice_timer); struct cfq_queue *cfqq; unsigned long flags; int timed_out = 1; @@ -4496,11 +4498,12 @@ out_kick: cfq_schedule_dispatch(cfqd); out_cont: spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); + return HRTIMER_NORESTART; } static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) { - del_timer_sync(&cfqd->idle_slice_timer); + hrtimer_cancel(&cfqd->idle_slice_timer); cancel_work_sync(&cfqd->unplug_work); } @@ -4596,9 +4599,9 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e) cfqg_put(cfqd->root_group); spin_unlock_irq(q->queue_lock); - init_timer(&cfqd->idle_slice_timer); + hrtimer_init(&cfqd->idle_slice_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); cfqd->idle_slice_timer.function = cfq_idle_slice_timer; - cfqd->idle_slice_timer.data = (unsigned long) cfqd; INIT_WORK(&cfqd->unplug_work, cfq_kick_queue); -- 2.6.6 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-06-08 13:11 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1459783781-25537-1-git-send-email-jack@suse.cz>
2016-04-04 15:29 ` [PATCH 3/3] cfq-iosched: Convert to use highres timers Jan Kara
2016-04-18 18:26 ` Jeff Moyer
2016-05-31 15:42 ` Jan Kara
2016-05-31 21:01 ` Jens Axboe
2016-06-08 13:11 [PATCH 0/3 v2] cfq: High precision slice tuning Jan Kara
2016-06-08 13:11 ` [PATCH 3/3] cfq-iosched: Convert to use highres timers Jan Kara
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.