mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Nauman Rafique <nauman@google.com>
To: Vivek Goyal <vgoyal@redhat.com>
Cc: Gui Jianfeng <guijianfeng@cn.fujitsu.com>,
	Dhaval Giani <dhaval@linux.vnet.ibm.com>,
	dpshah@google.com, lizf@cn.fujitsu.com, mikew@google.com,
	fchecconi@gmail.com, paolo.valente@unimore.it,
	jens.axboe@oracle.com, ryov@valinux.co.jp,
	fernando@intellilink.co.jp, s-uchida@ap.jp.nec.com,
	taka@valinux.co.jp, arozansk@redhat.com, jmoyer@redhat.com,
	oz-kernel@redhat.com, balbir@linux.vnet.ibm.com,
	linux-kernel@vger.kernel.org,
	containers@lists.linux-foundation.org, akpm@linux-foundation.org,
	menage@google.com, peterz@infradead.org
Subject: Re: [PATCH 01/10] Documentation
Date: Tue, 24 Mar 2009 11:14:13 -0700	[thread overview]
Message-ID: <e98e18940903241114u1e03ae7dhf654d7d8d0fc0302@mail.gmail.com> (raw)
In-Reply-To: <20090324125842.GA21389@redhat.com>

On Tue, Mar 24, 2009 at 5:58 AM, Vivek Goyal <vgoyal@redhat.com> wrote:
> On Mon, Mar 23, 2009 at 10:32:41PM -0700, Nauman Rafique wrote:
>
> [..]
>> > DESC
>> > io-controller: idle for sometime on sync queue before expiring it
>> > EDESC
>> >
>> > o When a sync queue expires, in many cases it might be empty and then
>> > áit will be deleted from the active tree. This will lead to a scenario
>> > áwhere out of two competing queues, only one is on the tree and when a
>> > ánew queue is selected, vtime jump takes place and we don't see services
>> > áprovided in proportion to weight.
>> >
>> > o In general this is a fundamental problem with fairness of sync queues
>> > áwhere queues are not continuously backlogged. Looks like idling is
>> > áonly solution to make sure such kind of queues can get some decent amount
>> > áof disk bandwidth in the face of competion from continusouly backlogged
>> > áqueues. But excessive idling has potential to reduce performance on SSD
>> > áand disks with commnad queuing.
>> >
>> > o This patch experiments with waiting for next request to come before a
>> > áqueue is expired after it has consumed its time slice. This can ensure
>> > ámore accurate fairness numbers in some cases.
>>
>> Vivek, have you introduced this option just to play with it, or you
>> are planning to make it a part of the patch set. Waiting for a new
>> request to come before expiring time slice sounds problematic.
>
> Why are the issues you forsee with it. This is just an extra 8ms idling
> on the sync queue that is also if think time of the queue is not high.
>
> We already do idling on sync queues. In this case we are doing an extra
> idle even if queue has consumed its allocated quota. It helps me get
> fairness numbers and I have put it under a tunable "fairness". So by
> default this code will not kick in.
>
> Other possible option could be that when expiring a sync queue, don't
> remove the queue immediately from the tree and remove it later if there
> is no request from the queue in 8ms or so. I am not sure with BFQ, is it
> feasible to do that without creating issues with current implementation.
> Current implementation was simple, so I stick to it to begin with.

If the maximum wait is bounded by 8ms, then it should be fine. The
comments on the patch did not talk about such limit; it sounded like
unbounded wait to me.

Does keeping the sync queue in ready tree solves the problem too? Is
it because it avoid a virtual time jump?

