summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0180-block-mq-don-t-complete-requests-via-IPI.patch
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/patches-rt/0180-block-mq-don-t-complete-requests-via-IPI.patch119
1 files changed, 119 insertions, 0 deletions
diff --git a/debian/patches-rt/0180-block-mq-don-t-complete-requests-via-IPI.patch b/debian/patches-rt/0180-block-mq-don-t-complete-requests-via-IPI.patch
new file mode 100644
index 000000000..b29ad2ead
--- /dev/null
+++ b/debian/patches-rt/0180-block-mq-don-t-complete-requests-via-IPI.patch
@@ -0,0 +1,119 @@
+From 229760413c4138a40587def4f9420bdb432fa502 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Thu, 29 Jan 2015 15:10:08 +0100
+Subject: [PATCH 180/347] block/mq: don't complete requests via IPI
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.246-rt110.tar.xz
+
+The IPI runs in hardirq context and there are sleeping locks. This patch
+moves the completion into a workqueue.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ block/blk-core.c | 3 +++
+ block/blk-mq.c | 23 +++++++++++++++++++++++
+ include/linux/blk-mq.h | 2 +-
+ include/linux/blkdev.h | 3 +++
+ 4 files changed, 30 insertions(+), 1 deletion(-)
+
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 80f3e729fdd4..461a93c08c14 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -189,6 +189,9 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
+
+ INIT_LIST_HEAD(&rq->queuelist);
+ INIT_LIST_HEAD(&rq->timeout_list);
++#ifdef CONFIG_PREEMPT_RT_FULL
++ INIT_WORK(&rq->work, __blk_mq_complete_request_remote_work);
++#endif
+ rq->cpu = -1;
+ rq->q = q;
+ rq->__sector = (sector_t) -1;
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index ea41d67e4db5..0f8dcb68b8a8 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -320,6 +320,9 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data,
+ rq->extra_len = 0;
+ rq->__deadline = 0;
+
++#ifdef CONFIG_PREEMPT_RT_FULL
++ INIT_WORK(&rq->work, __blk_mq_complete_request_remote_work);
++#endif
+ INIT_LIST_HEAD(&rq->timeout_list);
+ rq->timeout = 0;
+
+@@ -547,12 +550,24 @@ void blk_mq_end_request(struct request *rq, blk_status_t error)
+ }
+ EXPORT_SYMBOL(blk_mq_end_request);
+
++#ifdef CONFIG_PREEMPT_RT_FULL
++
++void __blk_mq_complete_request_remote_work(struct work_struct *work)
++{
++ struct request *rq = container_of(work, struct request, work);
++
++ rq->q->softirq_done_fn(rq);
++}
++
++#else
++
+ static void __blk_mq_complete_request_remote(void *data)
+ {
+ struct request *rq = data;
+
+ rq->q->softirq_done_fn(rq);
+ }
++#endif
+
+ static void __blk_mq_complete_request(struct request *rq)
+ {
+@@ -575,10 +590,18 @@ static void __blk_mq_complete_request(struct request *rq)
+ shared = cpus_share_cache(cpu, ctx->cpu);
+
+ if (cpu != ctx->cpu && !shared && cpu_online(ctx->cpu)) {
++#ifdef CONFIG_PREEMPT_RT_FULL
++ /*
++ * We could force QUEUE_FLAG_SAME_FORCE then we would not get in
++ * here. But we could try to invoke it one the CPU like this.
++ */
++ schedule_work_on(ctx->cpu, &rq->work);
++#else
+ rq->csd.func = __blk_mq_complete_request_remote;
+ rq->csd.info = rq;
+ rq->csd.flags = 0;
+ smp_call_function_single_async(ctx->cpu, &rq->csd);
++#endif
+ } else {
+ rq->q->softirq_done_fn(rq);
+ }
+diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
+index 2885dce1ad49..8dbb9ecf9993 100644
+--- a/include/linux/blk-mq.h
++++ b/include/linux/blk-mq.h
+@@ -256,7 +256,7 @@ static inline u16 blk_mq_unique_tag_to_tag(u32 unique_tag)
+ return unique_tag & BLK_MQ_UNIQUE_TAG_MASK;
+ }
+
+-
++void __blk_mq_complete_request_remote_work(struct work_struct *work);
+ int blk_mq_request_started(struct request *rq);
+ void blk_mq_start_request(struct request *rq);
+ void blk_mq_end_request(struct request *rq, blk_status_t error);
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 56fe682d9beb..39d90bf9b5fa 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -157,6 +157,9 @@ enum mq_rq_state {
+ */
+ struct request {
+ struct request_queue *q;
++#ifdef CONFIG_PREEMPT_RT_FULL
++ struct work_struct work;
++#endif
+ struct blk_mq_ctx *mq_ctx;
+
+ int cpu;
+--
+2.36.1
+