Commit 15b81ce5 authored by Ahmed S. Darwish's avatar Ahmed S. Darwish Committed by Jens Axboe

block: nr_sects_write(): Disable preemption on seqcount write

For optimized block readers not holding a mutex, the "number of sectors"
64-bit value is protected from tearing on 32-bit architectures by a
sequence counter.

Disable preemption before entering that sequence counter's write side
critical section. Otherwise, the read side can preempt the write side
section and spin for the entire scheduler tick. If the reader belongs to
a real-time scheduling class, it can spin forever and the kernel will
livelock.

Fixes: c83f6bf9 ("block: add partition resize function to blkpg ioctl")
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarAhmed S. Darwish <a.darwish@linutronix.de>
Reviewed-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent d24de76a
...@@ -420,9 +420,11 @@ static inline sector_t part_nr_sects_read(struct hd_struct *part) ...@@ -420,9 +420,11 @@ static inline sector_t part_nr_sects_read(struct hd_struct *part)
static inline void part_nr_sects_write(struct hd_struct *part, sector_t size) static inline void part_nr_sects_write(struct hd_struct *part, sector_t size)
{ {
#if BITS_PER_LONG==32 && defined(CONFIG_SMP) #if BITS_PER_LONG==32 && defined(CONFIG_SMP)
preempt_disable();
write_seqcount_begin(&part->nr_sects_seq); write_seqcount_begin(&part->nr_sects_seq);
part->nr_sects = size; part->nr_sects = size;
write_seqcount_end(&part->nr_sects_seq); write_seqcount_end(&part->nr_sects_seq);
preempt_enable();
#elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPTION) #elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPTION)
preempt_disable(); preempt_disable();
part->nr_sects = size; part->nr_sects = size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment