Re: [PATCH 8/8] IB/srp: Add multichannel support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 09/19/14 17:38, Jens Axboe wrote:
> ctx was meant to be private, unfortunately it's leaked a bit into other
> parts of block/. But it's still private within that, at least.
> 
> Lets not add more stuff to struct request, it's already way too large.
> We could add an exported
> 
> struct blk_mq_hw_ctx *blk_mq_request_to_hctx(struct request *rq)
> {
> 	struct request_queue *q = rq->q;
> 
> 	return q->mq_ops->map_queue(q, rq->mq_ctx->cpu);
> }
> 
> for this.

How about the patch below ? That patch makes it easy for SCSI LLDs to obtain
the hardware context index.
 
[PATCH] blk-mq: Add blk_get_mq_tag()

The queuecommand() callback functions in SCSI low-level drivers
must know which hardware context has been selected by the block
layer. Since passing the hctx pointer directly to the queuecommand
callback function would require modification of all SCSI LLDs,
add a function to the block layer that allows to query the hardware
context index.

Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx>
---
 block/blk-mq-tag.c     | 24 ++++++++++++++++++++++++
 include/linux/blk-mq.h | 16 ++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index c1b9242..5618759 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -595,6 +595,30 @@ int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int tdepth)
 	return 0;
 }
 
+/**
+ * blk_get_mq_tag() - return a tag that is unique queue-wide
+ *
+ * The tag field in struct request is unique per hardware queue but not
+ * queue-wide. Hence this function. It is not only safe to use this function
+ * for multiqueue request queues but also for single-queue request queues.
+ * Note: rq->tag == -1 if tagging is not enabled for single-queue request
+ * queues.
+ */
+struct blk_mq_tag blk_get_mq_tag(struct request *rq)
+{
+	struct request_queue *q = rq->q;
+	struct blk_mq_tag tag = { rq->tag & ((1 << 16) - 1) };
+	struct blk_mq_hw_ctx *hctx;
+
+	if (q->mq_ops) {
+		hctx = q->mq_ops->map_queue(q, rq->mq_ctx->cpu);
+		tag.tag |= hctx->queue_num << 16;
+	}
+
+	return tag;
+}
+EXPORT_SYMBOL(blk_get_mq_tag);
+
 ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page)
 {
 	char *orig_page = page;
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index eac4f31..eb419bc 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -88,6 +88,13 @@ struct blk_mq_tag_set {
 	struct list_head	tag_list;
 };
 
+/**
+ * struct blk_mq_tag - hardware queue index and per-queue tag
+ */
+struct blk_mq_tag {
+	u32 tag;
+};
+
 typedef int (queue_rq_fn)(struct blk_mq_hw_ctx *, struct request *);
 typedef struct blk_mq_hw_ctx *(map_queue_fn)(struct request_queue *, const int);
 typedef int (init_hctx_fn)(struct blk_mq_hw_ctx *, void *, unsigned int);
@@ -166,6 +173,15 @@ bool blk_mq_can_queue(struct blk_mq_hw_ctx *);
 struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
 		gfp_t gfp, bool reserved);
 struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag);
+struct blk_mq_tag blk_get_mq_tag(struct request *rq);
+static inline u16 blk_mq_tag_to_hwq(struct blk_mq_tag t)
+{
+	return t.tag >> 16;
+}
+static inline u16 blk_mq_tag_to_tag(struct blk_mq_tag t)
+{
+	return t.tag & ((1 << 16) - 1);
+}
 
 struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index);
 struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int);
-- 
1.8.4.5


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux