From: Christoffer Dall <christoffer.dall(a)arm.com>
kvm_timer_update_state() is called when changing the phys timer
configuration registers, either via vcpu reset, as a result of a trap
from the guest, or when userspace programs the registers.
phys_timer_emulate() is in turn called by kvm_timer_update_state() to
either cancel an existing software timer, or program a new software
timer, to emulate the behavior of a real phys timer, based on the change
in configuration registers.
Unfortunately, the interaction between these two functions left a small
race; if the conceptual emulated phys timer should actually fire, but
the soft timer hasn't executed its callback yet, we cancel the timer in
phys_timer_emulate without injecting an irq. This only happens if the
check in kvm_timer_update_state is called before the timer should fire,
which is relatively unlikely, but possible.
The solution is to update the state of the phys timer after calling
phys_timer_emulate, which will pick up the pending timer state and
update the interrupt value.
Note that this leaves the opportunity of raising the interrupt twice,
once in the just-programmed soft timer, and once in
kvm_timer_update_state. Since this always happens synchronously with
the VCPU execution, there is no harm in this, and the guest ever only
sees a single timer interrupt.
Cc: Stable <stable(a)vger.kernel.org> # 4.15+
Signed-off-by: Christoffer Dall <christoffer.dall(a)arm.com>
---
virt/kvm/arm/arch_timer.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index bd3d57f40f1b..18ff6203079d 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -295,9 +295,9 @@ static void phys_timer_emulate(struct kvm_vcpu *vcpu)
struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
/*
- * If the timer can fire now we have just raised the IRQ line and we
- * don't need to have a soft timer scheduled for the future. If the
- * timer cannot fire at all, then we also don't need a soft timer.
+ * If the timer can fire now, we don't need to have a soft timer
+ * scheduled for the future. If the timer cannot fire at all,
+ * then we also don't need a soft timer.
*/
if (kvm_timer_should_fire(ptimer) || !kvm_timer_irq_can_fire(ptimer)) {
soft_timer_cancel(&timer->phys_timer, NULL);
@@ -332,10 +332,10 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
level = kvm_timer_should_fire(vtimer);
kvm_timer_update_irq(vcpu, level, vtimer);
+ phys_timer_emulate(vcpu);
+
if (kvm_timer_should_fire(ptimer) != ptimer->irq.level)
kvm_timer_update_irq(vcpu, !ptimer->irq.level, ptimer);
-
- phys_timer_emulate(vcpu);
}
static void vtimer_save_state(struct kvm_vcpu *vcpu)
--
2.14.4
How are you?
I would like to speak with the person in charge of purchasing your branded
promotional products for your company?
We create custom LOGO USB flash drives for our clients throughout the US.
We can print your logo, and load your digital images, videos and files!
If you need marketing, advertising, gifts or incentives, USB flash drives
are the solution!
Here is what we include:
-All Memory Sizes from 64MB up to 128GB!
-Second Side Printing
-Low Minimum Quantities
-Rush Service Available
-Full color Printing
NEW: We can make a custom shaped USB drive to look like your Logo or
product!
Send us your product image or logo files; we will create a design mock up
for you at no cost!
We are always running a new deals; email to get pricing!
Ask about the “Double Your Memory” upgrade promotion going on right
now!
Pricing is low right now, so let us know what you need and we will get you
a quick quote.
We will beat any competitors pricing, send us your last invoice and we will
beat it!
We always offer great rates for schools and nonprofits as well.
Regards,
Vanessa Kellen
Logo USB Account Manager
This is a note to let you know that I've just added the patch titled
iio: sca3000: Fix missing return in switch
to my staging git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
in the staging-testing branch.
The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)
The patch will be merged to the staging-next branch sometime soon,
after it passes testing, and the merge window is open.
If you have any questions about this process, please let me know.
>From c5b974bee9d2ceae4c441ae5a01e498c2674e100 Mon Sep 17 00:00:00 2001
From: "Gustavo A. R. Silva" <gustavo(a)embeddedor.com>
Date: Sat, 7 Jul 2018 12:44:01 -0500
Subject: iio: sca3000: Fix missing return in switch
The IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY case is missing a
return and will fall through to the default case and errorenously
return -EINVAL.
Fix this by adding in missing *return ret*.
Fixes: 626f971b5b07 ("staging:iio:accel:sca3000 Add write support to the low pass filter control")
Reported-by: Jonathan Cameron <jic23(a)kernel.org>
Signed-off-by: Gustavo A. R. Silva <gustavo(a)embeddedor.com>
Cc: <Stable(a)vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron(a)huawei.com>
---
drivers/iio/accel/sca3000.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c
index 4dceb75e3586..4964561595f5 100644
--- a/drivers/iio/accel/sca3000.c
+++ b/drivers/iio/accel/sca3000.c
@@ -797,6 +797,7 @@ static int sca3000_write_raw(struct iio_dev *indio_dev,
mutex_lock(&st->lock);
ret = sca3000_write_3db_freq(st, val);
mutex_unlock(&st->lock);
+ return ret;
default:
return -EINVAL;
}
--
2.18.0
This is a note to let you know that I've just added the patch titled
iio: ad9523: Fix displayed phase
to my staging git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
in the staging-testing branch.
The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)
The patch will be merged to the staging-next branch sometime soon,
after it passes testing, and the merge window is open.
If you have any questions about this process, please let me know.
>From 5a4e33c1c53ae7d4425f7d94e60e4458a37b349e Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars(a)metafoo.de>
Date: Mon, 25 Jun 2018 11:03:07 +0300
Subject: iio: ad9523: Fix displayed phase
Fix the displayed phase for the ad9523 driver. Currently the most
significant decimal place is dropped and all other digits are shifted one
to the left. This is due to a multiplication by 10, which is not necessary,
so remove it.
Signed-off-by: Lars-Peter Clausen <lars(a)metafoo.de>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean(a)analog.com>
Fixes: cd1678f9632 ("iio: frequency: New driver for AD9523 SPI Low Jitter Clock Generator")
Cc: <Stable(a)vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron(a)huawei.com>
---
drivers/iio/frequency/ad9523.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c
index 48ea46a1bc38..37504739c277 100644
--- a/drivers/iio/frequency/ad9523.c
+++ b/drivers/iio/frequency/ad9523.c
@@ -653,7 +653,7 @@ static int ad9523_read_raw(struct iio_dev *indio_dev,
code = (AD9523_CLK_DIST_DIV_PHASE_REV(ret) * 3141592) /
AD9523_CLK_DIST_DIV_REV(ret);
*val = code / 1000000;
- *val2 = (code % 1000000) * 10;
+ *val2 = code % 1000000;
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
--
2.18.0
From: Roman Pen <roman.penyaev(a)profitbricks.com>
The patch below fixes queue stalling when shared hctx marked for restart
(BLK_MQ_S_SCHED_RESTART bit) but q->shared_hctx_restart stays zero. The
root cause is that hctxs are shared between queues, but 'shared_hctx_restart'
belongs to the particular queue, which in fact may not need to be restarted,
thus we return from blk_mq_sched_restart() and leave shared hctx of another
queue never restarted.
The fix is to make shared_hctx_restart counter belong not to the queue, but
to tags, thereby counter will reflect real number of shared hctx needed to
be restarted.
During tests 1 hctx (set->nr_hw_queues) was used and all stalled requests
were noticed in dd->fifo_list of mq-deadline scheduler.
Seeming possible sequence of events:
1. Request A of queue A is inserted into dd->fifo_list of the scheduler.
2. Request B of queue A bypasses scheduler and goes directly to
hctx->dispatch.
3. Request C of queue B is inserted.
4. blk_mq_sched_dispatch_requests() is invoked, since hctx->dispatch is not
empty (request B is in the list) hctx is only marked for for next restart
and request A is left in a list (see comment "So it's best to leave them
there for as long as we can. Mark the hw queue as needing a restart in
that case." in blk-mq-sched.c)
5. Eventually request B is completed/freed and blk_mq_sched_restart() is
called, but by chance hctx from queue B is chosen for restart and request C
gets a chance to be dispatched.
6. Eventually request C is completed/freed and blk_mq_sched_restart() is
called, but shared_hctx_restart for queue B is zero and we return without
attempt to restart hctx from queue A, thus request A is stuck forever.
But stalling queue is not the only one problem with blk_mq_sched_restart().
My tests show that those loops thru all queues and hctxs can be very costly,
even with shared_hctx_restart counter, which aims to fix performance issue.
For my tests I create 128 devices with 64 hctx each, which share same tags
set.
The following is the fio and ftrace output for v4.14-rc4 kernel:
READ: io=5630.3MB, aggrb=573208KB/s, minb=573208KB/s, maxb=573208KB/s, mint=10058msec, maxt=10058msec
WRITE: io=5650.9MB, aggrb=575312KB/s, minb=575312KB/s, maxb=575312KB/s, mint=10058msec, maxt=10058msec
root@pserver16:~/roman# cat /sys/kernel/debug/tracing/trace_stat/* | grep blk_mq
Function Hit Time Avg s^2
-------- --- ---- --- ---
blk_mq_sched_restart 16347 9540759 us 583.639 us 8804801 us
blk_mq_sched_restart 7884 6073471 us 770.354 us 8780054 us
blk_mq_sched_restart 14176 7586794 us 535.185 us 2822731 us
blk_mq_sched_restart 7843 6205435 us 791.206 us 12424960 us
blk_mq_sched_restart 1490 4786107 us 3212.153 us 1949753 us
blk_mq_sched_restart 7892 6039311 us 765.244 us 2994627 us
blk_mq_sched_restart 15382 7511126 us 488.306 us 3090912 us
[cut]
And here are results with two patches reverted:
8e8320c9315c ("blk-mq: fix performance regression with shared tags")
6d8c6c0f97ad ("blk-mq: Restart a single queue if tag sets are shared")
READ: io=12884MB, aggrb=1284.3MB/s, minb=1284.3MB/s, maxb=1284.3MB/s, mint=10032msec, maxt=10032msec
WRITE: io=12987MB, aggrb=1294.6MB/s, minb=1294.6MB/s, maxb=1294.6MB/s, mint=10032msec, maxt=10032msec
root@pserver16:~/roman# cat /sys/kernel/debug/tracing/trace_stat/* | grep blk_mq
Function Hit Time Avg s^2
-------- --- ---- --- ---
blk_mq_sched_restart 50699 8802.349 us 0.173 us 121.771 us
blk_mq_sched_restart 50362 8740.470 us 0.173 us 161.494 us
blk_mq_sched_restart 50402 9066.337 us 0.179 us 113.009 us
blk_mq_sched_restart 50104 9366.197 us 0.186 us 188.645 us
blk_mq_sched_restart 50375 9317.727 us 0.184 us 54.218 us
blk_mq_sched_restart 50136 9311.657 us 0.185 us 446.790 us
blk_mq_sched_restart 50103 9179.625 us 0.183 us 114.472 us
[cut]
Timings and stdevs are terrible, which leads to significant difference:
570MB/s vs 1280MB/s.
Signed-off-by: Roman Pen <roman.penyaev(a)profitbricks.com>
Cc: Christoph Hellwig <hch(a)lst.de>
Cc: Ming Lei <ming.lei(a)redhat.com>
Cc: Jianchao Wang <jianchao.w.wang(a)oracle.com>
Cc: Johannes Thumshirn <jthumshirn(a)suse.de>
Cc: Jack Wang <jack.wang.usish(a)gmail.com>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Bart Van Assche <bart.vanassche(a)wdc.com>
[ bvanassche: modified patch title, description and Cc-list ]
---
block/blk-mq-sched.c | 10 ++++------
block/blk-mq-tag.c | 1 +
block/blk-mq-tag.h | 1 +
block/blk-mq.c | 4 ++--
include/linux/blkdev.h | 2 --
5 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 56c493c6cd90..d863b1b32b07 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -60,10 +60,10 @@ static void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx)
return;
if (hctx->flags & BLK_MQ_F_TAG_SHARED) {
- struct request_queue *q = hctx->queue;
+ struct blk_mq_tags *tags = hctx->tags;
if (!test_and_set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
- atomic_inc(&q->shared_hctx_restart);
+ atomic_inc(&tags->shared_hctx_restart);
} else
set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
}
@@ -74,10 +74,8 @@ static bool blk_mq_sched_restart_hctx(struct blk_mq_hw_ctx *hctx)
return false;
if (hctx->flags & BLK_MQ_F_TAG_SHARED) {
- struct request_queue *q = hctx->queue;
-
if (test_and_clear_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
- atomic_dec(&q->shared_hctx_restart);
+ atomic_dec(&hctx->tags->shared_hctx_restart);
} else
clear_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
@@ -415,7 +413,7 @@ void blk_mq_sched_restart(struct blk_mq_hw_ctx *const hctx)
* If this is 0, then we know that no hardware queues
* have RESTART marked. We're done.
*/
- if (!atomic_read(&queue->shared_hctx_restart))
+ if (!atomic_read(&tags->shared_hctx_restart))
return;
rcu_read_lock();
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index 09b2ee6694fb..82cd73631adc 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -379,6 +379,7 @@ struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
tags->nr_tags = total_tags;
tags->nr_reserved_tags = reserved_tags;
+ atomic_set(&tags->shared_hctx_restart, 0);
return blk_mq_init_bitmap_tags(tags, node, alloc_policy);
}
diff --git a/block/blk-mq-tag.h b/block/blk-mq-tag.h
index 61deab0b5a5a..477a9d67fb3d 100644
--- a/block/blk-mq-tag.h
+++ b/block/blk-mq-tag.h
@@ -12,6 +12,7 @@ struct blk_mq_tags {
unsigned int nr_reserved_tags;
atomic_t active_queues;
+ atomic_t shared_hctx_restart;
struct sbitmap_queue bitmap_tags;
struct sbitmap_queue breserved_tags;
diff --git a/block/blk-mq.c b/block/blk-mq.c
index d394cdd8d8c6..a0fdf80db8fd 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2335,11 +2335,11 @@ static void queue_set_hctx_shared(struct request_queue *q, bool shared)
queue_for_each_hw_ctx(q, hctx, i) {
if (shared) {
if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
- atomic_inc(&q->shared_hctx_restart);
+ atomic_inc(&hctx->tags->shared_hctx_restart);
hctx->flags |= BLK_MQ_F_TAG_SHARED;
} else {
if (test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
- atomic_dec(&q->shared_hctx_restart);
+ atomic_dec(&hctx->tags->shared_hctx_restart);
hctx->flags &= ~BLK_MQ_F_TAG_SHARED;
}
}
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 79226ca8f80f..62b20da653ca 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -442,8 +442,6 @@ struct request_queue {
int nr_rqs[2]; /* # allocated [a]sync rqs */
int nr_rqs_elvpriv; /* # allocated rqs w/ elvpriv */
- atomic_t shared_hctx_restart;
-
struct blk_queue_stats *stats;
struct rq_wb *rq_wb;
--
2.18.0