projects
/
linux.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
| inline |
side by side
(parent:
795fe54
)
blk-iocost: Fix incorrect operation order during iocg free
author
Tejun Heo
<tj@kernel.org>
Tue, 10 Sep 2019 16:15:25 +0000
(09:15 -0700)
committer
Jens Axboe
<axboe@kernel.dk>
Tue, 10 Sep 2019 18:17:04 +0000
(12:17 -0600)
ioc_pd_free() first cancels the hrtimers and then deactivates the
iocg. However, the iocg timer can run inbetween and reschedule the
hrtimers which will end up running after the iocg is freed leading to
crashes like the following.
general protection fault: 0000 [#1] SMP
...
RIP: 0010:iocg_kick_delay+0xbe/0x1b0
RSP: 0018:
ffffc90003598ea0
EFLAGS:
00010046
RAX:
1cee00fd69512b54
RBX:
ffff8881bba48400
RCX:
00000000000003e8
RDX:
0000000000000000
RSI:
0000000000000001
RDI:
ffff8881bba48400
RBP:
0000000000004e20
R08:
0000000000000002
R09:
00000000000003e8
R10:
0000000000000000
R11:
0000000000000000
R12:
ffffc90003598ef0
R13:
00979f3810ad461f
R14:
ffff8881bba4b400
R15:
25439f950d26e1d1
FS:
0000000000000000
(0000) GS:
ffff88885f800000
(0000) knlGS:
0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
CR2:
00007f64328c7e40
CR3:
0000000002409005
CR4:
00000000003606e0
DR0:
0000000000000000
DR1:
0000000000000000
DR2:
0000000000000000
DR3:
0000000000000000
DR6:
00000000fffe0ff0
DR7:
0000000000000400
Call Trace:
<IRQ>
iocg_delay_timer_fn+0x3d/0x60
__hrtimer_run_queues+0xfe/0x270
hrtimer_interrupt+0xf4/0x210
smp_apic_timer_interrupt+0x5e/0x120
apic_timer_interrupt+0xf/0x20
</IRQ>
Fix it by canceling hrtimers after deactivating the iocg.
Fixes: 7caa47151ab2 ("blkcg: implement blk-iocost")
Reported-by: Dave Jones <davej@codemonkey.org.uk>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-iocost.c
patch
|
blob
|
history
diff --git
a/block/blk-iocost.c
b/block/blk-iocost.c
index 2aae8ec391ef0c81bf7b449ecc78b2b1342d6891..7af350293c2f16cbd08e755673c952f13e6785e9 100644
(file)
--- a/
block/blk-iocost.c
+++ b/
block/blk-iocost.c
@@
-1957,15
+1957,15
@@
static void ioc_pd_free(struct blkg_policy_data *pd)
struct ioc *ioc = iocg->ioc;
if (ioc) {
- hrtimer_cancel(&iocg->waitq_timer);
- hrtimer_cancel(&iocg->delay_timer);
-
spin_lock(&ioc->lock);
if (!list_empty(&iocg->active_list)) {
propagate_active_weight(iocg, 0, 0);
list_del_init(&iocg->active_list);
}
spin_unlock(&ioc->lock);
+
+ hrtimer_cancel(&iocg->waitq_timer);
+ hrtimer_cancel(&iocg->delay_timer);
}
kfree(iocg);
}