162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * CPU <-> hardware queue mapping helpers 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2013-2014 Jens Axboe 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#include <linux/kernel.h> 862306a36Sopenharmony_ci#include <linux/threads.h> 962306a36Sopenharmony_ci#include <linux/module.h> 1062306a36Sopenharmony_ci#include <linux/mm.h> 1162306a36Sopenharmony_ci#include <linux/smp.h> 1262306a36Sopenharmony_ci#include <linux/cpu.h> 1362306a36Sopenharmony_ci#include <linux/group_cpus.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "blk.h" 1662306a36Sopenharmony_ci#include "blk-mq.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_civoid blk_mq_map_queues(struct blk_mq_queue_map *qmap) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci const struct cpumask *masks; 2162306a36Sopenharmony_ci unsigned int queue, cpu; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci masks = group_cpus_evenly(qmap->nr_queues); 2462306a36Sopenharmony_ci if (!masks) { 2562306a36Sopenharmony_ci for_each_possible_cpu(cpu) 2662306a36Sopenharmony_ci qmap->mq_map[cpu] = qmap->queue_offset; 2762306a36Sopenharmony_ci return; 2862306a36Sopenharmony_ci } 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci for (queue = 0; queue < qmap->nr_queues; queue++) { 3162306a36Sopenharmony_ci for_each_cpu(cpu, &masks[queue]) 3262306a36Sopenharmony_ci qmap->mq_map[cpu] = qmap->queue_offset + queue; 3362306a36Sopenharmony_ci } 3462306a36Sopenharmony_ci kfree(masks); 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(blk_mq_map_queues); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/** 3962306a36Sopenharmony_ci * blk_mq_hw_queue_to_node - Look up the memory node for a hardware queue index 4062306a36Sopenharmony_ci * @qmap: CPU to hardware queue map. 4162306a36Sopenharmony_ci * @index: hardware queue index. 4262306a36Sopenharmony_ci * 4362306a36Sopenharmony_ci * We have no quick way of doing reverse lookups. This is only used at 4462306a36Sopenharmony_ci * queue init time, so runtime isn't important. 4562306a36Sopenharmony_ci */ 4662306a36Sopenharmony_ciint blk_mq_hw_queue_to_node(struct blk_mq_queue_map *qmap, unsigned int index) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci int i; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci for_each_possible_cpu(i) { 5162306a36Sopenharmony_ci if (index == qmap->mq_map[i]) 5262306a36Sopenharmony_ci return cpu_to_node(i); 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci return NUMA_NO_NODE; 5662306a36Sopenharmony_ci} 57