Thread (36 messages) 36 messages, 4 authors, 2017-08-05

Re: [PATCH 03/14] blk-mq: introduce blk_mq_dispatch_rq_from_ctxs()

From: Bart Van Assche <hidden>
Date: 2017-07-31 23:10:25
Also in: linux-scsi

On Tue, 2017-08-01 at 00:51 +0800, Ming Lei wrote:
quoted hunk ↗ jump to hunk
@@ -810,7 +810,11 @@ static void blk_mq_timeout_work(struct work_struct *=
work)
=20
 struct ctx_iter_data {
 	struct blk_mq_hw_ctx *hctx;
-	struct list_head *list;
+
+	union {
+		struct list_head *list;
+		struct request *rq;
+	};
 };
Hello Ming,

Please introduce a new data structure for dispatch_rq_from_ctx() /
blk_mq_dispatch_rq_from_ctxs() instead of introducing a union in struct
ctx_iter_data. That will avoid that .list can be used in a context where
a struct request * pointer has been stored in the structure and vice versa.
=20
 static bool flush_busy_ctx(struct sbitmap *sb, unsigned int bitnr, void =
*data)
quoted hunk ↗ jump to hunk
@@ -826,6 +830,26 @@ static bool flush_busy_ctx(struct sbitmap *sb, unsig=
ned int bitnr, void *data)
 	return true;
 }
=20
+static bool dispatch_rq_from_ctx(struct sbitmap *sb, unsigned int bitnr,=
 void *data)
+{
+	struct ctx_iter_data *dispatch_data =3D data;
+	struct blk_mq_hw_ctx *hctx =3D dispatch_data->hctx;
+	struct blk_mq_ctx *ctx =3D hctx->ctxs[bitnr];
+	bool empty =3D true;
+
+	spin_lock(&ctx->lock);
+	if (unlikely(!list_empty(&ctx->rq_list))) {
+		dispatch_data->rq =3D list_entry_rq(ctx->rq_list.next);
+		list_del_init(&dispatch_data->rq->queuelist);
+		empty =3D list_empty(&ctx->rq_list);
+	}
+	spin_unlock(&ctx->lock);
+	if (empty)
+		sbitmap_clear_bit(sb, bitnr);
This sbitmap_clear_bit() occurs without holding blk_mq_ctx.lock. Sorry but
I don't think this is safe. Please either remove this sbitmap_clear_bit() c=
all
or make sure that it happens with blk_mq_ctx.lock held.

Thanks,

Bart.=
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help