lkml.org 
[lkml]   [2017]   [Jul]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.12 063/196] PCI/MSI: Ignore affinity if pre/post vector count is more than min_vecs
    Date
    4.12-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Michael Hernandez <michael.hernandez@cavium.com>

    commit 6f9a22bc5775d231ab8fbe2c2f3c88e45e3e7c28 upstream.

    min_vecs is the minimum amount of vectors needed to operate in MSI-X mode
    which may just include the vectors that don't need affinity.

    Disabling affinity settings causes the qla2xxx driver scsi_add_host() to fail
    when blk_mq is enabled as the blk_mq_pci_map_queues() expects affinity masks
    on each vector.

    Fixes: dfef358bd1be ("PCI/MSI: Don't apply affinity if there aren't enough vectors left")
    Signed-off-by: Michael Hernandez <michael.hernandez@cavium.com>
    Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/pci/msi.c | 14 ++------------
    include/linux/interrupt.h | 4 ++--
    kernel/irq/affinity.c | 13 ++++++++++++-
    3 files changed, 16 insertions(+), 15 deletions(-)

    --- a/drivers/pci/msi.c
    +++ b/drivers/pci/msi.c
    @@ -1058,7 +1058,7 @@ static int __pci_enable_msi_range(struct

    for (;;) {
    if (affd) {
    - nvec = irq_calc_affinity_vectors(nvec, affd);
    + nvec = irq_calc_affinity_vectors(minvec, nvec, affd);
    if (nvec < minvec)
    return -ENOSPC;
    }
    @@ -1097,7 +1097,7 @@ static int __pci_enable_msix_range(struc

    for (;;) {
    if (affd) {
    - nvec = irq_calc_affinity_vectors(nvec, affd);
    + nvec = irq_calc_affinity_vectors(minvec, nvec, affd);
    if (nvec < minvec)
    return -ENOSPC;
    }
    @@ -1165,16 +1165,6 @@ int pci_alloc_irq_vectors_affinity(struc
    if (flags & PCI_IRQ_AFFINITY) {
    if (!affd)
    affd = &msi_default_affd;
    -
    - if (affd->pre_vectors + affd->post_vectors > min_vecs)
    - return -EINVAL;
    -
    - /*
    - * If there aren't any vectors left after applying the pre/post
    - * vectors don't bother with assigning affinity.
    - */
    - if (affd->pre_vectors + affd->post_vectors == min_vecs)
    - affd = NULL;
    } else {
    if (WARN_ON(affd))
    affd = NULL;
    --- a/include/linux/interrupt.h
    +++ b/include/linux/interrupt.h
    @@ -291,7 +291,7 @@ extern int
    irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);

    struct cpumask *irq_create_affinity_masks(int nvec, const struct irq_affinity *affd);
    -int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd);
    +int irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd);

    #else /* CONFIG_SMP */

    @@ -331,7 +331,7 @@ irq_create_affinity_masks(int nvec, cons
    }

    static inline int
    -irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd)
    +irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd)
    {
    return maxvec;
    }
    --- a/kernel/irq/affinity.c
    +++ b/kernel/irq/affinity.c
    @@ -66,6 +66,13 @@ irq_create_affinity_masks(int nvecs, con
    struct cpumask *masks;
    cpumask_var_t nmsk;

    + /*
    + * If there aren't any vectors left after applying the pre/post
    + * vectors don't bother with assigning affinity.
    + */
    + if (!affv)
    + return NULL;
    +
    if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL))
    return NULL;

    @@ -140,15 +147,19 @@ out:

    /**
    * 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
    */
    -int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd)
    +int irq_calc_affinity_vectors(int minvec, int maxvec, const struct irq_affinity *affd)
    {
    int resv = affd->pre_vectors + affd->post_vectors;
    int vecs = maxvec - resv;
    int cpus;

    + if (resv > minvec)
    + return 0;
    +
    /* Stabilize the cpumasks */
    get_online_cpus();
    cpus = cpumask_weight(cpu_online_mask);

    \
     
     \ /
      Last update: 2017-07-25 21:59    [W:4.191 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site