mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
mtd: block: prevent reclaim I/O during request processing
The blktrans request callbacks run under dev->lock and may allocate memory with GFP_KERNEL. For example, mtdblock_writesect() uses vmalloc() to allocate its eraseblock cache. Direct reclaim can then recurse into block I/O and deadlock on resources held by the request being processed. syzbot reports a circular locking dependency involving the device mutex and fs_reclaim. Commitd5ba1c8ffd("mtd: don't use PF_MEMALLOC") removed PF_MEMALLOC from the MTD request thread. That flag had prevented direct reclaim, so its removal made allocations during request processing eligible for reclaim without excluding I/O. Wrap request processing in mtd_queue_rq() in a NOIO scope. This covers both the request and background callbacks, including allocations made by lower MTD drivers, and prevents reclaim from initiating filesystem or block I/O. Fixes:d5ba1c8ffd("mtd: don't use PF_MEMALLOC") Assisted-by: Codex:gpt-6-astra Reported-by: syzbot+e08e0a15269eefa87790@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=e08e0a15269eefa87790 Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
parent
30c70e01f7
commit
d498b2ddda
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sched/mm.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include "mtdcore.h"
|
||||
|
|
@ -167,6 +168,7 @@ static blk_status_t mtd_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||
const struct blk_mq_queue_data *bd)
|
||||
{
|
||||
struct mtd_blktrans_dev *dev;
|
||||
unsigned int noio_flags;
|
||||
|
||||
dev = hctx->queue->queuedata;
|
||||
if (!dev) {
|
||||
|
|
@ -174,10 +176,13 @@ static blk_status_t mtd_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||
return BLK_STS_IOERR;
|
||||
}
|
||||
|
||||
/* Reclaim must not recurse into I/O while processing requests. */
|
||||
noio_flags = memalloc_noio_save();
|
||||
spin_lock_irq(&dev->queue_lock);
|
||||
list_add_tail(&bd->rq->queuelist, &dev->rq_list);
|
||||
mtd_blktrans_work(dev);
|
||||
spin_unlock_irq(&dev->queue_lock);
|
||||
memalloc_noio_restore(noio_flags);
|
||||
|
||||
return BLK_STS_OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user