Skip to content

Commit

Permalink
Merge branch 'for-4.9/block-irq' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull blk-mq irq/cpu mapping updates from Jens Axboe:
 "This is the block-irq topic branch for 4.9-rc. It's mostly from
  Christoph, and it allows drivers to specify their own mappings, and
  more importantly, to share the blk-mq mappings with the IRQ affinity
  mappings. It's a good step towards making this work better out of the
  box"

* 'for-4.9/block-irq' of git://git.kernel.dk/linux-block:
  blk_mq: linux/blk-mq.h does not include all the headers it depends on
  blk-mq: kill unused blk_mq_create_mq_map()
  blk-mq: get rid of the cpumask in struct blk_mq_tags
  nvme: remove the post_scan callout
  nvme: switch to use pci_alloc_irq_vectors
  blk-mq: provide a default queue mapping for PCI device
  blk-mq: allow the driver to pass in a queue mapping
  blk-mq: remove ->map_queue
  blk-mq: only allocate a single mq_map per tag_set
  blk-mq: don't redistribute hardware queues on a CPU hotplug event
  • Loading branch information
torvalds committed Oct 10, 2016
2 parents 48915c2 + 8ec2ef2 commit 12e3d3c
Show file tree
Hide file tree
Showing 27 changed files with 159 additions and 191 deletions.
5 changes: 5 additions & 0 deletions block/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,9 @@ config BLOCK_COMPAT
depends on BLOCK && COMPAT
default y

config BLK_MQ_PCI
bool
depends on BLOCK && PCI
default y

source block/Kconfig.iosched
2 changes: 1 addition & 1 deletion block/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o
obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o t10-pi.o

obj-$(CONFIG_BLK_MQ_PCI) += blk-mq-pci.o
6 changes: 3 additions & 3 deletions block/blk-flush.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ static void flush_end_io(struct request *flush_rq, int error)

/* release the tag's ownership to the req cloned from */
spin_lock_irqsave(&fq->mq_flush_lock, flags);
hctx = q->mq_ops->map_queue(q, flush_rq->mq_ctx->cpu);
hctx = blk_mq_map_queue(q, flush_rq->mq_ctx->cpu);
blk_mq_tag_set_rq(hctx, flush_rq->tag, fq->orig_rq);
flush_rq->tag = -1;
}
Expand Down Expand Up @@ -325,7 +325,7 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq)
flush_rq->tag = first_rq->tag;
fq->orig_rq = first_rq;

hctx = q->mq_ops->map_queue(q, first_rq->mq_ctx->cpu);
hctx = blk_mq_map_queue(q, first_rq->mq_ctx->cpu);
blk_mq_tag_set_rq(hctx, first_rq->tag, flush_rq);
}

Expand Down Expand Up @@ -358,7 +358,7 @@ static void mq_flush_data_end_io(struct request *rq, int error)
unsigned long flags;
struct blk_flush_queue *fq = blk_get_flush_queue(q, ctx);

hctx = q->mq_ops->map_queue(q, ctx->cpu);
hctx = blk_mq_map_queue(q, ctx->cpu);

/*
* After populating an empty queue, kick it to avoid stall. Read
Expand Down
25 changes: 5 additions & 20 deletions block/blk-mq-cpumap.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@ static int get_first_sibling(unsigned int cpu)
return cpu;
}

int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues,
const struct cpumask *online_mask)
int blk_mq_map_queues(struct blk_mq_tag_set *set)
{
unsigned int *map = set->mq_map;
unsigned int nr_queues = set->nr_hw_queues;
const struct cpumask *online_mask = cpu_online_mask;
unsigned int i, nr_cpus, nr_uniq_cpus, queue, first_sibling;
cpumask_var_t cpus;

if (!alloc_cpumask_var(&cpus, GFP_ATOMIC))
return 1;
return -ENOMEM;

cpumask_clear(cpus);
nr_cpus = nr_uniq_cpus = 0;
Expand Down Expand Up @@ -86,23 +88,6 @@ int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues,
return 0;
}

unsigned int *blk_mq_make_queue_map(struct blk_mq_tag_set *set)
{
unsigned int *map;

/* If cpus are offline, map them to first hctx */
map = kzalloc_node(sizeof(*map) * nr_cpu_ids, GFP_KERNEL,
set->numa_node);
if (!map)
return NULL;

