[PATCH V3 02/10] blk-mq: Introduce blk_mq_dev_map_queues
Ming Lei
ming.lei at redhat.com
Fri Jul 9 01:09:57 PDT 2021
Introduce blk_mq_dev_map_queues so that we can remove all kinds of
map_queues implementation(pci, virtio, rdma, ...) out of block layer.
Signed-off-by: Ming Lei <ming.lei at redhat.com>
---
block/blk-mq-map.c | 53 ++++++++++++++++++++++++++++++++++++++++++
include/linux/blk-mq.h | 5 ++++
2 files changed, 58 insertions(+)
diff --git a/block/blk-mq-map.c b/block/blk-mq-map.c
index 3db84d3197f1..e3ba2ef1e9e2 100644
--- a/block/blk-mq-map.c
+++ b/block/blk-mq-map.c
@@ -94,3 +94,56 @@ int blk_mq_hw_queue_to_node(struct blk_mq_queue_map *qmap, unsigned int index)
return NUMA_NO_NODE;
}
+
+/**
+ * blk_mq_dev_map_queues - provide generic queue mapping
+ * @qmap: CPU to hardware queue map.
+ * @dev_off: Offset to use for the device
+ * @get_queue_affinity: Callback to retrieve queue affinity
+ * @dev_data: Device data passed to get_queue_affinity()
+ * @fallback: If true, fallback to default blk-mq mapping in case of
+ * any failure
+ *
+ * Generic function to setup each queue mapping in @qmap. It will query
+ * each queue's affinity via @get_queue_affinity and built queue mapping
+ * that maps a queue to the CPUs in the queue affinity.
+ *
+ * Driver has to set correct @dev_data, so that the driver callback
+ * of @get_queue_affinity can work correctly.
+ */
+int blk_mq_dev_map_queues(struct blk_mq_queue_map *qmap, void *dev_data,
+ int dev_off, get_queue_affinty_fn *get_queue_affinity,
+ bool fallback)
+{
+ const struct cpumask *mask;
+ unsigned int queue, cpu;
+
+ /*
+ * fallback to default mapping if driver doesn't provide
+ * get_queue_affinity callback
+ */
+ if (!get_queue_affinity) {
+ fallback = true;
+ goto fallback;
+ }
+
+ for (queue = 0; queue < qmap->nr_queues; queue++) {
+ mask = get_queue_affinity(dev_data, dev_off, queue);
+ if (!mask)
+ goto fallback;
+
+ for_each_cpu(cpu, mask)
+ qmap->mq_map[cpu] = qmap->queue_offset + queue;
+ }
+
+ return 0;
+
+fallback:
+ if (!fallback) {
+ WARN_ON_ONCE(qmap->nr_queues > 1);
+ blk_mq_clear_mq_map(qmap);
+ return 0;
+ }
+ return blk_mq_map_queues(qmap);
+}
+EXPORT_SYMBOL_GPL(blk_mq_dev_map_queues);
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index fd2de2b422ed..b6090d691594 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -553,7 +553,12 @@ void blk_mq_freeze_queue_wait(struct request_queue *q);
int blk_mq_freeze_queue_wait_timeout(struct request_queue *q,
unsigned long timeout);
+typedef const struct cpumask * (get_queue_affinty_fn)(void *dev_data,
+ int dev_off, int queue_idx);
int blk_mq_map_queues(struct blk_mq_queue_map *qmap);
+int blk_mq_dev_map_queues(struct blk_mq_queue_map *qmap, void *dev_data,
+ int dev_off, get_queue_affinty_fn *get_queue_affinity,
+ bool fallback);
void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues);
void blk_mq_quiesce_queue_nowait(struct request_queue *q);
--
2.31.1
More information about the Linux-nvme
mailing list