mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 10:44:52 +01:00
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
127 lines
3.4 KiB
C
127 lines
3.4 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2016 Thomas Gleixner.
|
|
* Copyright (C) 2016-2017 Christoph Hellwig.
|
|
*/
|
|
#include <linux/interrupt.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/group_cpus.h>
|
|
|
|
static void default_calc_sets(struct irq_affinity *affd, unsigned int affvecs)
|
|
{
|
|
affd->nr_sets = 1;
|
|
affd->set_size[0] = affvecs;
|
|
}
|
|
|
|
/**
|
|
* irq_create_affinity_masks - Create affinity masks for multiqueue spreading
|
|
* @nvecs: The total number of vectors
|
|
* @affd: Description of the affinity requirements
|
|
*
|
|
* Returns the irq_affinity_desc pointer or NULL if allocation failed.
|
|
*/
|
|
struct irq_affinity_desc *
|
|
irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd)
|
|
{
|
|
unsigned int affvecs, curvec, usedvecs, i;
|
|
struct irq_affinity_desc *masks = NULL;
|
|
|
|
/*
|
|
* Determine the number of vectors which need interrupt affinities
|
|
* assigned. If the pre/post request exhausts the available vectors
|
|
* then nothing to do here except for invoking the calc_sets()
|
|
* callback so the device driver can adjust to the situation.
|
|
*/
|
|
if (nvecs > affd->pre_vectors + affd->post_vectors)
|
|
affvecs = nvecs - affd->pre_vectors - affd->post_vectors;
|
|
else
|
|
affvecs = 0;
|
|
|
|
/*
|
|
* Simple invocations do not provide a calc_sets() callback. Install
|
|
* the generic one.
|
|
*/
|
|
if (!affd->calc_sets)
|
|
affd->calc_sets = default_calc_sets;
|
|
|
|
/* Recalculate the sets */
|
|
affd->calc_sets(affd, affvecs);
|
|
|
|
if (WARN_ON_ONCE(affd->nr_sets > IRQ_AFFINITY_MAX_SETS))
|
|
return NULL;
|
|
|
|
/* Nothing to assign? */
|
|
if (!affvecs)
|
|
return NULL;
|
|
|
|
masks = kzalloc_objs(*masks, nvecs);
|
|
if (!masks)
|
|
return NULL;
|
|
|
|
/* Fill out vectors at the beginning that don't need affinity */
|
|
for (curvec = 0; curvec < affd->pre_vectors; curvec++)
|
|
cpumask_copy(&masks[curvec].mask, irq_default_affinity);
|
|
|
|
/*
|
|
* Spread on present CPUs starting from affd->pre_vectors. If we
|
|
* have multiple sets, build each sets affinity mask separately.
|
|
*/
|
|
for (i = 0, usedvecs = 0; i < affd->nr_sets; i++) {
|
|
unsigned int nr_masks, this_vecs = affd->set_size[i];
|
|
struct cpumask *result = group_cpus_evenly(this_vecs, &nr_masks);
|
|
|
|
if (!result) {
|
|
kfree(masks);
|
|
return NULL;
|
|
}
|
|
|
|
for (int j = 0; j < nr_masks; j++)
|
|
cpumask_copy(&masks[curvec + j].mask, &result[j]);
|
|
kfree(result);
|
|
|
|
curvec += nr_masks;
|
|
usedvecs += nr_masks;
|
|
}
|
|
|
|
/* Fill out vectors at the end that don't need affinity */
|
|
if (usedvecs >= affvecs)
|
|
curvec = affd->pre_vectors + affvecs;
|
|
else
|
|
curvec = affd->pre_vectors + usedvecs;
|
|
for (; curvec < nvecs; curvec++)
|
|
cpumask_copy(&masks[curvec].mask, irq_default_affinity);
|
|
|
|
/* Mark the managed interrupts */
|
|
for (i = affd->pre_vectors; i < nvecs - affd->post_vectors; i++)
|
|
masks[i].is_managed = 1;
|
|
|
|
return masks;
|
|
}
|
|
|
|
/**
|
|
* irq_calc_affinity_vectors - Calculate the optimal number of vectors
|
|
* @minvec: The minimum number of vectors available
|
|
* @maxvec: The maximum number of vectors available
|
|
* @affd: Description of the affinity requirements
|
|
*/
|
|
unsigned int irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec,
|
|
const struct irq_affinity *affd)
|
|
{
|
|
unsigned int resv = affd->pre_vectors + affd->post_vectors;
|
|
unsigned int set_vecs;
|
|
|
|
if (resv > minvec)
|
|
return 0;
|
|
|
|
if (affd->calc_sets) {
|
|
set_vecs = maxvec - resv;
|
|
} else {
|
|
cpus_read_lock();
|
|
set_vecs = cpumask_weight(cpu_possible_mask);
|
|
cpus_read_unlock();
|
|
}
|
|
|
|
return resv + min(set_vecs, maxvec - resv);
|
|
}
|