1. 18 10月, 2021 2 次提交
  2. 28 9月, 2021 1 次提交
  3. 02 9月, 2021 1 次提交
    • P
      block, bfq: honor already-setup queue merges · 2d52c58b
      Paolo Valente 提交于
      The function bfq_setup_merge prepares the merging between two
      bfq_queues, say bfqq and new_bfqq. To this goal, it assigns
      bfqq->new_bfqq = new_bfqq. Then, each time some I/O for bfqq arrives,
      the process that generated that I/O is disassociated from bfqq and
      associated with new_bfqq (merging is actually a redirection). In this
      respect, bfq_setup_merge increases new_bfqq->ref in advance, adding
      the number of processes that are expected to be associated with
      new_bfqq.
      
      Unfortunately, the stable-merging mechanism interferes with this
      setup. After bfqq->new_bfqq has been set by bfq_setup_merge, and
      before all the expected processes have been associated with
      bfqq->new_bfqq, bfqq may happen to be stably merged with a different
      queue than the current bfqq->new_bfqq. In this case, bfqq->new_bfqq
      gets changed. So, some of the processes that have been already
      accounted for in the ref counter of the previous new_bfqq will not be
      associated with that queue.  This creates an unbalance, because those
      references will never be decremented.
      
      This commit fixes this issue by reestablishing the previous, natural
      behaviour: once bfqq->new_bfqq has been set, it will not be changed
      until all expected redirections have occurred.
      Signed-off-by: NDavide Zini <davidezini2@gmail.com>
      Signed-off-by: NPaolo Valente <paolo.valente@linaro.org>
      Link: https://lore.kernel.org/r/20210802141352.74353-2-paolo.valente@linaro.orgSigned-off-by: NJens Axboe <axboe@kernel.dk>
      2d52c58b
  4. 24 8月, 2021 1 次提交
  5. 18 8月, 2021 3 次提交
  6. 10 8月, 2021 2 次提交
  7. 25 6月, 2021 2 次提交
    • J
      blk: Fix lock inversion between ioc lock and bfqd lock · fd2ef39c
      Jan Kara 提交于
      Lockdep complains about lock inversion between ioc->lock and bfqd->lock:
      
      bfqd -> ioc:
       put_io_context+0x33/0x90 -> ioc->lock grabbed
       blk_mq_free_request+0x51/0x140
       blk_put_request+0xe/0x10
       blk_attempt_req_merge+0x1d/0x30
       elv_attempt_insert_merge+0x56/0xa0
       blk_mq_sched_try_insert_merge+0x4b/0x60
       bfq_insert_requests+0x9e/0x18c0 -> bfqd->lock grabbed
       blk_mq_sched_insert_requests+0xd6/0x2b0
       blk_mq_flush_plug_list+0x154/0x280
       blk_finish_plug+0x40/0x60
       ext4_writepages+0x696/0x1320
       do_writepages+0x1c/0x80
       __filemap_fdatawrite_range+0xd7/0x120
       sync_file_range+0xac/0xf0
      
      ioc->bfqd:
       bfq_exit_icq+0xa3/0xe0 -> bfqd->lock grabbed
       put_io_context_active+0x78/0xb0 -> ioc->lock grabbed
       exit_io_context+0x48/0x50
       do_exit+0x7e9/0xdd0
       do_group_exit+0x54/0xc0
      
      To avoid this inversion we change blk_mq_sched_try_insert_merge() to not
      free the merged request but rather leave that upto the caller similarly
      to blk_mq_sched_try_merge(). And in bfq_insert_requests() we make sure
      to free all the merged requests after dropping bfqd->lock.
      
      Fixes: aee69d78 ("block, bfq: introduce the BFQ-v0 I/O scheduler as an extra scheduler")
      Reviewed-by: NMing Lei <ming.lei@redhat.com>
      Acked-by: NPaolo Valente <paolo.valente@linaro.org>
      Signed-off-by: NJan Kara <jack@suse.cz>
      Link: https://lore.kernel.org/r/20210623093634.27879-3-jack@suse.czSigned-off-by: NJens Axboe <axboe@kernel.dk>
      fd2ef39c
    • J
      bfq: Remove merged request already in bfq_requests_merged() · a921c655
      Jan Kara 提交于
      Currently, bfq does very little in bfq_requests_merged() and handles all
      the request cleanup in bfq_finish_requeue_request() called from
      blk_mq_free_request(). That is currently safe only because
      blk_mq_free_request() is called shortly after bfq_requests_merged()
      while bfqd->lock is still held. However to fix a lock inversion between
      bfqd->lock and ioc->lock, we need to call blk_mq_free_request() after
      dropping bfqd->lock. That would mean that already merged request could
      be seen by other processes inside bfq queues and possibly dispatched to
      the device which is wrong. So move cleanup of the request from
      bfq_finish_requeue_request() to bfq_requests_merged().
      Acked-by: NPaolo Valente <paolo.valente@linaro.org>
      Signed-off-by: NJan Kara <jack@suse.cz>
      Link: https://lore.kernel.org/r/20210623093634.27879-2-jack@suse.czSigned-off-by: NJens Axboe <axboe@kernel.dk>
      a921c655
  8. 22 6月, 2021 7 次提交
    • P
      block, bfq: reset waker pointer with shared queues · 9a2ac41b
      Paolo Valente 提交于
      Commit 85686d0d ("block, bfq: keep shared queues out of the waker
      mechanism") leaves shared bfq_queues out of the waker-detection
      mechanism. It attains this goal by not updating the pointer
      last_completed_rq_bfqq, if the last request completed belongs to a
      shared bfq_queue (so that the pointer will not point to the shared
      bfq_queue).
      
      Yet this has a side effect: the pointer last_completed_rq_bfqq keeps
      pointing, deceptively, to a bfq_queue that actually is not the last
      one to have had a request completed. As a consequence, such a
      bfq_queue may deceptively be considered as a waker of some bfq_queue,
      even of some shared bfq_queue.
      
      To address this issue, reset last_completed_rq_bfqq if the last
      request completed belongs to a shared queue.
      
      Fixes: 85686d0d ("block, bfq: keep shared queues out of the waker mechanism")
      Signed-off-by: NPaolo Valente <paolo.valente@linaro.org>
      Link: https://lore.kernel.org/r/20210619140948.98712-8-paolo.valente@linaro.orgSigned-off-by: NJens Axboe <axboe@kernel.dk>
      9a2ac41b
    • P
      block, bfq: check waker only for queues with no in-flight I/O · efc72524
      Paolo Valente 提交于
      Consider two bfq_queues, say Q1 and Q2, with Q2 empty. If a request of
      Q1 gets completed shortly before a new request arrives for Q2, then
      BFQ flags Q1 as a candidate waker for Q2. Yet, the arrival of this new
      request may have a different cause, in the following case. If also Q2
      has requests in flight while waiting for the arrival of a new request,
      then the completion of its own requests may be the actual cause of the
      awakening of the process that sends I/O to Q2. So Q1 may be flagged
      wrongly as a candidate waker.
      
      This commit avoids this deceptive flagging, by disabling
      candidate-waker flagging for Q2, if Q2 has in-flight I/O.
      Signed-off-by: NPaolo Valente <paolo.valente@linaro.org>
      Link: https://lore.kernel.org/r/20210619140948.98712-7-paolo.valente@linaro.orgSigned-off-by: NJens Axboe <axboe@kernel.dk>
      efc72524
    • P
      block, bfq: avoid delayed merge of async queues · bd3664b3
      Paolo Valente 提交于
      Since commit 430a67f9 ("block, bfq: merge bursts of newly-created
      queues"), BFQ may schedule a merge between a newly created sync
      bfq_queue, say Q2, and the last sync bfq_queue created, say Q1. To this
      goal, BFQ stores the address of Q1 in the field bic->stable_merge_bfqq
      of the bic associated with Q2. So, when the time for the possible merge
      arrives, BFQ knows which bfq_queue to merge Q2 with. In particular,
      BFQ checks for possible merges on request arrivals.
      
      Yet the same bic may also be associated with an async bfq_queue, say
      Q3. So, if a request for Q3 arrives, then the above check may happen
      to be executed while the bfq_queue at hand is Q3, instead of Q2. In
      this case, Q1 happens to be merged with an async bfq_queue. This is
      not only a conceptual mistake, because async queues are to be kept out
      of queue merging, but also a bug that leads to inconsistent states.
      
      This commits simply filters async queues out of delayed merges.
      
      Fixes: 430a67f9 ("block, bfq: merge bursts of newly-created queues")
      Tested-by: NHolger Hoffstätte <holger@applied-asynchrony.com>
      Signed-off-by: NPaolo Valente <paolo.valente@linaro.org>
      Link: https://lore.kernel.org/r/20210619140948.98712-6-paolo.valente@linaro.orgSigned-off-by: NJens Axboe <axboe@kernel.dk>
      bd3664b3
    • P
      block, bfq: boost throughput by extending queue-merging times · 7812472f
      Pietro Pedroni 提交于
      One of the methods with which bfq boosts throughput is by merging queues.
      One of the merging variants in bfq is the stable merge.
      This mechanism is activated between two queues only if they are created
      within a certain maximum time T1 from each other.
      Merging can happen soon or be delayed. In the second case, before
      merging, bfq needs to evaluate a throughput-boost parameter that
      indicates whether the queue generates a high throughput is served alone.
      Merging occurs when this throughput-boost is not high enough.
      In particular, this parameter is evaluated and late merging may occur
      only after at least a time T2 from the creation of the queue.
      
      Currently T1 and T2 are set to 180ms and 200ms, respectively.
      In this way the merging mechanism rarely occurs because time is not
      enough. This results in a noticeable lowering of the overall throughput
      with some workloads (see the example below).
      
      This commit introduces two constants bfq_activation_stable_merging and
      bfq_late_stable_merging in order to increase the duration of T1 and T2.
      Both the stable merging activation time and the late merging
      time are set to 600ms. This value has been experimentally evaluated
      using sqlite benchmark in the Phoronix Test Suite on a HDD.
      The duration of the benchmark before this fix was 111.02s, while now
      it has reached 97.02s, a better result than that of all the other
      schedulers.
      Signed-off-by: NPietro Pedroni <pedroni.pietro.96@gmail.com>
      Signed-off-by: NPaolo Valente <paolo.valente@linaro.org>
      Link: https://lore.kernel.org/r/20210619140948.98712-5-paolo.valente@linaro.orgSigned-off-by: NJens Axboe <axboe@kernel.dk>
      7812472f
    • P
      block, bfq: consider also creation time in delayed stable merge · d4f49983
      Paolo Valente 提交于
      Since commit 430a67f9 ("block, bfq: merge bursts of newly-created
      queues"), BFQ may schedule a merge between a newly created sync
      bfq_queue and the last sync bfq_queue created. Such a merging is not
      performed immediately, because BFQ needs first to find out whether the
      newly created queue actually reaches a higher throughput if not merged
      at all (and in that case BFQ will not perform any stable merging). To
      check that, a little time must be waited after the creation of the new
      queue, so that some I/O can flow in the queue, and statistics on such
      I/O can be computed.
      
      Yet, to evaluate the above waiting time, the last split time is
      considered as start time, instead of the creation time of the
      queue. This is a mistake, because considering the split time is
      correct only in the following scenario.
      
      The queue undergoes a non-stable merges on the arrival of its very
      first I/O request, due to close I/O with some other queue. While the
      queue is merged for close I/O, stable merging is not considered. Yet
      the queue may then happen to be split, if the close I/O finishes (or
      happens to be a false positive). From this time on, the queue can
      again be considered for stable merging. But, again, a little time must
      elapse, to let some new I/O flow in the queue and to get updated
      statistics. To wait for this time, the split time is to be taken into
      account.
      
      Yet, if the queue does not undergo a non-stable merge on the arrival
      of its very first request, then BFQ immediately checks whether the
      stable merge is to be performed. It happens because the split time for
      a queue is initialized to minus infinity when the queue is created.
      
      This commit fixes this mistake by adding the missing condition. Now
      the check for delayed stable-merge is performed after a little time is
      elapsed not only from the last queue split time, but also from the
      creation time of the queue.
      
      Fixes: 430a67f9 ("block, bfq: merge bursts of newly-created queues")
      Signed-off-by: NPaolo Valente <paolo.valente@linaro.org>
      Link: https://lore.kernel.org/r/20210619140948.98712-4-paolo.valente@linaro.orgSigned-off-by: NJens Axboe <axboe@kernel.dk>
      d4f49983
    • L
      block, bfq: fix delayed stable merge check · e03f2ab7
      Luca Mariotti 提交于
      When attempting to schedule a merge of a given bfq_queue with the currently
      in-service bfq_queue or with a cooperating bfq_queue among the scheduled
      bfq_queues, delayed stable merge is checked for rotational or non-queueing
      devs. For this stable merge to be performed, some conditions must be met.
      If the current bfq_queue underwent some split from some merged bfq_queue,
      one of these conditions is that two hundred milliseconds must elapse from
      split, otherwise this condition is always met.
      
      Unfortunately, by mistake, time_is_after_jiffies() was written instead of
      time_is_before_jiffies() for this check, verifying that less than two
      hundred milliseconds have elapsed instead of verifying that at least two
      hundred milliseconds have elapsed.
      
      Fix this issue by replacing time_is_after_jiffies() with
      time_is_before_jiffies().
      Signed-off-by: NLuca Mariotti <mariottiluca1@hotmail.it>
      Signed-off-by: NPaolo Valente <paolo.valente@unimore.it>
      Signed-off-by: NPietro Pedroni <pedroni.pietro.96@gmail.com>
      Link: https://lore.kernel.org/r/20210619140948.98712-3-paolo.valente@linaro.orgSigned-off-by: NJens Axboe <axboe@kernel.dk>
      e03f2ab7
    • P
      block, bfq: let also stably merged queues enjoy weight raising · 511a2699
      Paolo Valente 提交于
      Merged bfq_queues are kept out of weight-raising (low-latency)
      mechanisms. The reason is that these queues are usually created for
      non-interactive and non-soft-real-time tasks. Yet this is not the case
      for stably-merged queues. These queues are merged just because they
      are created shortly after each other. So they may easily serve the I/O
      of an interactive or soft-real time application, if the application
      happens to spawn multiple processes.
      
      To address this issue, this commits lets also stably-merged queued
      enjoy weight raising.
      Signed-off-by: NPaolo Valente <paolo.valente@linaro.org>
      Link: https://lore.kernel.org/r/20210619140948.98712-2-paolo.valente@linaro.orgSigned-off-by: NJens Axboe <axboe@kernel.dk>
      511a2699
  9. 12 5月, 2021 1 次提交
    • P
      block, bfq: avoid circular stable merges · 7ea96eef
      Paolo Valente 提交于
      BFQ may merge a new bfq_queue, stably, with the last bfq_queue
      created. In particular, BFQ first waits a little bit for some I/O to
      flow inside the new queue, say Q2, if this is needed to understand
      whether it is better or worse to merge Q2 with the last queue created,
      say Q1. This delayed stable merge is performed by assigning
      bic->stable_merge_bfqq = Q1, for the bic associated with Q1.
      
      Yet, while waiting for some I/O to flow in Q2, a non-stable queue
      merge of Q2 with Q1 may happen, causing the bic previously associated
      with Q2 to be associated with exactly Q1 (bic->bfqq = Q1). After that,
      Q2 and Q1 may happen to be split, and, in the split, Q1 may happen to
      be recycled as a non-shared bfq_queue. In that case, Q1 may then
      happen to undergo a stable merge with the bfq_queue pointed by
      bic->stable_merge_bfqq. Yet bic->stable_merge_bfqq still points to
      Q1. So Q1 would be merged with itself.
      
      This commit fixes this error by intercepting this situation, and
      canceling the schedule of the stable merge.
      
      Fixes: 430a67f9 ("block, bfq: merge bursts of newly-created queues")
      Signed-off-by: NPietro Pedroni <pedroni.pietro.96@gmail.com>
      Signed-off-by: NPaolo Valente <paolo.valente@linaro.org>
      Link: https://lore.kernel.org/r/20210512094352.85545-2-paolo.valente@linaro.orgSigned-off-by: NJens Axboe <axboe@kernel.dk>
      7ea96eef
  10. 11 5月, 2021 1 次提交
    • O
      kyber: fix out of bounds access when preempted · efed9a33
      Omar Sandoval 提交于
      __blk_mq_sched_bio_merge() gets the ctx and hctx for the current CPU and
      passes the hctx to ->bio_merge(). kyber_bio_merge() then gets the ctx
      for the current CPU again and uses that to get the corresponding Kyber
      context in the passed hctx. However, the thread may be preempted between
      the two calls to blk_mq_get_ctx(), and the ctx returned the second time
      may no longer correspond to the passed hctx. This "works" accidentally
      most of the time, but it can cause us to read garbage if the second ctx
      came from an hctx with more ctx's than the first one (i.e., if
      ctx->index_hw[hctx->type] > hctx->nr_ctx).
      
      This manifested as this UBSAN array index out of bounds error reported
      by Jakub:
      
      UBSAN: array-index-out-of-bounds in ../kernel/locking/qspinlock.c:130:9
      index 13106 is out of range for type 'long unsigned int [128]'
      Call Trace:
       dump_stack+0xa4/0xe5
       ubsan_epilogue+0x5/0x40
       __ubsan_handle_out_of_bounds.cold.13+0x2a/0x34
       queued_spin_lock_slowpath+0x476/0x480
       do_raw_spin_lock+0x1c2/0x1d0
       kyber_bio_merge+0x112/0x180
       blk_mq_submit_bio+0x1f5/0x1100
       submit_bio_noacct+0x7b0/0x870
       submit_bio+0xc2/0x3a0
       btrfs_map_bio+0x4f0/0x9d0
       btrfs_submit_data_bio+0x24e/0x310
       submit_one_bio+0x7f/0xb0
       submit_extent_page+0xc4/0x440
       __extent_writepage_io+0x2b8/0x5e0
       __extent_writepage+0x28d/0x6e0
       extent_write_cache_pages+0x4d7/0x7a0
       extent_writepages+0xa2/0x110
       do_writepages+0x8f/0x180
       __writeback_single_inode+0x99/0x7f0
       writeback_sb_inodes+0x34e/0x790
       __writeback_inodes_wb+0x9e/0x120
       wb_writeback+0x4d2/0x660
       wb_workfn+0x64d/0xa10
       process_one_work+0x53a/0xa80
       worker_thread+0x69/0x5b0
       kthread+0x20b/0x240
       ret_from_fork+0x1f/0x30
      
      Only Kyber uses the hctx, so fix it by passing the request_queue to
      ->bio_merge() instead. BFQ and mq-deadline just use that, and Kyber can
      map the queues itself to avoid the mismatch.
      
      Fixes: a6088845 ("block: kyber: make kyber more friendly with merging")
      Reported-by: NJakub Kicinski <kuba@kernel.org>
      Signed-off-by: NOmar Sandoval <osandov@fb.com>
      Link: https://lore.kernel.org/r/c7598605401a48d5cfeadebb678abd10af22b83f.1620691329.git.osandov@fb.comSigned-off-by: NJens Axboe <axboe@kernel.dk>
      efed9a33
  11. 16 4月, 2021 1 次提交
    • L
      bfq/mq-deadline: remove redundant check for passthrough request · 7687b38a
      Lin Feng 提交于
      Since commit 01e99aec 'blk-mq: insert passthrough request into
      hctx->dispatch directly', passthrough request should not appear in
      IO-scheduler any more, so blk_rq_is_passthrough checking in addon IO
      schedulers is redundant.
      
      (Notes: this patch passes generic IO load test with hdds under SAS
      controller and hdds under AHCI controller but obviously not covers all.
      Not sure if passthrough request can still escape into IO scheduler from
      blk_mq_sched_insert_requests, which is used by blk_mq_flush_plug_list and
      has lots of indirect callers.)
      Signed-off-by: NLin Feng <linf@wangsu.com>
      Reviewed-by: NMing Lei <ming.lei@redhat.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      7687b38a
  12. 26 3月, 2021 6 次提交
  13. 03 3月, 2021 1 次提交
  14. 22 2月, 2021 1 次提交
  15. 03 2月, 2021 1 次提交
    • L
      bfq-iosched: Revert "bfq: Fix computation of shallow depth" · 388c705b
      Lin Feng 提交于
      This reverts commit 6d4d2735.
      
      bfq.limit_depth passes word_depths[] as shallow_depth down to sbitmap core
      sbitmap_get_shallow, which uses just the number to limit the scan depth of
      each bitmap word, formula:
      scan_percentage_for_each_word = shallow_depth / (1 << sbimap->shift) * 100%
      
      That means the comments's percentiles 50%, 75%, 18%, 37% of bfq are correct.
      But after commit patch 'bfq: Fix computation of shallow depth', we use
      sbitmap.depth instead, as a example in following case:
      
      sbitmap.depth = 256, map_nr = 4, shift = 6; sbitmap_word.depth = 64.
      The resulsts of computed bfqd->word_depths[] are {128, 192, 48, 96}, and
      three of the numbers exceed core dirver's 'sbitmap_word.depth=64' limit
      nothing.
      Signed-off-by: NLin Feng <linf@wangsu.com>
      Reviewed-by: NJan Kara <jack@suse.cz>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      388c705b
  16. 28 1月, 2021 3 次提交
    • J
      bfq: Use only idle IO periods for think time calculations · 7684fbde
      Jan Kara 提交于
      Currently whenever bfq queue has a request queued we add now -
      last_completion_time to the think time statistics. This is however
      misleading in case the process is able to submit several requests in
      parallel because e.g. if the queue has request completed at time T0 and
      then queues new requests at times T1, T2, then we will add T1-T0 and
      T2-T0 to think time statistics which just doesn't make any sence (the
      queue's think time is penalized by the queue being able to submit more
      IO). So add to think time statistics only time intervals when the queue
      had no IO pending.
      Signed-off-by: NJan Kara <jack@suse.cz>
      Acked-by: NPaolo Valente <paolo.valente@linaro.org>
      [axboe: fix whitespace on empty line]
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      7684fbde
    • J
      bfq: Use 'ttime' local variable · 28c6def0
      Jan Kara 提交于
      Use local variable 'ttime' instead of dereferencing bfqq.
      Signed-off-by: NJan Kara <jack@suse.cz>
      Acked-by: NPaolo Valente <paolo.valente@linaro.org>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      28c6def0
    • J
      bfq: Avoid false bfq queue merging · 41e76c85
      Jan Kara 提交于
      bfq_setup_cooperator() uses bfqd->in_serv_last_pos so detect whether it
      makes sense to merge current bfq queue with the in-service queue.
      However if the in-service queue is freshly scheduled and didn't dispatch
      any requests yet, bfqd->in_serv_last_pos is stale and contains value
      from the previously scheduled bfq queue which can thus result in a bogus
      decision that the two queues should be merged. This bug can be observed
      for example with the following fio jobfile:
      
      [global]
      direct=0
      ioengine=sync
      invalidate=1
      size=1g
      rw=read
      
      [reader]
      numjobs=4
      directory=/mnt
      
      where the 4 processes will end up in the one shared bfq queue although
      they do IO to physically very distant files (for some reason I was able to
      observe this only with slice_idle=1ms setting).
      
      Fix the problem by invalidating bfqd->in_serv_last_pos when switching
      in-service queue.
      
      Fixes: 058fdecc ("block, bfq: fix in-service-queue check for queue merging")
      CC: stable@vger.kernel.org
      Signed-off-by: NJan Kara <jack@suse.cz>
      Acked-by: NPaolo Valente <paolo.valente@linaro.org>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      41e76c85
  17. 26 1月, 2021 6 次提交