if (!blk_mq_update_queue_map(map, set->nr_hw_queues, cpu_online_mask))
return map;

kfree(map);
return NULL;
}

/*
* We have no quick way of doing reverse lookups. This is only used at
* queue init time, so runtime isn't important.
Expand Down
47 changes: 47 additions & 0 deletions block/blk-mq-pci.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2016 Christoph Hellwig.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/kobject.h>
#include <linux/blkdev.h>
#include <linux/blk-mq.h>
#include <linux/blk-mq-pci.h>
#include <linux/pci.h>
#include <linux/module.h>

/**
* blk_mq_pci_map_queues - provide a default queue mapping for PCI device
* @set: tagset to provide the mapping for
* @pdev: PCI device associated with @set.
*
* This function assumes the PCI device @pdev has at least as many available
* interrupt vetors as @set has queues. It will then queuery the vector
* corresponding to each queue for it's affinity mask and built queue mapping
* that maps a queue to the CPUs that have irq affinity for the corresponding
* vector.
*/
int blk_mq_pci_map_queues(struct blk_mq_tag_set *set, struct pci_dev *pdev)
{
const struct cpumask *mask;
unsigned int queue, cpu;

for (queue = 0; queue < set->nr_hw_queues; queue++) {
mask = pci_irq_get_affinity(pdev, queue);
if (!mask)
return -EINVAL;

for_each_cpu(cpu, mask)
set->mq_map[cpu] = queue;
}

return 0;
}
EXPORT_SYMBOL_GPL(blk_mq_pci_map_queues);
11 changes: 2 additions & 9 deletions block/blk-mq-tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,7 @@ static int bt_get(struct blk_mq_alloc_data *data, struct sbitmap_queue *bt,
io_schedule();

data->ctx = blk_mq_get_ctx(data->q);
data->hctx = data->q->mq_ops->map_queue(data->q,
data->ctx->cpu);
data->hctx = blk_mq_map_queue(data->q, data->ctx->cpu);
if (data->flags & BLK_MQ_REQ_RESERVED) {
bt = &data->hctx->tags->breserved_tags;
} else {
Expand Down Expand Up @@ -399,11 +398,6 @@ struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
if (!tags)
return NULL;

if (!zalloc_cpumask_var(&tags->cpumask, GFP_KERNEL)) {
kfree(tags);
return NULL;
}

tags->nr_tags = total_tags;
tags->nr_reserved_tags = reserved_tags;

Expand All @@ -414,7 +408,6 @@ void blk_mq_free_tags(struct blk_mq_tags *tags)
{
sbitmap_queue_free(&tags->bitmap_tags);
sbitmap_queue_free(&tags->breserved_tags);
free_cpumask_var(tags->cpumask);
kfree(tags);
}

Expand Down Expand Up @@ -453,7 +446,7 @@ u32 blk_mq_unique_tag(struct request *rq)
int hwq = 0;

if (q->mq_ops) {
hctx = q->mq_ops->map_queue(q, rq->mq_ctx->cpu);
hctx = blk_mq_map_queue(q, rq->mq_ctx->cpu);
hwq = hctx->queue_num;
}

Expand Down
2 changes: 0 additions & 2 deletions block/blk-mq-tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ struct blk_mq_tags {

struct request **rqs;
struct list_head page_list;

cpumask_var_t cpumask;
};


Expand Down
Loading

0 comments on commit 12e3d3c

Please sign in to comment.