>
> So yes, I am planning to keep it under tunable, unless there are
> significant issues in doing that.
>
> Thanks
> Vivek
>
>>
>> >
>> > o Introduced a tunable "fairness". If set, io-controller will put more
>> > áfocus on getting fairness right than getting throughput right.
>> >
>> >
>> > ---
>> > áblock/blk-sysfs.c á | á á7 ++++
>> > áblock/elevator-fq.c | á 85 +++++++++++++++++++++++++++++++++++++++++++++-------
>> > áblock/elevator-fq.h | á 12 +++++++
>> > á3 files changed, 94 insertions(+), 10 deletions(-)
>> >
>> > Index: linux1/block/elevator-fq.h
>> > ===================================================================
>> > --- linux1.orig/block/elevator-fq.h á á 2009-03-18 17:34:46.000000000 -0400
>> > +++ linux1/block/elevator-fq.h á2009-03-18 17:34:53.000000000 -0400
>> > @@ -318,6 +318,13 @@ struct elv_fq_data {
>> > á á á áunsigned long long rate_sampling_start; /*sampling window start jifies*/
>> > á á á á/* number of sectors finished io during current sampling window */
>> > á á á áunsigned long rate_sectors_current;
>> > +
>> > + á á á /*
>> > + á á á á* If set to 1, will disable many optimizations done for boost
>> > + á á á á* throughput and focus more on providing fairness for sync
>> > + á á á á* queues.
>> > + á á á á*/
>> > + á á á int fairness;
>> > á};
>> >
>> > áextern int elv_slice_idle;
>> > @@ -340,6 +347,7 @@ enum elv_queue_state_flags {
>> > á á á áELV_QUEUE_FLAG_idle_window, á á á /* elevator slice idling enabled */
>> > á á á áELV_QUEUE_FLAG_wait_request, á á á/* waiting for a request */
>> > á á á áELV_QUEUE_FLAG_slice_new, á á á á /* no requests dispatched in slice */
>> > + á á á ELV_QUEUE_FLAG_wait_busy, á á á á /* wait for this queue to get busy */
>> > á á á áELV_QUEUE_FLAG_NR,
>> > á};
>> >
>> > @@ -362,6 +370,7 @@ ELV_IO_QUEUE_FLAG_FNS(sync)
>> > áELV_IO_QUEUE_FLAG_FNS(wait_request)
>> > áELV_IO_QUEUE_FLAG_FNS(idle_window)
>> > áELV_IO_QUEUE_FLAG_FNS(slice_new)
>> > +ELV_IO_QUEUE_FLAG_FNS(wait_busy)
>> >
>> > ástatic inline struct io_service_tree *
>> > áio_entity_service_tree(struct io_entity *entity)
>> > @@ -554,6 +563,9 @@ static inline struct io_queue *elv_looku
>> > áextern ssize_t elv_slice_idle_show(struct request_queue *q, char *name);
>> > áextern ssize_t elv_slice_idle_store(struct request_queue *q, const char *name,
>> > á á á á á á á á á á á á á á á á á á á á á á á ásize_t count);
>> > +extern ssize_t elv_fairness_show(struct request_queue *q, char *name);
>> > +extern ssize_t elv_fairness_store(struct request_queue *q, const char *name,
>> > + á á á á á á á á á á á á á á á á á á á á á á á size_t count);
>> >
>> > á/* Functions used by elevator.c */
>> > áextern int elv_init_fq_data(struct request_queue *q, struct elevator_queue *e);
>> > Index: linux1/block/elevator-fq.c
>> > ===================================================================
>> > --- linux1.orig/block/elevator-fq.c á á 2009-03-18 17:34:46.000000000 -0400
>> > +++ linux1/block/elevator-fq.c á2009-03-18 17:34:53.000000000 -0400
>> > @@ -1837,6 +1837,44 @@ void elv_ioq_served(struct io_queue *ioq
>> > á á á á á á á á á á á áioq->total_service);
>> > á}
>> >
>> > +/* Functions to show and store fairness value through sysfs */
>> > +ssize_t elv_fairness_show(struct request_queue *q, char *name)
>> > +{
>> > + á á á struct elv_fq_data *efqd;
>> > + á á á unsigned int data;
>> > + á á á unsigned long flags;
>> > +
>> > + á á á spin_lock_irqsave(q->queue_lock, flags);
>> > + á á á efqd = &q->elevator->efqd;
>> > + á á á data = efqd->fairness;
>> > + á á á spin_unlock_irqrestore(q->queue_lock, flags);
>> > + á á á return sprintf(name, "%d\n", data);
>> > +}
>> > +
>> > +ssize_t elv_fairness_store(struct request_queue *q, const char *name,
>> > + á á á á á á á á á á á á size_t count)
>> > +{
>> > + á á á struct elv_fq_data *efqd;
>> > + á á á unsigned int data;
>> > + á á á unsigned long flags;
>> > +
>> > + á á á char *p = (char *)name;
>> > +
>> > + á á á data = simple_strtoul(p, &p, 10);
>> > +
>> > + á á á if (data < 0)
>> > + á á á á á á á data = 0;
>> > + á á á else if (data > INT_MAX)
>> > + á á á á á á á data = INT_MAX;
>> > +
>> > + á á á spin_lock_irqsave(q->queue_lock, flags);
>> > + á á á efqd = &q->elevator->efqd;
>> > + á á á efqd->fairness = data;
>> > + á á á spin_unlock_irqrestore(q->queue_lock, flags);
>> > +
>> > + á á á return count;
>> > +}
>> > +
>> > á/* Functions to show and store elv_idle_slice value through sysfs */
>> > ássize_t elv_slice_idle_show(struct request_queue *q, char *name)
>> > á{
>> > @@ -2263,10 +2301,11 @@ void __elv_ioq_slice_expired(struct requ
>> > á á á áassert_spin_locked(q->queue_lock);
>> > á á á áelv_log_ioq(efqd, ioq, "slice expired upd=%d", budget_update);
>> >
>> > - á á á if (elv_ioq_wait_request(ioq))
>> > + á á á if (elv_ioq_wait_request(ioq) || elv_ioq_wait_busy(ioq))
>> > á á á á á á á ádel_timer(&efqd->idle_slice_timer);
>> >
>> > á á á áelv_clear_ioq_wait_request(ioq);
>> > + á á á elv_clear_ioq_wait_busy(ioq);
>> >
>> > á á á á/*
>> > á á á á * if ioq->slice_end = 0, that means a queue was expired before first
>> > @@ -2482,8 +2521,9 @@ void elv_ioq_request_add(struct request_
>> > á á á á á á á á * immediately and flag that we must not expire this queue
>> > á á á á á á á á * just now
>> > á á á á á á á á */
>> > - á á á á á á á if (elv_ioq_wait_request(ioq)) {
>> > + á á á á á á á if (elv_ioq_wait_request(ioq) || elv_ioq_wait_busy(ioq)) {
>> > á á á á á á á á á á á ádel_timer(&efqd->idle_slice_timer);
>> > + á á á á á á á á á á á elv_clear_ioq_wait_busy(ioq);
>> > á á á á á á á á á á á áblk_start_queueing(q);
>> > á á á á á á á á}
>> > á á á á} else if (elv_should_preempt(q, ioq, rq)) {
>> > @@ -2519,6 +2559,9 @@ void elv_idle_slice_timer(unsigned long
>> >
>> > á á á áif (ioq) {
>> >
>> > + á á á á á á á if (elv_ioq_wait_busy(ioq))
>> > + á á á á á á á á á á á goto expire;
>> > +
>> > á á á á á á á á/*
>> > á á á á á á á á * expired
>> > á á á á á á á á */
>> > @@ -2546,7 +2589,7 @@ out_cont:
>> > á á á áspin_unlock_irqrestore(q->queue_lock, flags);
>> > á}
>> >
>> > -void elv_ioq_arm_slice_timer(struct request_queue *q)
>> > +void elv_ioq_arm_slice_timer(struct request_queue *q, int wait_for_busy)
>> > á{
>> > á á á ástruct elv_fq_data *efqd = &q->elevator->efqd;
>> > á á á ástruct io_queue *ioq = elv_active_ioq(q->elevator);
>> > @@ -2563,15 +2606,27 @@ void elv_ioq_arm_slice_timer(struct requ
>> > á á á á á á á áreturn;
>> >
>> > á á á á/*
>> > - á á á á* still requests with the driver, don't idle
>> > + á á á á* idle is disabled, either manually or by past process history
>> > á á á á */
>> > - á á á if (efqd->rq_in_driver)
>> > + á á á if (!efqd->elv_slice_idle || !elv_ioq_idle_window(ioq))
>> > á á á á á á á áreturn;
>> >
>> > á á á á/*
>> > - á á á á* idle is disabled, either manually or by past process history
>> > + á á á á* This queue has consumed its time slice. We are waiting only for
>> > + á á á á* it to become busy before we select next queue for dispatch.
>> > á á á á */
>> > - á á á if (!efqd->elv_slice_idle || !elv_ioq_idle_window(ioq))
>> > + á á á if (efqd->fairness && wait_for_busy) {
>> > + á á á á á á á elv_mark_ioq_wait_busy(ioq);
>> > + á á á á á á á sl = efqd->elv_slice_idle;
>> > + á á á á á á á mod_timer(&efqd->idle_slice_timer, jiffies + sl);
>> > + á á á á á á á elv_log(efqd, "arm idle: %lu wait busy=1", sl);
>> > + á á á á á á á return;
>> > + á á á }
>> > +
>> > + á á á /*
>> > + á á á á* still requests with the driver, don't idle
>> > + á á á á*/
>> > + á á á if (efqd->rq_in_driver)
>> > á á á á á á á áreturn;
>> >
>> > á á á á/*
>> > @@ -2628,6 +2683,12 @@ void *elv_fq_select_ioq(struct request_q
>> > á á á á á á á á}
>> > á á á á}
>> >
>> > + á á á /* We are waiting for this queue to become busy before it expires.*/
>> > + á á á if (efqd->fairness && elv_ioq_wait_busy(ioq)) {
>> > + á á á á á á á ioq = NULL;
>> > + á á á á á á á goto keep_queue;
>> > + á á á }
>> > +
>> > á á á á/*
>> > á á á á * The active queue has run out of time, expire it and select new.
>> > á á á á */
>> > @@ -2802,10 +2863,14 @@ void elv_ioq_completed_request(struct re
>> > á á á á á á á á á á á áelv_ioq_set_prio_slice(q, ioq);
>> > á á á á á á á á á á á áelv_clear_ioq_slice_new(ioq);
>> > á á á á á á á á}
>> > - á á á á á á á if (elv_ioq_slice_used(ioq) || elv_ioq_class_idle(ioq))
>> > + á á á á á á á if (elv_ioq_class_idle(ioq))
>> > á á á á á á á á á á á áelv_ioq_slice_expired(q, 1);
>> > - á á á á á á á else if (sync && !ioq->nr_queued)
>> > - á á á á á á á á á á á elv_ioq_arm_slice_timer(q);
>> > + á á á á á á á else if (sync && !ioq->nr_queued) {
>> > + á á á á á á á á á á á if (elv_ioq_slice_used(ioq))
>> > + á á á á á á á á á á á á á á á elv_ioq_arm_slice_timer(q, 1);
>> > + á á á á á á á á á á á else
>> > + á á á á á á á á á á á á á á á elv_ioq_arm_slice_timer(q, 0);
>> > + á á á á á á á }
>> > á á á á}
>> >
>> > á á á áif (!efqd->rq_in_driver)
>> > Index: linux1/block/blk-sysfs.c
>> > ===================================================================
>> > --- linux1.orig/block/blk-sysfs.c á á á 2009-03-18 17:34:28.000000000 -0400
>> > +++ linux1/block/blk-sysfs.c á á2009-03-18 17:34:53.000000000 -0400
>> > @@ -282,6 +282,12 @@ static struct queue_sysfs_entry queue_sl
>> > á á á á.show = elv_slice_idle_show,
>> > á á á á.store = elv_slice_idle_store,
>> > á};
>> > +
>> > +static struct queue_sysfs_entry queue_fairness_entry = {
>> > + á á á .attr = {.name = "fairness", .mode = S_IRUGO | S_IWUSR },
>> > + á á á .show = elv_fairness_show,
>> > + á á á .store = elv_fairness_store,
>> > +};
>> > á#endif
>> > ástatic struct attribute *default_attrs[] = {
>> > á á á á&queue_requests_entry.attr,
>> > @@ -296,6 +302,7 @@ static struct attribute *default_attrs[]
>> > á á á á&queue_iostats_entry.attr,
>> > á#ifdef CONFIG_ELV_FAIR_QUEUING
>> > á á á á&queue_slice_idle_entry.attr,
>> > + á á á &queue_fairness_entry.attr,
>> > á#endif
>> > á á á áNULL,
>> > á};
>> >
>

  reply	other threads:[~2009-03-24 18:14 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-12  1:56 [RFC] IO Controller Vivek Goyal
2009-03-12  1:56 ` [PATCH 01/10] Documentation Vivek Goyal
2009-03-12  7:11   ` Andrew Morton
2009-03-12 10:07     ` Ryo Tsuruta
2009-03-12 18:01     ` Vivek Goyal
2009-03-16  8:40       ` Ryo Tsuruta
2009-03-16 13:39         ` Vivek Goyal
2009-04-05 15:15       ` Andrea Righi
2009-04-06  6:50         ` Nauman Rafique
2009-04-07  6:40         ` Vivek Goyal
2009-04-08 20:37           ` Andrea Righi
2009-04-16 18:37             ` Vivek Goyal
2009-04-17  5:35               ` Dhaval Giani
2009-04-17 13:49                 ` IO Controller discussion (Was: Re: [PATCH 01/10] Documentation) Vivek Goyal
2009-04-17  9:37               ` [PATCH 01/10] Documentation Andrea Righi
2009-04-17 14:13                 ` IO controller discussion (Was: Re: [PATCH 01/10] Documentation) Vivek Goyal
2009-04-17 18:09                   ` Nauman Rafique
2009-04-18  8:13                     ` Andrea Righi
2009-04-19 12:59                     ` Vivek Goyal
2009-04-19 13:08                     ` Vivek Goyal
2009-04-17 22:38                   ` Andrea Righi
2009-04-19 13:21                     ` Vivek Goyal
2009-04-18 13:19                   ` Balbir Singh
2009-04-19 13:45                     ` Vivek Goyal
2009-04-19 15:53                       ` Andrea Righi
2009-04-21  1:16                         ` KAMEZAWA Hiroyuki
2009-04-19  4:35                   ` Nauman Rafique
2009-03-12  7:45   ` [PATCH 01/10] Documentation Yang Hongyang
2009-03-12 13:51     ` Vivek Goyal
2009-03-12 10:00   ` Dhaval Giani
2009-03-12 14:04     ` Vivek Goyal
2009-03-12 14:48       ` Fabio Checconi
2009-03-12 15:03         ` Vivek Goyal
2009-03-18  7:23       ` Gui Jianfeng
2009-03-18 21:55         ` Vivek Goyal
2009-03-19  3:38           ` Gui Jianfeng
2009-03-24  5:32           ` Nauman Rafique
2009-03-24 12:58             ` Vivek Goyal
2009-03-24 18:14               ` Nauman Rafique [this message]
2009-03-24 18:29                 ` Vivek Goyal
2009-03-24 18:41                   ` Fabio Checconi
2009-03-24 18:35                     ` Vivek Goyal
2009-03-24 18:49                       ` Nauman Rafique
2009-03-24 19:04                       ` Fabio Checconi
2009-03-12 10:24   ` Peter Zijlstra
2009-03-12 14:09     ` Vivek Goyal
2009-04-06 14:35   ` Balbir Singh
2009-04-06 22:00     ` Nauman Rafique
2009-04-07  5:59     ` Gui Jianfeng
2009-04-13 13:40     ` Vivek Goyal
2009-05-01 22:04       ` IKEDA, Munehiro
2009-05-01 22:45         ` IO Controller per cgroup request descriptors (Re: [PATCH 01/10] Documentation) Vivek Goyal
2009-05-01 23:39           ` Nauman Rafique
2009-05-04 17:18             ` IKEDA, Munehiro
2009-03-12  1:56 ` [PATCH 02/10] Common flat fair queuing code in elevaotor layer Vivek Goyal
2009-03-19  6:27   ` Gui Jianfeng
2009-03-27  8:30   ` [PATCH] IO Controller: Don't store the pid in single queue circumstances Gui Jianfeng
2009-03-27 13:52     ` Vivek Goyal
2009-04-02  4:06   ` [PATCH 02/10] Common flat fair queuing code in elevaotor layer Divyesh Shah
2009-04-02 13:52     ` Vivek Goyal
2009-03-12  1:56 ` [PATCH 03/10] Modify cfq to make use of flat elevator fair queuing Vivek Goyal
2009-03-12  1:56 ` [PATCH 04/10] Common hierarchical fair queuing code in elevaotor layer Vivek Goyal
2009-03-12  1:56 ` [PATCH 05/10] cfq changes to use " Vivek Goyal
2009-04-16  5:25   ` [PATCH] IO-Controller: Fix kernel panic after moving a task Gui Jianfeng
2009-04-16 19:15     ` Vivek Goyal
2009-03-12  1:56 ` [PATCH 06/10] Separate out queue and data Vivek Goyal
2009-03-12  1:56 ` [PATCH 07/10] Prepare elevator layer for single queue schedulers Vivek Goyal
2009-03-12  1:56 ` [PATCH 08/10] noop changes for hierarchical fair queuing Vivek Goyal
2009-03-12  1:56 ` [PATCH 09/10] deadline " Vivek Goyal
2009-03-12  1:56 ` [PATCH 10/10] anticipatory " Vivek Goyal
2009-03-27  6:58   ` [PATCH] IO Controller: No need to stop idling in as Gui Jianfeng
2009-03-27 14:05     ` Vivek Goyal
2009-03-30  1:09       ` Gui Jianfeng
2009-03-12  3:27 ` [RFC] IO Controller Takuya Yoshikawa
2009-03-12  6:40   ` anqin
2009-03-12  6:55     ` Li Zefan
2009-03-12  7:11       ` anqin
2009-03-12 14:57         ` Vivek Goyal
2009-03-12 13:46     ` Vivek Goyal
2009-03-12 13:43   ` Vivek Goyal
2009-04-02  6:39 ` Gui Jianfeng
2009-04-02 14:00   ` Vivek Goyal
2009-04-07  1:40     ` Gui Jianfeng
2009-04-07  6:40       ` Gui Jianfeng
2009-04-10  9:33 ` Gui Jianfeng
2009-04-10 17:49   ` Nauman Rafique
2009-04-13 13:09   ` Vivek Goyal
2009-04-22  3:04     ` Gui Jianfeng
2009-04-22  3:10       ` Nauman Rafique
2009-04-22 13:23       ` Vivek Goyal
2009-04-30 19:38         ` Nauman Rafique
2009-05-05  3:18           ` Gui Jianfeng
2009-05-01  1:25 ` Divyesh Shah
2009-05-01  2:45   ` Vivek Goyal
2009-05-01  3:00     ` Divyesh Shah

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e98e18940903241114u1e03ae7dhf654d7d8d0fc0302@mail.gmail.com \
    --to=nauman@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=arozansk@redhat.com \
    --cc=balbir@linux.vnet.ibm.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=dhaval@linux.vnet.ibm.com \
    --cc=dpshah@google.com \
    --cc=fchecconi@gmail.com \
    --cc=fernando@intellilink.co.jp \
    --cc=guijianfeng@cn.fujitsu.com \
    --cc=jens.axboe@oracle.com \
    --cc=jmoyer@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizf@cn.fujitsu.com \
    --cc=menage@google.com \
    --cc=mikew@google.com \
    --cc=oz-kernel@redhat.com \
    --cc=paolo.valente@unimore.it \
    --cc=peterz@infradead.org \
    --cc=ryov@valinux.co.jp \
    --cc=s-uchida@ap.jp.nec.com \
    --cc=taka@valinux.co.jp \
    --cc=vgoyal@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®